From ecdcc4f2dd93b21412ffbbe918a07a4a52bdcb4b Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 13 Apr 2026 01:38:21 +0900 Subject: [PATCH 01/27] Import ESP32-P4 support files from florianL21/esp32p4-support Cherry-picked new files only (no conflicting modifications) from florianL21's esp32p4-support branch (commit 606f0060). Includes: - Linker scripts (esp32p4.x, memory.x, linkall.x) - eFuse field definitions - RTC control and sleep mode support - SoC clock definitions and regi2c - Generated metadata for esp32p4 - ROM linker scripts (including eco5/P4X variants) - Radio clocks low-level (relocated to esp-radio/) These files need verification against ESP32-P4X (chip rev v3.1+) datasheet and TRM. P4X has significant silicon differences from earlier P4 revisions (eco4/NRND). Based on work by FlorianL21 <6053565+florianL21@users.noreply.github.com> --- esp-hal/ld/esp32p4/esp32p4.x | 74 + esp-hal/ld/esp32p4/linkall.x | 13 + esp-hal/ld/esp32p4/memory.x | 26 + esp-hal/src/efuse/esp32p4/fields.rs | 608 +++ esp-hal/src/efuse/esp32p4/mod.rs | 63 + esp-hal/src/rtc_cntl/rtc/esp32p4.rs | 1084 +++++ esp-hal/src/rtc_cntl/sleep/esp32p4.rs | 1064 +++++ esp-hal/src/soc/esp32p4/clocks.rs | 345 ++ esp-hal/src/soc/esp32p4/mod.rs | 26 + esp-hal/src/soc/esp32p4/regi2c.rs | 9 + .../src/_generated_esp32p4.rs | 3549 +++++++++++++++++ .../src/radio_clocks/clocks_ll/esp32p4.rs | 53 + esp-rom-sys/ld/esp32p4/libesp_rom_sys.a | 1 + esp-rom-sys/ld/esp32p4/rom-functions.x | 10 + esp-rom-sys/ld/esp32p4/rom/additional.ld | 12 + esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.api.ld | 67 + .../ld/esp32p4/rom/esp32p4.rom.eco5.ld | 592 +++ .../ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld | 95 + .../ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld | 101 + esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld | 585 +++ .../ld/esp32p4/rom/esp32p4.rom.libgcc.ld | 95 + .../ld/esp32p4/rom/esp32p4.rom.rvfp.ld | 116 + .../ld/esp32p4/rom/esp32p4.rom.version.ld | 14 + esp-rom-sys/libs/esp32p4/unused | 0 24 files changed, 8602 insertions(+) create mode 100644 esp-hal/ld/esp32p4/esp32p4.x create mode 100644 esp-hal/ld/esp32p4/linkall.x create mode 100644 esp-hal/ld/esp32p4/memory.x create mode 100644 esp-hal/src/efuse/esp32p4/fields.rs create mode 100644 esp-hal/src/efuse/esp32p4/mod.rs create mode 100644 esp-hal/src/rtc_cntl/rtc/esp32p4.rs create mode 100644 esp-hal/src/rtc_cntl/sleep/esp32p4.rs create mode 100644 esp-hal/src/soc/esp32p4/clocks.rs create mode 100644 esp-hal/src/soc/esp32p4/mod.rs create mode 100644 esp-hal/src/soc/esp32p4/regi2c.rs create mode 100644 esp-metadata-generated/src/_generated_esp32p4.rs create mode 100644 esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs create mode 100644 esp-rom-sys/ld/esp32p4/libesp_rom_sys.a create mode 100644 esp-rom-sys/ld/esp32p4/rom-functions.x create mode 100644 esp-rom-sys/ld/esp32p4/rom/additional.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.api.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld create mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.version.ld create mode 100644 esp-rom-sys/libs/esp32p4/unused diff --git a/esp-hal/ld/esp32p4/esp32p4.x b/esp-hal/ld/esp32p4/esp32p4.x new file mode 100644 index 00000000000..552d4aa7e8a --- /dev/null +++ b/esp-hal/ld/esp32p4/esp32p4.x @@ -0,0 +1,74 @@ +ENTRY(_start) + +PROVIDE(_stext = ORIGIN(ROTEXT)); +PROVIDE(_max_hart_id = 1); + +PROVIDE(UserSoft = DefaultHandler); +PROVIDE(SupervisorSoft = DefaultHandler); +PROVIDE(MachineSoft = DefaultHandler); +PROVIDE(UserTimer = DefaultHandler); +PROVIDE(SupervisorTimer = DefaultHandler); +PROVIDE(MachineTimer = DefaultHandler); +PROVIDE(UserExternal = DefaultHandler); +PROVIDE(SupervisorExternal = DefaultHandler); +PROVIDE(MachineExternal = DefaultHandler); + +PROVIDE(ExceptionHandler = DefaultExceptionHandler); + +/* The ESP32-C2 and ESP32-C3 have interrupt IDs 1-31, while the ESP32-C6, + ESP32-H2, and ESP32-P4 have IDs 0-31, so we much define the handler for the + one additional interrupt ID: */ +PROVIDE(interrupt0 = DefaultHandler); + +PROVIDE(__post_init = default_post_init); + +/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ +PROVIDE(_setup_interrupts = default_setup_interrupts); + +/* # Multi-processing hook function + fn _mp_hook() -> bool; + This function is called from all the harts and must return true only for one hart, + which will perform memory initialization. For other harts it must return false + and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt). +*/ +PROVIDE(_mp_hook = default_mp_hook); + +/* # Start trap function override + By default uses the riscv crates default trap handler + but by providing the `_start_trap` symbol external crates can override. +*/ +PROVIDE(_start_trap = default_start_trap); + +/* Must be called __global_pointer$ for linker relaxations to work. */ +PROVIDE(__global_pointer$ = _data_start + 0x800); + +SECTIONS { + .trap : ALIGN(4) + { + KEEP(*(.trap)); + *(.trap.*); + } > RWTEXT +} +INSERT BEFORE .rwtext; + +SECTIONS { + /** + * Bootloader really wants to have separate segments for ROTEXT and RODATA + * It also needs to be located in a separate 64k flash segment. + */ + .text_gap (NOLOAD): { + . = ALIGN(0x10000) + 0x20; + } > ROM +} +INSERT BEFORE .rodata; + +/* Shared sections - ordering matters */ +INCLUDE "text.x" +INCLUDE "rwtext.x" +INCLUDE "rodata.x" +INCLUDE "rwdata.x" +INCLUDE "rtc_fast.x" +INCLUDE "stack.x" +/* End of Shared sections */ + +INCLUDE "debug.x" \ No newline at end of file diff --git a/esp-hal/ld/esp32p4/linkall.x b/esp-hal/ld/esp32p4/linkall.x new file mode 100644 index 00000000000..e542fd602de --- /dev/null +++ b/esp-hal/ld/esp32p4/linkall.x @@ -0,0 +1,13 @@ +INCLUDE "memory.x" + +REGION_ALIAS("ROTEXT", ROM); +REGION_ALIAS("RODATA", ROM); + +REGION_ALIAS("RWTEXT", RAM); +REGION_ALIAS("RWDATA", RAM); + +REGION_ALIAS("RTC_FAST_RWTEXT", RTC_FAST); +REGION_ALIAS("RTC_FAST_RWDATA", RTC_FAST); + +INCLUDE "esp32p4.x" +INCLUDE "hal-defaults.x" \ No newline at end of file diff --git a/esp-hal/ld/esp32p4/memory.x b/esp-hal/ld/esp32p4/memory.x new file mode 100644 index 00000000000..b972e30be3e --- /dev/null +++ b/esp-hal/ld/esp32p4/memory.x @@ -0,0 +1,26 @@ +MEMORY +{ + /* MEMORY_MAP = [ + [0x00000000, 0x00010000, "PADDING"], + [0x40000000, 0x4C000000, "DROM"], + [0x4FF00000, 0x4FFA0000, "DRAM"], + [0x4FF00000, 0x4FFA0000, "BYTE_ACCESSIBLE"], + [0x4FC00000, 0x4FC20000, "DROM_MASK"], + [0x4FC00000, 0x4FC20000, "IROM_MASK"], + [0x40000000, 0x4C000000, "IROM"], + [0x4FF00000, 0x4FFA0000, "IRAM"], + [0x50108000, 0x50110000, "RTC_IRAM"], + [0x50108000, 0x50110000, "RTC_DRAM"], + [0x600FE000, 0x60100000, "MEM_INTERNAL2"], + ] */ + + /* 768K of on soc RAM */ + RAM : ORIGIN = 0x4FF00000, LENGTH = 0xC0000 + + /* External flash */ + /* Instruction and Data ROM */ + ROM : ORIGIN = 0x40000000 + 0x20, LENGTH = 0x400000 - 0x20 + + /* RTC fast memory (executable). Persists over deep sleep. */ + RTC_FAST : ORIGIN = 0x50108000, LENGTH = 32K /*- ESP_BOOTLOADER_RESERVE_RTC*/ +} \ No newline at end of file diff --git a/esp-hal/src/efuse/esp32p4/fields.rs b/esp-hal/src/efuse/esp32p4/fields.rs new file mode 100644 index 00000000000..f9223d68c89 --- /dev/null +++ b/esp-hal/src/efuse/esp32p4/fields.rs @@ -0,0 +1,608 @@ +//! eFuse fields for the ESP32-P4. +//! +//! This file was automatically generated, please do not edit it manually! +//! +//! For information on how to regenerate these files, please refer to the +//! `xtask` package's `README.md` file. +//! +//! Generated on: 2024-03-11 +//! ESP-IDF Commit: 0de2912f +use crate::efuse::EfuseField; + +/// `[]` Disable programming of individual eFuses +pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32); +/// `[]` wr_dis of RD_DIS +pub const WR_DIS_RD_DIS: EfuseField = EfuseField::new(0, 0, 0, 1); +/// `[]` wr_dis of KM_RND_SWITCH_CYCLE +pub const WR_DIS_KM_RND_SWITCH_CYCLE: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of KM_DEPLOY_ONLY_ONCE +pub const WR_DIS_KM_DEPLOY_ONLY_ONCE: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of FORCE_USE_KEY_MANAGER_KEY +pub const WR_DIS_FORCE_USE_KEY_MANAGER_KEY: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of FORCE_DISABLE_SW_INIT_KEY +pub const WR_DIS_FORCE_DISABLE_SW_INIT_KEY: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of KM_XTS_KEY_LENGTH_256 +pub const WR_DIS_KM_XTS_KEY_LENGTH_256: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of KM_DEPLOY_ONLY_ONCE_H +pub const WR_DIS_KM_DEPLOY_ONLY_ONCE_H: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of FORCE_USE_KEY_MANAGER_KEY_H +pub const WR_DIS_FORCE_USE_KEY_MANAGER_KEY_H: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of LOCK_KM_KEY +pub const WR_DIS_LOCK_KM_KEY: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of KM_DISABLE_DEPLOY_MODE_H +pub const WR_DIS_KM_DISABLE_DEPLOY_MODE_H: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of KM_DISABLE_DEPLOY_MODE +pub const WR_DIS_KM_DISABLE_DEPLOY_MODE: EfuseField = EfuseField::new(0, 0, 1, 1); +/// `[]` wr_dis of DIS_USB_JTAG +pub const WR_DIS_DIS_USB_JTAG: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of DIS_FORCE_DOWNLOAD +pub const WR_DIS_DIS_FORCE_DOWNLOAD: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of SPI_DOWNLOAD_MSPI_DIS +pub const WR_DIS_SPI_DOWNLOAD_MSPI_DIS: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of DIS_TWAI +pub const WR_DIS_DIS_TWAI: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of JTAG_SEL_ENABLE +pub const WR_DIS_JTAG_SEL_ENABLE: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of DIS_PAD_JTAG +pub const WR_DIS_DIS_PAD_JTAG: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT +pub const WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of WDT_DELAY_SEL +pub const WR_DIS_WDT_DELAY_SEL: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of HYS_EN_PAD +pub const WR_DIS_HYS_EN_PAD: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of PXA0_TIEH_SEL_0 +pub const WR_DIS_PXA0_TIEH_SEL_0: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of DIS_WDT +pub const WR_DIS_DIS_WDT: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of DIS_SWD +pub const WR_DIS_DIS_SWD: EfuseField = EfuseField::new(0, 0, 2, 1); +/// `[]` wr_dis of PVT_GLITCH_EN +pub const WR_DIS_PVT_GLITCH_EN: EfuseField = EfuseField::new(0, 0, 3, 1); +/// `[]` wr_dis of PVT_GLITCH_MODE +pub const WR_DIS_PVT_GLITCH_MODE: EfuseField = EfuseField::new(0, 0, 3, 1); +/// `[]` wr_dis of SPI_BOOT_CRYPT_CNT +pub const WR_DIS_SPI_BOOT_CRYPT_CNT: EfuseField = EfuseField::new(0, 0, 4, 1); +/// `[]` wr_dis of SECURE_BOOT_KEY_REVOKE0 +pub const WR_DIS_SECURE_BOOT_KEY_REVOKE0: EfuseField = EfuseField::new(0, 0, 5, 1); +/// `[]` wr_dis of SECURE_BOOT_KEY_REVOKE1 +pub const WR_DIS_SECURE_BOOT_KEY_REVOKE1: EfuseField = EfuseField::new(0, 0, 6, 1); +/// `[]` wr_dis of SECURE_BOOT_KEY_REVOKE2 +pub const WR_DIS_SECURE_BOOT_KEY_REVOKE2: EfuseField = EfuseField::new(0, 0, 7, 1); +/// `[WR_DIS.KEY0_PURPOSE]` wr_dis of KEY_PURPOSE_0 +pub const WR_DIS_KEY_PURPOSE_0: EfuseField = EfuseField::new(0, 0, 8, 1); +/// `[]` wr_dis of KEY_PURPOSE_0_H +pub const WR_DIS_KEY_PURPOSE_0_H: EfuseField = EfuseField::new(0, 0, 8, 1); +/// `[WR_DIS.KEY1_PURPOSE]` wr_dis of KEY_PURPOSE_1 +pub const WR_DIS_KEY_PURPOSE_1: EfuseField = EfuseField::new(0, 0, 9, 1); +/// `[]` wr_dis of KEY_PURPOSE_1_H +pub const WR_DIS_KEY_PURPOSE_1_H: EfuseField = EfuseField::new(0, 0, 9, 1); +/// `[WR_DIS.KEY2_PURPOSE]` wr_dis of KEY_PURPOSE_2 +pub const WR_DIS_KEY_PURPOSE_2: EfuseField = EfuseField::new(0, 0, 10, 1); +/// `[]` wr_dis of KEY_PURPOSE_2_H +pub const WR_DIS_KEY_PURPOSE_2_H: EfuseField = EfuseField::new(0, 0, 10, 1); +/// `[WR_DIS.KEY3_PURPOSE]` wr_dis of KEY_PURPOSE_3 +pub const WR_DIS_KEY_PURPOSE_3: EfuseField = EfuseField::new(0, 0, 11, 1); +/// `[]` wr_dis of KEY_PURPOSE_3_H +pub const WR_DIS_KEY_PURPOSE_3_H: EfuseField = EfuseField::new(0, 0, 11, 1); +/// `[WR_DIS.KEY4_PURPOSE]` wr_dis of KEY_PURPOSE_4 +pub const WR_DIS_KEY_PURPOSE_4: EfuseField = EfuseField::new(0, 0, 12, 1); +/// `[]` wr_dis of KEY_PURPOSE_4_H +pub const WR_DIS_KEY_PURPOSE_4_H: EfuseField = EfuseField::new(0, 0, 12, 1); +/// `[WR_DIS.KEY5_PURPOSE]` wr_dis of KEY_PURPOSE_5 +pub const WR_DIS_KEY_PURPOSE_5: EfuseField = EfuseField::new(0, 0, 13, 1); +/// `[]` wr_dis of KEY_PURPOSE_5_H +pub const WR_DIS_KEY_PURPOSE_5_H: EfuseField = EfuseField::new(0, 0, 13, 1); +/// `[]` wr_dis of ECC_FORCE_CONST_TIME +pub const WR_DIS_ECC_FORCE_CONST_TIME: EfuseField = EfuseField::new(0, 0, 14, 1); +/// `[]` wr_dis of SEC_DPA_LEVEL +pub const WR_DIS_SEC_DPA_LEVEL: EfuseField = EfuseField::new(0, 0, 14, 1); +/// `[]` wr_dis of XTS_DPA_CLK_ENABLE +pub const WR_DIS_XTS_DPA_CLK_ENABLE: EfuseField = EfuseField::new(0, 0, 14, 1); +/// `[]` wr_dis of XTS_DPA_PSEUDO_LEVEL +pub const WR_DIS_XTS_DPA_PSEUDO_LEVEL: EfuseField = EfuseField::new(0, 0, 14, 1); +/// `[]` wr_dis of SECURE_BOOT_EN +pub const WR_DIS_SECURE_BOOT_EN: EfuseField = EfuseField::new(0, 0, 15, 1); +/// `[]` wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE +pub const WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE: EfuseField = EfuseField::new(0, 0, 16, 1); +/// `[]` wr_dis of HP_PWR_SRC_SEL +pub const WR_DIS_HP_PWR_SRC_SEL: EfuseField = EfuseField::new(0, 0, 17, 1); +/// `[]` wr_dis of FLASH_ECC_EN +pub const WR_DIS_FLASH_ECC_EN: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of DIS_USB_OTG_DOWNLOAD_MODE +pub const WR_DIS_DIS_USB_OTG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of FLASH_TPUW +pub const WR_DIS_FLASH_TPUW: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of DIS_DOWNLOAD_MODE +pub const WR_DIS_DIS_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of DIS_DIRECT_BOOT +pub const WR_DIS_DIS_DIRECT_BOOT: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT +pub const WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE +pub const WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of ENABLE_SECURITY_DOWNLOAD +pub const WR_DIS_ENABLE_SECURITY_DOWNLOAD: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of UART_PRINT_CONTROL +pub const WR_DIS_UART_PRINT_CONTROL: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of FORCE_SEND_RESUME +pub const WR_DIS_FORCE_SEND_RESUME: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of SECURE_VERSION +pub const WR_DIS_SECURE_VERSION: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE +pub const WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE: EfuseField = EfuseField::new(0, 0, 18, 1); +/// `[]` wr_dis of HUK_GEN_STATE +pub const WR_DIS_HUK_GEN_STATE: EfuseField = EfuseField::new(0, 0, 19, 1); +/// `[]` wr_dis of BLOCK1 +pub const WR_DIS_BLK1: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[WR_DIS.MAC_FACTORY]` wr_dis of MAC +pub const WR_DIS_MAC: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of WAFER_VERSION_MINOR +pub const WR_DIS_WAFER_VERSION_MINOR: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of WAFER_VERSION_MAJOR_LO +pub const WR_DIS_WAFER_VERSION_MAJOR_LO: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of DISABLE_WAFER_VERSION_MAJOR +pub const WR_DIS_DISABLE_WAFER_VERSION_MAJOR: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of DISABLE_BLK_VERSION_MAJOR +pub const WR_DIS_DISABLE_BLK_VERSION_MAJOR: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of BLK_VERSION_MINOR +pub const WR_DIS_BLK_VERSION_MINOR: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of BLK_VERSION_MAJOR +pub const WR_DIS_BLK_VERSION_MAJOR: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of PSRAM_CAP +pub const WR_DIS_PSRAM_CAP: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of TEMP +pub const WR_DIS_TEMP: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of PSRAM_VENDOR +pub const WR_DIS_PSRAM_VENDOR: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of PKG_VERSION +pub const WR_DIS_PKG_VERSION: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of BLOCK2 +pub const WR_DIS_SYS_DATA_PART1: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of WAFER_VERSION_MAJOR_HI +pub const WR_DIS_WAFER_VERSION_MAJOR_HI: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO1_DREF +pub const WR_DIS_LDO_VO1_DREF: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO2_DREF +pub const WR_DIS_LDO_VO2_DREF: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO1_MUL +pub const WR_DIS_LDO_VO1_MUL: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO2_MUL +pub const WR_DIS_LDO_VO2_MUL: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO3_K +pub const WR_DIS_LDO_VO3_K: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO3_VOS +pub const WR_DIS_LDO_VO3_VOS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO3_C +pub const WR_DIS_LDO_VO3_C: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO4_K +pub const WR_DIS_LDO_VO4_K: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO4_VOS +pub const WR_DIS_LDO_VO4_VOS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LDO_VO4_C +pub const WR_DIS_LDO_VO4_C: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of ACTIVE_HP_DBIAS +pub const WR_DIS_ACTIVE_HP_DBIAS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of ACTIVE_LP_DBIAS +pub const WR_DIS_ACTIVE_LP_DBIAS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of DSLP_DBG +pub const WR_DIS_DSLP_DBG: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of DSLP_LP_DBIAS +pub const WR_DIS_DSLP_LP_DBIAS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of LP_DCDC_DBIAS_VOL_GAP +pub const WR_DIS_LP_DCDC_DBIAS_VOL_GAP: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of PVT_400M_BIAS +pub const WR_DIS_PVT_400M_BIAS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of PVT_40M_BIAS +pub const WR_DIS_PVT_40M_BIAS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of PVT_100M_BIAS +pub const WR_DIS_PVT_100M_BIAS: EfuseField = EfuseField::new(0, 0, 20, 1); +/// `[]` wr_dis of OPTIONAL_UNIQUE_ID +pub const WR_DIS_OPTIONAL_UNIQUE_ID: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN0 +pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN1 +pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN2 +pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN3 +pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN0 +pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN1 +pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN2 +pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN3 +pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN0 +pub const WR_DIS_ADC1_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN1 +pub const WR_DIS_ADC1_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN2 +pub const WR_DIS_ADC1_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN3 +pub const WR_DIS_ADC1_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(0, 0, 21, 1); +/// `[WR_DIS.USER_DATA]` wr_dis of BLOCK_USR_DATA +pub const WR_DIS_BLOCK_USR_DATA: EfuseField = EfuseField::new(0, 0, 22, 1); +/// `[WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM]` wr_dis of CUSTOM_MAC +pub const WR_DIS_CUSTOM_MAC: EfuseField = EfuseField::new(0, 0, 22, 1); +/// `[WR_DIS.KEY0]` wr_dis of BLOCK_KEY0 +pub const WR_DIS_BLOCK_KEY0: EfuseField = EfuseField::new(0, 0, 23, 1); +/// `[WR_DIS.KEY1]` wr_dis of BLOCK_KEY1 +pub const WR_DIS_BLOCK_KEY1: EfuseField = EfuseField::new(0, 0, 24, 1); +/// `[WR_DIS.KEY2]` wr_dis of BLOCK_KEY2 +pub const WR_DIS_BLOCK_KEY2: EfuseField = EfuseField::new(0, 0, 25, 1); +/// `[WR_DIS.KEY3]` wr_dis of BLOCK_KEY3 +pub const WR_DIS_BLOCK_KEY3: EfuseField = EfuseField::new(0, 0, 26, 1); +/// `[WR_DIS.KEY4]` wr_dis of BLOCK_KEY4 +pub const WR_DIS_BLOCK_KEY4: EfuseField = EfuseField::new(0, 0, 27, 1); +/// `[WR_DIS.KEY5]` wr_dis of BLOCK_KEY5 +pub const WR_DIS_BLOCK_KEY5: EfuseField = EfuseField::new(0, 0, 28, 1); +/// `[WR_DIS.SYS_DATA_PART2]` wr_dis of BLOCK_SYS_DATA2 +pub const WR_DIS_BLOCK_SYS_DATA2: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN0 +pub const WR_DIS_ADC2_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN1 +pub const WR_DIS_ADC2_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN2 +pub const WR_DIS_ADC2_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN3 +pub const WR_DIS_ADC2_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH5_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH6_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH6_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC1_CH7_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC1_CH7_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_CH0_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC2_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_CH1_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC2_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_CH2_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC2_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_CH3_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC2_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_CH4_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC2_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of ADC2_CH5_ATTEN0_INITCODE_DIFF +pub const WR_DIS_ADC2_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of TEMPERATURE_SENSOR +pub const WR_DIS_TEMPERATURE_SENSOR: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of USB_DEVICE_EXCHG_PINS +pub const WR_DIS_USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of USB_OTG11_EXCHG_PINS +pub const WR_DIS_USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(0, 0, 29, 1); +/// `[]` wr_dis of SOFT_DIS_JTAG +pub const WR_DIS_SOFT_DIS_JTAG: EfuseField = EfuseField::new(0, 0, 31, 1); +/// `[]` Disable reading from BlOCK4-10 +pub const RD_DIS: EfuseField = EfuseField::new(0, 1, 32, 7); +/// `[RD_DIS.KEY0]` rd_dis of BLOCK_KEY0 +pub const RD_DIS_BLOCK_KEY0: EfuseField = EfuseField::new(0, 1, 32, 1); +/// `[RD_DIS.KEY1]` rd_dis of BLOCK_KEY1 +pub const RD_DIS_BLOCK_KEY1: EfuseField = EfuseField::new(0, 1, 33, 1); +/// `[RD_DIS.KEY2]` rd_dis of BLOCK_KEY2 +pub const RD_DIS_BLOCK_KEY2: EfuseField = EfuseField::new(0, 1, 34, 1); +/// `[RD_DIS.KEY3]` rd_dis of BLOCK_KEY3 +pub const RD_DIS_BLOCK_KEY3: EfuseField = EfuseField::new(0, 1, 35, 1); +/// `[RD_DIS.KEY4]` rd_dis of BLOCK_KEY4 +pub const RD_DIS_BLOCK_KEY4: EfuseField = EfuseField::new(0, 1, 36, 1); +/// `[RD_DIS.KEY5]` rd_dis of BLOCK_KEY5 +pub const RD_DIS_BLOCK_KEY5: EfuseField = EfuseField::new(0, 1, 37, 1); +/// `[RD_DIS.SYS_DATA_PART2]` rd_dis of BLOCK_SYS_DATA2 +pub const RD_DIS_BLOCK_SYS_DATA2: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN0 +pub const RD_DIS_ADC2_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN1 +pub const RD_DIS_ADC2_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN2 +pub const RD_DIS_ADC2_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN3 +pub const RD_DIS_ADC2_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH5_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH6_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH6_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC1_CH7_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC1_CH7_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_CH0_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC2_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_CH1_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC2_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_CH2_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC2_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_CH3_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC2_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_CH4_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC2_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of ADC2_CH5_ATTEN0_INITCODE_DIFF +pub const RD_DIS_ADC2_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of TEMPERATURE_SENSOR +pub const RD_DIS_TEMPERATURE_SENSOR: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of USB_DEVICE_EXCHG_PINS +pub const RD_DIS_USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` rd_dis of USB_OTG11_EXCHG_PINS +pub const RD_DIS_USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(0, 1, 38, 1); +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1: EfuseField = EfuseField::new(0, 1, 39, 2); +/// `[]` Set this bit to disable function of usb switch to jtag in module of usb device +pub const DIS_USB_JTAG: EfuseField = EfuseField::new(0, 1, 41, 1); +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2: EfuseField = EfuseField::new(0, 1, 42, 1); +/// `[]` Set this bit to disable the function that forces chip into download mode +pub const DIS_FORCE_DOWNLOAD: EfuseField = EfuseField::new(0, 1, 44, 1); +/// `[]` Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during boot_mode_download +pub const SPI_DOWNLOAD_MSPI_DIS: EfuseField = EfuseField::new(0, 1, 45, 1); +/// `[]` Set this bit to disable TWAI function +pub const DIS_TWAI: EfuseField = EfuseField::new(0, 1, 46, 1); +/// `[]` Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio25 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 +pub const JTAG_SEL_ENABLE: EfuseField = EfuseField::new(0, 1, 47, 1); +/// `[]` Set odd bits to disable JTAG in the soft way. JTAG can be enabled in HMAC module +pub const SOFT_DIS_JTAG: EfuseField = EfuseField::new(0, 1, 48, 3); +/// `[]` Set this bit to disable JTAG in the hard way. JTAG is disabled permanently +pub const DIS_PAD_JTAG: EfuseField = EfuseField::new(0, 1, 51, 1); +/// `[]` Set this bit to disable flash manual encrypt function (except in SPI boot mode) +pub const DIS_DOWNLOAD_MANUAL_ENCRYPT: EfuseField = EfuseField::new(0, 1, 52, 1); +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6: EfuseField = EfuseField::new(0, 1, 53, 4); +/// `[]` 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) <---> usb_device 1: intphy(24/25) <---> usb_otg11 +pub const USB_PHY_SEL: EfuseField = EfuseField::new(0, 1, 57, 1); +/// `[]` Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid +pub const HUK_GEN_STATE: EfuseField = EfuseField::new(0, 1, 58, 5); +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7: EfuseField = EfuseField::new(0, 1, 63, 1); +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10: EfuseField = EfuseField::new(0, 2, 64, 3); +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11: EfuseField = EfuseField::new(0, 2, 67, 1); +/// `[]` Set the bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles +pub const KM_RND_SWITCH_CYCLE: EfuseField = EfuseField::new(0, 2, 68, 1); +/// `[]` EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: {EFUSE_KM_DEPLOY_ONLY_ONCE_H; EFUSE_KM_DEPLOY_ONLY_ONCE`[3:0]`}. Set each bit to control whether corresponding key can only be deployed once. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram +pub const KM_DEPLOY_ONLY_ONCE: EfuseField = EfuseField::new(0, 3, 118, 5); +/// `[]` EFUSE_FORCE_USE_KEY_MANAGER_KEY and EFUSE_FORCE_USE_KEY_MANAGER_KEY_H together form one field: {EFUSE_FORCE_USE_KEY_MANAGER_KEY_H; EFUSE_FORCE_USE_KEY_MANAGER_KEY`[3:0]`}. Set each bit to control whether corresponding key must come from key manager. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram +pub const FORCE_USE_KEY_MANAGER_KEY: EfuseField = EfuseField::new(0, 3, 119, 5); +/// `[]` Set this bit to disable software written init key; and force use efuse_init_key +pub const FORCE_DISABLE_SW_INIT_KEY: EfuseField = EfuseField::new(0, 2, 77, 1); +/// `[]` Set this bit to config flash encryption xts-512 key; else use xts-256 key when using the key manager +pub const KM_XTS_KEY_LENGTH_256: EfuseField = EfuseField::new(0, 2, 78, 1); +/// `[]` Set this bit to permanently turn on ECC const-time mode +pub const ECC_FORCE_CONST_TIME: EfuseField = EfuseField::new(0, 2, 79, 1); +/// `[]` Select lp wdt timeout threshold at startup = initial timeout value * (2 ^ (EFUSE_WDT_DELAY_SEL + 1)) +pub const WDT_DELAY_SEL: EfuseField = EfuseField::new(0, 2, 81, 1); +/// `[]` Set this bit to enable SPI boot encrypt/decrypt. Odd number of 1: enable. even number of 1: disable {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"} +pub const SPI_BOOT_CRYPT_CNT: EfuseField = EfuseField::new(0, 2, 82, 3); +/// `[]` Revoke 1st secure boot key +pub const SECURE_BOOT_KEY_REVOKE0: EfuseField = EfuseField::new(0, 2, 85, 1); +/// `[]` Revoke 2nd secure boot key +pub const SECURE_BOOT_KEY_REVOKE1: EfuseField = EfuseField::new(0, 2, 86, 1); +/// `[]` Revoke 3rd secure boot key +pub const SECURE_BOOT_KEY_REVOKE2: EfuseField = EfuseField::new(0, 2, 87, 1); +/// `[KEY0_PURPOSE]` Purpose of Key0 +pub const KEY_PURPOSE_0: EfuseField = EfuseField::new(0, 4, 155, 5); +/// `[KEY1_PURPOSE]` Purpose of Key1 +pub const KEY_PURPOSE_1: EfuseField = EfuseField::new(0, 4, 156, 5); +/// `[KEY2_PURPOSE]` Purpose of Key2 +pub const KEY_PURPOSE_2: EfuseField = EfuseField::new(0, 4, 157, 5); +/// `[KEY3_PURPOSE]` Purpose of Key3 +pub const KEY_PURPOSE_3: EfuseField = EfuseField::new(0, 4, 158, 5); +/// `[KEY4_PURPOSE]` Purpose of Key4 +pub const KEY_PURPOSE_4: EfuseField = EfuseField::new(0, 4, 159, 5); +/// `[KEY5_PURPOSE]` Purpose of Key5 +pub const KEY_PURPOSE_5: EfuseField = EfuseField::new(0, 5, 164, 5); +/// `[]` Configures the clock random divide mode to determine the dpa secure level +pub const SEC_DPA_LEVEL: EfuseField = EfuseField::new(0, 3, 112, 2); +/// `[]` Sets this bit to enable xts clock anti-dpa attack function +pub const XTS_DPA_CLK_ENABLE: EfuseField = EfuseField::new(0, 3, 115, 1); +/// `[]` Set this bit to enable secure boot +pub const SECURE_BOOT_EN: EfuseField = EfuseField::new(0, 3, 116, 1); +/// `[]` Set this bit to enable revoking aggressive secure boot +pub const SECURE_BOOT_AGGRESSIVE_REVOKE: EfuseField = EfuseField::new(0, 3, 117, 1); +/// `[]` Set this bit to enable ECC for flash boot +pub const FLASH_ECC_EN: EfuseField = EfuseField::new(0, 3, 122, 1); +/// `[]` Set this bit to disable download via USB-OTG +pub const DIS_USB_OTG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 3, 123, 1); +/// `[]` Configures flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the configurable value. Otherwise; the waiting time is 30 +pub const FLASH_TPUW: EfuseField = EfuseField::new(0, 3, 124, 4); +/// `[]` Set this bit to disable download mode (boot_mode`[3:0]` = 0; 1; 2; 4; 5; 6; 7) +pub const DIS_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 4, 128, 1); +/// `[]` Set this bit to disable direct boot mode +pub const DIS_DIRECT_BOOT: EfuseField = EfuseField::new(0, 4, 129, 1); +/// `[]` Set this bit to disable USB-Serial-JTAG print during rom boot +pub const DIS_USB_SERIAL_JTAG_ROM_PRINT: EfuseField = EfuseField::new(0, 4, 130, 1); +/// `[]` set this bit to lock the key manager key after deploy +pub const LOCK_KM_KEY: EfuseField = EfuseField::new(0, 4, 131, 1); +/// `[]` Set this bit to disable the USB-Serial-JTAG download function +pub const DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 4, 132, 1); +/// `[]` Set this bit to enable security download mode +pub const ENABLE_SECURITY_DOWNLOAD: EfuseField = EfuseField::new(0, 4, 133, 1); +/// `[]` Set the type of UART printing; 00: force enable printing; 01: enable printing when GPIO8 is reset at low level; 10: enable printing when GPIO8 is reset at high level; 11: force disable printing +pub const UART_PRINT_CONTROL: EfuseField = EfuseField::new(0, 4, 134, 2); +/// `[]` Set this bit to force ROM code to send a resume command during SPI boot +pub const FORCE_SEND_RESUME: EfuseField = EfuseField::new(0, 4, 136, 1); +/// `[]` Secure version used by ESP-IDF anti-rollback feature +pub const SECURE_VERSION: EfuseField = EfuseField::new(0, 4, 137, 16); +/// `[]` Represents whether secure boot do fast verification on wake is disabled. 0: enabled 1: disabled +pub const SECURE_BOOT_DISABLE_FAST_WAKE: EfuseField = EfuseField::new(0, 4, 153, 1); +/// `[]` Set bits to enable hysteresis function of PAD0~27 +pub const HYS_EN_PAD: EfuseField = EfuseField::new(0, 4, 154, 1); +/// `[]` Output LDO VO0 tieh source select. 0: 1'b1 1: sdmmc1 2: reg 3:sdmmc0 +pub const PXA0_TIEH_SEL_0: EfuseField = EfuseField::new(0, 5, 160, 2); +/// `[]` Represents whether to enable PVT power glitch monitor function.1:Enable. 0:Disable +pub const PVT_GLITCH_EN: EfuseField = EfuseField::new(0, 5, 162, 1); +/// `[]` EFUSE_KM_DISABLE_DEPLOY_MODE and EFUSE_KM_DISABLE_DEPLOY_MODE_H together form one field: {EFUSE_KM_DISABLE_DEPLOY_MODE_H; EFUSE_KM_DISABLE_DEPLOY_MODE`[3:0]`}. Set each bit to control whether corresponding key's deploy mode of new value deployment is disabled. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram +pub const KM_DISABLE_DEPLOY_MODE: EfuseField = EfuseField::new(0, 5, 167, 5); +/// `[]` Sets this bit to control the xts pseudo-round anti-dpa attack function. 0: controlled by register. 1-3: the higher the value is; the more pseudo-rounds are inserted to the xts-aes calculation +pub const XTS_DPA_PSEUDO_LEVEL: EfuseField = EfuseField::new(0, 5, 176, 2); +/// `[]` HP system power source select. 0:LDO 1: DCDC +pub const HP_PWR_SRC_SEL: EfuseField = EfuseField::new(0, 5, 178, 1); +/// `[]` Represents whether secure boot using SHA-384 is enabled. 0: disable 1: enable +pub const SECURE_BOOT_SHA384_EN: EfuseField = EfuseField::new(0, 5, 179, 1); +/// `[]` Set this bit to disable watch dog +pub const DIS_WDT: EfuseField = EfuseField::new(0, 5, 180, 1); +/// `[]` Set bit to disable super-watchdog +pub const DIS_SWD: EfuseField = EfuseField::new(0, 5, 181, 1); +/// `[]` Use to configure glitch mode +pub const PVT_GLITCH_MODE: EfuseField = EfuseField::new(0, 5, 182, 2); +/// `[MAC_FACTORY]` MAC address +pub const MAC0: EfuseField = EfuseField::new(1, 0, 0, 32); +pub const MAC1: EfuseField = EfuseField::new(1, 0, 32, 16); +/// `[]` Minor chip version +pub const WAFER_VERSION_MINOR: EfuseField = EfuseField::new(1, 2, 64, 4); +/// `[]` Major chip version (lower 2 bits) +pub const WAFER_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 87, 3); +/// `[]` Disables check of wafer version major +pub const DISABLE_WAFER_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 70, 1); +/// `[]` Disables check of blk version major +pub const DISABLE_BLK_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 71, 1); +/// `[]` BLK_VERSION_MINOR of BLOCK2 +pub const BLK_VERSION_MINOR: EfuseField = EfuseField::new(1, 2, 72, 3); +/// `[]` BLK_VERSION_MAJOR of BLOCK2 +pub const BLK_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 75, 2); +/// `[]` PSRAM capacity +pub const PSRAM_CAP: EfuseField = EfuseField::new(1, 2, 77, 3); +/// `[]` Operating temperature of the ESP chip +pub const TEMP: EfuseField = EfuseField::new(1, 2, 80, 2); +/// `[]` PSRAM vendor +pub const PSRAM_VENDOR: EfuseField = EfuseField::new(1, 2, 82, 2); +/// `[]` Package version +pub const PKG_VERSION: EfuseField = EfuseField::new(1, 2, 84, 3); +/// `[]` Output VO1 parameter +pub const LDO_VO1_DREF: EfuseField = EfuseField::new(1, 2, 88, 4); +/// `[]` Output VO2 parameter +pub const LDO_VO2_DREF: EfuseField = EfuseField::new(1, 2, 92, 4); +/// `[]` Output VO1 parameter +pub const LDO_VO1_MUL: EfuseField = EfuseField::new(1, 3, 96, 3); +/// `[]` Output VO2 parameter +pub const LDO_VO2_MUL: EfuseField = EfuseField::new(1, 3, 99, 3); +/// `[]` Output VO3 calibration parameter +pub const LDO_VO3_K: EfuseField = EfuseField::new(1, 3, 102, 8); +/// `[]` Output VO3 calibration parameter +pub const LDO_VO3_VOS: EfuseField = EfuseField::new(1, 3, 110, 6); +/// `[]` Output VO3 calibration parameter +pub const LDO_VO3_C: EfuseField = EfuseField::new(1, 3, 116, 6); +/// `[]` Output VO4 calibration parameter +pub const LDO_VO4_K: EfuseField = EfuseField::new(1, 3, 122, 8); +/// `[]` Output VO4 calibration parameter +pub const LDO_VO4_VOS: EfuseField = EfuseField::new(1, 4, 130, 6); +/// `[]` Output VO4 calibration parameter +pub const LDO_VO4_C: EfuseField = EfuseField::new(1, 4, 136, 6); +/// `[]` Active HP DBIAS of fixed voltage +pub const ACTIVE_HP_DBIAS: EfuseField = EfuseField::new(1, 4, 144, 4); +/// `[]` Active LP DBIAS of fixed voltage +pub const ACTIVE_LP_DBIAS: EfuseField = EfuseField::new(1, 4, 148, 4); +/// `[]` DSLP BDG of fixed voltage +pub const DSLP_DBG: EfuseField = EfuseField::new(1, 4, 156, 4); +/// `[]` DSLP LP DBIAS of fixed voltage +pub const DSLP_LP_DBIAS: EfuseField = EfuseField::new(1, 5, 160, 5); +/// `[]` DBIAS gap between LP and DCDC +pub const LP_DCDC_DBIAS_VOL_GAP: EfuseField = EfuseField::new(1, 5, 165, 5); +/// `[]` PVT_DCM_VSET when the CPU is at 400M +pub const PVT_400M_BIAS: EfuseField = EfuseField::new(1, 5, 171, 5); +/// `[]` PVT_DCM_VSET corresponding to about 0.9V fixed voltage when the CPU is at 40M +pub const PVT_40M_BIAS: EfuseField = EfuseField::new(1, 5, 176, 5); +/// `[]` PVT_DCM_VSET corresponding to about 1.0V fixed voltage when the CPU is at 100M +pub const PVT_100M_BIAS: EfuseField = EfuseField::new(1, 5, 181, 5); +/// `[]` Optional unique 128-bit ID +pub const OPTIONAL_UNIQUE_ID: EfuseField = EfuseField::new(2, 0, 0, 128); +/// `[]` Average initcode of ADC1 atten0 +pub const ADC1_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(2, 4, 128, 10); +/// `[]` Average initcode of ADC1 atten1 +pub const ADC1_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(2, 4, 138, 10); +/// `[]` Average initcode of ADC1 atten2 +pub const ADC1_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(2, 4, 148, 10); +/// `[]` Average initcode of ADC1 atten3 +pub const ADC1_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(2, 4, 158, 10); +/// `[]` Average initcode of ADC2 atten0 +pub const ADC2_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(2, 5, 168, 10); +/// `[]` Average initcode of ADC2 atten1 +pub const ADC2_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(2, 5, 178, 10); +/// `[]` Average initcode of ADC2 atten2 +pub const ADC2_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(2, 5, 188, 10); +/// `[]` Average initcode of ADC2 atten3 +pub const ADC2_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(2, 6, 198, 10); +/// `[]` HI_DOUT of ADC1 atten0 +pub const ADC1_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(2, 6, 208, 10); +/// `[]` HI_DOUT of ADC1 atten1 +pub const ADC1_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(2, 6, 218, 10); +/// `[]` HI_DOUT of ADC1 atten2 +pub const ADC1_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(2, 7, 228, 10); +/// `[]` HI_DOUT of ADC1 atten3 +pub const ADC1_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(2, 7, 238, 10); +/// `[BLOCK_USR_DATA]` User data +pub const USER_DATA: EfuseField = EfuseField::new(3, 0, 0, 256); +/// `[MAC_CUSTOM CUSTOM_MAC]` Custom MAC +pub const USER_DATA_MAC_CUSTOM: EfuseField = EfuseField::new(3, 6, 200, 48); +/// `[BLOCK_KEY0]` Key0 or user data +pub const KEY0: EfuseField = EfuseField::new(4, 0, 0, 256); +/// `[BLOCK_KEY1]` Key1 or user data +pub const KEY1: EfuseField = EfuseField::new(5, 0, 0, 256); +/// `[BLOCK_KEY2]` Key2 or user data +pub const KEY2: EfuseField = EfuseField::new(6, 0, 0, 256); +/// `[BLOCK_KEY3]` Key3 or user data +pub const KEY3: EfuseField = EfuseField::new(7, 0, 0, 256); +/// `[BLOCK_KEY4]` Key4 or user data +pub const KEY4: EfuseField = EfuseField::new(8, 0, 0, 256); +/// `[BLOCK_KEY5]` Key5 or user data +pub const KEY5: EfuseField = EfuseField::new(9, 0, 0, 256); +/// `[]` HI_DOUT of ADC2 atten0 +pub const ADC2_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(10, 0, 0, 10); +/// `[]` HI_DOUT of ADC2 atten1 +pub const ADC2_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(10, 0, 10, 10); +/// `[]` HI_DOUT of ADC2 atten2 +pub const ADC2_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(10, 0, 20, 10); +/// `[]` HI_DOUT of ADC2 atten3 +pub const ADC2_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(10, 0, 30, 10); +/// `[]` Gap between ADC1_ch0 and average initcode +pub const ADC1_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 40, 4); +/// `[]` Gap between ADC1_ch1 and average initcode +pub const ADC1_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 44, 4); +/// `[]` Gap between ADC1_ch2 and average initcode +pub const ADC1_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 48, 4); +/// `[]` Gap between ADC1_ch3 and average initcode +pub const ADC1_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 52, 4); +/// `[]` Gap between ADC1_ch4 and average initcode +pub const ADC1_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 56, 4); +/// `[]` Gap between ADC1_ch5 and average initcode +pub const ADC1_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 60, 4); +/// `[]` Gap between ADC1_ch6 and average initcode +pub const ADC1_CH6_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 64, 4); +/// `[]` Gap between ADC1_ch7 and average initcode +pub const ADC1_CH7_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 68, 4); +/// `[]` Gap between ADC2_ch0 and average initcode +pub const ADC2_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 72, 4); +/// `[]` Gap between ADC2_ch1 and average initcode +pub const ADC2_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 76, 4); +/// `[]` Gap between ADC2_ch2 and average initcode +pub const ADC2_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 80, 4); +/// `[]` Gap between ADC2_ch3 and average initcode +pub const ADC2_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 84, 4); +/// `[]` Gap between ADC2_ch4 and average initcode +pub const ADC2_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 88, 4); +/// `[]` Gap between ADC2_ch5 and average initcode +pub const ADC2_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 92, 4); +/// `[]` Temperature calibration data +pub const TEMPERATURE_SENSOR: EfuseField = EfuseField::new(10, 3, 96, 10); +/// `[]` Enable usb device exchange pins of D+ and D- +pub const USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(10, 7, 228, 1); +/// `[]` Enable usb otg11 exchange pins of D+ and D- +pub const USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(10, 7, 229, 1); diff --git a/esp-hal/src/efuse/esp32p4/mod.rs b/esp-hal/src/efuse/esp32p4/mod.rs new file mode 100644 index 00000000000..48dd08cc5c9 --- /dev/null +++ b/esp-hal/src/efuse/esp32p4/mod.rs @@ -0,0 +1,63 @@ +//! # Reading of eFuses (ESP32-P4) +pub use self::fields::*; +use crate::peripherals::pac::EFUSE; + +mod fields; + +impl super::Efuse { + /// Get status of SPI boot encryption. + pub fn get_flash_encryption() -> bool { + (Self::read_field_le::(SPI_BOOT_CRYPT_CNT).count_ones() % 2) != 0 + } + + /// Get the multiplier for the timeout value of the RWDT STAGE 0 register. + pub fn get_rwdt_multiplier() -> u8 { + Self::read_field_le::(WDT_DELAY_SEL) + } + + /// Returns the major hardware revision + pub fn major_chip_version() -> u8 { + Self::read_field_le(WAFER_VERSION_MAJOR) + } + + /// Returns the minor hardware revision + pub fn minor_chip_version() -> u8 { + Self::read_field_le(WAFER_VERSION_MINOR) + } +} + +#[derive(Debug, Clone, Copy, strum::FromRepr)] +#[repr(u32)] +pub(crate) enum EfuseBlock { + Block0, + Block1, + Block2, + Block3, + Block4, + Block5, + Block6, + Block7, + Block8, + Block9, + Block10, +} + +impl EfuseBlock { + pub(crate) fn address(self) -> *const u32 { + use EfuseBlock::*; + let efuse = unsafe { &*EFUSE::PTR }; + match self { + Block0 => efuse.rd_wr_dis().as_ptr(), + Block1 => efuse.rd_mac_sys_0().as_ptr(), + Block2 => efuse.rd_sys_part1_data0().as_ptr(), + Block3 => efuse.rd_usr_data0().as_ptr(), + Block4 => efuse.rd_key0_data0().as_ptr(), + Block5 => efuse.rd_key1_data0().as_ptr(), + Block6 => efuse.rd_key2_data0().as_ptr(), + Block7 => efuse.rd_key3_data0().as_ptr(), + Block8 => efuse.rd_key4_data0().as_ptr(), + Block9 => efuse.rd_key5_data0().as_ptr(), + Block10 => efuse.rd_sys_part2_data0().as_ptr(), + } + } +} \ No newline at end of file diff --git a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs new file mode 100644 index 00000000000..82ed01c0339 --- /dev/null +++ b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs @@ -0,0 +1,1084 @@ +// Note: the PMU setup is based on esp-idf v5.1.2. Related code should be based +// on the same version until documentation is released and the code can be +// reasoned about. + +use strum::FromRepr; + +use crate::{ + clock::{RtcClock, RtcFastClock, RtcSlowClock}, + peripherals::{PMU, LPWR}, + rtc_cntl::RtcCalSel, + soc::{ + clocks::{ClockTree}, + regi2c, + }, +}; + +fn pmu_power_domain_force_default() { + // for bypass reserved power domain + + // PMU_HP_PD_TOP + PMU::regs().power_pd_top_cntl().modify(|_, w| { + w.force_top_reset().bit(false); // pmu_ll_hp_set_power_force_reset + w.force_top_iso().bit(false); // pmu_ll_hp_set_power_force_isolate + w.force_top_pu().bit(false); // pmu_ll_hp_set_power_force_power_up + w.force_top_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset + w.force_top_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate + w.force_top_pd().bit(false) // pmu_ll_hp_set_power_force_power_down + }); + + // PMU_HP_PD_HP_AON + PMU::regs().power_pd_hpaon_cntl().modify(|_, w| { + w.force_hp_aon_reset().bit(false); // pmu_ll_hp_set_power_force_reset + w.force_hp_aon_iso().bit(false); // pmu_ll_hp_set_power_force_isolate + w.force_hp_aon_pu().bit(false); // pmu_ll_hp_set_power_force_power_up + w.force_hp_aon_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset + w.force_hp_aon_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate + w.force_hp_aon_pd().bit(false) // pmu_ll_hp_set_power_force_power_down + }); + + // PMU_HP_PD_CPU + PMU::regs().power_pd_hpcpu_cntl().modify(|_, w| { + w.force_hp_cpu_reset().bit(false); // pmu_ll_hp_set_power_force_reset + w.force_hp_cpu_iso().bit(false); // pmu_ll_hp_set_power_force_isolate + w.force_hp_cpu_pu().bit(false); // pmu_ll_hp_set_power_force_power_up + w.force_hp_cpu_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset + w.force_hp_cpu_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate + w.force_hp_cpu_pd().bit(false) // pmu_ll_hp_set_power_force_power_down + }); + + // PMU_HP_PD_WIFI + PMU::regs().power_pd_hpwifi_cntl().modify(|_, w| { + w.force_hp_wifi_reset().bit(false); // pmu_ll_hp_set_power_force_reset + w.force_hp_wifi_iso().bit(false); // pmu_ll_hp_set_power_force_isolate + w.force_hp_wifi_pu().bit(false); // pmu_ll_hp_set_power_force_power_up + w.force_hp_wifi_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset + w.force_hp_wifi_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate + w.force_hp_wifi_pd().bit(false) // pmu_ll_hp_set_power_force_power_down + }); + + // Isolate all memory banks while sleeping, avoid memory leakage current + + PMU::regs().power_pd_mem_cntl().modify(|_, w| unsafe { + w.force_hp_mem_no_iso().bits(0) // pmu_ll_hp_set_memory_no_isolate + }); + + PMU::regs().power_pd_lpperi_cntl().modify(|_, w| { + w.force_lp_peri_reset().bit(false); // pmu_ll_lp_set_power_force_reset + w.force_lp_peri_iso().bit(false); // pmu_ll_lp_set_power_force_isolate + w.force_lp_peri_pu().bit(false); // pmu_ll_lp_set_power_force_power_up + w.force_lp_peri_no_reset().bit(false); // pmu_ll_lp_set_power_force_no_reset + w.force_lp_peri_no_iso().bit(false); // pmu_ll_lp_set_power_force_no_isolate + w.force_lp_peri_pd().bit(false) // pmu_ll_lp_set_power_force_power_down + }); +} + +fn modem_clock_domain_power_state_icg_map_init() { + todo!(); +} + +enum RtcSlowClockSource { + /// Select RC_SLOW_CLK as RTC_SLOW_CLK source + RcSlow = 0, + + /// Select XTAL32K_CLK as RTC_SLOW_CLK source + XTAL32K = 1, + + /// Select RC32K_CLK as RTC_SLOW_CLK source + RC32K = 2, + + /// Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source + OscSlow = 3, + + /// Invalid RTC_SLOW_CLK source + Invalid, +} + +impl RtcSlowClockSource { + fn current() -> Self { + // clk_ll_rtc_slow_get_src() + match LPWR::regs().lp_clk_conf().read().slow_clk_sel().bits() { + 0 => Self::RcSlow, + 1 => Self::XTAL32K, + 2 => Self::RC32K, + 3 => Self::OscSlow, + _ => Self::Invalid, + } + } +} + +#[allow(unused)] +enum ModemClockLpclkSource { + RcSlow = 0, + RcFast, + MainXtal, + RC32K, + XTAL32K, + EXT32K, +} + +impl From for ModemClockLpclkSource { + fn from(src: RtcSlowClockSource) -> Self { + match src { + RtcSlowClockSource::RcSlow => Self::RcSlow, + RtcSlowClockSource::XTAL32K => Self::XTAL32K, + RtcSlowClockSource::RC32K => Self::RC32K, + RtcSlowClockSource::OscSlow => Self::EXT32K, + _ => Self::RcSlow, + } + } +} + +fn modem_clock_hal_deselect_all_wifi_lpclk_source() { + todo!() +} + +fn modem_clock_hal_select_wifi_lpclk_source(src: ModemClockLpclkSource) { + todo!() +} + +fn modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider: u16) { + todo!() +} + +fn modem_clock_hal_enable_wifipwr_clock(enable: bool) { + todo!() +} + +// PHY, BT, IEEE802154 are not used by the init code so they are unimplemented +fn modem_clock_select_lp_clock_source_wifi(src: ModemClockLpclkSource, divider: u16) { + modem_clock_hal_deselect_all_wifi_lpclk_source(); + modem_clock_hal_select_wifi_lpclk_source(src); + modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider); + modem_clock_hal_enable_wifipwr_clock(true); +} + +const fn hp_retention_regdma_config(dir: u8, entry: u8) -> u8 { + (((dir) << 2) | (entry & 0x3)) & 0x7 +} + +const HP_CALI_DBIAS: u8 = 25; +const LP_CALI_DBIAS: u8 = 26; + +const ICG_MODEM_CODE_SLEEP: u8 = 0; +const ICG_MODEM_CODE_MODEM: u8 = 1; +const ICG_MODEM_CODE_ACTIVE: u8 = 2; + +const HP_SYSCLK_XTAL: u8 = 0; +const HP_SYSCLK_PLL: u8 = 1; + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_power_t.0 + pub struct HpDigPower(u32); + + pub bool, vdd_spi_pd_en, set_vdd_spi_pd_en: 21; + pub bool, mem_dslp , set_mem_dslp : 22; + pub u8, mem_pd_en , set_mem_pd_en : 26, 23; + pub bool, wifi_pd_en , set_wifi_pd_en : 27; + pub bool, cpu_pd_en , set_cpu_pd_en : 29; + pub bool, aon_pd_en , set_aon_pd_en : 30; + pub bool, top_pd_en , set_top_pd_en : 31; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_power_t.1 + pub struct HpClkPower(u32); + + pub bool, i2c_iso_en , set_i2c_iso_en : 26; + pub bool, i2c_retention, set_i2c_retention: 27; + pub bool, xpd_bb_i2c , set_xpd_bb_i2c : 28; + pub bool, xpd_bbpll_i2c, set_xpd_bbpll_i2c: 29; + pub bool, xpd_bbpll , set_xpd_bbpll : 30; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_power_t.2 + pub struct HpXtalPower(u32); + + pub bool, xpd_xtal , set_xpd_xtal : 31; +} + +#[derive(Clone, Copy, Default)] +// pmu_sleep_power_config_t.0 +pub struct HpSysPower { + // This is a best-guess assignment of the variants in the union `pmu_hp_power_t` union + // In esp-idf, all three fields are `pmu_hp_power_t` + pub dig_power: HpDigPower, + pub clk: HpClkPower, + pub xtal: HpXtalPower, +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_sys_cntl_reg_t + pub struct HpSysCntlReg(u32); + + pub bool, uart_wakeup_en , set_uart_wakeup_en : 24; + pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25; + pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26; + pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27; + pub bool, dig_pause_wdt , set_dig_pause_wdt : 28; + pub bool, dig_cpu_stall , set_dig_cpu_stall : 29; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_icg_modem_reg_t + pub struct HpIcgModem(u32); + + pub u8, code, set_code: 31, 30; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_sysclk_reg_t + pub struct HpSysclk(u32); + + pub bool, dig_sysclk_nodiv , set_dig_sysclk_nodiv : 26; + pub bool, icg_sysclk_en , set_icg_sysclk_en : 27; + pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28; + pub bool, icg_slp_sel , set_icg_slp_sel : 29; + pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30; +} + +// pmu_hp_system_clock_param_t +#[derive(Clone, Copy, Default)] +struct SystemClockParam { + icg_func: u32, + icg_apb: u32, + icg_modem: HpIcgModem, + sysclk: HpSysclk, +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_analog_t.0 + pub struct HpAnalogBias(u32); + + pub bool, xpd_bias , set_xpd_bias : 25; + pub u8, dbg_atten , set_dbg_atten : 29, 26; + pub bool, pd_cur , set_pd_cur : 30; + pub bool, bias_sleep, set_bias_sleep: 31; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_analog_t.1 + pub struct HpAnalogRegulator0(u32); + + // Only HP_ACTIVE modem under hp system is valid + pub u8, lp_dbias_vol , set_lp_dbias_vol : 8, 4; + // Only HP_ACTIVE modem under hp system is valid + pub u8, hp_dbias_vol , set_hp_dbias_vol : 13, 9; + // Only HP_ACTIVE modem under hp system is valid + pub bool, dbias_sel , set_dbias_sel : 14; + // Only HP_ACTIVE modem under hp system is valid + pub bool, dbias_init , set_dbias_init : 15; + + pub bool, slp_mem_xpd , set_slp_mem_xpd : 16; + pub bool, slp_logic_xpd , set_slp_logic_xpd : 17; + pub bool, xpd , set_xpd : 18; + pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19; + pub u8, slp_logic_dbias, set_slp_logic_dbias: 26, 23; + pub u8, dbias , set_dbias : 31, 27; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_analog_t.2 + pub struct HpAnalogRegulator1(u32); + + pub u32, drv_b , set_drv_b : 31, 8; +} + +#[derive(Clone, Copy, Default)] +// pmu_hp_analog_t +pub struct HpAnalog { + pub bias: HpAnalogBias, + pub regulator0: HpAnalogRegulator0, + pub regulator1: HpAnalogRegulator1, +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_backup_reg_t/active + pub struct HpActiveBackup(u32); + + pub u8, hp_sleep2active_backup_modem_clk_code, set_hp_sleep2active_backup_modem_clk_code: 5, 4; + pub u8, hp_modem2active_backup_modem_clk_code, set_hp_modem2active_backup_modem_clk_code: 7, 6; + pub bool, hp_active_retention_mode , set_hp_active_retention_mode : 10; + pub bool, hp_sleep2active_retention_en , set_hp_sleep2active_retention_en : 11; + pub bool, hp_modem2active_retention_en , set_hp_modem2active_retention_en : 12; + pub u8, hp_sleep2active_backup_clk_sel , set_hp_sleep2active_backup_clk_sel : 15, 14; + pub u8, hp_modem2active_backup_clk_sel , set_hp_modem2active_backup_clk_sel : 17, 16; + pub u8, hp_sleep2active_backup_mode , set_hp_sleep2active_backup_mode : 22, 20; + pub u8, hp_modem2active_backup_mode , set_hp_modem2active_backup_mode : 25, 23; + pub bool, hp_sleep2active_backup_en , set_hp_sleep2active_backup_en : 29; + pub bool, hp_modem2active_backup_en , set_hp_modem2active_backup_en : 30; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_backup_reg_t/modem + pub struct HpModemBackup(u32); + + pub u8, hp_sleep2modem_backup_modem_clk_code , set_hp_sleep2modem_backup_modem_clk_code : 5, 4; + pub bool, hp_modem_retention_mode , set_hp_modem_retention_mode : 10; + pub bool, hp_sleep2modem_retention_en , set_hp_sleep2modem_retention_en : 11; + pub u8, hp_sleep2modem_backup_clk_sel , set_hp_sleep2modem_backup_clk_sel : 15, 14; + pub u8, hp_sleep2modem_backup_mode , set_hp_sleep2modem_backup_mode : 22, 20; + pub bool, hp_sleep2modem_backup_en , set_hp_sleep2modem_backup_en : 29; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_hp_backup_reg_t/sleep + pub struct HpSleepBackup(u32); + + pub u8, hp_modem2sleep_backup_modem_clk_code , set_hp_modem2sleep_backup_modem_clk_code : 7, 6; + pub u8, hp_active2sleep_backup_modem_clk_code, set_hp_active2sleep_backup_modem_clk_code: 9, 8; + pub bool, hp_sleep_retention_mode , set_hp_sleep_retention_mode : 10; + pub bool, hp_modem2sleep_retention_en , set_hp_modem2sleep_retention_en : 12; + pub bool, hp_active2sleep_retention_en , set_hp_active2sleep_retention_en : 13; + pub u8, hp_modem2sleep_backup_clk_sel , set_hp_modem2sleep_backup_clk_sel : 17, 16; + pub u8, hp_active2sleep_backup_clk_sel , set_hp_active2sleep_backup_clk_sel : 19, 18; + pub u8, hp_modem2sleep_backup_mode , set_hp_modem2sleep_backup_mode : 25, 23; + pub u8, hp_active2sleep_backup_mode , set_hp_active2sleep_backup_mode : 28, 26; + pub bool, hp_modem2sleep_backup_en , set_hp_modem2sleep_backup_en : 30; + pub bool, hp_active2sleep_backup_en , set_hp_active2sleep_backup_en : 31; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // custom based on `PMU_ICG_FUNC_ENA_*` bitflag constants + pub struct HpBackupClk(u32); + + pub bool, gdma , set_gdma : 0; + pub bool, spi2 , set_spi2 : 1; + pub bool, i2s_rx , set_i2s_rx : 2; + pub bool, uart0 , set_uart0 : 3; + pub bool, uart1 , set_uart1 : 4; + pub bool, uhci , set_uhci : 5; + pub bool, usb_device , set_usb_device : 6; + pub bool, i2s_tx , set_i2s_tx : 7; + pub bool, regdma , set_regdma : 8; + pub bool, retention , set_retention : 9; + pub bool, mem_monitor , set_mem_monitor : 10; + pub bool, sdio_slave , set_sdio_slave : 11; + pub bool, tsens , set_tsens : 12; + pub bool, tg1 , set_tg1 : 13; + pub bool, tg0 , set_tg0 : 14; + pub bool, hpbus , set_hpbus : 15; + pub bool, soc_etm , set_soc_etm : 16; + pub bool, hpcore , set_hpcore : 17; + pub bool, systimer , set_systimer : 18; + pub bool, sec , set_sec : 19; + pub bool, saradc , set_saradc : 20; + pub bool, rmt , set_rmt : 21; + pub bool, pwm , set_pwm : 22; + pub bool, pvt_monitor , set_pvt_monitor : 23; + pub bool, parl_tx , set_parl_tx : 24; + pub bool, parl_rx , set_parl_rx : 25; + pub bool, mspi , set_mspi : 26; + pub bool, ledc , set_ledc : 27; + pub bool, iomux , set_iomux : 28; + pub bool, i2c , set_i2c : 29; + pub bool, can1 , set_can1 : 30; + pub bool, can0 , set_can0 : 31; +} + +macro_rules! hp_system_init { + ($state:ident => $s:ident) => { + paste::paste! { + unsafe { + // Default configuration of hp-system power in active, modem and sleep modes + PMU::regs().[<$state _dig_power >]().modify(|_, w| w.bits($s.power.dig_power.0)); + PMU::regs().[<$state _hp_ck_power >]().modify(|_, w| w.bits($s.power.clk.0)); + PMU::regs().[<$state _xtal >]().modify(|_, w| w + .[<$state _xpd_xtal >]().bit($s.power.xtal.xpd_xtal()) + ); + + // Default configuration of hp-system clock in active, modem and sleep modes + PMU::regs().[<$state _icg_hp_func >]().write(|w| w.bits($s.clock.icg_func)); + PMU::regs().[<$state _icg_hp_apb >]().write(|w| w.bits($s.clock.icg_apb)); + PMU::regs().[<$state _icg_modem >]().write(|w| w + .[<$state _dig_icg_modem_code >]().bits($s.clock.icg_modem.code()) + ); + PMU::regs().[<$state _sysclk >]().modify(|_, w| w + .[<$state _dig_sys_clk_no_div >]().bit($s.clock.sysclk.dig_sysclk_nodiv()) + .[<$state _icg_sys_clock_en >]().bit($s.clock.sysclk.icg_sysclk_en()) + .[<$state _sys_clk_slp_sel >]().bit($s.clock.sysclk.sysclk_slp_sel()) + .[<$state _icg_slp_sel >]().bit($s.clock.sysclk.icg_slp_sel()) + .[<$state _dig_sys_clk_sel >]().bits($s.clock.sysclk.dig_sysclk_sel()) + ); + + // Default configuration of hp-system digital sub-system in active, modem + // and sleep modes + PMU::regs().[<$state _hp_sys_cntl >]().modify(|_, w| w + .[<$state _uart_wakeup_en >]().bit($s.syscntl.uart_wakeup_en()) + .[<$state _lp_pad_hold_all >]().bit($s.syscntl.lp_pad_hold_all()) + .[<$state _hp_pad_hold_all >]().bit($s.syscntl.hp_pad_hold_all()) + .[<$state _dig_pad_slp_sel >]().bit($s.syscntl.dig_pad_slp_sel()) + .[<$state _dig_pause_wdt >]().bit($s.syscntl.dig_pause_wdt()) + .[<$state _dig_cpu_stall >]().bit($s.syscntl.dig_cpu_stall()) + ); + + // Default configuration of hp-system analog sub-system in active, modem and + // sleep modes + PMU::regs().[<$state _bias >]().modify(|_, w| w + .[<$state _xpd_bias >]().bit($s.anlg.bias.xpd_bias()) + .[<$state _dbg_atten >]().bits($s.anlg.bias.dbg_atten()) + .[<$state _pd_cur >]().bit($s.anlg.bias.pd_cur()) + .sleep().bit($s.anlg.bias.bias_sleep()) + ); + + PMU::regs().[<$state _hp_regulator0 >]().modify(|_, w| w + .[<$state _hp_regulator_slp_mem_xpd >]().bit($s.anlg.regulator0.slp_mem_xpd()) + .[<$state _hp_regulator_slp_logic_xpd >]().bit($s.anlg.regulator0.slp_logic_xpd()) + .[<$state _hp_regulator_xpd >]().bit($s.anlg.regulator0.xpd()) + .[<$state _hp_regulator_slp_mem_dbias >]().bits($s.anlg.regulator0.slp_mem_dbias()) + .[<$state _hp_regulator_slp_logic_dbias >]().bits($s.anlg.regulator0.slp_logic_dbias()) + .[<$state _hp_regulator_dbias >]().bits($s.anlg.regulator0.dbias()) + ); + + PMU::regs().[<$state _hp_regulator1 >]().modify(|_, w| w + .[<$state _hp_regulator_drv_b >]().bits($s.anlg.regulator1.drv_b()) + ); + + // Default configuration of hp-system retention sub-system in active, modem + // and sleep modes + PMU::regs().[<$state _backup >]().write(|w| w.bits($s.retention)); + PMU::regs().[<$state _backup_clk >]().write(|w| w.bits($s.backup_clk)); + } + } + }; +} + +struct HpSystemInit { + power: HpSysPower, + clock: SystemClockParam, + syscntl: HpSysCntlReg, + anlg: HpAnalog, + retention: u32, + backup_clk: u32, +} +impl HpSystemInit { + fn active() -> Self { + // pmu_hp_system_init_default + + let mut power = HpSysPower::default(); + power.dig_power.set_vdd_spi_pd_en(false); + power.dig_power.set_wifi_pd_en(false); + power.dig_power.set_cpu_pd_en(false); + power.dig_power.set_aon_pd_en(false); + power.dig_power.set_top_pd_en(false); + power.dig_power.set_mem_pd_en(0); + power.dig_power.set_mem_dslp(false); + + power.clk.set_i2c_iso_en(false); + power.clk.set_i2c_retention(false); + power.clk.set_xpd_bb_i2c(true); + power.clk.set_xpd_bbpll_i2c(true); + power.clk.set_xpd_bbpll(true); + + power.xtal.set_xpd_xtal(true); + + let mut clock = SystemClockParam { + icg_func: 0xffffffff, + icg_apb: 0xffffffff, + ..SystemClockParam::default() + }; + clock.icg_modem.set_code(ICG_MODEM_CODE_ACTIVE); + clock.sysclk.set_dig_sysclk_nodiv(false); + clock.sysclk.set_icg_sysclk_en(true); + clock.sysclk.set_sysclk_slp_sel(false); + clock.sysclk.set_icg_slp_sel(false); + clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL); + + let mut syscntl = HpSysCntlReg::default(); + syscntl.set_uart_wakeup_en(false); + syscntl.set_lp_pad_hold_all(false); + syscntl.set_hp_pad_hold_all(false); + syscntl.set_dig_pad_slp_sel(false); + syscntl.set_dig_pause_wdt(false); + syscntl.set_dig_cpu_stall(false); + + // PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT + let mut anlg = HpAnalog::default(); + anlg.bias.set_xpd_bias(true); + anlg.bias.set_dbg_atten(0x0); + anlg.bias.set_pd_cur(false); + anlg.bias.set_bias_sleep(false); + + // TODO: These 4 aren't applied currently? + anlg.regulator0.set_lp_dbias_vol(0xD); + anlg.regulator0.set_hp_dbias_vol(0x1C); + anlg.regulator0.set_dbias_sel(true); + anlg.regulator0.set_dbias_init(true); + + anlg.regulator0.set_slp_mem_xpd(false); + anlg.regulator0.set_slp_logic_xpd(false); + anlg.regulator0.set_xpd(true); + anlg.regulator0.set_slp_mem_dbias(0); + anlg.regulator0.set_slp_logic_dbias(0); + anlg.regulator0.set_dbias(HP_CALI_DBIAS); + + anlg.regulator1.set_drv_b(0); + + let mut retention = HpActiveBackup::default(); + retention.set_hp_sleep2active_backup_modem_clk_code(2); + retention.set_hp_modem2active_backup_modem_clk_code(2); + retention.set_hp_active_retention_mode(false); + retention.set_hp_sleep2active_retention_en(false); + retention.set_hp_modem2active_retention_en(false); + retention.set_hp_sleep2active_backup_clk_sel(0); + retention.set_hp_modem2active_backup_clk_sel(1); + retention.set_hp_sleep2active_backup_mode(hp_retention_regdma_config(0, 0)); + retention.set_hp_modem2active_backup_mode(hp_retention_regdma_config(0, 2)); + retention.set_hp_sleep2active_backup_en(false); + retention.set_hp_modem2active_backup_en(false); + + let mut backup_clk = HpBackupClk::default(); + backup_clk.set_regdma(true); + backup_clk.set_tg0(true); + backup_clk.set_tg1(true); + backup_clk.set_hpbus(true); + backup_clk.set_mspi(true); + backup_clk.set_iomux(true); + backup_clk.set_spi2(true); + backup_clk.set_uart0(true); + backup_clk.set_systimer(true); + + Self { + power, + clock, + syscntl, + anlg, + retention: retention.0, + backup_clk: backup_clk.0, + } + } + + fn modem() -> Self { + let mut power = HpSysPower::default(); + power.dig_power.set_vdd_spi_pd_en(false); + power.dig_power.set_wifi_pd_en(false); + power.dig_power.set_cpu_pd_en(true); + power.dig_power.set_aon_pd_en(false); + power.dig_power.set_top_pd_en(false); + power.dig_power.set_mem_pd_en(0); + power.dig_power.set_mem_dslp(false); + + power.clk.set_xpd_bb_i2c(true); + power.clk.set_xpd_bbpll_i2c(true); + power.clk.set_xpd_bbpll(true); + power.clk.set_i2c_iso_en(false); + power.clk.set_i2c_retention(false); + + power.xtal.set_xpd_xtal(true); + + let mut clock = SystemClockParam { + icg_func: 0, + icg_apb: 0, + ..SystemClockParam::default() + }; + clock.icg_modem.set_code(ICG_MODEM_CODE_MODEM); + clock.sysclk.set_dig_sysclk_nodiv(false); + clock.sysclk.set_icg_sysclk_en(true); + clock.sysclk.set_sysclk_slp_sel(true); + clock.sysclk.set_icg_slp_sel(true); + clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_PLL); + + let mut syscntl = HpSysCntlReg::default(); + syscntl.set_uart_wakeup_en(true); + syscntl.set_lp_pad_hold_all(false); + syscntl.set_hp_pad_hold_all(false); + syscntl.set_dig_pad_slp_sel(false); + syscntl.set_dig_pause_wdt(true); + syscntl.set_dig_cpu_stall(true); + + let mut anlg = HpAnalog::default(); + anlg.bias.set_xpd_bias(false); + anlg.bias.set_dbg_atten(0x0); + anlg.bias.set_pd_cur(false); + anlg.bias.set_bias_sleep(false); + + anlg.regulator0.set_slp_mem_xpd(false); + anlg.regulator0.set_slp_logic_xpd(false); + anlg.regulator0.set_xpd(true); + anlg.regulator0.set_slp_mem_dbias(0); + anlg.regulator0.set_slp_logic_dbias(0); + anlg.regulator0.set_dbias(HP_CALI_DBIAS); + + anlg.regulator1.set_drv_b(0); + + let mut retention = HpModemBackup::default(); + retention.set_hp_sleep2modem_backup_modem_clk_code(1); + retention.set_hp_modem_retention_mode(false); + retention.set_hp_sleep2modem_retention_en(false); + retention.set_hp_sleep2modem_backup_clk_sel(0); + retention.set_hp_sleep2modem_backup_mode(hp_retention_regdma_config(0, 1)); + retention.set_hp_sleep2modem_backup_en(false); + + let mut backup_clk = HpBackupClk::default(); + backup_clk.set_regdma(true); + backup_clk.set_tg0(true); + backup_clk.set_tg1(true); + backup_clk.set_hpbus(true); + backup_clk.set_mspi(true); + backup_clk.set_iomux(true); + backup_clk.set_spi2(true); + backup_clk.set_uart0(true); + backup_clk.set_systimer(true); + + Self { + power, + clock, + syscntl, + anlg, + retention: retention.0, + backup_clk: backup_clk.0, + } + } + + fn sleep() -> Self { + let mut power = HpSysPower::default(); + power.dig_power.set_vdd_spi_pd_en(true); + power.dig_power.set_mem_dslp(false); + power.dig_power.set_mem_pd_en(0); + power.dig_power.set_wifi_pd_en(true); + power.dig_power.set_cpu_pd_en(false); + power.dig_power.set_aon_pd_en(false); + power.dig_power.set_top_pd_en(false); + + power.clk.set_i2c_iso_en(true); + power.clk.set_i2c_retention(true); + power.clk.set_xpd_bb_i2c(true); + power.clk.set_xpd_bbpll_i2c(false); + power.clk.set_xpd_bbpll(false); + + power.xtal.set_xpd_xtal(false); + + let mut clock = SystemClockParam { + icg_func: 0, + icg_apb: 0, + ..SystemClockParam::default() + }; + clock.icg_modem.set_code(ICG_MODEM_CODE_SLEEP); + clock.sysclk.set_dig_sysclk_nodiv(false); + clock.sysclk.set_icg_sysclk_en(false); + clock.sysclk.set_sysclk_slp_sel(true); + clock.sysclk.set_icg_slp_sel(true); + clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL); + + let mut anlg = HpAnalog::default(); + anlg.bias.set_xpd_bias(false); + anlg.bias.set_dbg_atten(0x0); + anlg.bias.set_pd_cur(false); + anlg.bias.set_bias_sleep(false); + + anlg.regulator0.set_slp_mem_xpd(false); + anlg.regulator0.set_slp_logic_xpd(false); + anlg.regulator0.set_xpd(true); + anlg.regulator0.set_slp_mem_dbias(0); + anlg.regulator0.set_slp_logic_dbias(0); + anlg.regulator0.set_dbias(1); + + anlg.regulator1.set_drv_b(0); + + let mut retention = HpSleepBackup::default(); + retention.set_hp_modem2sleep_backup_modem_clk_code(0); + retention.set_hp_active2sleep_backup_modem_clk_code(2); + retention.set_hp_sleep_retention_mode(false); + retention.set_hp_modem2sleep_retention_en(false); + retention.set_hp_active2sleep_retention_en(false); + retention.set_hp_modem2sleep_backup_clk_sel(0); + retention.set_hp_active2sleep_backup_clk_sel(0); + retention.set_hp_modem2sleep_backup_mode(hp_retention_regdma_config(1, 1)); + retention.set_hp_active2sleep_backup_mode(hp_retention_regdma_config(1, 0)); + retention.set_hp_modem2sleep_backup_en(false); + retention.set_hp_active2sleep_backup_en(false); + + let mut backup_clk = HpBackupClk::default(); + backup_clk.set_regdma(true); + backup_clk.set_tg0(true); + backup_clk.set_tg1(true); + backup_clk.set_hpbus(true); + backup_clk.set_mspi(true); + backup_clk.set_iomux(true); + backup_clk.set_spi2(true); + backup_clk.set_uart0(true); + backup_clk.set_systimer(true); + + let mut syscntl = HpSysCntlReg::default(); + syscntl.set_uart_wakeup_en(true); + syscntl.set_lp_pad_hold_all(false); + syscntl.set_hp_pad_hold_all(false); + syscntl.set_dig_pad_slp_sel(true); + syscntl.set_dig_pause_wdt(true); + syscntl.set_dig_cpu_stall(true); + + Self { + power, + clock, + syscntl, + anlg, + retention: retention.0, + backup_clk: backup_clk.0, + } + } + + fn init_default() { + let active = Self::active(); + let modem = Self::modem(); + let sleep = Self::sleep(); + + hp_system_init!(hp_active => active); + hp_system_init!(hp_modem => modem); + hp_system_init!(hp_sleep => sleep); + + unsafe { + // Some PMU initial parameter configuration + PMU::regs() + .imm_modem_icg() + .write(|w| w.update_dig_icg_modem_en().bit(true)); + PMU::regs() + .imm_sleep_sysclk() + .write(|w| w.update_dig_icg_switch().bit(true)); + + const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2; + PMU::regs() + .slp_wakeup_cntl3() + .modify(|_, w| w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP)); + } + } +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_lp_power_t.0 + pub struct LpDigPower(u32); + + pub u32, mem_dslp , set_mem_dslp : 30; + pub u32, peri_pd_en, set_peri_pd_en: 31; + +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_lp_power_t.1 + pub struct LpClkPower(u32); + + pub u32, xpd_xtal32k, set_xpd_xtal32k: 28; + pub u32, xpd_rc32k , set_xpd_rc32k : 29; + pub u32, xpd_fosc , set_xpd_fosc : 30; + pub u32, pd_osc , set_pd_osc : 31; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_lp_power_t.2 + pub struct LpXtalPower(u32); + + pub bool, xpd_xtal , set_xpd_xtal : 31; +} + +#[derive(Clone, Copy, Default)] +// pmu_sleep_power_config_t.1 +pub struct LpSysPower { + // This is a best-guess assignment of the variants in the union `pmu_lp_power_t` union + // In esp-idf, all three fields are `pmu_lp_power_t` + pub dig_power: LpDigPower, + pub clk_power: LpClkPower, + pub xtal: LpXtalPower, +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_lp_analog_t.0 + pub struct LpAnalogBias(u32); + + pub bool, xpd_bias , set_xpd_bias : 25; + pub u8, dbg_atten , set_dbg_atten : 29, 26; + pub bool, pd_cur , set_pd_cur : 30; + pub bool, bias_sleep, set_bias_sleep: 31; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_lp_analog_t.1 + pub struct LpAnalogRegulator0(u32); + + pub bool, slp_xpd , set_slp_xpd : 21; + pub bool, xpd , set_xpd : 22; + pub u8, slp_dbias, set_slp_dbias: 26, 23; + pub u8, dbias , set_dbias : 31, 27; +} + +bitfield::bitfield! { + #[derive(Clone, Copy, Default)] + // pmu_lp_analog_t.2 + pub struct LpAnalogRegulator1(u32); + + pub u8, drv_b , set_drv_b : 31, 28; +} + +#[derive(Clone, Copy, Default)] +// pmu_lp_analog_t +pub struct LpAnalog { + pub bias: LpAnalogBias, + pub regulator0: LpAnalogRegulator0, + pub regulator1: LpAnalogRegulator1, +} + +macro_rules! lp_system_init { + ($state:ident => $s:ident) => { + paste::paste! { + unsafe { + // Default configuration of lp-system power in active and sleep modes + PMU::regs().[< $state _dig_power >]().modify(|_, w| w.bits($s.dig_power.0)); + PMU::regs().[< $state _ck_power >]().modify(|_, w| w.bits($s.clk_power.0)); + + // Default configuration of lp-system analog sub-system in active and sleep modes + PMU::regs().[< $state _regulator0 >]().modify(|_, w| w + .[< $state _regulator_slp_xpd >]().bit($s.analog_regulator0.slp_xpd()) + .[< $state _regulator_xpd >]().bit($s.analog_regulator0.xpd()) + .[< $state _regulator_slp_dbias >]().bits($s.analog_regulator0.slp_dbias()) + .[< $state _regulator_dbias >]().bits($s.analog_regulator0.dbias()) + ); + + PMU::regs().[< $state _regulator1 >]().modify(|_, w| w + .[< $state _regulator_drv_b >]().bits($s.analog_regulator1.drv_b()) + ); + } + } + }; +} + +struct LpSystemInit { + dig_power: LpDigPower, + clk_power: LpClkPower, + xtal: LpXtalPower, + bias: LpAnalogBias, + analog_regulator0: LpAnalogRegulator0, + analog_regulator1: LpAnalogRegulator1, +} +impl LpSystemInit { + fn active() -> Self { + let mut dig_power = LpDigPower::default(); + dig_power.set_peri_pd_en(false); + dig_power.set_mem_dslp(false); + + let mut clk_power = LpClkPower::default(); + clk_power.set_xpd_xtal32k(true); + clk_power.set_xpd_rc32k(true); + clk_power.set_xpd_fosc(true); + + let mut analog_regulator0 = LpAnalogRegulator0::default(); + analog_regulator0.set_slp_xpd(false); + analog_regulator0.set_xpd(true); + analog_regulator0.set_slp_dbias(0); + analog_regulator0.set_dbias(26); + + let mut analog_regulator1 = LpAnalogRegulator1::default(); + analog_regulator1.set_drv_b(0); + + Self { + dig_power, + clk_power, + xtal: LpXtalPower::default(), + bias: LpAnalogBias::default(), + analog_regulator0, + analog_regulator1, + } + } + + fn sleep() -> Self { + let mut dig_power = LpDigPower::default(); + dig_power.set_mem_dslp(true); + dig_power.set_peri_pd_en(false); + + let mut clk_power = LpClkPower::default(); + clk_power.set_xpd_xtal32k(false); + clk_power.set_xpd_rc32k(false); + clk_power.set_xpd_fosc(false); + clk_power.set_pd_osc(false); + + let mut xtal = LpXtalPower::default(); + xtal.set_xpd_xtal(false); + + let mut analog_bias = LpAnalogBias::default(); + analog_bias.set_xpd_bias(false); + analog_bias.set_dbg_atten(0); + analog_bias.set_pd_cur(true); + analog_bias.set_bias_sleep(true); + + let mut analog_regulator0 = LpAnalogRegulator0::default(); + analog_regulator0.set_slp_xpd(false); + analog_regulator0.set_xpd(true); + analog_regulator0.set_slp_dbias(0); + analog_regulator0.set_dbias(12); + + let mut analog_regulator1 = LpAnalogRegulator1::default(); + analog_regulator1.set_drv_b(0); + + Self { + dig_power, + clk_power, + xtal, + bias: analog_bias, + analog_regulator0, + analog_regulator1, + } + } + + fn init_default() { + let active = Self::active(); + let sleep = Self::sleep(); + + lp_system_init!(hp_sleep_lp => active); + lp_system_init!(lp_sleep_lp => sleep); + + PMU::regs() + .lp_sleep_xtal() + .modify(|_, w| w.lp_sleep_xpd_xtal().bit(sleep.xtal.xpd_xtal())); + + PMU::regs().lp_sleep_bias().modify(|_, w| unsafe { + w.lp_sleep_xpd_bias().bit(sleep.bias.xpd_bias()); // pmu_ll_lp_set_bias_xpd + w.lp_sleep_dbg_atten().bits(sleep.bias.dbg_atten()); // pmu_ll_lp_set_bias_dbg_atten + w.lp_sleep_pd_cur().bit(sleep.bias.pd_cur()); // pmu_ll_lp_set_bias_pd_cur + w.sleep().bit(sleep.bias.bias_sleep()) // pmu_ll_lp_set_bias_sleep + }); + } +} + +pub(crate) fn init() { + // pmu_init() + PMU::regs() + .rf_pwc() + .modify(|_, w| w.perif_i2c_rstb().set_bit().xpd_perif_i2c().set_bit()); + + // regi2c::I2C_DIG_REG_ENIF_RTC_DREG.write_field(1); + // regi2c::I2C_DIG_REG_ENIF_DIG_DREG.write_field(1); + // regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0); + // regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0); + + HpSystemInit::init_default(); + LpSystemInit::init_default(); + + pmu_power_domain_force_default(); + + // esp_perip_clk_init() + modem_clock_domain_power_state_icg_map_init(); + + // During system initialization, the low-power clock source of the modem + // (WiFi, BLE or Coexist) follows the configuration of the slow clock source + // of the system. If the WiFi, BLE or Coexist module needs a higher + // precision sleep clock (for example, the BLE needs to use the main XTAL + // oscillator (40 MHz) to provide the clock during the sleep process in some + // scenarios), the module needs to switch to the required clock source by + // itself. + // TODO - WIFI-5233 + let modem_lpclk_src = ModemClockLpclkSource::from(RtcSlowClockSource::current()); + + modem_clock_select_lp_clock_source_wifi(modem_lpclk_src, 0); + + RtcClock::set_fast_freq(RtcFastClock::RcFast); + RtcClock::set_slow_freq(RtcSlowClock::RcSlow); +} + +pub(crate) fn configure_clock() { + let cal_val = loop { + let res = RtcClock::calibrate(RtcCalSel::RtcMux, 1024); + if res != 0 { + break res; + } + }; + + LPWR::regs() + .store1() + .modify(|_, w| unsafe { w.bits(cal_val) }); + + modem_clk_domain_active_state_icg_map_preinit(); +} + +fn modem_clk_domain_active_state_icg_map_preinit() { + todo!() +} + +// Terminology: +// +// CPU Reset: Reset CPU core only, once reset done, CPU will execute from +// reset vector +// Core Reset: Reset the whole digital system except RTC sub-system +// System Reset: Reset the whole digital system, including RTC sub-system +// Chip Reset: Reset the whole chip, including the analog part + +/// SOC Reset Reason. +#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] +pub enum SocResetReason { + /// Power on reset + /// + /// In ESP-IDF this value (0x01) can *also* be `ChipBrownOut` or + /// `ChipSuperWdt`, however that is not really compatible with Rust-style + /// enums. + ChipPowerOn = 0x01, + /// Software resets the digital core by RTC_CNTL_SW_SYS_RST + CoreSw = 0x03, + /// Deep sleep reset the digital core + CoreDeepSleep = 0x05, + /// SDIO Core reset + CoreSDIO = 0x06, + /// Main watch dog 0 resets digital core + CoreMwdt0 = 0x07, + /// Main watch dog 1 resets digital core + CoreMwdt1 = 0x08, + /// RTC watch dog resets digital core + CoreRtcWdt = 0x09, + /// Main watch dog 0 resets CPU 0 + Cpu0Mwdt0 = 0x0B, + /// Software resets CPU 0 by RTC_CNTL_SW_PROCPU_RST + Cpu0Sw = 0x0C, + /// RTC watch dog resets CPU 0 + Cpu0RtcWdt = 0x0D, + /// VDD voltage is not stable and resets the digital core + SysBrownOut = 0x0F, + /// RTC watch dog resets digital core and rtc module + SysRtcWdt = 0x10, + /// Main watch dog 1 resets CPU 0 + Cpu0Mwdt1 = 0x11, + /// Super watch dog resets the digital core and rtc module + SysSuperWdt = 0x12, + /// eFuse CRC error resets the digital core + CoreEfuseCrc = 0x14, + /// USB UART resets the digital core + CoreUsbUart = 0x15, + /// USB JTAG resets the digital core + CoreUsbJtag = 0x16, + /// JTAG resets CPU + Cpu0JtagCpu = 0x18, +} + +// #[derive(Clone, Copy)] +// pub(crate) struct SavedClockConfig { +// /// The clock from which CPU clock is derived +// old_soc_root_clk: Option, +// } + +// impl SavedClockConfig { +// pub(crate) fn save(clocks: &ClockTree) -> Self { +// let old_soc_root_clk = clocks.soc_root_clk(); + +// SavedClockConfig { old_soc_root_clk } +// } + +// // rtc_clk_cpu_freq_set_config +// pub(crate) fn restore(self, clocks: &mut ClockTree) { +// if let Some(old_soc_root_clk) = self.old_soc_root_clk { +// // crate::soc::clocks::configure_soc_root_clk(clocks, old_soc_root_clk); +// } +// } +// } diff --git a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs new file mode 100644 index 00000000000..9bac1c24a24 --- /dev/null +++ b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs @@ -0,0 +1,1064 @@ +use core::ops::Not; + +use crate::{ + clock::Clock, + efuse::Efuse, + gpio::RtcFunction, + rtc_cntl::{ + Rtc, + RtcCalSel, + RtcClock, + rtc::{HpAnalog, HpSysCntlReg, HpSysPower, LpAnalog, LpSysPower, SavedClockConfig}, + sleep::{ + Ext1WakeupSource, + TimerWakeupSource, + WakeFromLpCoreWakeupSource, + WakeSource, + WakeTriggers, + WakeupLevel, + }, + }, + soc::clocks::ClockTree, +}; + +impl WakeSource for TimerWakeupSource { + fn apply( + &self, + rtc: &Rtc<'_>, + triggers: &mut WakeTriggers, + _sleep_config: &mut RtcSleepConfig, + ) { + triggers.set_timer(true); + + let lp_timer = unsafe { &*esp32p4::LP_TIMER::ptr() }; + let clock_freq = RtcClock::slow_freq(); + // TODO: maybe add sleep time adjustment like idf + // TODO: maybe add check to prevent overflow? + let clock_hz = clock_freq.frequency().as_hz() as u64; + let ticks = self.duration.as_micros() as u64 * clock_hz / 1_000_000u64; + // "alarm" time in slow rtc ticks + let now = rtc.time_since_boot_raw(); + let time_in_ticks = now + ticks; + unsafe { + lp_timer.tar0_high().write(|w| { + w.main_timer_tar_high0() + .bits(((time_in_ticks >> 32) & 0xffff) as u16) + }); + lp_timer.tar0_low().write(|w| { + w.main_timer_tar_low0() + .bits((time_in_ticks & 0xffffffff) as u32) + }); + lp_timer + .int_clr() + .write(|w| w.soc_wakeup().clear_bit_by_one()); + lp_timer + .tar0_high() + .modify(|_, w| w.main_timer_tar_en0().set_bit()); + } + } +} + +impl Ext1WakeupSource<'_, '_> { + /// Returns the currently configured wakeup pins. + fn wakeup_pins() -> u8 { + unsafe { lp_aon().ext_wakeup_cntl().read().ext_wakeup_sel().bits() } + } + + fn wake_io_reset() { + use crate::gpio::RtcPin; + + fn uninit_pin(pin: impl RtcPin, wakeup_pins: u8) { + if wakeup_pins & (1 << pin.number()) != 0 { + pin.rtcio_pad_hold(false); + pin.rtc_set_config(false, false, RtcFunction::Rtc); + } + } + + let wakeup_pins = Ext1WakeupSource::wakeup_pins(); + uninit_pin(unsafe { crate::peripherals::GPIO0::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO1::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO2::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO3::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO4::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO5::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO6::steal() }, wakeup_pins); + uninit_pin(unsafe { crate::peripherals::GPIO7::steal() }, wakeup_pins); + } +} + +impl WakeSource for Ext1WakeupSource<'_, '_> { + fn apply( + &self, + _rtc: &Rtc<'_>, + triggers: &mut WakeTriggers, + _sleep_config: &mut RtcSleepConfig, + ) { + // We don't have to keep the LP domain powered if we hold the wakeup pin states. + triggers.set_ext1(true); + + // set pins to RTC function + let mut pins = self.pins.borrow_mut(); + let mut pin_mask = 0u8; + let mut level_mask = 0u8; + for (pin, level) in pins.iter_mut() { + pin_mask |= 1 << pin.number(); + level_mask |= match level { + WakeupLevel::High => 1 << pin.number(), + WakeupLevel::Low => 0, + }; + + pin.rtc_set_config(true, true, RtcFunction::Rtc); + pin.rtcio_pad_hold(true); + } + + unsafe { + // clear previous wakeup status + lp_aon() + .ext_wakeup_cntl() + .modify(|_, w| w.ext_wakeup_status_clr().set_bit()); + + // set pin + level register fields + lp_aon().ext_wakeup_cntl().modify(|r, w| { + w.ext_wakeup_sel() + .bits(r.ext_wakeup_sel().bits() | pin_mask) + .ext_wakeup_lv() + .bits(r.ext_wakeup_lv().bits() & !pin_mask | level_mask) + }); + } + } +} + +impl Drop for Ext1WakeupSource<'_, '_> { + fn drop(&mut self) { + // should we have saved the pin configuration first? + // set pin back to IO_MUX (input_enable and func have no effect when pin is sent + // to IO_MUX) + let mut pins = self.pins.borrow_mut(); + for (pin, _level) in pins.iter_mut() { + pin.rtc_set_config(true, false, RtcFunction::Rtc); + } + } +} + +impl WakeSource for WakeFromLpCoreWakeupSource { + fn apply( + &self, + _rtc: &Rtc<'_>, + triggers: &mut WakeTriggers, + _sleep_config: &mut RtcSleepConfig, + ) { + triggers.set_lp_core(true); + } +} + +/// Configuration for controlling the behavior during sleep modes. +#[derive(Clone, Copy)] +// pmu_sleep_analog_config_t +pub struct AnalogSleepConfig { + /// High-power system configuration. + pub hp_sys: HpAnalog, + // pub lp_sys_active: LpAnalog, // unused + /// Low-power system analog configuration. + pub lp_sys_sleep: LpAnalog, +} + +impl AnalogSleepConfig { + fn defaults_deep_sleep() -> Self { + Self { + // PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT + hp_sys: { + let mut cfg = HpAnalog::default(); + + cfg.bias.set_pd_cur(false); + cfg.bias.set_bias_sleep(false); + cfg.regulator0.set_xpd(false); + cfg.bias.set_dbg_atten(0); + + cfg + }, + // lp_sys_active: LpAnalog::default(), + lp_sys_sleep: { + let mut cfg = LpAnalog::default(); + + cfg.regulator1.set_drv_b(0); + cfg.bias.set_pd_cur(true); + cfg.bias.set_bias_sleep(true); + cfg.regulator0.set_slp_xpd(false); + cfg.regulator0.set_slp_dbias(0); + cfg.regulator0.set_xpd(true); + cfg.bias.set_dbg_atten(12); + cfg.regulator0.set_dbias(23); // 0.7V + + cfg + }, + } + } + + fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self { + let mut this = Self { + // PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT + hp_sys: { + let mut cfg = HpAnalog::default(); + + cfg.regulator1.set_drv_b(0); + cfg.bias.set_pd_cur(true); + cfg.bias.set_bias_sleep(true); + cfg.regulator0.set_xpd(true); + cfg.bias.set_dbg_atten(0); + cfg.regulator0.set_dbias(1); // 0.6V + + cfg + }, + // lp_sys_active: LpAnalog::default(), + lp_sys_sleep: { + let mut cfg = LpAnalog::default(); + + cfg.regulator1.set_drv_b(0); + cfg.bias.set_pd_cur(true); + cfg.bias.set_bias_sleep(true); + cfg.regulator0.set_slp_xpd(false); + cfg.regulator0.set_slp_dbias(0); + cfg.regulator0.set_xpd(true); + cfg.bias.set_dbg_atten(0); + cfg.regulator0.set_dbias(12); // 0.7V + + cfg + }, + }; + + if !pd_flags.pd_xtal() { + this.hp_sys.bias.set_pd_cur(false); + this.hp_sys.bias.set_bias_sleep(false); + this.hp_sys.regulator0.set_dbias(25); + + this.lp_sys_sleep.bias.set_pd_cur(false); + this.lp_sys_sleep.bias.set_bias_sleep(false); + this.lp_sys_sleep.regulator0.set_dbias(26); + } + + this + } + + fn apply(&self) { + // pmu_sleep_analog_init + + unsafe { + // HP SLEEP (hp_sleep_*) + pmu().hp_sleep_bias().modify(|_, w| { + w.hp_sleep_dbg_atten() // pmu_ll_hp_set_dbg_atten + .bits(self.hp_sys.bias.dbg_atten()) + .hp_sleep_pd_cur() // pmu_ll_hp_set_current_power_off + .bit(self.hp_sys.bias.pd_cur()) + .sleep() // pmu_ll_hp_set_bias_sleep_enable + .bit(self.hp_sys.bias.bias_sleep()) + }); + pmu().hp_sleep_hp_regulator0().modify(|_, w| { + w.hp_sleep_hp_regulator_xpd() // pmu_ll_hp_set_regulator_xpd + .bit(self.hp_sys.regulator0.xpd()) + .hp_sleep_hp_regulator_dbias() // pmu_ll_hp_set_regulator_dbias + .bits(self.hp_sys.regulator0.dbias()) + }); + pmu().hp_sleep_hp_regulator1().modify(|_, w| { + w.hp_sleep_hp_regulator_drv_b() // pmu_ll_hp_set_regulator_driver_bar + .bits(self.hp_sys.regulator1.drv_b()) + }); + + // LP SLEEP (lp_sleep_*) + pmu().lp_sleep_bias().modify(|_, w| { + w.lp_sleep_dbg_atten() // pmu_ll_lp_set_dbg_atten + .bits(self.lp_sys_sleep.bias.dbg_atten()) + .lp_sleep_pd_cur() // pmu_ll_lp_set_current_power_off + .bit(self.lp_sys_sleep.bias.pd_cur()) + .sleep() // pmu_ll_lp_set_bias_sleep_enable + .bit(self.lp_sys_sleep.bias.bias_sleep()) + }); + + pmu().lp_sleep_lp_regulator0().modify(|_, w| { + w.lp_sleep_lp_regulator_slp_xpd() // pmu_ll_lp_set_regulator_slp_xpd + .bit(self.lp_sys_sleep.regulator0.slp_xpd()) + .lp_sleep_lp_regulator_xpd() // pmu_ll_lp_set_regulator_xpd + .bit(self.lp_sys_sleep.regulator0.xpd()) + .lp_sleep_lp_regulator_slp_dbias() // pmu_ll_lp_set_regulator_sleep_dbias + .bits(self.lp_sys_sleep.regulator0.slp_dbias()) + .lp_sleep_lp_regulator_dbias() // pmu_ll_lp_set_regulator_dbias + .bits(self.lp_sys_sleep.regulator0.dbias()) + }); + + pmu().lp_sleep_lp_regulator1().modify(|_, w| { + w.lp_sleep_lp_regulator_drv_b() // pmu_ll_lp_set_regulator_driver_bar + .bits(self.lp_sys_sleep.regulator1.drv_b()) + }); + } + } +} + +/// Configuration for controlling the behavior of digital peripherals during +/// sleep modes. +#[derive(Clone, Copy)] +// pmu_sleep_digital_config_t +pub struct DigitalSleepConfig { + /// High-power system control register configuration. + pub syscntl: HpSysCntlReg, +} + +impl DigitalSleepConfig { + fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self { + Self { + // PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT + syscntl: { + let mut cfg = HpSysCntlReg::default(); + + cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not()); + + cfg + }, + } + } + + fn apply(&self) { + // pmu_sleep_digital_init + unsafe { + pmu().hp_sleep_hp_sys_cntl().modify(|_, w| { + w.hp_sleep_dig_pad_slp_sel() + .bit(self.syscntl.dig_pad_slp_sel()) + }) + }; + } +} + +/// Configuration for controlling the power settings of high-power and low-power +/// systems during sleep modes. +#[derive(Clone, Copy)] +// pmu_sleep_power_config_t +pub struct PowerSleepConfig { + /// Power configuration for the high-power system during sleep. + pub hp_sys: HpSysPower, + /// Power configuration for the low-power system when it is active. + pub lp_sys_active: LpSysPower, + /// Power configuration for the low-power system when it is in sleep mode. + pub lp_sys_sleep: LpSysPower, +} + +impl PowerSleepConfig { + fn defaults(pd_flags: PowerDownFlags) -> Self { + let mut this = Self { + hp_sys: HpSysPower::default(), + lp_sys_active: LpSysPower::default(), + lp_sys_sleep: LpSysPower::default(), + }; + this.apply_flags(pd_flags); + this + } + + fn apply_flags(&mut self, pd_flags: PowerDownFlags) { + // PMU_SLEEP_POWER_CONFIG_DEFAULT + self.hp_sys + .dig_power + .set_vdd_spi_pd_en(pd_flags.pd_vddsdio()); + self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem()); + self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu()); + self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon()); + self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top()); + + self.hp_sys.clk.set_i2c_iso_en(true); + self.hp_sys.clk.set_i2c_retention(true); + + self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not()); + + self.lp_sys_active.clk_power.set_xpd_xtal32k(true); + self.lp_sys_active.clk_power.set_xpd_rc32k(true); + self.lp_sys_active.clk_power.set_xpd_fosc(true); + + self.lp_sys_sleep + .dig_power + .set_peri_pd_en(pd_flags.pd_lp_periph()); + self.lp_sys_sleep.dig_power.set_mem_dslp(true); + + self.lp_sys_sleep + .clk_power + .set_xpd_xtal32k(pd_flags.pd_xtal32k().not()); + self.lp_sys_sleep + .clk_power + .set_xpd_rc32k(pd_flags.pd_rc32k().not()); + self.lp_sys_sleep + .clk_power + .set_xpd_fosc(pd_flags.pd_rc_fast().not()); + + self.lp_sys_sleep + .xtal + .set_xpd_xtal(pd_flags.pd_xtal().not()); + } + + fn apply(&self) { + // pmu_sleep_power_init + + unsafe { + // HP SLEEP (hp_sleep_*) + pmu() + .hp_sleep_dig_power() + .modify(|_, w| w.bits(self.hp_sys.dig_power.0)); + pmu() + .hp_sleep_hp_ck_power() + .modify(|_, w| w.bits(self.hp_sys.clk.0)); + pmu() + .hp_sleep_xtal() + .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal())); + + // LP ACTIVE (hp_sleep_lp_*) + pmu() + .hp_sleep_lp_dig_power() + .modify(|_, w| w.bits(self.lp_sys_active.dig_power.0)); + pmu() + .hp_sleep_lp_ck_power() + .modify(|_, w| w.bits(self.lp_sys_active.clk_power.0)); + + // LP SLEEP (lp_sleep_*) + pmu() + .lp_sleep_lp_dig_power() + .modify(|_, w| w.bits(self.lp_sys_sleep.dig_power.0)); + pmu() + .lp_sleep_lp_ck_power() + .modify(|_, w| w.bits(self.lp_sys_sleep.clk_power.0)); + pmu() + .lp_sleep_xtal() + .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal())); + } + } +} + +/// Parameters for high-power system configurations during sleep modes. +#[derive(Clone, Copy)] +// pmu_hp_param_t +pub struct HpParam { + /// Number of cycles to wait for the modem to wake up. + pub modem_wakeup_wait_cycle: u32, + /// Number of cycles to wait for the analog component stabilization. + pub analog_wait_target_cycle: u16, + /// Number of cycles to wait for the digital power-down sequence. + pub digital_power_down_wait_cycle: u16, + /// Number of cycles to wait for the digital power supply to stabilize. + pub digital_power_supply_wait_cycle: u16, + /// Number of cycles to wait for the digital power-up sequence. + pub digital_power_up_wait_cycle: u16, + /// Number of cycles to wait for the PLL to stabilize. + pub pll_stable_wait_cycle: u16, + /// Number of cycles to wait for modifying the ICG control. + pub modify_icg_cntl_wait_cycle: u8, + /// Number of cycles to wait for switching the ICG coйntrol. + pub switch_icg_cntl_wait_cycle: u8, + /// Minimum sleep time measured in slow clock cycles. + pub min_slp_slow_clk_cycle: u8, +} + +/// Parameters for low-power system configurations during sleep modes. +#[derive(Clone, Copy)] +// pmu_lp_param_t +pub struct LpParam { + /// Number of cycles to wait for the digital power supply to stabilize. + pub digital_power_supply_wait_cycle: u16, + /// Minimum sleep time measured in slow clock cycles. + pub min_slp_slow_clk_cycle: u8, + /// Number of cycles to wait for the analog component stabilization. + pub analog_wait_target_cycle: u8, + /// Number of cycles to wait for the digital power-down sequence. + pub digital_power_down_wait_cycle: u8, + /// Number of cycles to wait for the digital power-up sequence. + pub digital_power_up_wait_cycle: u8, +} + +/// Parameters for high-power and low-power system configurations during sleep +/// modes. +#[derive(Clone, Copy)] +// pmu_hp_lp_param_t +pub struct HpLpParam { + /// Union of two u16 variants + pub xtal_stable_wait_cycle: u16, +} + +/// Configuration of parameters for sleep modes +#[derive(Clone, Copy)] +// pmu_sleep_param_config_t +pub struct ParamSleepConfig { + /// Configuration of high-power system parameters. + pub hp_sys: HpParam, + /// Configuration of low-power system parameters. + pub lp_sys: LpParam, + /// Shared configuration parameters for high-power and low-power systems. + pub hp_lp: HpLpParam, +} +impl ParamSleepConfig { + const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self { + hp_sys: HpParam { + min_slp_slow_clk_cycle: 10, + analog_wait_target_cycle: 2419, + digital_power_supply_wait_cycle: 32, + digital_power_up_wait_cycle: 32, + modem_wakeup_wait_cycle: 20700, + pll_stable_wait_cycle: 2, + + digital_power_down_wait_cycle: 0, + modify_icg_cntl_wait_cycle: 0, + switch_icg_cntl_wait_cycle: 0, + }, + lp_sys: LpParam { + min_slp_slow_clk_cycle: 10, + analog_wait_target_cycle: 23, + digital_power_supply_wait_cycle: 32, + digital_power_up_wait_cycle: 32, + + digital_power_down_wait_cycle: 0, + }, + hp_lp: HpLpParam { + xtal_stable_wait_cycle: 30, + }, + }; + + fn apply(&self) { + // pmu_sleep_param_init + + unsafe { + pmu().slp_wakeup_cntl3().modify(|_, w| { + w.hp_min_slp_val() // pmu_ll_hp_set_min_sleep_cycle + .bits(self.hp_sys.min_slp_slow_clk_cycle) + .lp_min_slp_val() // pmu_ll_lp_set_min_sleep_cycle + .bits(self.lp_sys.min_slp_slow_clk_cycle) + }); + + pmu().slp_wakeup_cntl7().modify(|_, w| { + w.ana_wait_target() // pmu_ll_hp_set_analog_wait_target_cycle + .bits(self.hp_sys.analog_wait_target_cycle) + }); + + pmu().power_wait_timer0().modify(|_, w| { + w.dg_hp_wait_timer() // pmu_ll_hp_set_digital_power_supply_wait_cycle + .bits(self.hp_sys.digital_power_supply_wait_cycle) + .dg_hp_powerup_timer() // pmu_ll_hp_set_digital_power_up_wait_cycle + .bits(self.hp_sys.digital_power_up_wait_cycle) + }); + + pmu().power_wait_timer1().modify(|_, w| { + w.dg_lp_wait_timer() // pmu_ll_lp_set_digital_power_supply_wait_cycle + .bits(self.lp_sys.digital_power_supply_wait_cycle) + .dg_lp_powerup_timer() // pmu_ll_lp_set_digital_power_up_wait_cycle + .bits(self.lp_sys.digital_power_up_wait_cycle) + }); + + pmu().slp_wakeup_cntl5().modify(|_, w| { + w.lp_ana_wait_target() // pmu_ll_lp_set_analog_wait_target_cycle + .bits(self.lp_sys.analog_wait_target_cycle) + .modem_wait_target() // pmu_ll_hp_set_modem_wakeup_wait_cycle + .bits(self.hp_sys.modem_wakeup_wait_cycle) + }); + pmu().power_ck_wait_cntl().modify(|_, w| { + w.wait_xtl_stable() // pmu_ll_hp_set_xtal_stable_wait_cycle + .bits(self.hp_lp.xtal_stable_wait_cycle) + .wait_pll_stable() // pmu_ll_hp_set_pll_stable_wait_cycle + .bits(self.hp_sys.pll_stable_wait_cycle) + }); + } + } + + fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self { + let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT; + + // pmu_sleep_param_config_default + param.hp_sys.min_slp_slow_clk_cycle = + config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8; + param.hp_sys.analog_wait_target_cycle = + config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16; + param.hp_sys.digital_power_supply_wait_cycle = + config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16; + param.hp_sys.digital_power_up_wait_cycle = + config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16; + param.hp_sys.pll_stable_wait_cycle = + config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16; + + let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags); + + let modem_wakeup_wait_time_us = (config.sleep_time_adjustment + + MachineConstants::MODEM_STATE_SKIP_TIME_US + + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US) + .saturating_sub(hw_wait_time_us); + param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us); + + param.lp_sys.min_slp_slow_clk_cycle = + config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8; + param.lp_sys.analog_wait_target_cycle = + config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8; + param.lp_sys.digital_power_supply_wait_cycle = + config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16; + param.lp_sys.digital_power_up_wait_cycle = + config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8; + + // This looks different from esp-idf but it is the same: + // Both `xtal_stable_wait_cycle` and `xtal_stable_wait_slow_clk_cycle` are + // u16 variants of the same union + param.hp_lp.xtal_stable_wait_cycle = if pd_xtal { + config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16 + } else { + config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16 + }; + + param + } +} + +#[derive(Clone, Copy)] +struct SleepTimeConfig { + sleep_time_adjustment: u32, + // TODO: esp-idf does some calibration here to determine slowclk_period + slowclk_period: u32, + fastclk_period: u32, +} + +const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160; + +impl SleepTimeConfig { + const RTC_CLK_CAL_FRACT: u32 = 19; + + fn rtc_clk_cal_fast(mut slowclk_cycles: u32) -> u32 { + let xtal_freq = 40; // esp-idf has a very complicated way of determining this + + // The Fosc CLK of calibration circuit is divided by 32 for ECO1. + // So we need to divide the calibrate cycles of the FOSC for ECO1 and above + // chips by 32 to avoid excessive calibration time. + if Efuse::chip_revision() >= 1 { + slowclk_cycles /= 32; + } + + let xtal_cycles = RtcClock::calibrate_internal(RtcCalSel::RcFast, slowclk_cycles) as u64; + + let divider: u64 = xtal_freq as u64 * slowclk_cycles as u64; + let period_64: u64 = ((xtal_cycles << Self::RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; + (period_64 & (u32::MAX as u64)) as u32 + } + + fn new(_deep: bool) -> Self { + // https://github.com/espressif/esp-idf/commit/e1d24ebd7f43c7c7ded183bc8800b20af3bf014b + + // Calibrate rtc slow clock + // TODO: do an actual calibration instead of a read + let slowclk_period = unsafe { lp_aon().store1().read().data().bits() }; + + // Calibrate rtc fast clock, only PMU supported chips sleep process is needed. + const FAST_CLK_SRC_CAL_CYCLES: u32 = 2048; + let fastclk_period = Self::rtc_clk_cal_fast(FAST_CLK_SRC_CAL_CYCLES); + + Self { + sleep_time_adjustment: 0, + slowclk_period, + fastclk_period, + } + } + + fn light_sleep(pd_flags: PowerDownFlags) -> Self { + const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56; + + let mut this = Self::new(false); + + let sw = LIGHT_SLEEP_TIME_OVERHEAD_US; // TODO + let hw = this.pmu_sleep_calculate_hw_wait_time(pd_flags); + + this.sleep_time_adjustment = sw + hw; + + this + } + + fn deep_sleep() -> Self { + let mut this = Self::new(true); + + this.sleep_time_adjustment = 250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; + + this + } + + fn us_to_slowclk(&self, us: u32) -> u32 { + (us << Self::RTC_CLK_CAL_FRACT) / self.slowclk_period + } + + fn slowclk_to_us(&self, rtc_cycles: u32) -> u32 { + (rtc_cycles * self.slowclk_period) >> Self::RTC_CLK_CAL_FRACT + } + + fn us_to_fastclk(&self, us: u32) -> u32 { + (us << Self::RTC_CLK_CAL_FRACT) / self.fastclk_period + } + + fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 { + // LP core hardware wait time, microsecond + let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE); + let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE); + let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() { + MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US + } else { + self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE) + }; + + let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US + + MachineConstants::LP_ANALOG_WAIT_TIME_US + + lp_clk_power_on_wait_time_us + + lp_wakeup_wait_time_us + + lp_clk_switch_time_us + + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US + + MachineConstants::LP_POWER_UP_WAIT_TIME_US; + + // HP core hardware wait time, microsecond + let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US + + MachineConstants::HP_POWER_UP_WAIT_TIME_US; + let hp_regdma_wait_time_us = u32::max( + MachineConstants::HP_REGDMA_S2M_WORK_TIME_US + + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US, + MachineConstants::HP_REGDMA_S2A_WORK_TIME_US, + ); + let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US + + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US; + + let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US + + u32::max( + hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us, + hp_clock_wait_time_us, + ); + + #[rustfmt::skip] // ASCII art + // When the SOC wakeup (lp timer or GPIO wakeup) and Modem wakeup (Beacon wakeup) complete, + // the soc wakeup will be delayed until the RF is turned on in Modem state. + // + // modem wakeup TBTT, RF on by HW + // | | + // \|/ \|/ + // PMU_HP_ACTIVE /------ + // PMU_HP_MODEM /------------////////////////// + // PMU_HP_SLEEP ----------------------////////////////// + // /|\ /|\ /|\ /|\ /|\ /|\ + // |<- some hw wait ->| | | |<- M2A switch ->| + // | slow cycles & | soc wakeup | | + // | FOSC cycles |<- S2M switch ->| | + // | | + // |<-- PMU guard time, also the maximum time for the SOC -->| + // | wake-up delay | + // + const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true; + + let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP { + ( + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US, + MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US, + ) + } else { + (0, 0) + }; + + lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us + } +} + +/// Configuration for the RTC sleep behavior. +#[derive(Clone, Copy)] +// pmu_sleep_config_t + deep sleep flag + pd flags +pub struct RtcSleepConfig { + /// Deep Sleep flag + pub deep: bool, + /// Power Down flags + pub pd_flags: PowerDownFlags, +} + +impl Default for RtcSleepConfig { + fn default() -> Self { + // from pmu_sleep_param_config_default + // sleep flags will be applied by wakeup methods and apply + + Self { + deep: false, + pd_flags: PowerDownFlags(0), + } + } +} + +unsafe fn pmu<'a>() -> &'a esp32p4::pmu::RegisterBlock { + unsafe { &*esp32p4::PMU::ptr() } +} + +unsafe fn lp_aon<'a>() -> &'a esp32p4::lp_aon_clkrst::RegisterBlock { + unsafe { &*esp32p4::LP_AON_CLKRST::ptr() } +} + +bitfield::bitfield! { + #[derive(Clone, Copy)] + /// Power domains to be powered down during sleep + pub struct PowerDownFlags(u32); + + /// Controls the power-down status of the top power domain. + pub u32, pd_top , set_pd_top : 0; + /// Controls the power-down status of the VDD_SDIO power domain. + pub u32, pd_vddsdio , set_pd_vddsdio : 1; + /// Controls the power-down status of the modem power domain. + pub u32, pd_modem , set_pd_modem : 2; + /// Controls the power-down status of the high-performance peripheral power domain. + pub u32, pd_hp_periph, set_pd_hp_periph: 3; + /// Controls the power-down status of the CPU power domain. + pub u32, pd_cpu , set_pd_cpu : 4; + /// Controls the power-down status of the high-performance always-on domain. + pub u32, pd_hp_aon , set_pd_hp_aon : 5; + /// Controls the power-down status of memory group 0. + pub u32, pd_mem_g0 , set_pd_mem_g0 : 6; + /// Controls the power-down status of memory group 1. + pub u32, pd_mem_g1 , set_pd_mem_g1 : 7; + /// Controls the power-down status of memory group 2. + pub u32, pd_mem_g2 , set_pd_mem_g2 : 8; + /// Controls the power-down status of memory group 3. + pub u32, pd_mem_g3 , set_pd_mem_g3 : 9; + /// Controls the power-down status of the crystal oscillator. + pub u32, pd_xtal , set_pd_xtal : 10; + /// Controls the power-down status of the fast RC oscillator. + pub u32, pd_rc_fast , set_pd_rc_fast : 11; + /// Controls the power-down status of the 32kHz crystal oscillator. + pub u32, pd_xtal32k , set_pd_xtal32k : 12; + /// Controls the power-down status of the 32kHz RC oscillator. + pub u32, pd_rc32k , set_pd_rc32k : 13; + /// Controls the power-down status of the low-power peripheral domain. + pub u32, pd_lp_periph, set_pd_lp_periph: 14; +} + +impl PowerDownFlags { + /// Checks whether all memory groups (G0, G1, G2, G3) are powered down. + pub fn pd_mem(self) -> bool { + self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3() + } + + /// Sets the power-down status for all memory groups (G0, G1, G2, G3) at + /// once. + pub fn set_pd_mem(&mut self, value: bool) { + self.set_pd_mem_g0(value); + self.set_pd_mem_g1(value); + self.set_pd_mem_g2(value); + self.set_pd_mem_g3(value); + } +} + +// Constants defined in `PMU_SLEEP_MC_DEFAULT()` +struct MachineConstants; +impl MachineConstants { + const LP_MIN_SLP_TIME_US: u32 = 450; + const LP_WAKEUP_WAIT_CYCLE: u32 = 4; + const LP_ANALOG_WAIT_TIME_US: u32 = 154; + const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250; + const LP_CLK_SWITCH_CYCLE: u32 = 1; + const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1; + const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2; + const LP_POWER_UP_WAIT_TIME_US: u32 = 2; + + const HP_MIN_SLP_TIME_US: u32 = 450; + const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 150; + const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124; + const HP_ANALOG_WAIT_TIME_US: u32 = 154; + const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2; + const HP_POWER_UP_WAIT_TIME_US: u32 = 2; + const HP_REGDMA_S2M_WORK_TIME_US: u32 = 172; + const HP_REGDMA_S2A_WORK_TIME_US: u32 = 480; + const HP_REGDMA_M2A_WORK_TIME_US: u32 = 278; + // Unused, but defined in esp-idf. May be needed later. + // const HP_REGDMA_A2S_WORK_TIME_US: u32 = 382; + const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 70; + // Unused, but defined in esp-idf. May be needed later. + // const HP_REGDMA_RF_OFF_WORK_TIME_US: u32 = 23; + const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250; + const HP_PLL_WAIT_STABLE_TIME_US: u32 = 1; + + const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US + + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US + + Self::LP_MIN_SLP_TIME_US; +} + +impl RtcSleepConfig { + /// Returns whether the device is in deep sleep mode. + pub fn deep_slp(&self) -> bool { + self.deep + } + + /// Configures the device for deep sleep mode with ultra-low power settings. + pub fn deep() -> Self { + // Set up for ultra-low power sleep. Wakeup sources may modify these settings. + Self { + deep: true, + ..Self::default() + } + } + + pub(crate) fn base_settings(_rtc: &Rtc<'_>) { + Self::wake_io_reset(); + } + + fn wake_io_reset() { + // loosely based on esp_deep_sleep_wakeup_io_reset + Ext1WakeupSource::wake_io_reset(); + } + + /// Finalize power-down flags, apply configuration based on the flags. + pub(crate) fn apply(&mut self) { + if self.deep { + // force-disable certain power domains + self.pd_flags.set_pd_top(true); + self.pd_flags.set_pd_vddsdio(true); + self.pd_flags.set_pd_modem(true); + self.pd_flags.set_pd_hp_periph(true); + self.pd_flags.set_pd_cpu(true); + self.pd_flags.set_pd_mem(true); + self.pd_flags.set_pd_xtal(true); + self.pd_flags.set_pd_hp_aon(true); + self.pd_flags.set_pd_lp_periph(true); + self.pd_flags.set_pd_xtal32k(true); + self.pd_flags.set_pd_rc32k(true); + self.pd_flags.set_pd_rc_fast(true); + } + } + + /// Configures wakeup options and enters sleep. + /// + /// This function does not return if deep sleep is requested. + pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) { + const PMU_EXT0_WAKEUP_EN: u32 = 1 << 0; + const PMU_EXT1_WAKEUP_EN: u32 = 1 << 1; + const PMU_GPIO_WAKEUP_EN: u32 = 1 << 2; + const PMU_LP_TIMER_WAKEUP_EN: u32 = 1 << 4; + const PMU_WIFI_SOC_WAKEUP_EN: u32 = 1 << 5; + const PMU_UART0_WAKEUP_EN: u32 = 1 << 6; + const PMU_UART1_WAKEUP_EN: u32 = 1 << 7; + const PMU_SDIO_WAKEUP_EN: u32 = 1 << 8; + const PMU_BLE_SOC_WAKEUP_EN: u32 = 1 << 10; + const PMU_LP_CORE_WAKEUP_EN: u32 = 1 << 11; + const PMU_USB_WAKEUP_EN: u32 = 1 << 14; + const MODEM_REJECT: u32 = 1 << 16; + + const RTC_SLEEP_REJECT_MASK: u32 = PMU_EXT0_WAKEUP_EN + | PMU_EXT1_WAKEUP_EN + | PMU_GPIO_WAKEUP_EN + | PMU_LP_TIMER_WAKEUP_EN + | PMU_WIFI_SOC_WAKEUP_EN + | PMU_UART0_WAKEUP_EN + | PMU_UART1_WAKEUP_EN + | PMU_SDIO_WAKEUP_EN + | PMU_BLE_SOC_WAKEUP_EN + | PMU_LP_CORE_WAKEUP_EN + | PMU_USB_WAKEUP_EN; + + let wakeup_mask = wakeup_triggers.0 as u32; + let reject_mask = if self.deep { + 0 + } else { + // TODO: MODEM_REJECT if s_sleep_modem.wifi.phy_link != NULL + let reject_mask = RTC_SLEEP_REJECT_MASK | MODEM_REJECT; + wakeup_mask & reject_mask + }; + + let cpu_freq_config = ClockTree::with(|clocks| { + let cpu_freq_config = SavedClockConfig::save(clocks); + crate::soc::clocks::configure_soc_root_clk( + clocks, + crate::soc::clocks::SocRootClkConfig::Xtal, + ); + cpu_freq_config + }); + + // pmu_sleep_config_default + pmu_sleep_init. + + let power = PowerSleepConfig::defaults(self.pd_flags); + power.apply(); + + // Needs to happen after rtc_clk_cpu_freq_set_xtal + let config = if self.deep { + SleepTimeConfig::deep_sleep() + } else { + SleepTimeConfig::light_sleep(self.pd_flags) + }; + + let mut param = + ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal()); + + if self.deep { + const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500; + param.lp_sys.analog_wait_target_cycle = + config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8; + + AnalogSleepConfig::defaults_deep_sleep().apply(); + } else { + AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply(); + DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply(); + } + + param.apply(); + + // like esp-idf pmu_sleep_start() + + unsafe { + // lp_aon_hal_inform_wakeup_type - tells ROM which wakeup stub to run + lp_aon() + .store9() + .modify(|r, w| w.bits(r.bits() & !0x01 | self.deep as u32)); + + // pmu_ll_hp_set_wakeup_enable + pmu().slp_wakeup_cntl2().write(|w| w.bits(wakeup_mask)); + + // pmu_ll_hp_set_reject_enable + pmu().slp_wakeup_cntl1().modify(|_, w| { + w.slp_reject_en() + .bit(true) + .sleep_reject_ena() + .bits(reject_mask) + }); + + // pmu_ll_hp_clear_reject_cause + pmu() + .slp_wakeup_cntl4() + .write(|w| w.slp_reject_cause_clr().bit(true)); + + pmu().int_clr().write(|w| { + w.sw() // pmu_ll_hp_clear_sw_intr_status + .clear_bit_by_one() + .soc_sleep_reject() // pmu_ll_hp_clear_reject_intr_status + .clear_bit_by_one() + .soc_wakeup() // pmu_ll_hp_clear_wakeup_intr_status + .clear_bit_by_one() + }); + + // misc_modules_sleep_prepare + + // TODO: IDF-7370 + #[cfg(not(soc_has_pmu))] + if !(self.deep && wakeup_triggers.touch) { + APB_SARADC::regs() + .ctrl() + .modify(|_, w| w.saradc2_pwdet_drv().bit(false)); + } + + // Start entry into sleep mode + + // pmu_ll_hp_set_sleep_enable + pmu().slp_wakeup_cntl0().write(|w| w.sleep_req().bit(true)); + + // In pd_cpu lightsleep and deepsleep mode, we never get here + loop { + let int_raw = pmu().int_raw().read(); + if int_raw.soc_wakeup().bit_is_set() || int_raw.soc_sleep_reject().bit_is_set() { + break; + } + } + } + + // esp-idf returns if the sleep was rejected, we don't return anything + + ClockTree::with(|clocks| { + cpu_freq_config.restore(clocks); + }); + } + + /// Cleans up after sleep + pub(crate) fn finish_sleep(&self) { + // like esp-idf pmu_sleep_finish() + // In "pd_cpu lightsleep" and "deepsleep" modes we never get here + + // esp-idf returns if the sleep was rejected, we do nothing + // pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev) + + Self::wake_io_reset(); + } +} diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs new file mode 100644 index 00000000000..b09cdbfbe02 --- /dev/null +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -0,0 +1,345 @@ +//! Clock tree definitions and implementations for ESP32-C6. +//! +//! Remarks: +//! - Enabling a clock node assumes it has first been configured. Some fixed clock nodes don't need +//! to be configured. +//! - Some information may be assumed, e.g. the possibility to disable watchdog timers before clock +//! configuration. +//! - Internal RC oscillators (136k RC_SLOW and 17.5M RC_FAST) are not calibrated here, this system +//! can only give a rough estimate of their frequency. They can be calibrated separately using a +//! known crystal frequency. +//! - Some of the SOC capabilities are not implemented: I2S external pad clock source, external 32k +//! oscillator, LP_DYN_FAST_CLK, APB_DECREASE_DIV (which seems unnecessary to model), +//! PCR_CPU_HS_120M_FORCE. +#![allow(dead_code, reason = "Some of this is bound to be unused")] + +// TODO: This is a temporary place for this, should probably be moved into clocks_ll. + +use crate::peripherals::{LP_AON_CLKRST, PMU, SYSTEM}; + +define_clock_tree_types!(); + +/// Clock configuration options. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[allow( + clippy::enum_variant_names, + reason = "MHz suffix indicates physical unit." +)] +#[non_exhaustive] +pub enum CpuClock { + /// 360 MHz CPU clock + #[default] + _360MHz = 360, +} + +impl CpuClock { + const PRESET_360: ClockConfig = ClockConfig { + xtal_clk: None, + apb_clk: Some(ApbClkConfig::new(0)), + lp_fast_clk: Some(LpFastClkConfig::RcFast), + lp_slow_clk: Some(LpSlowClkConfig::RcSlow), + ..Default::default() + }; +} + +impl From for ClockConfig { + fn from(value: CpuClock) -> ClockConfig { + match value { + CpuClock::_360MHz => CpuClock::PRESET_360, + } + } +} + +impl Default for ClockConfig { + fn default() -> Self { + Self::from(CpuClock::default()) + } +} + +impl ClockConfig { + pub(crate) fn try_get_preset(self) -> Option { + match self { + v if v == CpuClock::PRESET_360 => Some(CpuClock::_360MHz), + _ => None, + } + } + + pub(crate) fn configure(mut self) { + if self.xtal_clk.is_none() { + self.xtal_clk = Some(XtalClkConfig::_40); + } + self.apply(); + } +} + +// XTAL_CLK + +fn configure_xtal_clk_impl(_clocks: &mut ClockTree, _config: XtalClkConfig) { + // The stored configuration affects PLL settings instead. +} + +// CPLL_CLK + +fn enable_cpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_cpll_clk_impl(_clocks: &mut ClockTree, _config: CpllClkConfig) { + todo!() +} + +// RC_FAST_CLK + +fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, en: bool) { + HP_SYS_CLKRST::regs().hp_rst_en1().modify(|_,w| w.rst_en_uart0_core().bit(en)) + PMU::regs() + .hp_sleep_lp_ck_power() + .modify(|_, w| w.hp_sleep_xpd_fosc_clk().bit(en)); + // TODO: Should the digital clock gate be a different clock node? + LP_AON_CLKRST::regs() + .clk_to_hp() + .modify(|_, w| w.icg_hp_fosc().bit(en)); + crate::rom::ets_delay_us(5); +} + +// MPLL_CLK + +fn enable_mpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_mpll_clk_impl(_clocks: &mut ClockTree, _config: MpllClkConfig) { + todo!() +} + +// SPLL_CLK + +fn enable_spll_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_spll_clk_impl(_clocks: &mut ClockTree, _config: SpllClkConfig) { + todo!() +} + +// XTAL32K_CLK + +fn enable_xtal32k_clk_impl(_clocks: &mut ClockTree, en: bool) { + LP_AON_CLKRST::regs().xtal32k().write(|w| unsafe { + w.dac_xtal32k().bits(3); + w.dres_xtal32k().bits(3); + w.dgm_xtal32k().bits(3); + w.dbuf_xtal32k().bit(true) + }); + + PMU::regs() + .hp_sleep_lp_ck_power() + .modify(|_, w| w.hp_sleep_xpd_xtal32k().bit(en)); + + // Enable for digital part + // TODO: Should the digital clock gate be a different clock node? + LP_AON_CLKRST::regs() + .clk_to_hp() + .modify(|_, w| w.icg_hp_xtal32k().bit(en)); +} + +// RC_SLOW_CLK + +fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, en: bool) { + if en { + // SCK_DCAP value controls tuning of 136k clock. The higher the value of DCAP, the lower the + // frequency. There is no separate enable bit, just make sure the calibration value is set. + // const RTC_CNTL_SCK_DCAP_DEFAULT: u8 = 128; + // crate::soc::regi2c::I2C_DIG_REG_SCK_DCAP.write_reg(RTC_CNTL_SCK_DCAP_DEFAULT); + } + + PMU::regs() + .hp_sleep_lp_ck_power() + .modify(|_, w| w.hp_sleep_xpd_rc32k().bit(en)); + + // Enable for digital part + LP_AON_CLKRST::regs() + .clk_to_hp() + .modify(|_, w| w.icg_hp_osc32k().bit(en)); +} + +// OSC_SLOW_CLK + +fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { + // TODO: + // gpio_ll_input_enable(&GPIO, SOC_EXT_OSC_SLOW_GPIO_NUM); + // REG_SET_BIT(LP_AON_GPIO_HOLD0_REG, BIT(SOC_EXT_OSC_SLOW_GPIO_NUM)); + todo!(); + + // No need to configure anything else for OSC_SLOW_CLK +} + +// PLL_LP_CLK + +fn enable_pll_lp_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_pll_lp_clk_impl(_clocks: &mut ClockTree, _config: PllLpClkConfig) { + todo!() +} + +// ROOT_CLK + +fn configure_root_clk_impl( + _clocks: &mut ClockTree, + _old_selector: Option, + _new_selector: RootClkConfig, +) { + todo!() +} + +// CPU_CLK + +fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _new_config: CpuClkConfig) { + todo!() +} + +// MEM_CLK + +fn enable_mem_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_mem_clk_impl(_clocks: &mut ClockTree, _new_config: MemClkConfig) { + todo!() +} + +// SYS_CLK + +fn enable_sys_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_sys_clk_impl(_clocks: &mut ClockTree, _new_config: SysClkConfig) { + todo!() +} + +// APB_CLK + +fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) { + // Nothing to do. +} + +fn configure_apb_clk_impl(_clocks: &mut ClockTree, _new_config: ApbClkConfig) { + todo!() +} + +// PLL_F50M_CLK + +fn enable_pll_f50m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// PLL_F25M_CLK + +fn enable_pll_f25m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// PLL_F240M_CLK + +fn enable_pll_f240m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// PLL_F160M_CLK + +fn enable_pll_f160m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// PLL_F120M_CLK + +fn enable_pll_f120m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// PLL_F80M_CLK + +fn enable_pll_f80m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// PLL_F20M_CLK + +fn enable_pll_f20m_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +// LP_SLOW_CLK + +fn configure_lp_slow_clk_impl( + _clocks: &mut ClockTree, + _old_selector: Option, + new_selector: LpSlowClkConfig, +) { + LP_AON_CLKRST::regs().lp_clk_conf().modify(|_, w| unsafe { + w.slow_clk_sel().bits(match new_selector { + LpSlowClkConfig::Xtal32kClk => 1, + LpSlowClkConfig::RcSlow => 0, + LpSlowClkConfig::OscSlow => 2, + }) + }); +} + +// LP_FAST_CLK + +fn configure_lp_fast_clk_impl( + _clocks: &mut ClockTree, + _old_selector: Option, + new_selector: LpFastClkConfig, +) { + LP_AON_CLKRST::regs().lp_clk_conf().modify(|_, w| { + w.fast_clk_sel().bit(match new_selector { + LpFastClkConfig::RcFastClk => false, + LpFastClkConfig::XtalD2Clk => true, + }) + }); +} + +// LP_DYN_SLOW_CLK + +fn configure_lp_dyn_slow_clk_impl( + _clocks: &mut ClockTree, + _old_selector: Option, + _new_selector: LpDynSlowClkConfig, +) { + todo!() +} + +// LP_DYN_FAST_CLK + +fn configure_lp_dyn_fast_clk_impl( + _clocks: &mut ClockTree, + _old_selector: Option, + _new_selector: LpDynFastClkConfig, +) { + todo!() +} + +// LP_PERI_CLK + +fn enable_lp_peri_clk_impl(_clocks: &mut ClockTree, _en: bool) { + todo!() +} + +fn configure_lp_peri_clk_impl(_clocks: &mut ClockTree, _new_config: LpPeriClkConfig) { + todo!() +} + +// XTAL_D2_CLK + +fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) { + // Nothing to do, the divider is always on. +} \ No newline at end of file diff --git a/esp-hal/src/soc/esp32p4/mod.rs b/esp-hal/src/soc/esp32p4/mod.rs new file mode 100644 index 00000000000..55ec1a9eac0 --- /dev/null +++ b/esp-hal/src/soc/esp32p4/mod.rs @@ -0,0 +1,26 @@ +// pub mod efuse; +// pub mod gpio; +// pub mod peripherals; + +crate::unstable_module! { + pub mod clocks; +} + +pub(crate) mod regi2c; + +pub(crate) use esp32p4 as pac; + +pub(crate) mod registers { + pub const INTERRUPT_MAP_BASE: u32 = 0x500D_6000; + pub const INTERRUPT_MAP_BASE_APP_CPU: u32 = 0x500D_6800; +} + +pub(crate) mod constants { + pub const SOC_DRAM_LOW: u32 = 0x4FF0_0000; + pub const SOC_DRAM_HIGH: u32 = 0x4FFC_0000; +} + + +pub(crate) fn pre_init() { + // TODO: Check if anything needs to be done here +} diff --git a/esp-hal/src/soc/esp32p4/regi2c.rs b/esp-hal/src/soc/esp32p4/regi2c.rs new file mode 100644 index 00000000000..9023c56ac2b --- /dev/null +++ b/esp-hal/src/soc/esp32p4/regi2c.rs @@ -0,0 +1,9 @@ + + +pub(crate) fn regi2c_read(block: u8, _host_id: u8, reg_add: u8) -> u8 { + todo!() +} + +pub(crate) fn regi2c_write(block: u8, _host_id: u8, reg_add: u8, data: u8) { + todo!() +} diff --git a/esp-metadata-generated/src/_generated_esp32p4.rs b/esp-metadata-generated/src/_generated_esp32p4.rs new file mode 100644 index 00000000000..d72087812ea --- /dev/null +++ b/esp-metadata-generated/src/_generated_esp32p4.rs @@ -0,0 +1,3549 @@ +// Do NOT edit this file directly. Make your changes to esp-metadata, +// then run `cargo xtask update-metadata`. + +/// The name of the chip as `&str` +/// +/// # Example +/// +/// ```rust, no_run +/// use esp_hal::chip; +/// let chip_name = chip!(); +#[doc = concat!("assert_eq!(chip_name, ", chip!(), ")")] +/// ``` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! chip { + () => { + "esp32p4" + }; +} +/// The properties of this chip and its drivers. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! property { + ("chip") => { + "esp32p4" + }; + ("arch") => { + "riscv" + }; + ("cores") => { + 2 + }; + ("cores", str) => { + stringify!(2) + }; + ("trm") => { + "https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf" + }; + ("soc.cpu_has_csr_pc") => { + true + }; + ("soc.cpu_has_prv_mode") => { + false + }; + ("soc.rc_fast_clk_default") => { + 20000000 + }; + ("soc.rc_fast_clk_default", str) => { + stringify!(20000000) + }; + ("soc.rc_slow_clock") => { + 150000 + }; + ("soc.rc_slow_clock", str) => { + stringify!(150000) + }; + ("gpio.has_bank_1") => { + false + }; + ("gpio.gpio_function") => { + 1 + }; + ("gpio.gpio_function", str) => { + stringify!(1) + }; + ("gpio.constant_0_input") => { + 60 + }; + ("gpio.constant_0_input", str) => { + stringify!(60) + }; + ("gpio.constant_1_input") => { + 56 + }; + ("gpio.constant_1_input", str) => { + stringify!(56) + }; + ("gpio.remap_iomux_pin_registers") => { + false + }; + ("gpio.func_in_sel_offset") => { + 0 + }; + ("gpio.func_in_sel_offset", str) => { + stringify!(0) + }; + ("gpio.input_signal_max") => { + 255 + }; + ("gpio.input_signal_max", str) => { + stringify!(255) + }; + ("gpio.output_signal_max") => { + 255 + }; + ("gpio.output_signal_max", str) => { + stringify!(255) + }; + ("i2c_master.has_fsm_timeouts") => { + true + }; + ("i2c_master.has_hw_bus_clear") => { + true + }; + ("i2c_master.has_bus_timeout_enable") => { + true + }; + ("i2c_master.separate_filter_config_registers") => { + false + }; + ("i2c_master.can_estimate_nack_reason") => { + true + }; + ("i2c_master.has_conf_update") => { + true + }; + ("i2c_master.has_reliable_fsm_reset") => { + true + }; + ("i2c_master.has_arbitration_en") => { + true + }; + ("i2c_master.has_tx_fifo_watermark") => { + true + }; + ("i2c_master.bus_timeout_is_exponential") => { + true + }; + ("i2c_master.max_bus_timeout") => { + 31 + }; + ("i2c_master.max_bus_timeout", str) => { + stringify!(31) + }; + ("i2c_master.ll_intr_mask") => { + 262143 + }; + ("i2c_master.ll_intr_mask", str) => { + stringify!(262143) + }; + ("i2c_master.fifo_size") => { + 32 + }; + ("i2c_master.fifo_size", str) => { + stringify!(32) + }; + ("interrupts.status_registers") => { + 4 + }; + ("interrupts.status_registers", str) => { + stringify!(4) + }; + ("sleep.light_sleep") => { + true + }; + ("sleep.deep_sleep") => { + true + }; + ("timergroup.timg_has_timer1") => { + false + }; + ("timergroup.timg_has_divcnt_rst") => { + true + }; + ("uart.ram_size") => { + 128 + }; + ("uart.ram_size", str) => { + stringify!(128) + }; + ("uart.peripheral_controls_mem_clk") => { + true + }; +} +#[macro_export] +/// ESP-HAL must provide implementation for the following functions: +/// ```rust, no_run +/// // XTAL_CLK +/// +/// fn configure_xtal_clk_impl(_clocks: &mut ClockTree, _config: XtalClkConfig) { +/// todo!() +/// } +/// +/// // CPLL_CLK +/// +/// fn enable_cpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_cpll_clk_impl(_clocks: &mut ClockTree, _config: CpllClkConfig) { +/// todo!() +/// } +/// +/// // RC_FAST_CLK +/// +/// fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // MPLL_CLK +/// +/// fn enable_mpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_mpll_clk_impl(_clocks: &mut ClockTree, _config: MpllClkConfig) { +/// todo!() +/// } +/// +/// // SPLL_CLK +/// +/// fn enable_spll_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_spll_clk_impl(_clocks: &mut ClockTree, _config: SpllClkConfig) { +/// todo!() +/// } +/// +/// // XTAL32K_CLK +/// +/// fn enable_xtal32k_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // RC_SLOW_CLK +/// +/// fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // OSC_SLOW_CLK +/// +/// fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_LP_CLK +/// +/// fn enable_pll_lp_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_pll_lp_clk_impl(_clocks: &mut ClockTree, _config: PllLpClkConfig) { +/// todo!() +/// } +/// +/// // ROOT_CLK +/// +/// fn configure_root_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: RootClkConfig, +/// ) { +/// todo!() +/// } +/// +/// // CPU_CLK +/// +/// fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _new_config: CpuClkConfig) { +/// todo!() +/// } +/// +/// // MEM_CLK +/// +/// fn enable_mem_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_mem_clk_impl(_clocks: &mut ClockTree, _new_config: MemClkConfig) { +/// todo!() +/// } +/// +/// // SYS_CLK +/// +/// fn enable_sys_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_sys_clk_impl(_clocks: &mut ClockTree, _new_config: SysClkConfig) { +/// todo!() +/// } +/// +/// // APB_CLK +/// +/// fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_apb_clk_impl(_clocks: &mut ClockTree, _new_config: ApbClkConfig) { +/// todo!() +/// } +/// +/// // PLL_F50M_CLK +/// +/// fn enable_pll_f50m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_F25M_CLK +/// +/// fn enable_pll_f25m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_F240M_CLK +/// +/// fn enable_pll_f240m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_F160M_CLK +/// +/// fn enable_pll_f160m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_F120M_CLK +/// +/// fn enable_pll_f120m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_F80M_CLK +/// +/// fn enable_pll_f80m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // PLL_F20M_CLK +/// +/// fn enable_pll_f20m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // LP_SLOW_CLK +/// +/// fn configure_lp_slow_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: LpSlowClkConfig, +/// ) { +/// todo!() +/// } +/// +/// // LP_FAST_CLK +/// +/// fn configure_lp_fast_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: LpFastClkConfig, +/// ) { +/// todo!() +/// } +/// +/// // LP_DYN_SLOW_CLK +/// +/// fn configure_lp_dyn_slow_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: LpDynSlowClkConfig, +/// ) { +/// todo!() +/// } +/// +/// // LP_DYN_FAST_CLK +/// +/// fn configure_lp_dyn_fast_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: LpDynFastClkConfig, +/// ) { +/// todo!() +/// } +/// +/// // LP_PERI_CLK +/// +/// fn enable_lp_peri_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_lp_peri_clk_impl(_clocks: &mut ClockTree, _new_config: LpPeriClkConfig) { +/// todo!() +/// } +/// +/// // XTAL_D2_CLK +/// +/// fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// // TIMG0_FUNCTION_CLOCK +/// +/// fn enable_timg0_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_timg0_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Timg0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // TIMG1_FUNCTION_CLOCK +/// +/// fn enable_timg1_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_timg1_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Timg0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // UART0_FUNCTION_CLOCK +/// +/// fn enable_uart0_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_uart0_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Uart0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // UART1_FUNCTION_CLOCK +/// +/// fn enable_uart1_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_uart1_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Uart0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // UART2_FUNCTION_CLOCK +/// +/// fn enable_uart2_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_uart2_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Uart0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // UART3_FUNCTION_CLOCK +/// +/// fn enable_uart3_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_uart3_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Uart0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // UART4_FUNCTION_CLOCK +/// +/// fn enable_uart4_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_uart4_function_clock_impl( +/// _clocks: &mut ClockTree, +/// _old_selector: Option, +/// _new_selector: Uart0FunctionClockConfig, +/// ) { +/// todo!() +/// } +/// ``` +macro_rules! define_clock_tree_types { + () => { + /// Selects the output frequency of `XTAL_CLK`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum XtalClkConfig { + /// 40 MHz + _40, + } + impl XtalClkConfig { + pub fn value(&self) -> u32 { + match self { + XtalClkConfig::_40 => 40000000, + } + } + } + /// Selects the output frequency of `CPLL_CLK`. Depends on `XTAL_CLK`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum CpllClkConfig { + /// 360 MHz + _360, + } + impl CpllClkConfig { + pub fn value(&self) -> u32 { + match self { + CpllClkConfig::_360 => 360000000, + } + } + } + /// Selects the output frequency of `MPLL_CLK`. Depends on `XTAL_CLK`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum MpllClkConfig { + /// 500 MHz + _500, + } + impl MpllClkConfig { + pub fn value(&self) -> u32 { + match self { + MpllClkConfig::_500 => 500000000, + } + } + } + /// Selects the output frequency of `SPLL_CLK`. Depends on `XTAL_CLK`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum SpllClkConfig { + /// 480 MHz + _480, + } + impl SpllClkConfig { + pub fn value(&self) -> u32 { + match self { + SpllClkConfig::_480 => 480000000, + } + } + } + /// Selects the output frequency of `PLL_LP_CLK`. Depends on `XTAL32K_CLK`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum PllLpClkConfig { + /// 8 MHz + _8, + } + impl PllLpClkConfig { + pub fn value(&self) -> u32 { + match self { + PllLpClkConfig::_8 => 8000000, + } + } + } + /// The list of clock signals that the `ROOT_CLK` multiplexer can output. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum RootClkConfig { + /// Selects `XTAL_CLK`. + Xtal, + /// Selects `RC_FAST_CLK`. + RcFast, + /// Selects `CPLL_CLK`. + Pll, + } + /// Configures the `CPU_CLK` clock divider. + /// + /// The output is calculated as `OUTPUT = ROOT_CLK / DIVISOR`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct CpuClkConfig(u32); + impl CpuClkConfig { + /// Creates a new divider configuration. + pub const fn new(divisor: u32) -> Self { + Self(divisor) + } + fn value(self) -> u32 { + self.0 + } + } + /// Configures the `MEM_CLK` clock divider. + /// + /// The output is calculated as `OUTPUT = CPU_CLK / DIVISOR`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct MemClkConfig(u32); + impl MemClkConfig { + /// Creates a new divider configuration. + pub const fn new(divisor: u32) -> Self { + Self(divisor) + } + fn value(self) -> u32 { + self.0 + } + } + /// Configures the `SYS_CLK` clock divider. + /// + /// The output is calculated as `OUTPUT = MEM_CLK / DIVISOR`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct SysClkConfig(u32); + impl SysClkConfig { + /// Creates a new divider configuration. + pub const fn new(divisor: u32) -> Self { + Self(divisor) + } + fn value(self) -> u32 { + self.0 + } + } + /// Configures the `APB_CLK` clock divider. + /// + /// The output is calculated as `OUTPUT = SYS_CLK / DIVISOR`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct ApbClkConfig(u32); + impl ApbClkConfig { + /// Creates a new divider configuration. + pub const fn new(divisor: u32) -> Self { + Self(divisor) + } + fn value(self) -> u32 { + self.0 + } + } + /// The list of clock signals that the `LP_SLOW_CLK` multiplexer can output. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum LpSlowClkConfig { + /// Selects `XTAL32K_CLK`. + Xtal32k, + /// Selects `RC_SLOW_CLK`. + RcSlow, + /// Selects `OSC_SLOW_CLK`. + OscSlow, + } + /// The list of clock signals that the `LP_FAST_CLK` multiplexer can output. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum LpFastClkConfig { + /// Selects `XTAL_CLK`. + Xtal, + /// Selects `RC_FAST_CLK`. + RcFast, + /// Selects `PLL_LP_CLK`. + Pll, + } + /// The list of clock signals that the `LP_DYN_SLOW_CLK` multiplexer can output. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum LpDynSlowClkConfig { + /// Selects `LP_SLOW_CLK`. + LpSlow, + /// Selects `LP_FAST_CLK`. + LpFast, + } + /// The list of clock signals that the `LP_DYN_FAST_CLK` multiplexer can output. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum LpDynFastClkConfig { + /// Selects `LP_SLOW_CLK`. + LpSlow, + /// Selects `LP_FAST_CLK`. + LpFast, + } + /// Configures the `LP_PERI_CLK` clock divider. + /// + /// The output is calculated as `OUTPUT = LP_DYN_FAST_CLK / DIVISOR`. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct LpPeriClkConfig(u32); + impl LpPeriClkConfig { + /// Creates a new divider configuration. + /// + /// # Panics + /// + /// Panics if the divisor value is outside the + /// valid range (0 ..= 31). + pub const fn new(divisor: u32) -> Self { + ::core::assert!( + divisor <= 31u32, + "`LP_PERI_CLK` divisor value must be between 0 and 31 (inclusive)." + ); + Self(divisor) + } + fn value(self) -> u32 { + self.0 + } + } + /// The list of clock signals that the `TIMG0_FUNCTION_CLOCK` multiplexer can output. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Timg0FunctionClockConfig { + /// Selects `PLL_F80M_CLK`. + Pll80, + /// Selects `RC_FAST_CLK`. + RcFast, + /// Selects `XTAL_CLK`. + Xtal, + } + /// The list of clock signals that the `UART0_FUNCTION_CLOCK` multiplexer can output. + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Uart0FunctionClockConfig { + /// Selects `PLL_F80M_CLK`. + Pll80, + /// Selects `RC_FAST_CLK`. + RcFast, + #[default] + /// Selects `XTAL_CLK`. + Xtal, + } + /// Represents the device's clock tree. + pub struct ClockTree { + xtal_clk: Option, + cpll_clk: Option, + mpll_clk: Option, + spll_clk: Option, + pll_lp_clk: Option, + root_clk: Option, + cpu_clk: Option, + mem_clk: Option, + sys_clk: Option, + apb_clk: Option, + lp_slow_clk: Option, + lp_fast_clk: Option, + lp_dyn_slow_clk: Option, + lp_dyn_fast_clk: Option, + lp_peri_clk: Option, + timg0_function_clock: Option, + timg1_function_clock: Option, + uart0_function_clock: Option, + uart1_function_clock: Option, + uart2_function_clock: Option, + uart3_function_clock: Option, + uart4_function_clock: Option, + rc_fast_clk_refcount: u32, + mpll_clk_refcount: u32, + spll_clk_refcount: u32, + xtal32k_clk_refcount: u32, + apb_clk_refcount: u32, + pll_f50m_clk_refcount: u32, + pll_f25m_clk_refcount: u32, + pll_f240m_clk_refcount: u32, + pll_f160m_clk_refcount: u32, + pll_f120m_clk_refcount: u32, + pll_f80m_clk_refcount: u32, + pll_f20m_clk_refcount: u32, + lp_peri_clk_refcount: u32, + xtal_d2_clk_refcount: u32, + timg0_function_clock_refcount: u32, + timg1_function_clock_refcount: u32, + uart0_function_clock_refcount: u32, + uart1_function_clock_refcount: u32, + uart2_function_clock_refcount: u32, + uart3_function_clock_refcount: u32, + uart4_function_clock_refcount: u32, + } + impl ClockTree { + /// Locks the clock tree for exclusive access. + pub fn with(f: impl FnOnce(&mut ClockTree) -> R) -> R { + CLOCK_TREE.with(f) + } + /// Returns the current configuration of the XTAL_CLK clock tree node + pub fn xtal_clk(&self) -> Option { + self.xtal_clk + } + /// Returns the current configuration of the CPLL_CLK clock tree node + pub fn cpll_clk(&self) -> Option { + self.cpll_clk + } + /// Returns the current configuration of the MPLL_CLK clock tree node + pub fn mpll_clk(&self) -> Option { + self.mpll_clk + } + /// Returns the current configuration of the SPLL_CLK clock tree node + pub fn spll_clk(&self) -> Option { + self.spll_clk + } + /// Returns the current configuration of the PLL_LP_CLK clock tree node + pub fn pll_lp_clk(&self) -> Option { + self.pll_lp_clk + } + /// Returns the current configuration of the ROOT_CLK clock tree node + pub fn root_clk(&self) -> Option { + self.root_clk + } + /// Returns the current configuration of the CPU_CLK clock tree node + pub fn cpu_clk(&self) -> Option { + self.cpu_clk + } + /// Returns the current configuration of the MEM_CLK clock tree node + pub fn mem_clk(&self) -> Option { + self.mem_clk + } + /// Returns the current configuration of the SYS_CLK clock tree node + pub fn sys_clk(&self) -> Option { + self.sys_clk + } + /// Returns the current configuration of the APB_CLK clock tree node + pub fn apb_clk(&self) -> Option { + self.apb_clk + } + /// Returns the current configuration of the LP_SLOW_CLK clock tree node + pub fn lp_slow_clk(&self) -> Option { + self.lp_slow_clk + } + /// Returns the current configuration of the LP_FAST_CLK clock tree node + pub fn lp_fast_clk(&self) -> Option { + self.lp_fast_clk + } + /// Returns the current configuration of the LP_DYN_SLOW_CLK clock tree node + pub fn lp_dyn_slow_clk(&self) -> Option { + self.lp_dyn_slow_clk + } + /// Returns the current configuration of the LP_DYN_FAST_CLK clock tree node + pub fn lp_dyn_fast_clk(&self) -> Option { + self.lp_dyn_fast_clk + } + /// Returns the current configuration of the LP_PERI_CLK clock tree node + pub fn lp_peri_clk(&self) -> Option { + self.lp_peri_clk + } + /// Returns the current configuration of the TIMG0_FUNCTION_CLOCK clock tree node + pub fn timg0_function_clock(&self) -> Option { + self.timg0_function_clock + } + /// Returns the current configuration of the TIMG1_FUNCTION_CLOCK clock tree node + pub fn timg1_function_clock(&self) -> Option { + self.timg1_function_clock + } + /// Returns the current configuration of the UART0_FUNCTION_CLOCK clock tree node + pub fn uart0_function_clock(&self) -> Option { + self.uart0_function_clock + } + /// Returns the current configuration of the UART1_FUNCTION_CLOCK clock tree node + pub fn uart1_function_clock(&self) -> Option { + self.uart1_function_clock + } + /// Returns the current configuration of the UART2_FUNCTION_CLOCK clock tree node + pub fn uart2_function_clock(&self) -> Option { + self.uart2_function_clock + } + /// Returns the current configuration of the UART3_FUNCTION_CLOCK clock tree node + pub fn uart3_function_clock(&self) -> Option { + self.uart3_function_clock + } + /// Returns the current configuration of the UART4_FUNCTION_CLOCK clock tree node + pub fn uart4_function_clock(&self) -> Option { + self.uart4_function_clock + } + } + static CLOCK_TREE: ::esp_sync::NonReentrantMutex = + ::esp_sync::NonReentrantMutex::new(ClockTree { + xtal_clk: None, + cpll_clk: None, + mpll_clk: None, + spll_clk: None, + pll_lp_clk: None, + root_clk: None, + cpu_clk: None, + mem_clk: None, + sys_clk: None, + apb_clk: None, + lp_slow_clk: None, + lp_fast_clk: None, + lp_dyn_slow_clk: None, + lp_dyn_fast_clk: None, + lp_peri_clk: None, + timg0_function_clock: None, + timg1_function_clock: None, + uart0_function_clock: None, + uart1_function_clock: None, + uart2_function_clock: None, + uart3_function_clock: None, + uart4_function_clock: None, + rc_fast_clk_refcount: 0, + mpll_clk_refcount: 0, + spll_clk_refcount: 0, + xtal32k_clk_refcount: 0, + apb_clk_refcount: 0, + pll_f50m_clk_refcount: 0, + pll_f25m_clk_refcount: 0, + pll_f240m_clk_refcount: 0, + pll_f160m_clk_refcount: 0, + pll_f120m_clk_refcount: 0, + pll_f80m_clk_refcount: 0, + pll_f20m_clk_refcount: 0, + lp_peri_clk_refcount: 0, + xtal_d2_clk_refcount: 0, + timg0_function_clock_refcount: 0, + timg1_function_clock_refcount: 0, + uart0_function_clock_refcount: 0, + uart1_function_clock_refcount: 0, + uart2_function_clock_refcount: 0, + uart3_function_clock_refcount: 0, + uart4_function_clock_refcount: 0, + }); + pub fn configure_xtal_clk(clocks: &mut ClockTree, config: XtalClkConfig) { + clocks.xtal_clk = Some(config); + configure_xtal_clk_impl(clocks, config); + } + fn request_xtal_clk(_clocks: &mut ClockTree) {} + fn release_xtal_clk(_clocks: &mut ClockTree) {} + pub fn xtal_clk_frequency(clocks: &mut ClockTree) -> u32 { + unwrap!(clocks.xtal_clk).value() + } + pub fn configure_cpll_clk(clocks: &mut ClockTree, config: CpllClkConfig) { + clocks.cpll_clk = Some(config); + configure_cpll_clk_impl(clocks, config); + } + pub fn request_cpll_clk(clocks: &mut ClockTree) { + trace!("Requesting CPLL_CLK"); + trace!("Enabling CPLL_CLK"); + request_xtal_clk(clocks); + enable_cpll_clk_impl(clocks, true); + } + pub fn release_cpll_clk(clocks: &mut ClockTree) { + trace!("Releasing CPLL_CLK"); + trace!("Disabling CPLL_CLK"); + enable_cpll_clk_impl(clocks, false); + release_xtal_clk(clocks); + } + pub fn cpll_clk_frequency(clocks: &mut ClockTree) -> u32 { + unwrap!(clocks.cpll_clk).value() + } + pub fn request_rc_fast_clk(clocks: &mut ClockTree) { + trace!("Requesting RC_FAST_CLK"); + if increment_reference_count(&mut clocks.rc_fast_clk_refcount) { + trace!("Enabling RC_FAST_CLK"); + enable_rc_fast_clk_impl(clocks, true); + } + } + pub fn release_rc_fast_clk(clocks: &mut ClockTree) { + trace!("Releasing RC_FAST_CLK"); + if decrement_reference_count(&mut clocks.rc_fast_clk_refcount) { + trace!("Disabling RC_FAST_CLK"); + enable_rc_fast_clk_impl(clocks, false); + } + } + pub fn rc_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { + 20000000 + } + pub fn configure_mpll_clk(clocks: &mut ClockTree, config: MpllClkConfig) { + clocks.mpll_clk = Some(config); + configure_mpll_clk_impl(clocks, config); + } + pub fn request_mpll_clk(clocks: &mut ClockTree) { + trace!("Requesting MPLL_CLK"); + if increment_reference_count(&mut clocks.mpll_clk_refcount) { + trace!("Enabling MPLL_CLK"); + request_xtal_clk(clocks); + enable_mpll_clk_impl(clocks, true); + } + } + pub fn release_mpll_clk(clocks: &mut ClockTree) { + trace!("Releasing MPLL_CLK"); + if decrement_reference_count(&mut clocks.mpll_clk_refcount) { + trace!("Disabling MPLL_CLK"); + enable_mpll_clk_impl(clocks, false); + release_xtal_clk(clocks); + } + } + pub fn mpll_clk_frequency(clocks: &mut ClockTree) -> u32 { + unwrap!(clocks.mpll_clk).value() + } + pub fn configure_spll_clk(clocks: &mut ClockTree, config: SpllClkConfig) { + clocks.spll_clk = Some(config); + configure_spll_clk_impl(clocks, config); + } + pub fn request_spll_clk(clocks: &mut ClockTree) { + trace!("Requesting SPLL_CLK"); + if increment_reference_count(&mut clocks.spll_clk_refcount) { + trace!("Enabling SPLL_CLK"); + request_xtal_clk(clocks); + enable_spll_clk_impl(clocks, true); + } + } + pub fn release_spll_clk(clocks: &mut ClockTree) { + trace!("Releasing SPLL_CLK"); + if decrement_reference_count(&mut clocks.spll_clk_refcount) { + trace!("Disabling SPLL_CLK"); + enable_spll_clk_impl(clocks, false); + release_xtal_clk(clocks); + } + } + pub fn spll_clk_frequency(clocks: &mut ClockTree) -> u32 { + unwrap!(clocks.spll_clk).value() + } + pub fn request_xtal32k_clk(clocks: &mut ClockTree) { + trace!("Requesting XTAL32K_CLK"); + if increment_reference_count(&mut clocks.xtal32k_clk_refcount) { + trace!("Enabling XTAL32K_CLK"); + enable_xtal32k_clk_impl(clocks, true); + } + } + pub fn release_xtal32k_clk(clocks: &mut ClockTree) { + trace!("Releasing XTAL32K_CLK"); + if decrement_reference_count(&mut clocks.xtal32k_clk_refcount) { + trace!("Disabling XTAL32K_CLK"); + enable_xtal32k_clk_impl(clocks, false); + } + } + pub fn xtal32k_clk_frequency(clocks: &mut ClockTree) -> u32 { + 32768 + } + pub fn request_rc_slow_clk(clocks: &mut ClockTree) { + trace!("Requesting RC_SLOW_CLK"); + trace!("Enabling RC_SLOW_CLK"); + enable_rc_slow_clk_impl(clocks, true); + } + pub fn release_rc_slow_clk(clocks: &mut ClockTree) { + trace!("Releasing RC_SLOW_CLK"); + trace!("Disabling RC_SLOW_CLK"); + enable_rc_slow_clk_impl(clocks, false); + } + pub fn rc_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { + 150000 + } + pub fn request_osc_slow_clk(clocks: &mut ClockTree) { + trace!("Requesting OSC_SLOW_CLK"); + trace!("Enabling OSC_SLOW_CLK"); + enable_osc_slow_clk_impl(clocks, true); + } + pub fn release_osc_slow_clk(clocks: &mut ClockTree) { + trace!("Releasing OSC_SLOW_CLK"); + trace!("Disabling OSC_SLOW_CLK"); + enable_osc_slow_clk_impl(clocks, false); + } + pub fn osc_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { + 32768 + } + pub fn configure_pll_lp_clk(clocks: &mut ClockTree, config: PllLpClkConfig) { + clocks.pll_lp_clk = Some(config); + configure_pll_lp_clk_impl(clocks, config); + } + pub fn request_pll_lp_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_LP_CLK"); + trace!("Enabling PLL_LP_CLK"); + request_xtal32k_clk(clocks); + enable_pll_lp_clk_impl(clocks, true); + } + pub fn release_pll_lp_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_LP_CLK"); + trace!("Disabling PLL_LP_CLK"); + enable_pll_lp_clk_impl(clocks, false); + release_xtal32k_clk(clocks); + } + pub fn pll_lp_clk_frequency(clocks: &mut ClockTree) -> u32 { + unwrap!(clocks.pll_lp_clk).value() + } + pub fn configure_root_clk(clocks: &mut ClockTree, new_selector: RootClkConfig) { + let old_selector = clocks.root_clk.replace(new_selector); + match new_selector { + RootClkConfig::Xtal => request_xtal_clk(clocks), + RootClkConfig::RcFast => request_rc_fast_clk(clocks), + RootClkConfig::Pll => request_cpll_clk(clocks), + } + configure_root_clk_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + RootClkConfig::Xtal => release_xtal_clk(clocks), + RootClkConfig::RcFast => release_rc_fast_clk(clocks), + RootClkConfig::Pll => release_cpll_clk(clocks), + } + } + } + fn request_root_clk(_clocks: &mut ClockTree) {} + fn release_root_clk(_clocks: &mut ClockTree) {} + pub fn root_clk_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.root_clk) { + RootClkConfig::Xtal => xtal_clk_frequency(clocks), + RootClkConfig::RcFast => rc_fast_clk_frequency(clocks), + RootClkConfig::Pll => cpll_clk_frequency(clocks), + } + } + pub fn configure_cpu_clk(clocks: &mut ClockTree, config: CpuClkConfig) { + clocks.cpu_clk = Some(config); + configure_cpu_clk_impl(clocks, config); + } + pub fn request_cpu_clk(clocks: &mut ClockTree) { + trace!("Requesting CPU_CLK"); + trace!("Enabling CPU_CLK"); + request_root_clk(clocks); + enable_cpu_clk_impl(clocks, true); + } + pub fn release_cpu_clk(clocks: &mut ClockTree) { + trace!("Releasing CPU_CLK"); + trace!("Disabling CPU_CLK"); + enable_cpu_clk_impl(clocks, false); + release_root_clk(clocks); + } + pub fn cpu_clk_frequency(clocks: &mut ClockTree) -> u32 { + (root_clk_frequency(clocks) / unwrap!(clocks.cpu_clk).value()) + } + pub fn configure_mem_clk(clocks: &mut ClockTree, config: MemClkConfig) { + clocks.mem_clk = Some(config); + configure_mem_clk_impl(clocks, config); + } + pub fn request_mem_clk(clocks: &mut ClockTree) { + trace!("Requesting MEM_CLK"); + trace!("Enabling MEM_CLK"); + request_cpu_clk(clocks); + enable_mem_clk_impl(clocks, true); + } + pub fn release_mem_clk(clocks: &mut ClockTree) { + trace!("Releasing MEM_CLK"); + trace!("Disabling MEM_CLK"); + enable_mem_clk_impl(clocks, false); + release_cpu_clk(clocks); + } + pub fn mem_clk_frequency(clocks: &mut ClockTree) -> u32 { + (cpu_clk_frequency(clocks) / unwrap!(clocks.mem_clk).value()) + } + pub fn configure_sys_clk(clocks: &mut ClockTree, config: SysClkConfig) { + clocks.sys_clk = Some(config); + configure_sys_clk_impl(clocks, config); + } + pub fn request_sys_clk(clocks: &mut ClockTree) { + trace!("Requesting SYS_CLK"); + trace!("Enabling SYS_CLK"); + request_mem_clk(clocks); + enable_sys_clk_impl(clocks, true); + } + pub fn release_sys_clk(clocks: &mut ClockTree) { + trace!("Releasing SYS_CLK"); + trace!("Disabling SYS_CLK"); + enable_sys_clk_impl(clocks, false); + release_mem_clk(clocks); + } + pub fn sys_clk_frequency(clocks: &mut ClockTree) -> u32 { + (mem_clk_frequency(clocks) / unwrap!(clocks.sys_clk).value()) + } + pub fn configure_apb_clk(clocks: &mut ClockTree, config: ApbClkConfig) { + clocks.apb_clk = Some(config); + configure_apb_clk_impl(clocks, config); + } + pub fn request_apb_clk(clocks: &mut ClockTree) { + trace!("Requesting APB_CLK"); + if increment_reference_count(&mut clocks.apb_clk_refcount) { + trace!("Enabling APB_CLK"); + request_sys_clk(clocks); + enable_apb_clk_impl(clocks, true); + } + } + pub fn release_apb_clk(clocks: &mut ClockTree) { + trace!("Releasing APB_CLK"); + if decrement_reference_count(&mut clocks.apb_clk_refcount) { + trace!("Disabling APB_CLK"); + enable_apb_clk_impl(clocks, false); + release_sys_clk(clocks); + } + } + pub fn apb_clk_frequency(clocks: &mut ClockTree) -> u32 { + (sys_clk_frequency(clocks) / unwrap!(clocks.apb_clk).value()) + } + pub fn request_pll_f50m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F50M_CLK"); + if increment_reference_count(&mut clocks.pll_f50m_clk_refcount) { + trace!("Enabling PLL_F50M_CLK"); + request_mpll_clk(clocks); + enable_pll_f50m_clk_impl(clocks, true); + } + } + pub fn release_pll_f50m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F50M_CLK"); + if decrement_reference_count(&mut clocks.pll_f50m_clk_refcount) { + trace!("Disabling PLL_F50M_CLK"); + enable_pll_f50m_clk_impl(clocks, false); + release_mpll_clk(clocks); + } + } + pub fn pll_f50m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 50000000 + } + pub fn request_pll_f25m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F25M_CLK"); + if increment_reference_count(&mut clocks.pll_f25m_clk_refcount) { + trace!("Enabling PLL_F25M_CLK"); + request_mpll_clk(clocks); + enable_pll_f25m_clk_impl(clocks, true); + } + } + pub fn release_pll_f25m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F25M_CLK"); + if decrement_reference_count(&mut clocks.pll_f25m_clk_refcount) { + trace!("Disabling PLL_F25M_CLK"); + enable_pll_f25m_clk_impl(clocks, false); + release_mpll_clk(clocks); + } + } + pub fn pll_f25m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 25000000 + } + pub fn request_pll_f240m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F240M_CLK"); + if increment_reference_count(&mut clocks.pll_f240m_clk_refcount) { + trace!("Enabling PLL_F240M_CLK"); + request_spll_clk(clocks); + enable_pll_f240m_clk_impl(clocks, true); + } + } + pub fn release_pll_f240m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F240M_CLK"); + if decrement_reference_count(&mut clocks.pll_f240m_clk_refcount) { + trace!("Disabling PLL_F240M_CLK"); + enable_pll_f240m_clk_impl(clocks, false); + release_spll_clk(clocks); + } + } + pub fn pll_f240m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 240000000 + } + pub fn request_pll_f160m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F160M_CLK"); + if increment_reference_count(&mut clocks.pll_f160m_clk_refcount) { + trace!("Enabling PLL_F160M_CLK"); + request_spll_clk(clocks); + enable_pll_f160m_clk_impl(clocks, true); + } + } + pub fn release_pll_f160m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F160M_CLK"); + if decrement_reference_count(&mut clocks.pll_f160m_clk_refcount) { + trace!("Disabling PLL_F160M_CLK"); + enable_pll_f160m_clk_impl(clocks, false); + release_spll_clk(clocks); + } + } + pub fn pll_f160m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 160000000 + } + pub fn request_pll_f120m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F120M_CLK"); + if increment_reference_count(&mut clocks.pll_f120m_clk_refcount) { + trace!("Enabling PLL_F120M_CLK"); + request_spll_clk(clocks); + enable_pll_f120m_clk_impl(clocks, true); + } + } + pub fn release_pll_f120m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F120M_CLK"); + if decrement_reference_count(&mut clocks.pll_f120m_clk_refcount) { + trace!("Disabling PLL_F120M_CLK"); + enable_pll_f120m_clk_impl(clocks, false); + release_spll_clk(clocks); + } + } + pub fn pll_f120m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 120000000 + } + pub fn request_pll_f80m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F80M_CLK"); + if increment_reference_count(&mut clocks.pll_f80m_clk_refcount) { + trace!("Enabling PLL_F80M_CLK"); + request_spll_clk(clocks); + enable_pll_f80m_clk_impl(clocks, true); + } + } + pub fn release_pll_f80m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F80M_CLK"); + if decrement_reference_count(&mut clocks.pll_f80m_clk_refcount) { + trace!("Disabling PLL_F80M_CLK"); + enable_pll_f80m_clk_impl(clocks, false); + release_spll_clk(clocks); + } + } + pub fn pll_f80m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 80000000 + } + pub fn request_pll_f20m_clk(clocks: &mut ClockTree) { + trace!("Requesting PLL_F20M_CLK"); + if increment_reference_count(&mut clocks.pll_f20m_clk_refcount) { + trace!("Enabling PLL_F20M_CLK"); + request_spll_clk(clocks); + enable_pll_f20m_clk_impl(clocks, true); + } + } + pub fn release_pll_f20m_clk(clocks: &mut ClockTree) { + trace!("Releasing PLL_F20M_CLK"); + if decrement_reference_count(&mut clocks.pll_f20m_clk_refcount) { + trace!("Disabling PLL_F20M_CLK"); + enable_pll_f20m_clk_impl(clocks, false); + release_spll_clk(clocks); + } + } + pub fn pll_f20m_clk_frequency(clocks: &mut ClockTree) -> u32 { + 20000000 + } + pub fn configure_lp_slow_clk(clocks: &mut ClockTree, new_selector: LpSlowClkConfig) { + let old_selector = clocks.lp_slow_clk.replace(new_selector); + match new_selector { + LpSlowClkConfig::Xtal32k => request_xtal32k_clk(clocks), + LpSlowClkConfig::RcSlow => request_rc_slow_clk(clocks), + LpSlowClkConfig::OscSlow => request_osc_slow_clk(clocks), + } + configure_lp_slow_clk_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + LpSlowClkConfig::Xtal32k => release_xtal32k_clk(clocks), + LpSlowClkConfig::RcSlow => release_rc_slow_clk(clocks), + LpSlowClkConfig::OscSlow => release_osc_slow_clk(clocks), + } + } + } + fn request_lp_slow_clk(_clocks: &mut ClockTree) {} + fn release_lp_slow_clk(_clocks: &mut ClockTree) {} + pub fn lp_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.lp_slow_clk) { + LpSlowClkConfig::Xtal32k => xtal32k_clk_frequency(clocks), + LpSlowClkConfig::RcSlow => rc_slow_clk_frequency(clocks), + LpSlowClkConfig::OscSlow => osc_slow_clk_frequency(clocks), + } + } + pub fn configure_lp_fast_clk(clocks: &mut ClockTree, new_selector: LpFastClkConfig) { + let old_selector = clocks.lp_fast_clk.replace(new_selector); + match new_selector { + LpFastClkConfig::Xtal => request_xtal_clk(clocks), + LpFastClkConfig::RcFast => request_rc_fast_clk(clocks), + LpFastClkConfig::Pll => request_pll_lp_clk(clocks), + } + configure_lp_fast_clk_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + LpFastClkConfig::Xtal => release_xtal_clk(clocks), + LpFastClkConfig::RcFast => release_rc_fast_clk(clocks), + LpFastClkConfig::Pll => release_pll_lp_clk(clocks), + } + } + } + fn request_lp_fast_clk(_clocks: &mut ClockTree) {} + fn release_lp_fast_clk(_clocks: &mut ClockTree) {} + pub fn lp_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.lp_fast_clk) { + LpFastClkConfig::Xtal => xtal_clk_frequency(clocks), + LpFastClkConfig::RcFast => rc_fast_clk_frequency(clocks), + LpFastClkConfig::Pll => pll_lp_clk_frequency(clocks), + } + } + pub fn configure_lp_dyn_slow_clk(clocks: &mut ClockTree, new_selector: LpDynSlowClkConfig) { + let old_selector = clocks.lp_dyn_slow_clk.replace(new_selector); + match new_selector { + LpDynSlowClkConfig::LpSlow => request_lp_slow_clk(clocks), + LpDynSlowClkConfig::LpFast => request_lp_fast_clk(clocks), + } + configure_lp_dyn_slow_clk_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + LpDynSlowClkConfig::LpSlow => release_lp_slow_clk(clocks), + LpDynSlowClkConfig::LpFast => release_lp_fast_clk(clocks), + } + } + } + fn request_lp_dyn_slow_clk(_clocks: &mut ClockTree) {} + fn release_lp_dyn_slow_clk(_clocks: &mut ClockTree) {} + pub fn lp_dyn_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.lp_dyn_slow_clk) { + LpDynSlowClkConfig::LpSlow => lp_slow_clk_frequency(clocks), + LpDynSlowClkConfig::LpFast => lp_fast_clk_frequency(clocks), + } + } + pub fn configure_lp_dyn_fast_clk(clocks: &mut ClockTree, new_selector: LpDynFastClkConfig) { + let old_selector = clocks.lp_dyn_fast_clk.replace(new_selector); + match new_selector { + LpDynFastClkConfig::LpSlow => request_lp_slow_clk(clocks), + LpDynFastClkConfig::LpFast => request_lp_fast_clk(clocks), + } + configure_lp_dyn_fast_clk_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + LpDynFastClkConfig::LpSlow => release_lp_slow_clk(clocks), + LpDynFastClkConfig::LpFast => release_lp_fast_clk(clocks), + } + } + } + fn request_lp_dyn_fast_clk(_clocks: &mut ClockTree) {} + fn release_lp_dyn_fast_clk(_clocks: &mut ClockTree) {} + pub fn lp_dyn_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.lp_dyn_fast_clk) { + LpDynFastClkConfig::LpSlow => lp_slow_clk_frequency(clocks), + LpDynFastClkConfig::LpFast => lp_fast_clk_frequency(clocks), + } + } + pub fn configure_lp_peri_clk(clocks: &mut ClockTree, config: LpPeriClkConfig) { + clocks.lp_peri_clk = Some(config); + configure_lp_peri_clk_impl(clocks, config); + } + pub fn request_lp_peri_clk(clocks: &mut ClockTree) { + trace!("Requesting LP_PERI_CLK"); + if increment_reference_count(&mut clocks.lp_peri_clk_refcount) { + trace!("Enabling LP_PERI_CLK"); + request_lp_dyn_fast_clk(clocks); + enable_lp_peri_clk_impl(clocks, true); + } + } + pub fn release_lp_peri_clk(clocks: &mut ClockTree) { + trace!("Releasing LP_PERI_CLK"); + if decrement_reference_count(&mut clocks.lp_peri_clk_refcount) { + trace!("Disabling LP_PERI_CLK"); + enable_lp_peri_clk_impl(clocks, false); + release_lp_dyn_fast_clk(clocks); + } + } + pub fn lp_peri_clk_frequency(clocks: &mut ClockTree) -> u32 { + (lp_dyn_fast_clk_frequency(clocks) / unwrap!(clocks.lp_peri_clk).value()) + } + pub fn request_xtal_d2_clk(clocks: &mut ClockTree) { + trace!("Requesting XTAL_D2_CLK"); + if increment_reference_count(&mut clocks.xtal_d2_clk_refcount) { + trace!("Enabling XTAL_D2_CLK"); + request_xtal_clk(clocks); + enable_xtal_d2_clk_impl(clocks, true); + } + } + pub fn release_xtal_d2_clk(clocks: &mut ClockTree) { + trace!("Releasing XTAL_D2_CLK"); + if decrement_reference_count(&mut clocks.xtal_d2_clk_refcount) { + trace!("Disabling XTAL_D2_CLK"); + enable_xtal_d2_clk_impl(clocks, false); + release_xtal_clk(clocks); + } + } + pub fn xtal_d2_clk_frequency(clocks: &mut ClockTree) -> u32 { + (xtal_clk_frequency(clocks) / 2) + } + pub fn configure_timg0_function_clock( + clocks: &mut ClockTree, + new_selector: Timg0FunctionClockConfig, + ) { + let old_selector = clocks.timg0_function_clock.replace(new_selector); + if clocks.timg0_function_clock_refcount > 0 { + match new_selector { + Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_timg0_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_timg0_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_timg0_function_clock(clocks: &mut ClockTree) { + trace!("Requesting TIMG0_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.timg0_function_clock_refcount) { + trace!("Enabling TIMG0_FUNCTION_CLOCK"); + match unwrap!(clocks.timg0_function_clock) { + Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_timg0_function_clock_impl(clocks, true); + } + } + pub fn release_timg0_function_clock(clocks: &mut ClockTree) { + trace!("Releasing TIMG0_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.timg0_function_clock_refcount) { + trace!("Disabling TIMG0_FUNCTION_CLOCK"); + enable_timg0_function_clock_impl(clocks, false); + match unwrap!(clocks.timg0_function_clock) { + Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn timg0_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.timg0_function_clock) { + Timg0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Timg0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Timg0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + pub fn configure_timg1_function_clock( + clocks: &mut ClockTree, + new_selector: Timg0FunctionClockConfig, + ) { + let old_selector = clocks.timg1_function_clock.replace(new_selector); + if clocks.timg1_function_clock_refcount > 0 { + match new_selector { + Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_timg1_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_timg1_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_timg1_function_clock(clocks: &mut ClockTree) { + trace!("Requesting TIMG1_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.timg1_function_clock_refcount) { + trace!("Enabling TIMG1_FUNCTION_CLOCK"); + match unwrap!(clocks.timg1_function_clock) { + Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_timg1_function_clock_impl(clocks, true); + } + } + pub fn release_timg1_function_clock(clocks: &mut ClockTree) { + trace!("Releasing TIMG1_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.timg1_function_clock_refcount) { + trace!("Disabling TIMG1_FUNCTION_CLOCK"); + enable_timg1_function_clock_impl(clocks, false); + match unwrap!(clocks.timg1_function_clock) { + Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn timg1_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.timg1_function_clock) { + Timg0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Timg0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Timg0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + pub fn configure_uart0_function_clock( + clocks: &mut ClockTree, + new_selector: Uart0FunctionClockConfig, + ) { + let old_selector = clocks.uart0_function_clock.replace(new_selector); + if clocks.uart0_function_clock_refcount > 0 { + match new_selector { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_uart0_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_uart0_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_uart0_function_clock(clocks: &mut ClockTree) { + trace!("Requesting UART0_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.uart0_function_clock_refcount) { + trace!("Enabling UART0_FUNCTION_CLOCK"); + match unwrap!(clocks.uart0_function_clock) { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_uart0_function_clock_impl(clocks, true); + } + } + pub fn release_uart0_function_clock(clocks: &mut ClockTree) { + trace!("Releasing UART0_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.uart0_function_clock_refcount) { + trace!("Disabling UART0_FUNCTION_CLOCK"); + enable_uart0_function_clock_impl(clocks, false); + match unwrap!(clocks.uart0_function_clock) { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn uart0_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.uart0_function_clock) { + Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + pub fn configure_uart1_function_clock( + clocks: &mut ClockTree, + new_selector: Uart0FunctionClockConfig, + ) { + let old_selector = clocks.uart1_function_clock.replace(new_selector); + if clocks.uart1_function_clock_refcount > 0 { + match new_selector { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_uart1_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_uart1_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_uart1_function_clock(clocks: &mut ClockTree) { + trace!("Requesting UART1_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.uart1_function_clock_refcount) { + trace!("Enabling UART1_FUNCTION_CLOCK"); + match unwrap!(clocks.uart1_function_clock) { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_uart1_function_clock_impl(clocks, true); + } + } + pub fn release_uart1_function_clock(clocks: &mut ClockTree) { + trace!("Releasing UART1_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.uart1_function_clock_refcount) { + trace!("Disabling UART1_FUNCTION_CLOCK"); + enable_uart1_function_clock_impl(clocks, false); + match unwrap!(clocks.uart1_function_clock) { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn uart1_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.uart1_function_clock) { + Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + pub fn configure_uart2_function_clock( + clocks: &mut ClockTree, + new_selector: Uart0FunctionClockConfig, + ) { + let old_selector = clocks.uart2_function_clock.replace(new_selector); + if clocks.uart2_function_clock_refcount > 0 { + match new_selector { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_uart2_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_uart2_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_uart2_function_clock(clocks: &mut ClockTree) { + trace!("Requesting UART2_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.uart2_function_clock_refcount) { + trace!("Enabling UART2_FUNCTION_CLOCK"); + match unwrap!(clocks.uart2_function_clock) { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_uart2_function_clock_impl(clocks, true); + } + } + pub fn release_uart2_function_clock(clocks: &mut ClockTree) { + trace!("Releasing UART2_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.uart2_function_clock_refcount) { + trace!("Disabling UART2_FUNCTION_CLOCK"); + enable_uart2_function_clock_impl(clocks, false); + match unwrap!(clocks.uart2_function_clock) { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn uart2_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.uart2_function_clock) { + Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + pub fn configure_uart3_function_clock( + clocks: &mut ClockTree, + new_selector: Uart0FunctionClockConfig, + ) { + let old_selector = clocks.uart3_function_clock.replace(new_selector); + if clocks.uart3_function_clock_refcount > 0 { + match new_selector { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_uart3_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_uart3_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_uart3_function_clock(clocks: &mut ClockTree) { + trace!("Requesting UART3_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.uart3_function_clock_refcount) { + trace!("Enabling UART3_FUNCTION_CLOCK"); + match unwrap!(clocks.uart3_function_clock) { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_uart3_function_clock_impl(clocks, true); + } + } + pub fn release_uart3_function_clock(clocks: &mut ClockTree) { + trace!("Releasing UART3_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.uart3_function_clock_refcount) { + trace!("Disabling UART3_FUNCTION_CLOCK"); + enable_uart3_function_clock_impl(clocks, false); + match unwrap!(clocks.uart3_function_clock) { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn uart3_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.uart3_function_clock) { + Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + pub fn configure_uart4_function_clock( + clocks: &mut ClockTree, + new_selector: Uart0FunctionClockConfig, + ) { + let old_selector = clocks.uart4_function_clock.replace(new_selector); + if clocks.uart4_function_clock_refcount > 0 { + match new_selector { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + configure_uart4_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } else { + configure_uart4_function_clock_impl(clocks, old_selector, new_selector); + } + } + pub fn request_uart4_function_clock(clocks: &mut ClockTree) { + trace!("Requesting UART4_FUNCTION_CLOCK"); + if increment_reference_count(&mut clocks.uart4_function_clock_refcount) { + trace!("Enabling UART4_FUNCTION_CLOCK"); + match unwrap!(clocks.uart4_function_clock) { + Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + } + enable_uart4_function_clock_impl(clocks, true); + } + } + pub fn release_uart4_function_clock(clocks: &mut ClockTree) { + trace!("Releasing UART4_FUNCTION_CLOCK"); + if decrement_reference_count(&mut clocks.uart4_function_clock_refcount) { + trace!("Disabling UART4_FUNCTION_CLOCK"); + enable_uart4_function_clock_impl(clocks, false); + match unwrap!(clocks.uart4_function_clock) { + Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), + Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), + Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + } + } + pub fn uart4_function_clock_frequency(clocks: &mut ClockTree) -> u32 { + match unwrap!(clocks.uart4_function_clock) { + Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), + Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), + Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + } + } + /// Clock tree configuration. + /// + /// The fields of this struct are optional, with the following caveats: + /// - If `XTAL_CLK` is not specified, the crystal frequency will be automatically detected + /// if possible. + /// - The CPU and its upstream clock nodes will be set to a default configuration. + /// - Other unspecified clock sources will not be useable by peripherals. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + #[instability::unstable] + pub struct ClockConfig { + /// `XTAL_CLK` configuration. + pub xtal_clk: Option, + /// `CPLL_CLK` configuration. + pub cpll_clk: Option, + /// `MPLL_CLK` configuration. + pub mpll_clk: Option, + /// `SPLL_CLK` configuration. + pub spll_clk: Option, + /// `PLL_LP_CLK` configuration. + pub pll_lp_clk: Option, + /// `ROOT_CLK` configuration. + pub root_clk: Option, + /// `CPU_CLK` configuration. + pub cpu_clk: Option, + /// `MEM_CLK` configuration. + pub mem_clk: Option, + /// `SYS_CLK` configuration. + pub sys_clk: Option, + /// `APB_CLK` configuration. + pub apb_clk: Option, + /// `LP_SLOW_CLK` configuration. + pub lp_slow_clk: Option, + /// `LP_FAST_CLK` configuration. + pub lp_fast_clk: Option, + /// `LP_DYN_SLOW_CLK` configuration. + pub lp_dyn_slow_clk: Option, + /// `LP_DYN_FAST_CLK` configuration. + pub lp_dyn_fast_clk: Option, + /// `LP_PERI_CLK` configuration. + pub lp_peri_clk: Option, + } + impl ClockConfig { + fn apply(&self) { + ClockTree::with(|clocks| { + if let Some(config) = self.xtal_clk { + configure_xtal_clk(clocks, config); + } + if let Some(config) = self.cpll_clk { + configure_cpll_clk(clocks, config); + } + if let Some(config) = self.mpll_clk { + configure_mpll_clk(clocks, config); + } + if let Some(config) = self.spll_clk { + configure_spll_clk(clocks, config); + } + if let Some(config) = self.pll_lp_clk { + configure_pll_lp_clk(clocks, config); + } + if let Some(config) = self.root_clk { + configure_root_clk(clocks, config); + } + if let Some(config) = self.cpu_clk { + configure_cpu_clk(clocks, config); + } + if let Some(config) = self.mem_clk { + configure_mem_clk(clocks, config); + } + if let Some(config) = self.sys_clk { + configure_sys_clk(clocks, config); + } + if let Some(config) = self.apb_clk { + configure_apb_clk(clocks, config); + } + if let Some(config) = self.lp_slow_clk { + configure_lp_slow_clk(clocks, config); + } + if let Some(config) = self.lp_fast_clk { + configure_lp_fast_clk(clocks, config); + } + if let Some(config) = self.lp_dyn_slow_clk { + configure_lp_dyn_slow_clk(clocks, config); + } + if let Some(config) = self.lp_dyn_fast_clk { + configure_lp_dyn_fast_clk(clocks, config); + } + if let Some(config) = self.lp_peri_clk { + configure_lp_peri_clk(clocks, config); + } + }); + } + } + fn increment_reference_count(refcount: &mut u32) -> bool { + let first = *refcount == 0; + *refcount = unwrap!(refcount.checked_add(1), "Reference count overflow"); + first + } + fn decrement_reference_count(refcount: &mut u32) -> bool { + *refcount = refcount.saturating_sub(1); + let last = *refcount == 0; + last + } + }; +} +/// Implement the `Peripheral` enum and enable/disable/reset functions. +/// +/// This macro is intended to be placed in `esp_hal::system`. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! implement_peripheral_clocks { + () => { + #[doc(hidden)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(u8)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Peripheral { + /// SYSTIMER peripheral clock signal + Systimer, + /// TIMG0 peripheral clock signal + Timg0, + /// TIMG1 peripheral clock signal + Timg1, + /// UART0 peripheral clock signal + Uart0, + /// UART1 peripheral clock signal + Uart1, + /// UART2 peripheral clock signal + Uart2, + /// UART3 peripheral clock signal + Uart3, + /// UART4 peripheral clock signal + Uart4, + } + impl Peripheral { + const KEEP_ENABLED: &[Peripheral] = &[Self::Systimer, Self::Timg0, Self::Uart0]; + const COUNT: usize = Self::ALL.len(); + const ALL: &[Self] = &[ + Self::Systimer, + Self::Timg0, + Self::Timg1, + Self::Uart0, + Self::Uart1, + Self::Uart2, + Self::Uart3, + Self::Uart4, + ]; + } + unsafe fn enable_internal_racey(peripheral: Peripheral, enable: bool) { + match peripheral { + Peripheral::Systimer => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.systimer_apb_clk_en().bit(enable)); + } + Peripheral::Timg0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl21() + .modify(|_, w| w.timergrp0_t0_clk_en().bit(enable)); + } + Peripheral::Timg1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl20() + .modify(|_, w| w.timergrp1_t0_clk_en().bit(enable)); + } + Peripheral::Uart0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl110() + .modify(|_, w| w.uart0_clk_en().bit(enable)); + } + Peripheral::Uart1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl111() + .modify(|_, w| w.uart1_clk_en().bit(enable)); + } + Peripheral::Uart2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl112() + .modify(|_, w| w.uart2_clk_en().bit(enable)); + } + Peripheral::Uart3 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl113() + .modify(|_, w| w.uart3_clk_en().bit(enable)); + } + Peripheral::Uart4 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl114() + .modify(|_, w| w.uart4_clk_en().bit(enable)); + } + } + } + unsafe fn assert_peri_reset_racey(peripheral: Peripheral, reset: bool) { + match peripheral { + Peripheral::Systimer => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_stimer().bit(reset)); + } + Peripheral::Timg0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_timergrp1().bit(reset)); + } + Peripheral::Timg1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_timergrp0().bit(reset)); + } + Peripheral::Uart0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_uart0_core().bit(reset)); + } + Peripheral::Uart1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_uart1_core().bit(reset)); + } + Peripheral::Uart2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_uart2_core().bit(reset)); + } + Peripheral::Uart3 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_uart3_core().bit(reset)); + } + Peripheral::Uart4 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_uart4_core().bit(reset)); + } + } + } + }; +} +/// Macro to get the address range of the given memory region. +/// +/// This macro provides two syntax options for each memory region: +/// +/// - `memory_range!("region_name")` returns the address range as a range expression (`start..end`). +/// - `memory_range!(size as str, "region_name")` returns the size of the region as a string +/// literal. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! memory_range { + ("DRAM") => { + 0x4FF00000..0x4FFC0000 + }; + (size as str, "DRAM") => { + "786432" + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_sw_interrupt { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((0, FROM_CPU_INTR0, software_interrupt0)); _for_each_inner!((1, + FROM_CPU_INTR1, software_interrupt1)); _for_each_inner!((2, FROM_CPU_INTR2, + software_interrupt2)); _for_each_inner!((3, FROM_CPU_INTR3, + software_interrupt3)); _for_each_inner!((all(0, FROM_CPU_INTR0, + software_interrupt0), (1, FROM_CPU_INTR1, software_interrupt1), (2, + FROM_CPU_INTR2, software_interrupt2), (3, FROM_CPU_INTR3, software_interrupt3))); + }; +} +#[macro_export] +macro_rules! sw_interrupt_delay { + () => { + unsafe { + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + } + }; +} +/// This macro can be used to generate code for each peripheral instance of the I2C master driver. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has one option for its "Individual matcher" case: +/// +/// Syntax: `($instance:ident, $sys:ident, $scl:ident, $sda:ident)` +/// +/// Macro fragments: +/// +/// - `$instance`: the name of the I2C instance +/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum. +/// - `$scl`, `$sda`: peripheral signal names. +/// +/// Example data: `(I2C0, I2cExt0, I2CEXT0_SCL, I2CEXT0_SDA)` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_i2c_master { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((all)); + }; +} +/// This macro can be used to generate code for each peripheral instance of the UART driver. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has one option for its "Individual matcher" case: +/// +/// Syntax: `($instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident, $rts:ident)` +/// +/// Macro fragments: +/// +/// - `$instance`: the name of the UART instance +/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum. +/// - `$rx`, `$tx`, `$cts`, `$rts`: signal names. +/// +/// Example data: `(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_uart { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((all)); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_peripheral { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((@ peri_type #[doc = "GPIO0 peripheral singleton"] GPIO0 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO1 peripheral singleton"] + GPIO1 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO2 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO2 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO3 peripheral singleton (Limitations exist)"] #[doc = ""] + #[doc = "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO3 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO4 peripheral singleton (Limitations exist)"] #[doc = ""] + #[doc = "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO4 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO5 peripheral singleton (Limitations exist)"] #[doc = ""] + #[doc = "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO5 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO6 peripheral singleton"] GPIO6 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO7 peripheral singleton"] GPIO7 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO8 peripheral singleton"] + GPIO8 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO9 peripheral singleton"] GPIO9 <= virtual())); _for_each_inner!((@ peri_type + #[doc = "GPIO10 peripheral singleton"] GPIO10 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO11 peripheral singleton"] GPIO11 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO12 peripheral singleton"] GPIO12 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO13 peripheral singleton"] + GPIO13 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO14 peripheral singleton"] GPIO14 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO15 peripheral singleton"] GPIO15 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO16 peripheral singleton"] GPIO16 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO17 peripheral singleton"] + GPIO17 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO18 peripheral singleton"] GPIO18 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO19 peripheral singleton"] GPIO19 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO20 peripheral singleton"] GPIO20 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO21 peripheral singleton"] + GPIO21 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO22 peripheral singleton"] GPIO22 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO23 peripheral singleton"] GPIO23 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO24 peripheral singleton"] GPIO24 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO25 peripheral singleton"] + GPIO25 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO26 peripheral singleton"] GPIO26 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO27 peripheral singleton"] GPIO27 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO28 peripheral singleton"] GPIO28 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO29 peripheral singleton"] + GPIO29 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO30 peripheral singleton"] GPIO30 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO31 peripheral singleton"] GPIO31 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO32 peripheral singleton"] GPIO32 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO33 peripheral singleton"] + GPIO33 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO34 peripheral singleton"] GPIO34 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO35 peripheral singleton"] GPIO35 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO36 peripheral singleton"] GPIO36 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO37 peripheral singleton"] + GPIO37 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO38 peripheral singleton"] GPIO38 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO39 peripheral singleton"] GPIO39 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO40 peripheral singleton"] GPIO40 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO41 peripheral singleton"] + GPIO41 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO42 peripheral singleton"] GPIO42 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO43 peripheral singleton"] GPIO43 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO44 peripheral singleton"] GPIO44 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO45 peripheral singleton"] + GPIO45 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO46 peripheral singleton"] GPIO46 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO47 peripheral singleton"] GPIO47 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO48 peripheral singleton"] GPIO48 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO49 peripheral singleton"] + GPIO49 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO50 peripheral singleton"] GPIO50 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "GPIO51 peripheral singleton"] GPIO51 <= virtual())); + _for_each_inner!((@ peri_type #[doc = "GPIO52 peripheral singleton"] GPIO52 <= + virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO53 peripheral singleton"] + GPIO53 <= virtual())); _for_each_inner!((@ peri_type #[doc = + "GPIO54 peripheral singleton"] GPIO54 <= virtual())); _for_each_inner!((@ + peri_type #[doc = "ADC peripheral singleton"] ADC <= ADC() (unstable))); + _for_each_inner!((@ peri_type #[doc = "AES peripheral singleton"] AES <= AES() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "AHB_DMA peripheral singleton"] AHB_DMA <= AHB_DMA() (unstable))); + _for_each_inner!((@ peri_type #[doc = "ASSIST_DEBUG peripheral singleton"] + ASSIST_DEBUG <= ASSIST_DEBUG() (unstable))); _for_each_inner!((@ peri_type #[doc + = "AXI_DMA peripheral singleton"] AXI_DMA <= AXI_DMA() (unstable))); + _for_each_inner!((@ peri_type #[doc = "AXI_ICM peripheral singleton"] AXI_ICM <= + AXI_ICM() (unstable))); _for_each_inner!((@ peri_type #[doc = + "BITSCRAMBLER peripheral singleton"] BITSCRAMBLER <= BITSCRAMBLER() (unstable))); + _for_each_inner!((@ peri_type #[doc = "CACHE peripheral singleton"] CACHE <= + CACHE() (unstable))); _for_each_inner!((@ peri_type #[doc = + "DMA peripheral singleton"] DMA <= DMA() (unstable))); _for_each_inner!((@ + peri_type #[doc = "DS peripheral singleton"] DS <= DS() (unstable))); + _for_each_inner!((@ peri_type #[doc = "ECC peripheral singleton"] ECC <= ECC() + (unstable))); _for_each_inner!((@ peri_type #[doc = "ECDSA peripheral singleton"] + ECDSA <= ECDSA() (unstable))); _for_each_inner!((@ peri_type #[doc = + "EFUSE peripheral singleton"] EFUSE <= EFUSE() (unstable))); _for_each_inner!((@ + peri_type #[doc = "GPIO peripheral singleton"] GPIO <= GPIO() (unstable))); + _for_each_inner!((@ peri_type #[doc = "GPIO_SD peripheral singleton"] GPIO_SD <= + GPIO_SD() (unstable))); _for_each_inner!((@ peri_type #[doc = + "H264 peripheral singleton"] H264 <= H264() (unstable))); _for_each_inner!((@ + peri_type #[doc = "H264_DMA peripheral singleton"] H264_DMA <= H264_DMA() + (unstable))); _for_each_inner!((@ peri_type #[doc = "HMAC peripheral singleton"] + HMAC <= HMAC() (unstable))); _for_each_inner!((@ peri_type #[doc = + "HP_SYS peripheral singleton"] HP_SYS <= HP_SYS() (unstable))); + _for_each_inner!((@ peri_type #[doc = "HP_SYS_CLKRST peripheral singleton"] + HP_SYS_CLKRST <= HP_SYS_CLKRST() (unstable))); _for_each_inner!((@ peri_type + #[doc = "I2C0 peripheral singleton"] I2C0 <= I2C0() (unstable))); + _for_each_inner!((@ peri_type #[doc = "I2C1 peripheral singleton"] I2C1 <= I2C1() + (unstable))); _for_each_inner!((@ peri_type #[doc = "I2S0 peripheral singleton"] + I2S0 <= I2S0() (unstable))); _for_each_inner!((@ peri_type #[doc = + "I2S1 peripheral singleton"] I2S1 <= I2S1() (unstable))); _for_each_inner!((@ + peri_type #[doc = "I2S2 peripheral singleton"] I2S2 <= I2S2() (unstable))); + _for_each_inner!((@ peri_type #[doc = "I3C_MST peripheral singleton"] I3C_MST <= + I3C_MST() (unstable))); _for_each_inner!((@ peri_type #[doc = + "I3C_MST_MEM peripheral singleton"] I3C_MST_MEM <= I3C_MST_MEM() (unstable))); + _for_each_inner!((@ peri_type #[doc = "I3C_SLV peripheral singleton"] I3C_SLV <= + I3C_SLV() (unstable))); _for_each_inner!((@ peri_type #[doc = + "INTERRUPT_CORE0 peripheral singleton"] INTERRUPT_CORE0 <= INTERRUPT_CORE0() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "INTERRUPT_CORE1 peripheral singleton"] INTERRUPT_CORE1 <= INTERRUPT_CORE1() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "IO_MUX peripheral singleton"] IO_MUX <= IO_MUX() (unstable))); + _for_each_inner!((@ peri_type #[doc = "ISP peripheral singleton"] ISP <= ISP() + (unstable))); _for_each_inner!((@ peri_type #[doc = "JPEG peripheral singleton"] + JPEG <= JPEG() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LCD_CAM peripheral singleton"] LCD_CAM <= LCD_CAM() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LEDC peripheral singleton"] LEDC <= LEDC() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_ADC peripheral singleton"] LP_ADC <= LP_ADC() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_ANA peripheral singleton"] LP_ANA <= + LP_ANA() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_AON_CLKRST peripheral singleton"] LP_AON_CLKRST <= LP_AON_CLKRST() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_GPIO peripheral singleton"] LP_GPIO <= LP_GPIO() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_HUK peripheral singleton"] LP_HUK <= + LP_HUK() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_I2C0 peripheral singleton"] LP_I2C0 <= LP_I2C0() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_I2C_ANA_MST peripheral singleton"] + LP_I2C_ANA_MST <= LP_I2C_ANA_MST() (unstable))); _for_each_inner!((@ peri_type + #[doc = "LP_I2S0 peripheral singleton"] LP_I2S0 <= LP_I2S0() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_INTR peripheral singleton"] LP_INTR <= + LP_INTR() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_IO_MUX peripheral singleton"] LP_IO_MUX <= LP_IO_MUX() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_PERI peripheral singleton"] LP_PERI <= + LP_PERI() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_SYS peripheral singleton"] LP_SYS <= LP_SYS() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_TIMER peripheral singleton"] LP_TIMER + <= LP_TIMER() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_TOUCH peripheral singleton"] LP_TOUCH <= LP_TOUCH() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_TSENS peripheral singleton"] LP_TSENS + <= LP_TSENS() (unstable))); _for_each_inner!((@ peri_type #[doc = + "LP_UART peripheral singleton"] LP_UART <= LP_UART() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LP_WDT peripheral singleton"] LP_WDT <= + LP_WDT() (unstable))); _for_each_inner!((@ peri_type #[doc = + "MCPWM0 peripheral singleton"] MCPWM0 <= MCPWM0() (unstable))); + _for_each_inner!((@ peri_type #[doc = "MCPWM1 peripheral singleton"] MCPWM1 <= + MCPWM1() (unstable))); _for_each_inner!((@ peri_type #[doc = + "MIPI_CSI_BRIDGE peripheral singleton"] MIPI_CSI_BRIDGE <= MIPI_CSI_BRIDGE() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "MIPI_CSI_HOST peripheral singleton"] MIPI_CSI_HOST <= MIPI_CSI_HOST() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "MIPI_DSI_BRIDGE peripheral singleton"] MIPI_DSI_BRIDGE <= MIPI_DSI_BRIDGE() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "MIPI_DSI_HOST peripheral singleton"] MIPI_DSI_HOST <= MIPI_DSI_HOST() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "PARL_IO peripheral singleton"] PARL_IO <= PARL_IO() (unstable))); + _for_each_inner!((@ peri_type #[doc = "PAU peripheral singleton"] PAU <= PAU() + (unstable))); _for_each_inner!((@ peri_type #[doc = "PCNT peripheral singleton"] + PCNT <= PCNT() (unstable))); _for_each_inner!((@ peri_type #[doc = + "PMU peripheral singleton"] PMU <= PMU() (unstable))); _for_each_inner!((@ + peri_type #[doc = "PPA peripheral singleton"] PPA <= PPA() (unstable))); + _for_each_inner!((@ peri_type #[doc = "PVT peripheral singleton"] PVT <= PVT() + (unstable))); _for_each_inner!((@ peri_type #[doc = "RMT peripheral singleton"] + RMT <= RMT() (unstable))); _for_each_inner!((@ peri_type #[doc = + "RSA peripheral singleton"] RSA <= RSA() (unstable))); _for_each_inner!((@ + peri_type #[doc = "SDHOST peripheral singleton"] SDHOST <= SDHOST() (unstable))); + _for_each_inner!((@ peri_type #[doc = "SHA peripheral singleton"] SHA <= SHA() + (unstable))); _for_each_inner!((@ peri_type #[doc = + "SOC_ETM peripheral singleton"] SOC_ETM <= SOC_ETM() (unstable))); + _for_each_inner!((@ peri_type #[doc = "SPI0 peripheral singleton"] SPI0 <= SPI0() + (unstable))); _for_each_inner!((@ peri_type #[doc = "SPI1 peripheral singleton"] + SPI1 <= SPI1() (unstable))); _for_each_inner!((@ peri_type #[doc = + "SPI2 peripheral singleton"] SPI2 <= SPI2() (unstable))); _for_each_inner!((@ + peri_type #[doc = "SPI3 peripheral singleton"] SPI3 <= SPI3() (unstable))); + _for_each_inner!((@ peri_type #[doc = "SYSTIMER peripheral singleton"] SYSTIMER + <= SYSTIMER() (unstable))); _for_each_inner!((@ peri_type #[doc = + "TIMG0 peripheral singleton"] TIMG0 <= TIMG0() (unstable))); _for_each_inner!((@ + peri_type #[doc = "TIMG1 peripheral singleton"] TIMG1 <= TIMG1() (unstable))); + _for_each_inner!((@ peri_type #[doc = "TRACE0 peripheral singleton"] TRACE0 <= + TRACE0() (unstable))); _for_each_inner!((@ peri_type #[doc = + "TRACE1 peripheral singleton"] TRACE1 <= TRACE1() (unstable))); + _for_each_inner!((@ peri_type #[doc = "TWAI0 peripheral singleton"] TWAI0 <= + TWAI0() (unstable))); _for_each_inner!((@ peri_type #[doc = + "TWAI1 peripheral singleton"] TWAI1 <= TWAI1() (unstable))); _for_each_inner!((@ + peri_type #[doc = "TWAI2 peripheral singleton"] TWAI2 <= TWAI2() (unstable))); + _for_each_inner!((@ peri_type #[doc = "UART0 peripheral singleton"] UART0 <= + UART0() (unstable))); _for_each_inner!((@ peri_type #[doc = + "UART1 peripheral singleton"] UART1 <= UART1() (unstable))); _for_each_inner!((@ + peri_type #[doc = "UART2 peripheral singleton"] UART2 <= UART2() (unstable))); + _for_each_inner!((@ peri_type #[doc = "UART3 peripheral singleton"] UART3 <= + UART3() (unstable))); _for_each_inner!((@ peri_type #[doc = + "UART4 peripheral singleton"] UART4 <= UART4() (unstable))); _for_each_inner!((@ + peri_type #[doc = "UHCI0 peripheral singleton"] UHCI0 <= UHCI0() (unstable))); + _for_each_inner!((@ peri_type #[doc = "USB_DEVICE peripheral singleton"] + USB_DEVICE <= USB_DEVICE() (unstable))); _for_each_inner!((@ peri_type #[doc = + "USB_WRAP peripheral singleton"] USB_WRAP <= USB_WRAP() (unstable))); + _for_each_inner!((@ peri_type #[doc = "LPWR peripheral singleton"] LPWR <= + LP_AON_CLKRST() (unstable))); _for_each_inner!((@ peri_type #[doc = + "SYSTEM peripheral singleton"] SYSTEM <= HP_SYS() (unstable))); + _for_each_inner!((@ peri_type #[doc = "SW_INTERRUPT peripheral singleton"] + SW_INTERRUPT <= virtual() (unstable))); _for_each_inner!((GPIO0)); + _for_each_inner!((GPIO1)); _for_each_inner!((GPIO2)); _for_each_inner!((GPIO3)); + _for_each_inner!((GPIO4)); _for_each_inner!((GPIO5)); _for_each_inner!((GPIO6)); + _for_each_inner!((GPIO7)); _for_each_inner!((GPIO8)); _for_each_inner!((GPIO9)); + _for_each_inner!((GPIO10)); _for_each_inner!((GPIO11)); + _for_each_inner!((GPIO12)); _for_each_inner!((GPIO13)); + _for_each_inner!((GPIO14)); _for_each_inner!((GPIO15)); + _for_each_inner!((GPIO16)); _for_each_inner!((GPIO17)); + _for_each_inner!((GPIO18)); _for_each_inner!((GPIO19)); + _for_each_inner!((GPIO20)); _for_each_inner!((GPIO21)); + _for_each_inner!((GPIO22)); _for_each_inner!((GPIO23)); + _for_each_inner!((GPIO24)); _for_each_inner!((GPIO25)); + _for_each_inner!((GPIO26)); _for_each_inner!((GPIO27)); + _for_each_inner!((GPIO28)); _for_each_inner!((GPIO29)); + _for_each_inner!((GPIO30)); _for_each_inner!((GPIO31)); + _for_each_inner!((GPIO32)); _for_each_inner!((GPIO33)); + _for_each_inner!((GPIO34)); _for_each_inner!((GPIO35)); + _for_each_inner!((GPIO36)); _for_each_inner!((GPIO37)); + _for_each_inner!((GPIO38)); _for_each_inner!((GPIO39)); + _for_each_inner!((GPIO40)); _for_each_inner!((GPIO41)); + _for_each_inner!((GPIO42)); _for_each_inner!((GPIO43)); + _for_each_inner!((GPIO44)); _for_each_inner!((GPIO45)); + _for_each_inner!((GPIO46)); _for_each_inner!((GPIO47)); + _for_each_inner!((GPIO48)); _for_each_inner!((GPIO49)); + _for_each_inner!((GPIO50)); _for_each_inner!((GPIO51)); + _for_each_inner!((GPIO52)); _for_each_inner!((GPIO53)); + _for_each_inner!((GPIO54)); _for_each_inner!((ADC(unstable))); + _for_each_inner!((AES(unstable))); _for_each_inner!((AHB_DMA(unstable))); + _for_each_inner!((ASSIST_DEBUG(unstable))); + _for_each_inner!((AXI_DMA(unstable))); _for_each_inner!((AXI_ICM(unstable))); + _for_each_inner!((BITSCRAMBLER(unstable))); _for_each_inner!((CACHE(unstable))); + _for_each_inner!((DMA(unstable))); _for_each_inner!((DS(unstable))); + _for_each_inner!((ECC(unstable))); _for_each_inner!((ECDSA(unstable))); + _for_each_inner!((EFUSE(unstable))); _for_each_inner!((GPIO(unstable))); + _for_each_inner!((GPIO_SD(unstable))); _for_each_inner!((H264(unstable))); + _for_each_inner!((H264_DMA(unstable))); _for_each_inner!((HMAC(unstable))); + _for_each_inner!((HP_SYS(unstable))); + _for_each_inner!((HP_SYS_CLKRST(unstable))); _for_each_inner!((I2C0(unstable))); + _for_each_inner!((I2C1(unstable))); _for_each_inner!((I2S0(unstable))); + _for_each_inner!((I2S1(unstable))); _for_each_inner!((I2S2(unstable))); + _for_each_inner!((I3C_MST(unstable))); _for_each_inner!((I3C_MST_MEM(unstable))); + _for_each_inner!((I3C_SLV(unstable))); + _for_each_inner!((INTERRUPT_CORE0(unstable))); + _for_each_inner!((INTERRUPT_CORE1(unstable))); + _for_each_inner!((IO_MUX(unstable))); _for_each_inner!((ISP(unstable))); + _for_each_inner!((JPEG(unstable))); _for_each_inner!((LCD_CAM(unstable))); + _for_each_inner!((LEDC(unstable))); _for_each_inner!((LP_ADC(unstable))); + _for_each_inner!((LP_ANA(unstable))); + _for_each_inner!((LP_AON_CLKRST(unstable))); + _for_each_inner!((LP_GPIO(unstable))); _for_each_inner!((LP_HUK(unstable))); + _for_each_inner!((LP_I2C0(unstable))); + _for_each_inner!((LP_I2C_ANA_MST(unstable))); + _for_each_inner!((LP_I2S0(unstable))); _for_each_inner!((LP_INTR(unstable))); + _for_each_inner!((LP_IO_MUX(unstable))); _for_each_inner!((LP_PERI(unstable))); + _for_each_inner!((LP_SYS(unstable))); _for_each_inner!((LP_TIMER(unstable))); + _for_each_inner!((LP_TOUCH(unstable))); _for_each_inner!((LP_TSENS(unstable))); + _for_each_inner!((LP_UART(unstable))); _for_each_inner!((LP_WDT(unstable))); + _for_each_inner!((MCPWM0(unstable))); _for_each_inner!((MCPWM1(unstable))); + _for_each_inner!((MIPI_CSI_BRIDGE(unstable))); + _for_each_inner!((MIPI_CSI_HOST(unstable))); + _for_each_inner!((MIPI_DSI_BRIDGE(unstable))); + _for_each_inner!((MIPI_DSI_HOST(unstable))); + _for_each_inner!((PARL_IO(unstable))); _for_each_inner!((PAU(unstable))); + _for_each_inner!((PCNT(unstable))); _for_each_inner!((PMU(unstable))); + _for_each_inner!((PPA(unstable))); _for_each_inner!((PVT(unstable))); + _for_each_inner!((RMT(unstable))); _for_each_inner!((RSA(unstable))); + _for_each_inner!((SDHOST(unstable))); _for_each_inner!((SHA(unstable))); + _for_each_inner!((SOC_ETM(unstable))); _for_each_inner!((SPI0(unstable))); + _for_each_inner!((SPI1(unstable))); _for_each_inner!((SPI2(unstable))); + _for_each_inner!((SPI3(unstable))); _for_each_inner!((SYSTIMER(unstable))); + _for_each_inner!((TIMG0(unstable))); _for_each_inner!((TIMG1(unstable))); + _for_each_inner!((TRACE0(unstable))); _for_each_inner!((TRACE1(unstable))); + _for_each_inner!((TWAI0(unstable))); _for_each_inner!((TWAI1(unstable))); + _for_each_inner!((TWAI2(unstable))); _for_each_inner!((UART0(unstable))); + _for_each_inner!((UART1(unstable))); _for_each_inner!((UART2(unstable))); + _for_each_inner!((UART3(unstable))); _for_each_inner!((UART4(unstable))); + _for_each_inner!((UHCI0(unstable))); _for_each_inner!((USB_DEVICE(unstable))); + _for_each_inner!((USB_WRAP(unstable))); _for_each_inner!((LPWR(unstable))); + _for_each_inner!((SYSTEM(unstable))); _for_each_inner!((SW_INTERRUPT(unstable))); + _for_each_inner!((all(@ peri_type #[doc = "GPIO0 peripheral singleton"] GPIO0 <= + virtual()), (@ peri_type #[doc = "GPIO1 peripheral singleton"] GPIO1 <= + virtual()), (@ peri_type #[doc = + "GPIO2 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO2 <= virtual()), (@ peri_type #[doc = + "GPIO3 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO3 <= virtual()), (@ peri_type #[doc = + "GPIO4 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO4 <= virtual()), (@ peri_type #[doc = + "GPIO5 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] + #[doc = "
"] #[doc = "
"] GPIO5 <= virtual()), (@ peri_type #[doc = + "GPIO6 peripheral singleton"] GPIO6 <= virtual()), (@ peri_type #[doc = + "GPIO7 peripheral singleton"] GPIO7 <= virtual()), (@ peri_type #[doc = + "GPIO8 peripheral singleton"] GPIO8 <= virtual()), (@ peri_type #[doc = + "GPIO9 peripheral singleton"] GPIO9 <= virtual()), (@ peri_type #[doc = + "GPIO10 peripheral singleton"] GPIO10 <= virtual()), (@ peri_type #[doc = + "GPIO11 peripheral singleton"] GPIO11 <= virtual()), (@ peri_type #[doc = + "GPIO12 peripheral singleton"] GPIO12 <= virtual()), (@ peri_type #[doc = + "GPIO13 peripheral singleton"] GPIO13 <= virtual()), (@ peri_type #[doc = + "GPIO14 peripheral singleton"] GPIO14 <= virtual()), (@ peri_type #[doc = + "GPIO15 peripheral singleton"] GPIO15 <= virtual()), (@ peri_type #[doc = + "GPIO16 peripheral singleton"] GPIO16 <= virtual()), (@ peri_type #[doc = + "GPIO17 peripheral singleton"] GPIO17 <= virtual()), (@ peri_type #[doc = + "GPIO18 peripheral singleton"] GPIO18 <= virtual()), (@ peri_type #[doc = + "GPIO19 peripheral singleton"] GPIO19 <= virtual()), (@ peri_type #[doc = + "GPIO20 peripheral singleton"] GPIO20 <= virtual()), (@ peri_type #[doc = + "GPIO21 peripheral singleton"] GPIO21 <= virtual()), (@ peri_type #[doc = + "GPIO22 peripheral singleton"] GPIO22 <= virtual()), (@ peri_type #[doc = + "GPIO23 peripheral singleton"] GPIO23 <= virtual()), (@ peri_type #[doc = + "GPIO24 peripheral singleton"] GPIO24 <= virtual()), (@ peri_type #[doc = + "GPIO25 peripheral singleton"] GPIO25 <= virtual()), (@ peri_type #[doc = + "GPIO26 peripheral singleton"] GPIO26 <= virtual()), (@ peri_type #[doc = + "GPIO27 peripheral singleton"] GPIO27 <= virtual()), (@ peri_type #[doc = + "GPIO28 peripheral singleton"] GPIO28 <= virtual()), (@ peri_type #[doc = + "GPIO29 peripheral singleton"] GPIO29 <= virtual()), (@ peri_type #[doc = + "GPIO30 peripheral singleton"] GPIO30 <= virtual()), (@ peri_type #[doc = + "GPIO31 peripheral singleton"] GPIO31 <= virtual()), (@ peri_type #[doc = + "GPIO32 peripheral singleton"] GPIO32 <= virtual()), (@ peri_type #[doc = + "GPIO33 peripheral singleton"] GPIO33 <= virtual()), (@ peri_type #[doc = + "GPIO34 peripheral singleton"] GPIO34 <= virtual()), (@ peri_type #[doc = + "GPIO35 peripheral singleton"] GPIO35 <= virtual()), (@ peri_type #[doc = + "GPIO36 peripheral singleton"] GPIO36 <= virtual()), (@ peri_type #[doc = + "GPIO37 peripheral singleton"] GPIO37 <= virtual()), (@ peri_type #[doc = + "GPIO38 peripheral singleton"] GPIO38 <= virtual()), (@ peri_type #[doc = + "GPIO39 peripheral singleton"] GPIO39 <= virtual()), (@ peri_type #[doc = + "GPIO40 peripheral singleton"] GPIO40 <= virtual()), (@ peri_type #[doc = + "GPIO41 peripheral singleton"] GPIO41 <= virtual()), (@ peri_type #[doc = + "GPIO42 peripheral singleton"] GPIO42 <= virtual()), (@ peri_type #[doc = + "GPIO43 peripheral singleton"] GPIO43 <= virtual()), (@ peri_type #[doc = + "GPIO44 peripheral singleton"] GPIO44 <= virtual()), (@ peri_type #[doc = + "GPIO45 peripheral singleton"] GPIO45 <= virtual()), (@ peri_type #[doc = + "GPIO46 peripheral singleton"] GPIO46 <= virtual()), (@ peri_type #[doc = + "GPIO47 peripheral singleton"] GPIO47 <= virtual()), (@ peri_type #[doc = + "GPIO48 peripheral singleton"] GPIO48 <= virtual()), (@ peri_type #[doc = + "GPIO49 peripheral singleton"] GPIO49 <= virtual()), (@ peri_type #[doc = + "GPIO50 peripheral singleton"] GPIO50 <= virtual()), (@ peri_type #[doc = + "GPIO51 peripheral singleton"] GPIO51 <= virtual()), (@ peri_type #[doc = + "GPIO52 peripheral singleton"] GPIO52 <= virtual()), (@ peri_type #[doc = + "GPIO53 peripheral singleton"] GPIO53 <= virtual()), (@ peri_type #[doc = + "GPIO54 peripheral singleton"] GPIO54 <= virtual()), (@ peri_type #[doc = + "ADC peripheral singleton"] ADC <= ADC() (unstable)), (@ peri_type #[doc = + "AES peripheral singleton"] AES <= AES() (unstable)), (@ peri_type #[doc = + "AHB_DMA peripheral singleton"] AHB_DMA <= AHB_DMA() (unstable)), (@ peri_type + #[doc = "ASSIST_DEBUG peripheral singleton"] ASSIST_DEBUG <= ASSIST_DEBUG() + (unstable)), (@ peri_type #[doc = "AXI_DMA peripheral singleton"] AXI_DMA <= + AXI_DMA() (unstable)), (@ peri_type #[doc = "AXI_ICM peripheral singleton"] + AXI_ICM <= AXI_ICM() (unstable)), (@ peri_type #[doc = + "BITSCRAMBLER peripheral singleton"] BITSCRAMBLER <= BITSCRAMBLER() (unstable)), + (@ peri_type #[doc = "CACHE peripheral singleton"] CACHE <= CACHE() (unstable)), + (@ peri_type #[doc = "DMA peripheral singleton"] DMA <= DMA() (unstable)), (@ + peri_type #[doc = "DS peripheral singleton"] DS <= DS() (unstable)), (@ peri_type + #[doc = "ECC peripheral singleton"] ECC <= ECC() (unstable)), (@ peri_type #[doc + = "ECDSA peripheral singleton"] ECDSA <= ECDSA() (unstable)), (@ peri_type #[doc + = "EFUSE peripheral singleton"] EFUSE <= EFUSE() (unstable)), (@ peri_type #[doc + = "GPIO peripheral singleton"] GPIO <= GPIO() (unstable)), (@ peri_type #[doc = + "GPIO_SD peripheral singleton"] GPIO_SD <= GPIO_SD() (unstable)), (@ peri_type + #[doc = "H264 peripheral singleton"] H264 <= H264() (unstable)), (@ peri_type + #[doc = "H264_DMA peripheral singleton"] H264_DMA <= H264_DMA() (unstable)), (@ + peri_type #[doc = "HMAC peripheral singleton"] HMAC <= HMAC() (unstable)), (@ + peri_type #[doc = "HP_SYS peripheral singleton"] HP_SYS <= HP_SYS() (unstable)), + (@ peri_type #[doc = "HP_SYS_CLKRST peripheral singleton"] HP_SYS_CLKRST <= + HP_SYS_CLKRST() (unstable)), (@ peri_type #[doc = "I2C0 peripheral singleton"] + I2C0 <= I2C0() (unstable)), (@ peri_type #[doc = "I2C1 peripheral singleton"] + I2C1 <= I2C1() (unstable)), (@ peri_type #[doc = "I2S0 peripheral singleton"] + I2S0 <= I2S0() (unstable)), (@ peri_type #[doc = "I2S1 peripheral singleton"] + I2S1 <= I2S1() (unstable)), (@ peri_type #[doc = "I2S2 peripheral singleton"] + I2S2 <= I2S2() (unstable)), (@ peri_type #[doc = "I3C_MST peripheral singleton"] + I3C_MST <= I3C_MST() (unstable)), (@ peri_type #[doc = + "I3C_MST_MEM peripheral singleton"] I3C_MST_MEM <= I3C_MST_MEM() (unstable)), (@ + peri_type #[doc = "I3C_SLV peripheral singleton"] I3C_SLV <= I3C_SLV() + (unstable)), (@ peri_type #[doc = "INTERRUPT_CORE0 peripheral singleton"] + INTERRUPT_CORE0 <= INTERRUPT_CORE0() (unstable)), (@ peri_type #[doc = + "INTERRUPT_CORE1 peripheral singleton"] INTERRUPT_CORE1 <= INTERRUPT_CORE1() + (unstable)), (@ peri_type #[doc = "IO_MUX peripheral singleton"] IO_MUX <= + IO_MUX() (unstable)), (@ peri_type #[doc = "ISP peripheral singleton"] ISP <= + ISP() (unstable)), (@ peri_type #[doc = "JPEG peripheral singleton"] JPEG <= + JPEG() (unstable)), (@ peri_type #[doc = "LCD_CAM peripheral singleton"] LCD_CAM + <= LCD_CAM() (unstable)), (@ peri_type #[doc = "LEDC peripheral singleton"] LEDC + <= LEDC() (unstable)), (@ peri_type #[doc = "LP_ADC peripheral singleton"] LP_ADC + <= LP_ADC() (unstable)), (@ peri_type #[doc = "LP_ANA peripheral singleton"] + LP_ANA <= LP_ANA() (unstable)), (@ peri_type #[doc = + "LP_AON_CLKRST peripheral singleton"] LP_AON_CLKRST <= LP_AON_CLKRST() + (unstable)), (@ peri_type #[doc = "LP_GPIO peripheral singleton"] LP_GPIO <= + LP_GPIO() (unstable)), (@ peri_type #[doc = "LP_HUK peripheral singleton"] LP_HUK + <= LP_HUK() (unstable)), (@ peri_type #[doc = "LP_I2C0 peripheral singleton"] + LP_I2C0 <= LP_I2C0() (unstable)), (@ peri_type #[doc = + "LP_I2C_ANA_MST peripheral singleton"] LP_I2C_ANA_MST <= LP_I2C_ANA_MST() + (unstable)), (@ peri_type #[doc = "LP_I2S0 peripheral singleton"] LP_I2S0 <= + LP_I2S0() (unstable)), (@ peri_type #[doc = "LP_INTR peripheral singleton"] + LP_INTR <= LP_INTR() (unstable)), (@ peri_type #[doc = + "LP_IO_MUX peripheral singleton"] LP_IO_MUX <= LP_IO_MUX() (unstable)), (@ + peri_type #[doc = "LP_PERI peripheral singleton"] LP_PERI <= LP_PERI() + (unstable)), (@ peri_type #[doc = "LP_SYS peripheral singleton"] LP_SYS <= + LP_SYS() (unstable)), (@ peri_type #[doc = "LP_TIMER peripheral singleton"] + LP_TIMER <= LP_TIMER() (unstable)), (@ peri_type #[doc = + "LP_TOUCH peripheral singleton"] LP_TOUCH <= LP_TOUCH() (unstable)), (@ peri_type + #[doc = "LP_TSENS peripheral singleton"] LP_TSENS <= LP_TSENS() (unstable)), (@ + peri_type #[doc = "LP_UART peripheral singleton"] LP_UART <= LP_UART() + (unstable)), (@ peri_type #[doc = "LP_WDT peripheral singleton"] LP_WDT <= + LP_WDT() (unstable)), (@ peri_type #[doc = "MCPWM0 peripheral singleton"] MCPWM0 + <= MCPWM0() (unstable)), (@ peri_type #[doc = "MCPWM1 peripheral singleton"] + MCPWM1 <= MCPWM1() (unstable)), (@ peri_type #[doc = + "MIPI_CSI_BRIDGE peripheral singleton"] MIPI_CSI_BRIDGE <= MIPI_CSI_BRIDGE() + (unstable)), (@ peri_type #[doc = "MIPI_CSI_HOST peripheral singleton"] + MIPI_CSI_HOST <= MIPI_CSI_HOST() (unstable)), (@ peri_type #[doc = + "MIPI_DSI_BRIDGE peripheral singleton"] MIPI_DSI_BRIDGE <= MIPI_DSI_BRIDGE() + (unstable)), (@ peri_type #[doc = "MIPI_DSI_HOST peripheral singleton"] + MIPI_DSI_HOST <= MIPI_DSI_HOST() (unstable)), (@ peri_type #[doc = + "PARL_IO peripheral singleton"] PARL_IO <= PARL_IO() (unstable)), (@ peri_type + #[doc = "PAU peripheral singleton"] PAU <= PAU() (unstable)), (@ peri_type #[doc + = "PCNT peripheral singleton"] PCNT <= PCNT() (unstable)), (@ peri_type #[doc = + "PMU peripheral singleton"] PMU <= PMU() (unstable)), (@ peri_type #[doc = + "PPA peripheral singleton"] PPA <= PPA() (unstable)), (@ peri_type #[doc = + "PVT peripheral singleton"] PVT <= PVT() (unstable)), (@ peri_type #[doc = + "RMT peripheral singleton"] RMT <= RMT() (unstable)), (@ peri_type #[doc = + "RSA peripheral singleton"] RSA <= RSA() (unstable)), (@ peri_type #[doc = + "SDHOST peripheral singleton"] SDHOST <= SDHOST() (unstable)), (@ peri_type #[doc + = "SHA peripheral singleton"] SHA <= SHA() (unstable)), (@ peri_type #[doc = + "SOC_ETM peripheral singleton"] SOC_ETM <= SOC_ETM() (unstable)), (@ peri_type + #[doc = "SPI0 peripheral singleton"] SPI0 <= SPI0() (unstable)), (@ peri_type + #[doc = "SPI1 peripheral singleton"] SPI1 <= SPI1() (unstable)), (@ peri_type + #[doc = "SPI2 peripheral singleton"] SPI2 <= SPI2() (unstable)), (@ peri_type + #[doc = "SPI3 peripheral singleton"] SPI3 <= SPI3() (unstable)), (@ peri_type + #[doc = "SYSTIMER peripheral singleton"] SYSTIMER <= SYSTIMER() (unstable)), (@ + peri_type #[doc = "TIMG0 peripheral singleton"] TIMG0 <= TIMG0() (unstable)), (@ + peri_type #[doc = "TIMG1 peripheral singleton"] TIMG1 <= TIMG1() (unstable)), (@ + peri_type #[doc = "TRACE0 peripheral singleton"] TRACE0 <= TRACE0() (unstable)), + (@ peri_type #[doc = "TRACE1 peripheral singleton"] TRACE1 <= TRACE1() + (unstable)), (@ peri_type #[doc = "TWAI0 peripheral singleton"] TWAI0 <= TWAI0() + (unstable)), (@ peri_type #[doc = "TWAI1 peripheral singleton"] TWAI1 <= TWAI1() + (unstable)), (@ peri_type #[doc = "TWAI2 peripheral singleton"] TWAI2 <= TWAI2() + (unstable)), (@ peri_type #[doc = "UART0 peripheral singleton"] UART0 <= UART0() + (unstable)), (@ peri_type #[doc = "UART1 peripheral singleton"] UART1 <= UART1() + (unstable)), (@ peri_type #[doc = "UART2 peripheral singleton"] UART2 <= UART2() + (unstable)), (@ peri_type #[doc = "UART3 peripheral singleton"] UART3 <= UART3() + (unstable)), (@ peri_type #[doc = "UART4 peripheral singleton"] UART4 <= UART4() + (unstable)), (@ peri_type #[doc = "UHCI0 peripheral singleton"] UHCI0 <= UHCI0() + (unstable)), (@ peri_type #[doc = "USB_DEVICE peripheral singleton"] USB_DEVICE + <= USB_DEVICE() (unstable)), (@ peri_type #[doc = + "USB_WRAP peripheral singleton"] USB_WRAP <= USB_WRAP() (unstable)), (@ peri_type + #[doc = "LPWR peripheral singleton"] LPWR <= LP_AON_CLKRST() (unstable)), (@ + peri_type #[doc = "SYSTEM peripheral singleton"] SYSTEM <= HP_SYS() (unstable)), + (@ peri_type #[doc = "SW_INTERRUPT peripheral singleton"] SW_INTERRUPT <= + virtual() (unstable)))); _for_each_inner!((singletons(GPIO0), (GPIO1), (GPIO2), + (GPIO3), (GPIO4), (GPIO5), (GPIO6), (GPIO7), (GPIO8), (GPIO9), (GPIO10), + (GPIO11), (GPIO12), (GPIO13), (GPIO14), (GPIO15), (GPIO16), (GPIO17), (GPIO18), + (GPIO19), (GPIO20), (GPIO21), (GPIO22), (GPIO23), (GPIO24), (GPIO25), (GPIO26), + (GPIO27), (GPIO28), (GPIO29), (GPIO30), (GPIO31), (GPIO32), (GPIO33), (GPIO34), + (GPIO35), (GPIO36), (GPIO37), (GPIO38), (GPIO39), (GPIO40), (GPIO41), (GPIO42), + (GPIO43), (GPIO44), (GPIO45), (GPIO46), (GPIO47), (GPIO48), (GPIO49), (GPIO50), + (GPIO51), (GPIO52), (GPIO53), (GPIO54), (ADC(unstable)), (AES(unstable)), + (AHB_DMA(unstable)), (ASSIST_DEBUG(unstable)), (AXI_DMA(unstable)), + (AXI_ICM(unstable)), (BITSCRAMBLER(unstable)), (CACHE(unstable)), + (DMA(unstable)), (DS(unstable)), (ECC(unstable)), (ECDSA(unstable)), + (EFUSE(unstable)), (GPIO(unstable)), (GPIO_SD(unstable)), (H264(unstable)), + (H264_DMA(unstable)), (HMAC(unstable)), (HP_SYS(unstable)), + (HP_SYS_CLKRST(unstable)), (I2C0(unstable)), (I2C1(unstable)), (I2S0(unstable)), + (I2S1(unstable)), (I2S2(unstable)), (I3C_MST(unstable)), (I3C_MST_MEM(unstable)), + (I3C_SLV(unstable)), (INTERRUPT_CORE0(unstable)), (INTERRUPT_CORE1(unstable)), + (IO_MUX(unstable)), (ISP(unstable)), (JPEG(unstable)), (LCD_CAM(unstable)), + (LEDC(unstable)), (LP_ADC(unstable)), (LP_ANA(unstable)), + (LP_AON_CLKRST(unstable)), (LP_GPIO(unstable)), (LP_HUK(unstable)), + (LP_I2C0(unstable)), (LP_I2C_ANA_MST(unstable)), (LP_I2S0(unstable)), + (LP_INTR(unstable)), (LP_IO_MUX(unstable)), (LP_PERI(unstable)), + (LP_SYS(unstable)), (LP_TIMER(unstable)), (LP_TOUCH(unstable)), + (LP_TSENS(unstable)), (LP_UART(unstable)), (LP_WDT(unstable)), + (MCPWM0(unstable)), (MCPWM1(unstable)), (MIPI_CSI_BRIDGE(unstable)), + (MIPI_CSI_HOST(unstable)), (MIPI_DSI_BRIDGE(unstable)), + (MIPI_DSI_HOST(unstable)), (PARL_IO(unstable)), (PAU(unstable)), + (PCNT(unstable)), (PMU(unstable)), (PPA(unstable)), (PVT(unstable)), + (RMT(unstable)), (RSA(unstable)), (SDHOST(unstable)), (SHA(unstable)), + (SOC_ETM(unstable)), (SPI0(unstable)), (SPI1(unstable)), (SPI2(unstable)), + (SPI3(unstable)), (SYSTIMER(unstable)), (TIMG0(unstable)), (TIMG1(unstable)), + (TRACE0(unstable)), (TRACE1(unstable)), (TWAI0(unstable)), (TWAI1(unstable)), + (TWAI2(unstable)), (UART0(unstable)), (UART1(unstable)), (UART2(unstable)), + (UART3(unstable)), (UART4(unstable)), (UHCI0(unstable)), (USB_DEVICE(unstable)), + (USB_WRAP(unstable)), (LPWR(unstable)), (SYSTEM(unstable)), + (SW_INTERRUPT(unstable)))); + }; +} +/// This macro can be used to generate code for each `GPIOn` instance. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has one option for its "Individual matcher" case: +/// +/// Syntax: `($n:literal, $gpio:ident ($($digital_input_function:ident => +/// $digital_input_signal:ident)*) ($($digital_output_function:ident => +/// $digital_output_signal:ident)*) ($([$pin_attribute:ident])*))` +/// +/// Macro fragments: +/// +/// - `$n`: the number of the GPIO. For `GPIO0`, `$n` is 0. +/// - `$gpio`: the name of the GPIO. +/// - `$digital_input_function`: the number of the digital function, as an identifier (i.e. for +/// function 0 this is `_0`). +/// - `$digital_input_function`: the name of the digital function, as an identifier. +/// - `$digital_output_function`: the number of the digital function, as an identifier (i.e. for +/// function 0 this is `_0`). +/// - `$digital_output_function`: the name of the digital function, as an identifier. +/// - `$pin_attribute`: `Input` and/or `Output`, marks the possible directions of the GPIO. +/// Bracketed so that they can also be matched as optional fragments. Order is always Input first. +/// +/// Example data: `(0, GPIO0 (_5 => EMAC_TX_CLK) (_1 => CLK_OUT1 _5 => EMAC_TX_CLK) ([Input] +/// [Output]))` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_gpio { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((0, GPIO0() () ([Input] [Output]))); _for_each_inner!((1, + GPIO1() () ([Input] [Output]))); _for_each_inner!((2, GPIO2(_0 => MTCK) () + ([Input] [Output]))); _for_each_inner!((3, GPIO3(_0 => MTDI) () ([Input] + [Output]))); _for_each_inner!((4, GPIO4(_0 => MTMS) () ([Input] [Output]))); + _for_each_inner!((5, GPIO5(_0 => MTDO) () ([Input] [Output]))); + _for_each_inner!((6, GPIO6(_3 => SPI2_HOLD_PAD) (_3 => SPI2_HOLD_PAD) ([Input] + [Output]))); _for_each_inner!((7, GPIO7(_3 => SPI2_CS_PAD) (_3 => SPI2_CS_PAD) + ([Input] [Output]))); _for_each_inner!((8, GPIO8(_3 => SPI2_D_PAD) (_2 => + UART0_RTS_PAD _3 => SPI2_D_PAD) ([Input] [Output]))); _for_each_inner!((9, + GPIO9(_2 => UART0_CTS_PAD _3 => SPI2_CK_PAD) (_3 => SPI2_CK_PAD) ([Input] + [Output]))); _for_each_inner!((10, GPIO10(_3 => SPI2_Q_PAD) (_2 => UART1_TXD_PAD + _3 => SPI2_Q_PAD) ([Input] [Output]))); _for_each_inner!((11, GPIO11(_2 => + UART1_RXD_PAD _3 => SPI2_WP_PAD) (_3 => SPI2_WP_PAD) ([Input] [Output]))); + _for_each_inner!((12, GPIO12() (_2 => UART1_RTS_PAD) ([Input] [Output]))); + _for_each_inner!((13, GPIO13(_2 => UART1_CTS_PAD) () ([Input] [Output]))); + _for_each_inner!((14, GPIO14() () ([Input] [Output]))); _for_each_inner!((15, + GPIO15() () ([Input] [Output]))); _for_each_inner!((16, GPIO16() () ([Input] + [Output]))); _for_each_inner!((17, GPIO17() () ([Input] [Output]))); + _for_each_inner!((18, GPIO18() () ([Input] [Output]))); _for_each_inner!((19, + GPIO19() () ([Input] [Output]))); _for_each_inner!((20, GPIO20() () ([Input] + [Output]))); _for_each_inner!((21, GPIO21() () ([Input] [Output]))); + _for_each_inner!((22, GPIO22() () ([Input] [Output]))); _for_each_inner!((23, + GPIO23(_3 => REF_50M_CLK_PAD) () ([Input] [Output]))); _for_each_inner!((24, + GPIO24() () ([Input] [Output]))); _for_each_inner!((25, GPIO25() () ([Input] + [Output]))); _for_each_inner!((26, GPIO26() () ([Input] [Output]))); + _for_each_inner!((27, GPIO27() () ([Input] [Output]))); _for_each_inner!((28, + GPIO28(_2 => SPI2_CS_PAD _3 => GMAC_PHY_RXDV_PAD) (_2 => SPI2_CS_PAD) ([Input] + [Output]))); _for_each_inner!((29, GPIO29(_2 => SPI2_D_PAD _3 => + GMAC_PHY_RXD0_PAD) (_2 => SPI2_D_PAD) ([Input] [Output]))); _for_each_inner!((30, + GPIO30(_2 => SPI2_CK_PAD _3 => GMAC_PHY_RXD1_PAD) (_2 => SPI2_CK_PAD) ([Input] + [Output]))); _for_each_inner!((31, GPIO31(_2 => SPI2_Q_PAD _3 => + GMAC_PHY_RXER_PAD) (_2 => SPI2_Q_PAD) ([Input] [Output]))); _for_each_inner!((32, + GPIO32(_2 => SPI2_HOLD_PAD _3 => GMAC_RMII_CLK_PAD) (_2 => SPI2_HOLD_PAD) + ([Input] [Output]))); _for_each_inner!((33, GPIO33(_2 => SPI2_WP_PAD) (_2 => + SPI2_WP_PAD _3 => GMAC_PHY_TXEN_PAD) ([Input] [Output]))); _for_each_inner!((34, + GPIO34(_2 => SPI2_IO4_PAD) (_2 => SPI2_IO4_PAD _3 => GMAC_PHY_TXD0_PAD) ([Input] + [Output]))); _for_each_inner!((35, GPIO35(_2 => SPI2_IO5_PAD) (_2 => SPI2_IO5_PAD + _3 => GMAC_PHY_TXD1_PAD) ([Input] [Output]))); _for_each_inner!((36, GPIO36(_2 => + SPI2_IO6_PAD) (_2 => SPI2_IO6_PAD _3 => GMAC_PHY_TXER_PAD) ([Input] [Output]))); + _for_each_inner!((37, GPIO37(_2 => SPI2_IO7_PAD) (_0 => UART0_TXD_PAD _2 => + SPI2_IO7_PAD) ([Input] [Output]))); _for_each_inner!((38, GPIO38(_0 => + UART0_RXD_PAD) (_2 => SPI2_DQS_PAD) ([Input] [Output]))); _for_each_inner!((39, + GPIO39(_0 => SD1_CDATA0_PAD _3 => REF_50M_CLK_PAD) () ([Input] [Output]))); + _for_each_inner!((40, GPIO40(_0 => SD1_CDATA1_PAD) (_3 => GMAC_PHY_TXEN_PAD) + ([Input] [Output]))); _for_each_inner!((41, GPIO41(_0 => SD1_CDATA2_PAD) (_3 => + GMAC_PHY_TXD0_PAD) ([Input] [Output]))); _for_each_inner!((42, GPIO42(_0 => + SD1_CDATA3_PAD) (_3 => GMAC_PHY_TXD1_PAD) ([Input] [Output]))); + _for_each_inner!((43, GPIO43(_0 => SD1_CCLK_PAD) (_3 => GMAC_PHY_TXER_PAD) + ([Input] [Output]))); _for_each_inner!((44, GPIO44(_0 => SD1_CCMD_PAD _3 => + GMAC_RMII_CLK_PAD) () ([Input] [Output]))); _for_each_inner!((45, GPIO45(_0 => + SD1_CDATA4_PAD _3 => GMAC_PHY_RXDV_PAD) () ([Input] [Output]))); + _for_each_inner!((46, GPIO46(_0 => SD1_CDATA5_PAD _3 => GMAC_PHY_RXD0_PAD) () + ([Input] [Output]))); _for_each_inner!((47, GPIO47(_0 => SD1_CDATA6_PAD _3 => + GMAC_PHY_RXD1_PAD) () ([Input] [Output]))); _for_each_inner!((48, GPIO48(_0 => + SD1_CDATA7_PAD _3 => GMAC_PHY_RXER_PAD) () ([Input] [Output]))); + _for_each_inner!((49, GPIO49() (_3 => GMAC_PHY_TXEN_PAD) ([Input] [Output]))); + _for_each_inner!((50, GPIO50(_3 => GMAC_RMII_CLK_PAD) () ([Input] [Output]))); + _for_each_inner!((51, GPIO51(_3 => GMAC_PHY_RXDV_PAD) () ([Input] [Output]))); + _for_each_inner!((52, GPIO52(_3 => GMAC_PHY_RXD0_PAD) () ([Input] [Output]))); + _for_each_inner!((53, GPIO53(_3 => GMAC_PHY_RXD1_PAD) () ([Input] [Output]))); + _for_each_inner!((54, GPIO54(_3 => GMAC_PHY_RXER_PAD) () ([Input] [Output]))); + _for_each_inner!((all(0, GPIO0() () ([Input] [Output])), (1, GPIO1() () ([Input] + [Output])), (2, GPIO2(_0 => MTCK) () ([Input] [Output])), (3, GPIO3(_0 => MTDI) + () ([Input] [Output])), (4, GPIO4(_0 => MTMS) () ([Input] [Output])), (5, + GPIO5(_0 => MTDO) () ([Input] [Output])), (6, GPIO6(_3 => SPI2_HOLD_PAD) (_3 => + SPI2_HOLD_PAD) ([Input] [Output])), (7, GPIO7(_3 => SPI2_CS_PAD) (_3 => + SPI2_CS_PAD) ([Input] [Output])), (8, GPIO8(_3 => SPI2_D_PAD) (_2 => + UART0_RTS_PAD _3 => SPI2_D_PAD) ([Input] [Output])), (9, GPIO9(_2 => + UART0_CTS_PAD _3 => SPI2_CK_PAD) (_3 => SPI2_CK_PAD) ([Input] [Output])), (10, + GPIO10(_3 => SPI2_Q_PAD) (_2 => UART1_TXD_PAD _3 => SPI2_Q_PAD) ([Input] + [Output])), (11, GPIO11(_2 => UART1_RXD_PAD _3 => SPI2_WP_PAD) (_3 => + SPI2_WP_PAD) ([Input] [Output])), (12, GPIO12() (_2 => UART1_RTS_PAD) ([Input] + [Output])), (13, GPIO13(_2 => UART1_CTS_PAD) () ([Input] [Output])), (14, + GPIO14() () ([Input] [Output])), (15, GPIO15() () ([Input] [Output])), (16, + GPIO16() () ([Input] [Output])), (17, GPIO17() () ([Input] [Output])), (18, + GPIO18() () ([Input] [Output])), (19, GPIO19() () ([Input] [Output])), (20, + GPIO20() () ([Input] [Output])), (21, GPIO21() () ([Input] [Output])), (22, + GPIO22() () ([Input] [Output])), (23, GPIO23(_3 => REF_50M_CLK_PAD) () ([Input] + [Output])), (24, GPIO24() () ([Input] [Output])), (25, GPIO25() () ([Input] + [Output])), (26, GPIO26() () ([Input] [Output])), (27, GPIO27() () ([Input] + [Output])), (28, GPIO28(_2 => SPI2_CS_PAD _3 => GMAC_PHY_RXDV_PAD) (_2 => + SPI2_CS_PAD) ([Input] [Output])), (29, GPIO29(_2 => SPI2_D_PAD _3 => + GMAC_PHY_RXD0_PAD) (_2 => SPI2_D_PAD) ([Input] [Output])), (30, GPIO30(_2 => + SPI2_CK_PAD _3 => GMAC_PHY_RXD1_PAD) (_2 => SPI2_CK_PAD) ([Input] [Output])), + (31, GPIO31(_2 => SPI2_Q_PAD _3 => GMAC_PHY_RXER_PAD) (_2 => SPI2_Q_PAD) ([Input] + [Output])), (32, GPIO32(_2 => SPI2_HOLD_PAD _3 => GMAC_RMII_CLK_PAD) (_2 => + SPI2_HOLD_PAD) ([Input] [Output])), (33, GPIO33(_2 => SPI2_WP_PAD) (_2 => + SPI2_WP_PAD _3 => GMAC_PHY_TXEN_PAD) ([Input] [Output])), (34, GPIO34(_2 => + SPI2_IO4_PAD) (_2 => SPI2_IO4_PAD _3 => GMAC_PHY_TXD0_PAD) ([Input] [Output])), + (35, GPIO35(_2 => SPI2_IO5_PAD) (_2 => SPI2_IO5_PAD _3 => GMAC_PHY_TXD1_PAD) + ([Input] [Output])), (36, GPIO36(_2 => SPI2_IO6_PAD) (_2 => SPI2_IO6_PAD _3 => + GMAC_PHY_TXER_PAD) ([Input] [Output])), (37, GPIO37(_2 => SPI2_IO7_PAD) (_0 => + UART0_TXD_PAD _2 => SPI2_IO7_PAD) ([Input] [Output])), (38, GPIO38(_0 => + UART0_RXD_PAD) (_2 => SPI2_DQS_PAD) ([Input] [Output])), (39, GPIO39(_0 => + SD1_CDATA0_PAD _3 => REF_50M_CLK_PAD) () ([Input] [Output])), (40, GPIO40(_0 => + SD1_CDATA1_PAD) (_3 => GMAC_PHY_TXEN_PAD) ([Input] [Output])), (41, GPIO41(_0 => + SD1_CDATA2_PAD) (_3 => GMAC_PHY_TXD0_PAD) ([Input] [Output])), (42, GPIO42(_0 => + SD1_CDATA3_PAD) (_3 => GMAC_PHY_TXD1_PAD) ([Input] [Output])), (43, GPIO43(_0 => + SD1_CCLK_PAD) (_3 => GMAC_PHY_TXER_PAD) ([Input] [Output])), (44, GPIO44(_0 => + SD1_CCMD_PAD _3 => GMAC_RMII_CLK_PAD) () ([Input] [Output])), (45, GPIO45(_0 => + SD1_CDATA4_PAD _3 => GMAC_PHY_RXDV_PAD) () ([Input] [Output])), (46, GPIO46(_0 => + SD1_CDATA5_PAD _3 => GMAC_PHY_RXD0_PAD) () ([Input] [Output])), (47, GPIO47(_0 => + SD1_CDATA6_PAD _3 => GMAC_PHY_RXD1_PAD) () ([Input] [Output])), (48, GPIO48(_0 => + SD1_CDATA7_PAD _3 => GMAC_PHY_RXER_PAD) () ([Input] [Output])), (49, GPIO49() (_3 + => GMAC_PHY_TXEN_PAD) ([Input] [Output])), (50, GPIO50(_3 => GMAC_RMII_CLK_PAD) + () ([Input] [Output])), (51, GPIO51(_3 => GMAC_PHY_RXDV_PAD) () ([Input] + [Output])), (52, GPIO52(_3 => GMAC_PHY_RXD0_PAD) () ([Input] [Output])), (53, + GPIO53(_3 => GMAC_PHY_RXD1_PAD) () ([Input] [Output])), (54, GPIO54(_3 => + GMAC_PHY_RXER_PAD) () ([Input] [Output])))); + }; +} +/// This macro can be used to generate code for each analog function of each GPIO. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has two options for its "Individual matcher" case: +/// +/// - `all`: `($signal:ident, $gpio:ident)` - simple case where you only need identifiers +/// - `all_expanded`: `(($signal:ident, $group:ident $(, $number:literal)+), $gpio:ident)` - +/// expanded signal case, where you need the number(s) of a signal, or the general group to which +/// the signal belongs. For example, in case of `ADC2_CH3` the expanded form looks like +/// `(ADC2_CH3, ADCn_CHm, 2, 3)`. +/// +/// Macro fragments: +/// +/// - `$signal`: the name of the signal. +/// - `$group`: the name of the signal, with numbers replaced by placeholders. For `ADC2_CH3` this +/// is `ADCn_CHm`. +/// - `$number`: the numbers extracted from `$signal`. +/// - `$gpio`: the name of the GPIO. +/// +/// Example data: +/// - `(ADC2_CH5, GPIO12)` +/// - `((ADC2_CH5, ADCn_CHm, 2, 5), GPIO12)` +/// +/// The expanded syntax is only available when the signal has at least one numbered component. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_analog_function { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((XTAL_32K_N, GPIO0)); _for_each_inner!((XTAL_32K_P, GPIO1)); + _for_each_inner!((TOUCH_CHANNEL0, GPIO2)); _for_each_inner!((TOUCH_CHANNEL1, + GPIO3)); _for_each_inner!((TOUCH_CHANNEL2, GPIO4)); + _for_each_inner!((TOUCH_CHANNEL3, GPIO5)); _for_each_inner!((TOUCH_CHANNEL4, + GPIO6)); _for_each_inner!((TOUCH_CHANNEL5, GPIO7)); + _for_each_inner!((TOUCH_CHANNEL6, GPIO8)); _for_each_inner!((TOUCH_CHANNEL7, + GPIO9)); _for_each_inner!((TOUCH_CHANNEL8, GPIO10)); + _for_each_inner!((TOUCH_CHANNEL9, GPIO11)); _for_each_inner!((TOUCH_CHANNEL10, + GPIO12)); _for_each_inner!((TOUCH_CHANNEL11, GPIO13)); + _for_each_inner!((TOUCH_CHANNEL12, GPIO14)); _for_each_inner!((TOUCH_CHANNEL13, + GPIO15)); _for_each_inner!((ADC1_CHANNEL0, GPIO16)); + _for_each_inner!((ADC1_CHANNEL1, GPIO17)); _for_each_inner!((ADC1_CHANNEL2, + GPIO18)); _for_each_inner!((ADC1_CHANNEL3, GPIO19)); + _for_each_inner!((ADC1_CHANNEL4, GPIO20)); _for_each_inner!((ADC1_CHANNEL5, + GPIO21)); _for_each_inner!((ADC1_CHANNEL6, GPIO22)); + _for_each_inner!((ADC1_CHANNEL7, GPIO23)); _for_each_inner!((USB1P1_N0, GPIO24)); + _for_each_inner!((USB1P1_P0, GPIO25)); _for_each_inner!((USB1P1_N1, GPIO26)); + _for_each_inner!((USB1P1_P1, GPIO27)); _for_each_inner!((ADC2_CHANNEL2, GPIO28)); + _for_each_inner!((ADC2_CHANNEL3, GPIO29)); _for_each_inner!((ADC2_CHANNEL4, + GPIO30)); _for_each_inner!((ANA_COMP0, GPIO30)); _for_each_inner!((ADC2_CHANNEL5, + GPIO31)); _for_each_inner!((ANA_COMP0, GPIO31)); _for_each_inner!((ADC2_CHANNEL6, + GPIO32)); _for_each_inner!((ANA_COMP1, GPIO32)); _for_each_inner!((ADC2_CHANNEL7, + GPIO33)); _for_each_inner!((ANA_COMP1, GPIO33)); + _for_each_inner!(((TOUCH_CHANNEL0, TOUCH_CHANNELn, 0), GPIO2)); + _for_each_inner!(((TOUCH_CHANNEL1, TOUCH_CHANNELn, 1), GPIO3)); + _for_each_inner!(((TOUCH_CHANNEL2, TOUCH_CHANNELn, 2), GPIO4)); + _for_each_inner!(((TOUCH_CHANNEL3, TOUCH_CHANNELn, 3), GPIO5)); + _for_each_inner!(((TOUCH_CHANNEL4, TOUCH_CHANNELn, 4), GPIO6)); + _for_each_inner!(((TOUCH_CHANNEL5, TOUCH_CHANNELn, 5), GPIO7)); + _for_each_inner!(((TOUCH_CHANNEL6, TOUCH_CHANNELn, 6), GPIO8)); + _for_each_inner!(((TOUCH_CHANNEL7, TOUCH_CHANNELn, 7), GPIO9)); + _for_each_inner!(((TOUCH_CHANNEL8, TOUCH_CHANNELn, 8), GPIO10)); + _for_each_inner!(((TOUCH_CHANNEL9, TOUCH_CHANNELn, 9), GPIO11)); + _for_each_inner!(((TOUCH_CHANNEL10, TOUCH_CHANNELn, 10), GPIO12)); + _for_each_inner!(((TOUCH_CHANNEL11, TOUCH_CHANNELn, 11), GPIO13)); + _for_each_inner!(((TOUCH_CHANNEL12, TOUCH_CHANNELn, 12), GPIO14)); + _for_each_inner!(((TOUCH_CHANNEL13, TOUCH_CHANNELn, 13), GPIO15)); + _for_each_inner!(((ADC1_CHANNEL0, ADCn_CHANNELm, 1, 0), GPIO16)); + _for_each_inner!(((ADC1_CHANNEL1, ADCn_CHANNELm, 1, 1), GPIO17)); + _for_each_inner!(((ADC1_CHANNEL2, ADCn_CHANNELm, 1, 2), GPIO18)); + _for_each_inner!(((ADC1_CHANNEL3, ADCn_CHANNELm, 1, 3), GPIO19)); + _for_each_inner!(((ADC1_CHANNEL4, ADCn_CHANNELm, 1, 4), GPIO20)); + _for_each_inner!(((ADC1_CHANNEL5, ADCn_CHANNELm, 1, 5), GPIO21)); + _for_each_inner!(((ADC1_CHANNEL6, ADCn_CHANNELm, 1, 6), GPIO22)); + _for_each_inner!(((ADC1_CHANNEL7, ADCn_CHANNELm, 1, 7), GPIO23)); + _for_each_inner!(((USB1P1_N0, USB1P1_Nn, 0), GPIO24)); + _for_each_inner!(((USB1P1_P0, USB1P1_Pn, 0), GPIO25)); + _for_each_inner!(((USB1P1_N1, USB1P1_Nn, 1), GPIO26)); + _for_each_inner!(((USB1P1_P1, USB1P1_Pn, 1), GPIO27)); + _for_each_inner!(((ADC2_CHANNEL2, ADCn_CHANNELm, 2, 2), GPIO28)); + _for_each_inner!(((ADC2_CHANNEL3, ADCn_CHANNELm, 2, 3), GPIO29)); + _for_each_inner!(((ADC2_CHANNEL4, ADCn_CHANNELm, 2, 4), GPIO30)); + _for_each_inner!(((ANA_COMP0, ANA_COMPn, 0), GPIO30)); + _for_each_inner!(((ADC2_CHANNEL5, ADCn_CHANNELm, 2, 5), GPIO31)); + _for_each_inner!(((ANA_COMP0, ANA_COMPn, 0), GPIO31)); + _for_each_inner!(((ADC2_CHANNEL6, ADCn_CHANNELm, 2, 6), GPIO32)); + _for_each_inner!(((ANA_COMP1, ANA_COMPn, 1), GPIO32)); + _for_each_inner!(((ADC2_CHANNEL7, ADCn_CHANNELm, 2, 7), GPIO33)); + _for_each_inner!(((ANA_COMP1, ANA_COMPn, 1), GPIO33)); + _for_each_inner!((all(XTAL_32K_N, GPIO0), (XTAL_32K_P, GPIO1), (TOUCH_CHANNEL0, + GPIO2), (TOUCH_CHANNEL1, GPIO3), (TOUCH_CHANNEL2, GPIO4), (TOUCH_CHANNEL3, + GPIO5), (TOUCH_CHANNEL4, GPIO6), (TOUCH_CHANNEL5, GPIO7), (TOUCH_CHANNEL6, + GPIO8), (TOUCH_CHANNEL7, GPIO9), (TOUCH_CHANNEL8, GPIO10), (TOUCH_CHANNEL9, + GPIO11), (TOUCH_CHANNEL10, GPIO12), (TOUCH_CHANNEL11, GPIO13), (TOUCH_CHANNEL12, + GPIO14), (TOUCH_CHANNEL13, GPIO15), (ADC1_CHANNEL0, GPIO16), (ADC1_CHANNEL1, + GPIO17), (ADC1_CHANNEL2, GPIO18), (ADC1_CHANNEL3, GPIO19), (ADC1_CHANNEL4, + GPIO20), (ADC1_CHANNEL5, GPIO21), (ADC1_CHANNEL6, GPIO22), (ADC1_CHANNEL7, + GPIO23), (USB1P1_N0, GPIO24), (USB1P1_P0, GPIO25), (USB1P1_N1, GPIO26), + (USB1P1_P1, GPIO27), (ADC2_CHANNEL2, GPIO28), (ADC2_CHANNEL3, GPIO29), + (ADC2_CHANNEL4, GPIO30), (ANA_COMP0, GPIO30), (ADC2_CHANNEL5, GPIO31), + (ANA_COMP0, GPIO31), (ADC2_CHANNEL6, GPIO32), (ANA_COMP1, GPIO32), + (ADC2_CHANNEL7, GPIO33), (ANA_COMP1, GPIO33))); + _for_each_inner!((all_expanded((TOUCH_CHANNEL0, TOUCH_CHANNELn, 0), GPIO2), + ((TOUCH_CHANNEL1, TOUCH_CHANNELn, 1), GPIO3), ((TOUCH_CHANNEL2, TOUCH_CHANNELn, + 2), GPIO4), ((TOUCH_CHANNEL3, TOUCH_CHANNELn, 3), GPIO5), ((TOUCH_CHANNEL4, + TOUCH_CHANNELn, 4), GPIO6), ((TOUCH_CHANNEL5, TOUCH_CHANNELn, 5), GPIO7), + ((TOUCH_CHANNEL6, TOUCH_CHANNELn, 6), GPIO8), ((TOUCH_CHANNEL7, TOUCH_CHANNELn, + 7), GPIO9), ((TOUCH_CHANNEL8, TOUCH_CHANNELn, 8), GPIO10), ((TOUCH_CHANNEL9, + TOUCH_CHANNELn, 9), GPIO11), ((TOUCH_CHANNEL10, TOUCH_CHANNELn, 10), GPIO12), + ((TOUCH_CHANNEL11, TOUCH_CHANNELn, 11), GPIO13), ((TOUCH_CHANNEL12, + TOUCH_CHANNELn, 12), GPIO14), ((TOUCH_CHANNEL13, TOUCH_CHANNELn, 13), GPIO15), + ((ADC1_CHANNEL0, ADCn_CHANNELm, 1, 0), GPIO16), ((ADC1_CHANNEL1, ADCn_CHANNELm, + 1, 1), GPIO17), ((ADC1_CHANNEL2, ADCn_CHANNELm, 1, 2), GPIO18), ((ADC1_CHANNEL3, + ADCn_CHANNELm, 1, 3), GPIO19), ((ADC1_CHANNEL4, ADCn_CHANNELm, 1, 4), GPIO20), + ((ADC1_CHANNEL5, ADCn_CHANNELm, 1, 5), GPIO21), ((ADC1_CHANNEL6, ADCn_CHANNELm, + 1, 6), GPIO22), ((ADC1_CHANNEL7, ADCn_CHANNELm, 1, 7), GPIO23), ((USB1P1_N0, + USB1P1_Nn, 0), GPIO24), ((USB1P1_P0, USB1P1_Pn, 0), GPIO25), ((USB1P1_N1, + USB1P1_Nn, 1), GPIO26), ((USB1P1_P1, USB1P1_Pn, 1), GPIO27), ((ADC2_CHANNEL2, + ADCn_CHANNELm, 2, 2), GPIO28), ((ADC2_CHANNEL3, ADCn_CHANNELm, 2, 3), GPIO29), + ((ADC2_CHANNEL4, ADCn_CHANNELm, 2, 4), GPIO30), ((ANA_COMP0, ANA_COMPn, 0), + GPIO30), ((ADC2_CHANNEL5, ADCn_CHANNELm, 2, 5), GPIO31), ((ANA_COMP0, ANA_COMPn, + 0), GPIO31), ((ADC2_CHANNEL6, ADCn_CHANNELm, 2, 6), GPIO32), ((ANA_COMP1, + ANA_COMPn, 1), GPIO32), ((ADC2_CHANNEL7, ADCn_CHANNELm, 2, 7), GPIO33), + ((ANA_COMP1, ANA_COMPn, 1), GPIO33))); + }; +} +/// This macro can be used to generate code for each LP/RTC function of each GPIO. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has two options for its "Individual matcher" case: +/// +/// - `all`: `($signal:ident, $gpio:ident)` - simple case where you only need identifiers +/// - `all_expanded`: `(($signal:ident, $group:ident $(, $number:literal)+), $gpio:ident)` - +/// expanded signal case, where you need the number(s) of a signal, or the general group to which +/// the signal belongs. For example, in case of `SAR_I2C_SCL_1` the expanded form looks like +/// `(SAR_I2C_SCL_1, SAR_I2C_SCL_n, 1)`. +/// +/// Macro fragments: +/// +/// - `$signal`: the name of the signal. +/// - `$group`: the name of the signal, with numbers replaced by placeholders. For `ADC2_CH3` this +/// is `ADCn_CHm`. +/// - `$number`: the numbers extracted from `$signal`. +/// - `$gpio`: the name of the GPIO. +/// +/// Example data: +/// - `(RTC_GPIO15, GPIO12)` +/// - `((RTC_GPIO15, RTC_GPIOn, 15), GPIO12)` +/// +/// The expanded syntax is only available when the signal has at least one numbered component. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_lp_function { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } + _for_each_inner!((LP_GPIO0, GPIO0)); _for_each_inner!((LP_GPIO0, GPIO0)); + _for_each_inner!((LP_GPIO1, GPIO1)); _for_each_inner!((LP_GPIO1, GPIO1)); + _for_each_inner!((LP_GPIO2, GPIO2)); _for_each_inner!((LP_GPIO2, GPIO2)); + _for_each_inner!((LP_GPIO3, GPIO3)); _for_each_inner!((LP_GPIO3, GPIO3)); + _for_each_inner!((LP_GPIO4, GPIO4)); _for_each_inner!((LP_GPIO4, GPIO4)); + _for_each_inner!((LP_GPIO5, GPIO5)); _for_each_inner!((LP_GPIO5, GPIO5)); + _for_each_inner!((LP_GPIO6, GPIO6)); _for_each_inner!((LP_GPIO6, GPIO6)); + _for_each_inner!((LP_GPIO7, GPIO7)); _for_each_inner!((LP_GPIO7, GPIO7)); + _for_each_inner!((LP_GPIO8, GPIO8)); _for_each_inner!((LP_GPIO8, GPIO8)); + _for_each_inner!((LP_GPIO9, GPIO9)); _for_each_inner!((LP_GPIO9, GPIO9)); + _for_each_inner!((LP_GPIO10, GPIO10)); _for_each_inner!((LP_GPIO10, GPIO10)); + _for_each_inner!((LP_GPIO11, GPIO11)); _for_each_inner!((LP_GPIO11, GPIO11)); + _for_each_inner!((LP_GPIO12, GPIO12)); _for_each_inner!((LP_GPIO12, GPIO12)); + _for_each_inner!((LP_GPIO13, GPIO13)); _for_each_inner!((LP_GPIO13, GPIO13)); + _for_each_inner!((LP_UART_TXD_PAD, GPIO14)); _for_each_inner!((LP_GPIO14, + GPIO14)); _for_each_inner!((LP_UART_RXD_PAD, GPIO15)); + _for_each_inner!((LP_GPIO15, GPIO15)); _for_each_inner!(((LP_GPIO0, LP_GPIOn, 0), + GPIO0)); _for_each_inner!(((LP_GPIO0, LP_GPIOn, 0), GPIO0)); + _for_each_inner!(((LP_GPIO1, LP_GPIOn, 1), GPIO1)); _for_each_inner!(((LP_GPIO1, + LP_GPIOn, 1), GPIO1)); _for_each_inner!(((LP_GPIO2, LP_GPIOn, 2), GPIO2)); + _for_each_inner!(((LP_GPIO2, LP_GPIOn, 2), GPIO2)); _for_each_inner!(((LP_GPIO3, + LP_GPIOn, 3), GPIO3)); _for_each_inner!(((LP_GPIO3, LP_GPIOn, 3), GPIO3)); + _for_each_inner!(((LP_GPIO4, LP_GPIOn, 4), GPIO4)); _for_each_inner!(((LP_GPIO4, + LP_GPIOn, 4), GPIO4)); _for_each_inner!(((LP_GPIO5, LP_GPIOn, 5), GPIO5)); + _for_each_inner!(((LP_GPIO5, LP_GPIOn, 5), GPIO5)); _for_each_inner!(((LP_GPIO6, + LP_GPIOn, 6), GPIO6)); _for_each_inner!(((LP_GPIO6, LP_GPIOn, 6), GPIO6)); + _for_each_inner!(((LP_GPIO7, LP_GPIOn, 7), GPIO7)); _for_each_inner!(((LP_GPIO7, + LP_GPIOn, 7), GPIO7)); _for_each_inner!(((LP_GPIO8, LP_GPIOn, 8), GPIO8)); + _for_each_inner!(((LP_GPIO8, LP_GPIOn, 8), GPIO8)); _for_each_inner!(((LP_GPIO9, + LP_GPIOn, 9), GPIO9)); _for_each_inner!(((LP_GPIO9, LP_GPIOn, 9), GPIO9)); + _for_each_inner!(((LP_GPIO10, LP_GPIOn, 10), GPIO10)); + _for_each_inner!(((LP_GPIO10, LP_GPIOn, 10), GPIO10)); + _for_each_inner!(((LP_GPIO11, LP_GPIOn, 11), GPIO11)); + _for_each_inner!(((LP_GPIO11, LP_GPIOn, 11), GPIO11)); + _for_each_inner!(((LP_GPIO12, LP_GPIOn, 12), GPIO12)); + _for_each_inner!(((LP_GPIO12, LP_GPIOn, 12), GPIO12)); + _for_each_inner!(((LP_GPIO13, LP_GPIOn, 13), GPIO13)); + _for_each_inner!(((LP_GPIO13, LP_GPIOn, 13), GPIO13)); + _for_each_inner!(((LP_GPIO14, LP_GPIOn, 14), GPIO14)); + _for_each_inner!(((LP_GPIO15, LP_GPIOn, 15), GPIO15)); + _for_each_inner!((all(LP_GPIO0, GPIO0), (LP_GPIO0, GPIO0), (LP_GPIO1, GPIO1), + (LP_GPIO1, GPIO1), (LP_GPIO2, GPIO2), (LP_GPIO2, GPIO2), (LP_GPIO3, GPIO3), + (LP_GPIO3, GPIO3), (LP_GPIO4, GPIO4), (LP_GPIO4, GPIO4), (LP_GPIO5, GPIO5), + (LP_GPIO5, GPIO5), (LP_GPIO6, GPIO6), (LP_GPIO6, GPIO6), (LP_GPIO7, GPIO7), + (LP_GPIO7, GPIO7), (LP_GPIO8, GPIO8), (LP_GPIO8, GPIO8), (LP_GPIO9, GPIO9), + (LP_GPIO9, GPIO9), (LP_GPIO10, GPIO10), (LP_GPIO10, GPIO10), (LP_GPIO11, GPIO11), + (LP_GPIO11, GPIO11), (LP_GPIO12, GPIO12), (LP_GPIO12, GPIO12), (LP_GPIO13, + GPIO13), (LP_GPIO13, GPIO13), (LP_UART_TXD_PAD, GPIO14), (LP_GPIO14, GPIO14), + (LP_UART_RXD_PAD, GPIO15), (LP_GPIO15, GPIO15))); + _for_each_inner!((all_expanded((LP_GPIO0, LP_GPIOn, 0), GPIO0), ((LP_GPIO0, + LP_GPIOn, 0), GPIO0), ((LP_GPIO1, LP_GPIOn, 1), GPIO1), ((LP_GPIO1, LP_GPIOn, 1), + GPIO1), ((LP_GPIO2, LP_GPIOn, 2), GPIO2), ((LP_GPIO2, LP_GPIOn, 2), GPIO2), + ((LP_GPIO3, LP_GPIOn, 3), GPIO3), ((LP_GPIO3, LP_GPIOn, 3), GPIO3), ((LP_GPIO4, + LP_GPIOn, 4), GPIO4), ((LP_GPIO4, LP_GPIOn, 4), GPIO4), ((LP_GPIO5, LP_GPIOn, 5), + GPIO5), ((LP_GPIO5, LP_GPIOn, 5), GPIO5), ((LP_GPIO6, LP_GPIOn, 6), GPIO6), + ((LP_GPIO6, LP_GPIOn, 6), GPIO6), ((LP_GPIO7, LP_GPIOn, 7), GPIO7), ((LP_GPIO7, + LP_GPIOn, 7), GPIO7), ((LP_GPIO8, LP_GPIOn, 8), GPIO8), ((LP_GPIO8, LP_GPIOn, 8), + GPIO8), ((LP_GPIO9, LP_GPIOn, 9), GPIO9), ((LP_GPIO9, LP_GPIOn, 9), GPIO9), + ((LP_GPIO10, LP_GPIOn, 10), GPIO10), ((LP_GPIO10, LP_GPIOn, 10), GPIO10), + ((LP_GPIO11, LP_GPIOn, 11), GPIO11), ((LP_GPIO11, LP_GPIOn, 11), GPIO11), + ((LP_GPIO12, LP_GPIOn, 12), GPIO12), ((LP_GPIO12, LP_GPIOn, 12), GPIO12), + ((LP_GPIO13, LP_GPIOn, 13), GPIO13), ((LP_GPIO13, LP_GPIOn, 13), GPIO13), + ((LP_GPIO14, LP_GPIOn, 14), GPIO14), ((LP_GPIO15, LP_GPIOn, 15), GPIO15))); + }; +} +/// Defines the `InputSignal` and `OutputSignal` enums. +/// +/// This macro is intended to be called in esp-hal only. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! define_io_mux_signals { + () => { + #[allow(non_camel_case_types, clippy::upper_case_acronyms)] + #[derive(Debug, PartialEq, Copy, Clone)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + #[doc(hidden)] + pub enum InputSignal { + SD_CARD_CCMD_2_PAD = 1, + SD_CARD_CDATA0_2_PAD = 2, + SD_CARD_CDATA1_2_PAD = 3, + SD_CARD_CDATA2_2_PAD = 4, + SD_CARD_CDATA3_2_PAD = 5, + SD_CARD_CDATA4_2_PAD = 6, + SD_CARD_CDATA5_2_PAD = 7, + SD_CARD_CDATA6_2_PAD = 8, + SD_CARD_CDATA7_2_PAD = 9, + UART0_RXD_PAD = 10, + UART0_CTS_PAD = 11, + UART0_DSR_PAD = 12, + UART1_RXD_PAD = 13, + UART1_CTS_PAD = 14, + UART1_DSR_PAD = 15, + UART2_RXD_PAD = 16, + UART2_CTS_PAD = 17, + UART2_DSR_PAD = 18, + UART3_RXD_PAD = 19, + UART3_CTS_PAD = 20, + UART3_DSR_PAD = 21, + UART4_RXD_PAD = 22, + UART4_CTS_PAD = 23, + UART4_DSR_PAD = 24, + I2S0_O_BCK_PAD = 25, + I2S0_MCLK_PAD = 26, + I2S0_O_WS_PAD = 27, + I2S0_I_SD_PAD = 28, + I2S0_I_BCK_PAD = 29, + I2S0_I_WS_PAD = 30, + I2S1_O_BCK_PAD = 31, + I2S1_MCLK_PAD = 32, + I2S1_O_WS_PAD = 33, + I2S1_I_SD_PAD = 34, + I2S1_I_BCK_PAD = 35, + I2S1_I_WS_PAD = 36, + I2S2_O_BCK_PAD = 37, + I2S2_MCLK_PAD = 38, + I2S2_O_WS_PAD = 39, + I2S2_I_SD_PAD = 40, + I2S2_I_BCK_PAD = 41, + I2S2_I_WS_PAD = 42, + I2S0_I_SD1_PAD = 43, + I2S0_I_SD2_PAD = 44, + I2S0_I_SD3_PAD = 45, + SPI3_CK_PAD = 47, + SPI3_Q_PAD = 48, + SPI3_D_PAD = 49, + SPI3_HOLD_PAD = 50, + SPI3_WP_PAD = 51, + SPI3_CS_PAD = 52, + SPI2_CK_PAD = 53, + SPI2_Q_PAD = 54, + SPI2_D_PAD = 55, + SPI2_HOLD_PAD = 56, + SPI2_WP_PAD = 57, + SPI2_IO4_PAD = 58, + SPI2_IO5_PAD = 59, + SPI2_IO6_PAD = 60, + SPI2_IO7_PAD = 61, + SPI2_CS_PAD = 62, + PCNT_RST_PAD_IN0 = 63, + PCNT_RST_PAD_IN1 = 64, + PCNT_RST_PAD_IN2 = 65, + PCNT_RST_PAD_IN3 = 66, + I2C0_SCL_PAD = 68, + I2C0_SDA_PAD = 69, + I2C1_SCL_PAD = 70, + I2C1_SDA_PAD = 71, + UART0_SLP_CLK_PAD = 74, + UART1_SLP_CLK_PAD = 75, + UART2_SLP_CLK_PAD = 76, + UART3_SLP_CLK_PAD = 77, + UART4_SLP_CLK_PAD = 78, + TWAI0_RX_PAD = 80, + TWAI1_RX_PAD = 83, + TWAI2_RX_PAD = 86, + PWM0_SYNC0_PAD = 89, + PWM0_SYNC1_PAD = 90, + PWM0_SYNC2_PAD = 91, + PWM0_F0_PAD = 92, + PWM0_F1_PAD = 93, + PWM0_F2_PAD = 94, + PWM0_CAP0_PAD = 95, + PWM0_CAP1_PAD = 96, + PWM0_CAP2_PAD = 97, + PWM1_SYNC0_PAD = 98, + PWM1_SYNC1_PAD = 99, + PWM1_SYNC2_PAD = 100, + PWM1_F0_PAD = 101, + PWM1_F1_PAD = 102, + PWM1_F2_PAD = 103, + PWM1_CAP0_PAD = 104, + PWM1_CAP1_PAD = 105, + PWM1_CAP2_PAD = 106, + GMII_MDI_PAD = 107, + GMAC_PHY_COL_PAD = 108, + GMAC_PHY_CRS_PAD = 109, + USB_OTG11_IDDIG_PAD = 110, + USB_OTG11_AVALID_PAD = 111, + USB_SRP_BVALID_PAD = 112, + USB_OTG11_VBUSVALID_PAD = 113, + USB_SRP_SESSEND_PAD = 114, + ULPI_CLK_PAD = 117, + USB_HSPHY_REFCLK = 118, + SD_CARD_DETECT_N_1_PAD = 126, + SD_CARD_DETECT_N_2_PAD = 127, + SD_CARD_INT_N_1_PAD = 128, + SD_CARD_INT_N_2_PAD = 129, + SD_CARD_WRITE_PRT_1_PAD = 130, + SD_CARD_WRITE_PRT_2_PAD = 131, + SD_DATA_STROBE_1_PAD = 132, + SD_DATA_STROBE_2_PAD = 133, + I3C_MST_SCL_PAD = 134, + I3C_MST_SDA_PAD = 135, + I3C_SLV_SCL_PAD = 136, + I3C_SLV_SDA_PAD = 137, + USB_JTAG_TDO_BRIDGE_PAD = 140, + PCNT_SIG_CH0_PAD_IN0 = 141, + PCNT_SIG_CH0_PAD_IN1 = 142, + PCNT_SIG_CH0_PAD_IN2 = 143, + PCNT_SIG_CH0_PAD_IN3 = 144, + PCNT_SIG_CH1_PAD_IN0 = 145, + PCNT_SIG_CH1_PAD_IN1 = 146, + PCNT_SIG_CH1_PAD_IN2 = 147, + PCNT_SIG_CH1_PAD_IN3 = 148, + PCNT_CTRL_CH0_PAD_IN0 = 149, + PCNT_CTRL_CH0_PAD_IN1 = 150, + PCNT_CTRL_CH0_PAD_IN2 = 151, + PCNT_CTRL_CH0_PAD_IN3 = 152, + PCNT_CTRL_CH1_PAD_IN0 = 153, + PCNT_CTRL_CH1_PAD_IN1 = 154, + PCNT_CTRL_CH1_PAD_IN2 = 155, + PCNT_CTRL_CH1_PAD_IN3 = 156, + CAM_PCLK_PAD = 158, + CAM_H_ENABLE_PAD = 159, + CAM_H_SYNC_PAD = 160, + CAM_V_SYNC_PAD = 161, + CAM_DATA_IN_PAD_IN0 = 162, + CAM_DATA_IN_PAD_IN1 = 163, + CAM_DATA_IN_PAD_IN2 = 164, + CAM_DATA_IN_PAD_IN3 = 165, + CAM_DATA_IN_PAD_IN4 = 166, + CAM_DATA_IN_PAD_IN5 = 167, + CAM_DATA_IN_PAD_IN6 = 168, + CAM_DATA_IN_PAD_IN7 = 169, + CAM_DATA_IN_PAD_IN8 = 170, + CAM_DATA_IN_PAD_IN9 = 171, + CAM_DATA_IN_PAD_IN10 = 172, + CAM_DATA_IN_PAD_IN11 = 173, + CAM_DATA_IN_PAD_IN12 = 174, + CAM_DATA_IN_PAD_IN13 = 175, + CAM_DATA_IN_PAD_IN14 = 176, + CAM_DATA_IN_PAD_IN15 = 177, + GMAC_PHY_RXDV_PAD = 178, + GMAC_PHY_RXD0_PAD = 179, + GMAC_PHY_RXD1_PAD = 180, + GMAC_PHY_RXD2_PAD = 181, + GMAC_PHY_RXD3_PAD = 182, + GMAC_PHY_RXER_PAD = 183, + GMAC_RX_CLK_PAD = 184, + GMAC_TX_CLK_PAD = 185, + PARLIO_RX_CLK_PAD = 186, + PARLIO_TX_CLK_PAD = 187, + PARLIO_RX_DATA0_PAD = 188, + PARLIO_RX_DATA1_PAD = 189, + PARLIO_RX_DATA2_PAD = 190, + PARLIO_RX_DATA3_PAD = 191, + PARLIO_RX_DATA4_PAD = 192, + PARLIO_RX_DATA5_PAD = 193, + PARLIO_RX_DATA6_PAD = 194, + PARLIO_RX_DATA7_PAD = 195, + PARLIO_RX_DATA8_PAD = 196, + PARLIO_RX_DATA9_PAD = 197, + PARLIO_RX_DATA10_PAD = 198, + PARLIO_RX_DATA11_PAD = 199, + PARLIO_RX_DATA12_PAD = 200, + PARLIO_RX_DATA13_PAD = 201, + PARLIO_RX_DATA14_PAD = 202, + PARLIO_RX_DATA15_PAD = 203, + CORE_GPIO_IN_PAD_IN0 = 214, + CORE_GPIO_IN_PAD_IN1 = 215, + CORE_GPIO_IN_PAD_IN2 = 216, + CORE_GPIO_IN_PAD_IN3 = 217, + CORE_GPIO_IN_PAD_IN4 = 218, + CORE_GPIO_IN_PAD_IN5 = 219, + CORE_GPIO_IN_PAD_IN6 = 220, + CORE_GPIO_IN_PAD_IN7 = 221, + CORE_GPIO_IN_PAD_IN8 = 222, + CORE_GPIO_IN_PAD_IN9 = 223, + CORE_GPIO_IN_PAD_IN10 = 224, + CORE_GPIO_IN_PAD_IN11 = 225, + CORE_GPIO_IN_PAD_IN12 = 226, + CORE_GPIO_IN_PAD_IN13 = 227, + CORE_GPIO_IN_PAD_IN14 = 228, + CORE_GPIO_IN_PAD_IN15 = 229, + CORE_GPIO_IN_PAD_IN16 = 230, + CORE_GPIO_IN_PAD_IN17 = 231, + CORE_GPIO_IN_PAD_IN18 = 232, + CORE_GPIO_IN_PAD_IN19 = 233, + CORE_GPIO_IN_PAD_IN20 = 234, + CORE_GPIO_IN_PAD_IN21 = 235, + CORE_GPIO_IN_PAD_IN22 = 236, + CORE_GPIO_IN_PAD_IN23 = 237, + CORE_GPIO_IN_PAD_IN24 = 238, + CORE_GPIO_IN_PAD_IN25 = 239, + CORE_GPIO_IN_PAD_IN26 = 240, + CORE_GPIO_IN_PAD_IN27 = 241, + CORE_GPIO_IN_PAD_IN28 = 242, + CORE_GPIO_IN_PAD_IN29 = 243, + CORE_GPIO_IN_PAD_IN30 = 244, + CORE_GPIO_IN_PAD_IN31 = 245, + RMT_SIG_PAD_IN0 = 246, + RMT_SIG_PAD_IN1 = 247, + RMT_SIG_PAD_IN2 = 248, + RMT_SIG_PAD_IN3 = 249, + SIG_IN_FUNC250 = 250, + SIG_IN_FUNC251 = 251, + SIG_IN_FUNC252 = 252, + SIG_IN_FUNC253 = 253, + SIG_IN_FUNC254 = 254, + SIG_IN_FUNC255 = 255, + REF_50M_CLK_PAD, + GMAC_RMII_CLK_PAD, + SD1_CDATA0_PAD, + SD1_CDATA1_PAD, + SD1_CDATA2_PAD, + SD1_CDATA3_PAD, + SD1_CCLK_PAD, + SD1_CCMD_PAD, + SD1_CDATA4_PAD, + SD1_CDATA5_PAD, + SD1_CDATA6_PAD, + SD1_CDATA7_PAD, + MTDI, + MTDO, + MTCK, + MTMS, + } + #[allow(non_camel_case_types, clippy::upper_case_acronyms)] + #[derive(Debug, PartialEq, Copy, Clone)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + #[doc(hidden)] + pub enum OutputSignal { + SD_CARD_CCLK_2_PAD = 0, + SD_CARD_CCMD_2_PAD = 1, + SD_CARD_CDATA0_2_PAD = 2, + SD_CARD_CDATA1_2_PAD = 3, + SD_CARD_CDATA2_2_PAD = 4, + SD_CARD_CDATA3_2_PAD = 5, + SD_CARD_CDATA4_2_PAD = 6, + SD_CARD_CDATA5_2_PAD = 7, + SD_CARD_CDATA6_2_PAD = 8, + SD_CARD_CDATA7_2_PAD = 9, + UART0_TXD_PAD = 10, + UART0_RTS_PAD = 11, + UART0_DTR_PAD = 12, + UART1_TXD_PAD = 13, + UART1_RTS_PAD = 14, + UART1_DTR_PAD = 15, + UART2_TXD_PAD = 16, + UART2_RTS_PAD = 17, + UART2_DTR_PAD = 18, + UART3_TXD_PAD = 19, + UART3_RTS_PAD = 20, + UART3_DTR_PAD = 21, + UART4_TXD_PAD = 22, + UART4_RTS_PAD = 23, + UART4_DTR_PAD = 24, + I2S0_O_BCK_PAD = 25, + I2S0_MCLK_PAD = 26, + I2S0_O_WS_PAD = 27, + I2S0_O_SD_PAD = 28, + I2S0_I_BCK_PAD = 29, + I2S0_I_WS_PAD = 30, + I2S1_O_BCK_PAD = 31, + I2S1_MCLK_PAD = 32, + I2S1_O_WS_PAD = 33, + I2S1_O_SD_PAD = 34, + I2S1_I_BCK_PAD = 35, + I2S1_I_WS_PAD = 36, + I2S2_O_BCK_PAD = 37, + I2S2_MCLK_PAD = 38, + I2S2_O_WS_PAD = 39, + I2S2_O_SD_PAD = 40, + I2S2_I_BCK_PAD = 41, + I2S2_I_WS_PAD = 42, + I2S0_O_SD1_PAD = 43, + SPI2_DQS_PAD = 44, + SPI3_CS2_PAD = 45, + SPI3_CS1_PAD = 46, + SPI3_CK_PAD = 47, + SPI3_QO_PAD = 48, + SPI3_D_PAD = 49, + SPI3_HOLD_PAD = 50, + SPI3_WP_PAD = 51, + SPI3_CS_PAD = 52, + SPI2_CK_PAD = 53, + SPI2_Q_PAD = 54, + SPI2_D_PAD = 55, + SPI2_HOLD_PAD = 56, + SPI2_WP_PAD = 57, + SPI2_IO4_PAD = 58, + SPI2_IO5_PAD = 59, + SPI2_IO6_PAD = 60, + SPI2_IO7_PAD = 61, + SPI2_CS_PAD = 62, + SPI2_CS1_PAD = 63, + SPI2_CS2_PAD = 64, + SPI2_CS3_PAD = 65, + SPI2_CS4_PAD = 66, + SPI2_CS5_PAD = 67, + I2C0_SCL_PAD = 68, + I2C0_SDA_PAD = 69, + I2C1_SCL_PAD = 70, + I2C1_SDA_PAD = 71, + GPIO_SD0 = 72, + GPIO_SD1 = 73, + GPIO_SD2 = 74, + GPIO_SD3 = 75, + GPIO_SD4 = 76, + GPIO_SD5 = 77, + GPIO_SD6 = 78, + GPIO_SD7 = 79, + TWAI0_TX_PAD = 80, + TWAI0_BUS_OFF_ON_PAD = 81, + TWAI0_CLKOUT_PAD = 82, + TWAI1_TX_PAD = 83, + TWAI1_BUS_OFF_ON_PAD = 84, + TWAI1_CLKOUT_PAD = 85, + TWAI2_TX_PAD = 86, + TWAI2_BUS_OFF_ON_PAD = 87, + TWAI2_CLKOUT_PAD = 88, + PWM0_CH0_A_PAD = 89, + PWM0_CH0_B_PAD = 90, + PWM0_CH1_A_PAD = 91, + PWM0_CH1_B_PAD = 92, + PWM0_CH2_A_PAD = 93, + PWM0_CH2_B_PAD = 94, + PWM1_CH0_A_PAD = 95, + PWM1_CH0_B_PAD = 96, + PWM1_CH1_A_PAD = 97, + PWM1_CH1_B_PAD = 98, + PWM1_CH2_A_PAD = 99, + PWM1_CH2_B_PAD = 100, + TWAI0_STANDBY_PAD = 105, + TWAI1_STANDBY_PAD = 106, + TWAI2_STANDBY_PAD = 107, + GMII_MDC_PAD = 108, + GMII_MDO_PAD = 109, + USB_SRP_DISCHRGVBUS_PAD = 110, + USB_OTG11_IDPULLUP_PAD = 111, + USB_OTG11_DPPULLDOWN_PAD = 112, + USB_OTG11_DMPULLDOWN_PAD = 113, + USB_OTG11_DRVVBUS_PAD = 114, + USB_SRP_CHRGVBUS_PAD = 115, + LEDC_LS_SIG_OUT_PAD_OUT0 = 126, + LEDC_LS_SIG_OUT_PAD_OUT1 = 127, + LEDC_LS_SIG_OUT_PAD_OUT2 = 128, + LEDC_LS_SIG_OUT_PAD_OUT3 = 129, + LEDC_LS_SIG_OUT_PAD_OUT4 = 130, + LEDC_LS_SIG_OUT_PAD_OUT5 = 131, + LEDC_LS_SIG_OUT_PAD_OUT6 = 132, + LEDC_LS_SIG_OUT_PAD_OUT7 = 133, + I3C_MST_SCL_PAD = 134, + I3C_MST_SDA_PAD = 135, + I3C_SLV_SCL_PAD = 136, + I3C_SLV_SDA_PAD = 137, + I3C_MST_SCL_PULLUP_EN_PAD = 138, + I3C_MST_SDA_PULLUP_EN_PAD = 139, + USB_JTAG_TDI_BRIDGE_PAD = 140, + USB_JTAG_TMS_BRIDGE_PAD = 141, + USB_JTAG_TCK_BRIDGE_PAD = 142, + USB_JTAG_TRST_BRIDGE_PAD = 143, + LCD_CS_PAD = 144, + LCD_DC_PAD = 145, + SD_RST_N_1_PAD = 146, + SD_RST_N_2_PAD = 147, + SD_CCMD_OD_PULLUP_EN_N_PAD = 148, + LCD_PCLK_PAD = 149, + CAM_CLK_PAD = 150, + LCD_H_ENABLE_PAD = 151, + LCD_H_SYNC_PAD = 152, + LCD_V_SYNC_PAD = 153, + LCD_DATA_OUT_PAD_OUT0 = 154, + LCD_DATA_OUT_PAD_OUT1 = 155, + LCD_DATA_OUT_PAD_OUT2 = 156, + LCD_DATA_OUT_PAD_OUT3 = 157, + LCD_DATA_OUT_PAD_OUT4 = 158, + LCD_DATA_OUT_PAD_OUT5 = 159, + LCD_DATA_OUT_PAD_OUT6 = 160, + LCD_DATA_OUT_PAD_OUT7 = 161, + LCD_DATA_OUT_PAD_OUT8 = 162, + LCD_DATA_OUT_PAD_OUT9 = 163, + LCD_DATA_OUT_PAD_OUT10 = 164, + LCD_DATA_OUT_PAD_OUT11 = 165, + LCD_DATA_OUT_PAD_OUT12 = 166, + LCD_DATA_OUT_PAD_OUT13 = 167, + LCD_DATA_OUT_PAD_OUT14 = 168, + LCD_DATA_OUT_PAD_OUT15 = 169, + LCD_DATA_OUT_PAD_OUT16 = 170, + LCD_DATA_OUT_PAD_OUT17 = 171, + LCD_DATA_OUT_PAD_OUT18 = 172, + LCD_DATA_OUT_PAD_OUT19 = 173, + LCD_DATA_OUT_PAD_OUT20 = 174, + LCD_DATA_OUT_PAD_OUT21 = 175, + LCD_DATA_OUT_PAD_OUT22 = 176, + LCD_DATA_OUT_PAD_OUT23 = 177, + GMAC_PHY_TXEN_PAD = 178, + GMAC_PHY_TXD0_PAD = 179, + GMAC_PHY_TXD1_PAD = 180, + GMAC_PHY_TXD2_PAD = 181, + GMAC_PHY_TXD3_PAD = 182, + GMAC_PHY_TXER_PAD = 183, + PARLIO_RX_CLK_PAD = 186, + PARLIO_TX_CLK_PAD = 187, + PARLIO_TX_DATA0_PAD = 188, + PARLIO_TX_DATA1_PAD = 189, + PARLIO_TX_DATA2_PAD = 190, + PARLIO_TX_DATA3_PAD = 191, + PARLIO_TX_DATA4_PAD = 192, + PARLIO_TX_DATA5_PAD = 193, + PARLIO_TX_DATA6_PAD = 194, + PARLIO_TX_DATA7_PAD = 195, + PARLIO_TX_DATA8_PAD = 196, + PARLIO_TX_DATA9_PAD = 197, + PARLIO_TX_DATA10_PAD = 198, + PARLIO_TX_DATA11_PAD = 199, + PARLIO_TX_DATA12_PAD = 200, + PARLIO_TX_DATA13_PAD = 201, + PARLIO_TX_DATA14_PAD = 202, + PARLIO_TX_DATA15_PAD = 203, + CONSTANT0_PAD = 212, + CONSTANT1_PAD = 213, + CORE_GPIO_OUT_PAD_OUT0 = 214, + CORE_GPIO_OUT_PAD_OUT1 = 215, + CORE_GPIO_OUT_PAD_OUT2 = 216, + CORE_GPIO_OUT_PAD_OUT3 = 217, + CORE_GPIO_OUT_PAD_OUT4 = 218, + CORE_GPIO_OUT_PAD_OUT5 = 219, + CORE_GPIO_OUT_PAD_OUT6 = 220, + CORE_GPIO_OUT_PAD_OUT7 = 221, + CORE_GPIO_OUT_PAD_OUT8 = 222, + CORE_GPIO_OUT_PAD_OUT9 = 223, + CORE_GPIO_OUT_PAD_OUT10 = 224, + CORE_GPIO_OUT_PAD_OUT11 = 225, + CORE_GPIO_OUT_PAD_OUT12 = 226, + CORE_GPIO_OUT_PAD_OUT13 = 227, + CORE_GPIO_OUT_PAD_OUT14 = 228, + CORE_GPIO_OUT_PAD_OUT15 = 229, + CORE_GPIO_OUT_PAD_OUT16 = 230, + CORE_GPIO_OUT_PAD_OUT17 = 231, + CORE_GPIO_OUT_PAD_OUT18 = 232, + CORE_GPIO_OUT_PAD_OUT19 = 233, + CORE_GPIO_OUT_PAD_OUT20 = 234, + CORE_GPIO_OUT_PAD_OUT21 = 235, + CORE_GPIO_OUT_PAD_OUT22 = 236, + CORE_GPIO_OUT_PAD_OUT23 = 237, + CORE_GPIO_OUT_PAD_OUT24 = 238, + CORE_GPIO_OUT_PAD_OUT25 = 239, + CORE_GPIO_OUT_PAD_OUT26 = 240, + CORE_GPIO_OUT_PAD_OUT27 = 241, + CORE_GPIO_OUT_PAD_OUT28 = 242, + CORE_GPIO_OUT_PAD_OUT29 = 243, + ANA_COMP0 = 244, + ANA_COMP1 = 245, + RMT_SIG_PAD_OUT0 = 246, + RMT_SIG_PAD_OUT1 = 247, + RMT_SIG_PAD_OUT2 = 248, + RMT_SIG_PAD_OUT3 = 249, + SIG_IN_FUNC250 = 250, + SIG_IN_FUNC251 = 251, + SIG_IN_FUNC252 = 252, + SIG_IN_FUNC253 = 253, + SIG_IN_FUNC254 = 254, + SIG_IN_FUNC255 = 255, + } + }; +} +/// Defines and implements the `io_mux_reg` function. +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub(crate) fn io_mux_reg(gpio_num: u8) -> &'static crate::pac::io_mux::GPIO0 { +/// // ... +/// # unimplemented!() +/// } +/// ``` +/// +/// This macro is intended to be called in esp-hal only. +#[macro_export] +#[expect(clippy::crate_in_macro_def)] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! define_io_mux_reg { + () => { + pub(crate) fn io_mux_reg(gpio_num: u8) -> &'static crate::pac::io_mux::GPIO { + crate::peripherals::IO_MUX::regs().gpio(gpio_num as usize) + } + }; +} diff --git a/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs b/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs new file mode 100644 index 00000000000..4e36fd95f84 --- /dev/null +++ b/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs @@ -0,0 +1,53 @@ +use crate::peripherals::PMU; + +pub(super) fn enable_phy(en: bool) { + // empty +} + +#[cfg_attr(not(feature = "unstable"), expect(unused))] +pub(super) fn enable_wifi(en: bool) { + // empty +} + +#[cfg_attr(not(feature = "unstable"), expect(unused))] +pub(super) fn enable_ieee802154(en: bool) { + // empty +} + +#[cfg_attr(not(feature = "unstable"), expect(unused))] +pub(super) fn enable_bt(en: bool) { + // empty +} + +pub(super) fn reset_wifi_mac() { + // empty +} + +pub(super) fn init_clocks() { + unsafe { + PMU::regs() + .hp_sleep_icg_modem() + .modify(|_, w| w.hp_sleep_dig_icg_modem_code().bits(0)); + PMU::regs() + .hp_modem_icg_modem() + .modify(|_, w| w.hp_modem_dig_icg_modem_code().bits(1)); + PMU::regs() + .hp_active_icg_modem() + .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(2)); + PMU::regs() + .imm_modem_icg() + .write(|w| w.update_dig_icg_modem_en().set_bit()); + PMU::regs() + .imm_sleep_sysclk() + .write(|w| w.update_dig_icg_switch().set_bit()); + + } +} + +pub(super) fn ble_rtc_clk_init() { + // nothing for this target (yet) +} + +pub(super) fn reset_rpa() { + // nothing for this target (yet) +} diff --git a/esp-rom-sys/ld/esp32p4/libesp_rom_sys.a b/esp-rom-sys/ld/esp32p4/libesp_rom_sys.a new file mode 100644 index 00000000000..aff08cf6348 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/libesp_rom_sys.a @@ -0,0 +1 @@ +INCLUDE "rom-functions.x" diff --git a/esp-rom-sys/ld/esp32p4/rom-functions.x b/esp-rom-sys/ld/esp32p4/rom-functions.x new file mode 100644 index 00000000000..55c3da4d6b4 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom-functions.x @@ -0,0 +1,10 @@ +INCLUDE "rom/esp32p4.rom.api.ld" +INCLUDE "rom/esp32p4.rom.eco5.ld" +INCLUDE "rom/esp32p4.rom.eco5.libgcc.ld" +INCLUDE "rom/esp32p4.rom.eco5.rvfp.ld" +INCLUDE "rom/esp32p4.rom.ld" +INCLUDE "rom/esp32p4.rom.libgcc.ld" +INCLUDE "rom/esp32p4.rom.rvfp.ld" +INCLUDE "rom/esp32p4.rom.version.ld" + +INCLUDE "rom/additional.ld" diff --git a/esp-rom-sys/ld/esp32p4/rom/additional.ld b/esp-rom-sys/ld/esp32p4/rom/additional.ld new file mode 100644 index 00000000000..318f1cd9372 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/additional.ld @@ -0,0 +1,12 @@ +ets_update_cpu_frequency = 0x4fc00044; +ets_printf = 0x4fc00024; +PROVIDE(ets_delay_us = 0x4fc0003c); + +memset = 0x4fc00268; +memcpy = 0x4fc0026c; +memmove = 0x4fc00270; +memcmp = 0x4fc00274; +strcpy = 0x4fc00278; +strncpy = 0x4fc0027c; +strcmp = 0x4fc00280; +strncmp = 0x4fc00284; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.api.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.api.ld new file mode 100644 index 00000000000..77409b31985 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.api.ld @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** ROM APIs + */ + +PROVIDE ( esp_rom_crc32_le = crc32_le ); +PROVIDE ( esp_rom_crc16_le = crc16_le ); +PROVIDE ( esp_rom_crc8_le = crc8_le ); +PROVIDE ( esp_rom_crc32_be = crc32_be ); +PROVIDE ( esp_rom_crc16_be = crc16_be ); +PROVIDE ( esp_rom_crc8_be = crc8_be ); + +PROVIDE ( esp_rom_gpio_pad_select_gpio = gpio_pad_select_gpio ); +PROVIDE ( esp_rom_gpio_pad_pullup_only = gpio_pad_pullup ); +PROVIDE ( esp_rom_gpio_pad_set_drv = gpio_pad_set_drv ); +PROVIDE ( esp_rom_gpio_pad_unhold = gpio_pad_unhold ); +PROVIDE ( esp_rom_gpio_connect_in_signal = gpio_matrix_in ); +PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out ); + +PROVIDE ( esp_rom_efuse_mac_address_crc8 = esp_crc8 ); +PROVIDE ( esp_rom_efuse_is_secure_boot_enabled = ets_efuse_secure_boot_enabled ); + +PROVIDE ( esp_rom_uart_flush_tx = uart_tx_flush ); +PROVIDE ( esp_rom_uart_tx_one_char = uart_tx_one_char2 ); +PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle ); +PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char ); +PROVIDE ( esp_rom_uart_rx_string = UartRxString ); +PROVIDE ( esp_rom_uart_set_as_console = uart_tx_switch ); +PROVIDE ( esp_rom_uart_putc = ets_write_char_uart ); + +PROVIDE ( esp_rom_usb_serial_putc = uart_tx_one_char3 ); + +PROVIDE ( esp_rom_output_flush_tx = uart_tx_flush ); +PROVIDE ( esp_rom_output_tx_one_char = uart_tx_one_char ); +PROVIDE ( esp_rom_output_tx_wait_idle = uart_tx_wait_idle ); +PROVIDE ( esp_rom_output_rx_one_char = uart_rx_one_char ); +PROVIDE ( esp_rom_output_rx_string = UartRxString ); +PROVIDE ( esp_rom_output_set_as_console = uart_tx_switch ); +PROVIDE ( esp_rom_output_putc = ets_write_char_uart ); + +PROVIDE ( esp_rom_md5_init = MD5Init ); +PROVIDE ( esp_rom_md5_update = MD5Update ); +PROVIDE ( esp_rom_md5_final = MD5Final ); + +PROVIDE ( esp_rom_software_reset_system = software_reset ); +PROVIDE ( esp_rom_software_reset_cpu = software_reset_cpu ); + +PROVIDE ( esp_rom_printf = ets_printf ); +PROVIDE ( esp_rom_install_uart_printf = ets_install_uart_printf ); +PROVIDE ( esp_rom_delay_us = ets_delay_us ); +PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason ); +PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set ); +PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency ); +PROVIDE ( esp_rom_set_cpu_ticks_per_us = ets_update_cpu_frequency ); + +PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach ); +PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock ); +PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable ); +PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea ); + +PROVIDE ( esp_rom_spiflash_fix_dummylen = spi_dummy_len_fix ); +PROVIDE ( esp_rom_spiflash_set_drvs = SetSpiDrvs); +PROVIDE ( esp_rom_spiflash_select_padsfunc = SelectSpiFunction ); +PROVIDE ( esp_rom_spiflash_common_cmd = SPI_Common_Command ); diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld new file mode 100644 index 00000000000..0df2f533eb2 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld @@ -0,0 +1,592 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32p4.rom.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 + * + * Compatible with ROM where ECO version equal or greater to 5. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group common + ***************************************/ + +/* Functions */ +rtc_get_reset_reason = 0x4fc00018; +rtc_get_wakeup_cause = 0x4fc0001c; +pmu_enable_unhold_pads = 0x4fc00020; +ets_printf = 0x4fc00024; +ets_install_putc1 = 0x4fc00028; +ets_install_putc2 = 0x4fc0002c; +ets_install_uart_printf = 0x4fc00030; +ets_install_usb_printf = 0x4fc00034; +ets_get_printf_channel = 0x4fc00038; +ets_delay_us = 0x4fc0003c; +ets_get_cpu_frequency = 0x4fc00040; +ets_update_cpu_frequency = 0x4fc00044; +ets_install_lock = 0x4fc00048; +UartRxString = 0x4fc0004c; +UartGetCmdLn = 0x4fc00050; +uart_tx_one_char = 0x4fc00054; +uart_tx_one_char2 = 0x4fc00058; +uart_tx_one_char3 = 0x4fc0005c; +uart_rx_one_char = 0x4fc00060; +uart_rx_one_char_block = 0x4fc00064; +uart_rx_intr_handler = 0x4fc00068; +uart_rx_readbuff = 0x4fc0006c; +uartAttach = 0x4fc00070; +uart_tx_flush = 0x4fc00074; +uart_tx_wait_idle = 0x4fc00078; +uart_div_modify = 0x4fc0007c; +ets_write_char_uart = 0x4fc00080; +uart_tx_switch = 0x4fc00084; +uart_buff_switch = 0x4fc00088; +roundup2 = 0x4fc0008c; +multofup = 0x4fc00090; +software_reset = 0x4fc00094; +software_reset_cpu = 0x4fc00098; +ets_clk_assist_debug_clock_enable = 0x4fc0009c; +clear_super_wdt_reset_flag = 0x4fc000a0; +disable_default_watchdog = 0x4fc000a4; +ets_set_appcpu_boot_addr = 0x4fc000a8; +send_packet = 0x4fc000ac; +recv_packet = 0x4fc000b0; +GetUartDevice = 0x4fc000b4; +UartDwnLdProc = 0x4fc000b8; +GetSecurityInfoProc = 0x4fc000bc; +Uart_Init = 0x4fc000c0; +ets_set_user_start = 0x4fc000c4; +/* Data (.data, .bss, .rodata) */ +ets_rom_layout_p = 0x4fc1fffc; +ets_ops_table_ptr = 0x4ffbfff4; +g_saved_pc = 0x4ffbfff8; + + +/*************************************** + Group miniz + ***************************************/ + +/* Functions */ +mz_adler32 = 0x4fc000c8; +mz_free = 0x4fc000cc; +tdefl_compress = 0x4fc000d0; +tdefl_compress_buffer = 0x4fc000d4; +tdefl_compress_mem_to_heap = 0x4fc000d8; +tdefl_compress_mem_to_mem = 0x4fc000dc; +tdefl_compress_mem_to_output = 0x4fc000e0; +tdefl_get_adler32 = 0x4fc000e4; +tdefl_get_prev_return_status = 0x4fc000e8; +tdefl_init = 0x4fc000ec; +tdefl_write_image_to_png_file_in_memory = 0x4fc000f0; +tdefl_write_image_to_png_file_in_memory_ex = 0x4fc000f4; +tinfl_decompress = 0x4fc000f8; +tinfl_decompress_mem_to_callback = 0x4fc000fc; +tinfl_decompress_mem_to_heap = 0x4fc00100; +tinfl_decompress_mem_to_mem = 0x4fc00104; + + +/*************************************** + Group spi_extmem_common + ***************************************/ + +/* Functions */ +esp_rom_spi_cmd_config = 0x4fc00108; +esp_rom_spi_cmd_start = 0x4fc0010c; +esp_rom_spi_set_op_mode = 0x4fc00110; +esp_rom_spi_set_dtr_swap_mode = 0x4fc00114; + + +/*************************************** + Group spiflash_legacy + ***************************************/ + +/* Functions */ +esp_rom_spiflash_wait_idle = 0x4fc00118; +esp_rom_spiflash_write_encrypted = 0x4fc0011c; +esp_rom_spiflash_write_encrypted_dest = 0x4fc00120; +esp_rom_spiflash_write_encrypted_enable = 0x4fc00124; +esp_rom_spiflash_write_encrypted_disable = 0x4fc00128; +esp_rom_spiflash_erase_chip = 0x4fc0012c; +_esp_rom_spiflash_erase_sector = 0x4fc00130; +_esp_rom_spiflash_erase_block = 0x4fc00134; +_esp_rom_spiflash_write = 0x4fc00138; +_esp_rom_spiflash_read = 0x4fc0013c; +_esp_rom_spiflash_unlock = 0x4fc00140; +_SPIEraseArea = 0x4fc00144; +_SPI_write_enable = 0x4fc00148; +esp_rom_spiflash_erase_sector = 0x4fc0014c; +esp_rom_spiflash_erase_block = 0x4fc00150; +esp_rom_spiflash_write = 0x4fc00154; +esp_rom_spiflash_read = 0x4fc00158; +esp_rom_spiflash_unlock = 0x4fc0015c; +SPIEraseArea = 0x4fc00160; +SPI_write_enable = 0x4fc00164; +esp_rom_spiflash_config_param = 0x4fc00168; +esp_rom_spiflash_read_user_cmd = 0x4fc0016c; +esp_rom_spiflash_select_qio_pins = 0x4fc00170; +esp_rom_spi_flash_auto_sus_res = 0x4fc00174; +esp_rom_spi_flash_send_resume = 0x4fc00178; +esp_rom_spi_flash_update_id = 0x4fc0017c; +esp_rom_spiflash_config_clk = 0x4fc00180; +esp_rom_spiflash_config_readmode = 0x4fc00184; +esp_rom_spiflash_read_status = 0x4fc00188; +esp_rom_spiflash_read_statushigh = 0x4fc0018c; +esp_rom_spiflash_write_status = 0x4fc00190; +esp_rom_spiflash_write_disable = 0x4fc00194; +spi_cache_mode_switch = 0x4fc00198; +spi_common_set_dummy_output = 0x4fc0019c; +spi_common_set_flash_cs_timing = 0x4fc001a0; +esp_rom_spi_set_address_bit_len = 0x4fc001a4; +SPILock = 0x4fc001a8; +SPIMasterReadModeCnfig = 0x4fc001ac; +SPI_Common_Command = 0x4fc001b0; +SPI_WakeUp = 0x4fc001b4; +SPI_block_erase = 0x4fc001b8; +SPI_chip_erase = 0x4fc001bc; +SPI_init = 0x4fc001c0; +SPI_page_program = 0x4fc001c4; +SPI_read_data = 0x4fc001c8; +SPI_sector_erase = 0x4fc001cc; +SelectSpiFunction = 0x4fc001d0; +SetSpiDrvs = 0x4fc001d4; +Wait_SPI_Idle = 0x4fc001d8; +spi_dummy_len_fix = 0x4fc001dc; +Disable_QMode = 0x4fc001e0; +Enable_QMode = 0x4fc001e4; +spi_flash_attach = 0x4fc001e8; +spi_flash_get_chip_size = 0x4fc001ec; +spi_flash_guard_set = 0x4fc001f0; +spi_flash_guard_get = 0x4fc001f4; +spi_flash_read_encrypted = 0x4fc001f8; +/* Data (.data, .bss, .rodata) */ +rom_spiflash_legacy_funcs = 0x4ffbffec; +rom_spiflash_legacy_data = 0x4ffbffe8; +g_flash_guard_ops = 0x4ffbfff0; + + +/*************************************** + Group cache + ***************************************/ + +/* Functions */ +Cache_Get_L1_ICache_Line_Size = 0x4fc003c4; +Cache_Get_L1_DCache_Line_Size = 0x4fc003c8; +Cache_Get_L2_Cache_Line_Size = 0x4fc003cc; +Cache_Get_Mode = 0x4fc003d0; +Cache_Set_L2_Cache_Mode = 0x4fc003d4; +Cache_Address_Through_Cache = 0x4fc003d8; +ROM_Boot_Cache_Init = 0x4fc003dc; +Cache_Sync_Addr = 0x4fc003e0; +Cache_Invalidate_Addr = 0x4fc003e4; +Cache_Invalidate_Addr_Gid = 0x4fc003e8; +Cache_Clean_Addr = 0x4fc003ec; +Cache_Clean_Addr_Gid = 0x4fc003f0; +Cache_WriteBack_Addr = 0x4fc003f4; +Cache_WriteBack_Addr_Gid = 0x4fc003f8; +Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; +Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; +Cache_Invalidate_All = 0x4fc00404; +Cache_Invalidate_All_Gid = 0x4fc00408; +Cache_Clean_All = 0x4fc0040c; +Cache_Clean_All_Gid = 0x4fc00410; +Cache_WriteBack_All = 0x4fc00414; +Cache_WriteBack_All_Gid = 0x4fc00418; +Cache_WriteBack_Invalidate_All = 0x4fc0041c; +Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; +Cache_Mask_All = 0x4fc00424; +Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; +Cache_Resume_L1_CORE0_ICache_Autoload = 0x4fc0042c; +Cache_Suspend_L1_CORE1_ICache_Autoload = 0x4fc00430; +Cache_Resume_L1_CORE1_ICache_Autoload = 0x4fc00434; +Cache_Suspend_L1_DCache_Autoload = 0x4fc00438; +Cache_Resume_L1_DCache_Autoload = 0x4fc0043c; +Cache_Suspend_L2_Cache_Autoload = 0x4fc00440; +Cache_Resume_L2_Cache_Autoload = 0x4fc00444; +Cache_Start_L1_CORE0_ICache_Preload = 0x4fc00448; +Cache_L1_CORE0_ICache_Preload_Done = 0x4fc0044c; +Cache_End_L1_CORE0_ICache_Preload = 0x4fc00450; +Cache_Start_L1_CORE1_ICache_Preload = 0x4fc00454; +Cache_L1_CORE1_ICache_Preload_Done = 0x4fc00458; +Cache_End_L1_CORE1_ICache_Preload = 0x4fc0045c; +Cache_Start_L1_DCache_Preload = 0x4fc00460; +Cache_L1_DCache_Preload_Done = 0x4fc00464; +Cache_End_L1_DCache_Preload = 0x4fc00468; +Cache_Start_L2_Cache_Preload = 0x4fc0046c; +Cache_L2_Cache_Preload_Done = 0x4fc00470; +Cache_End_L2_Cache_Preload = 0x4fc00474; +Cache_Config_L1_CORE0_ICache_Autoload = 0x4fc00478; +Cache_Enable_L1_CORE0_ICache_Autoload = 0x4fc0047c; +Cache_Disable_L1_CORE0_ICache_Autoload = 0x4fc00480; +Cache_Config_L1_CORE1_ICache_Autoload = 0x4fc00484; +Cache_Enable_L1_CORE1_ICache_Autoload = 0x4fc00488; +Cache_Disable_L1_CORE1_ICache_Autoload = 0x4fc0048c; +Cache_Config_L1_DCache_Autoload = 0x4fc00490; +Cache_Enable_L1_DCache_Autoload = 0x4fc00494; +Cache_Disable_L1_DCache_Autoload = 0x4fc00498; +Cache_Config_L2_Cache_Autoload = 0x4fc0049c; +Cache_Enable_L2_Cache_Autoload = 0x4fc004a0; +Cache_Disable_L2_Cache_Autoload = 0x4fc004a4; +Cache_Enable_L1_CORE0_ICache_PreLock = 0x4fc004a8; +Cache_Disable_L1_CORE0_ICache_PreLock = 0x4fc004ac; +Cache_Enable_L1_CORE1_ICache_PreLock = 0x4fc004b0; +Cache_Disable_L1_CORE1_ICache_PreLock = 0x4fc004b4; +Cache_Enable_L1_DCache_PreLock = 0x4fc004b8; +Cache_Disable_L1_DCache_PreLock = 0x4fc004bc; +Cache_Enable_L2_Cache_PreLock = 0x4fc004c0; +Cache_Disable_L2_Cache_PreLock = 0x4fc004c4; +Cache_Lock_Addr = 0x4fc004c8; +Cache_Unlock_Addr = 0x4fc004cc; +Cache_Disable_L1_CORE0_ICache = 0x4fc004d0; +Cache_Enable_L1_CORE0_ICache = 0x4fc004d4; +Cache_Suspend_L1_CORE0_ICache = 0x4fc004d8; +Cache_Resume_L1_CORE0_ICache = 0x4fc004dc; +Cache_Disable_L1_CORE1_ICache = 0x4fc004e0; +Cache_Enable_L1_CORE1_ICache = 0x4fc004e4; +Cache_Suspend_L1_CORE1_ICache = 0x4fc004e8; +Cache_Resume_L1_CORE1_ICache = 0x4fc004ec; +Cache_Disable_L1_DCache = 0x4fc004f0; +Cache_Enable_L1_DCache = 0x4fc004f4; +Cache_Suspend_L1_DCache = 0x4fc004f8; +Cache_Resume_L1_DCache = 0x4fc004fc; +Cache_Disable_L2_Cache = 0x4fc00500; +Cache_Enable_L2_Cache = 0x4fc00504; +Cache_Suspend_L2_Cache = 0x4fc00508; +Cache_Resume_L2_Cache = 0x4fc0050c; +Cache_FLASH_MMU_Init = 0x4fc00510; +Cache_PSRAM_MMU_Init = 0x4fc00514; +Cache_FLASH_MMU_Set = 0x4fc00518; +Cache_FLASH_MMU_Set_Secure = 0x4fc0051c; +Cache_PSRAM_MMU_Set = 0x4fc00520; +Cache_PSRAM_MMU_Set_Secure = 0x4fc00524; +Cache_Count_Flash_Pages = 0x4fc00528; +Cache_Flash_To_SPIRAM_Copy = 0x4fc0052c; +Cache_Set_IDROM_MMU_Size = 0x4fc00530; +flash2spiram_instruction_offset = 0x4fc00534; +flash2spiram_rodata_offset = 0x4fc00538; +flash_instr_rodata_start_page = 0x4fc0053c; +flash_instr_rodata_end_page = 0x4fc00540; +Cache_Set_IDROM_MMU_Info = 0x4fc00544; +Cache_Get_IROM_MMU_End = 0x4fc00548; +Cache_Get_DROM_MMU_End = 0x4fc0054c; +/* Data (.data, .bss, .rodata) */ +rom_cache_op_cb = 0x4ffbffdc; +rom_cache_internal_table_ptr = 0x4ffbffd8; + + +/*************************************** + Group clock + ***************************************/ + +/* Functions */ +ets_clk_get_xtal_freq = 0x4fc00550; +ets_clk_get_cpu_freq = 0x4fc00554; + + +/*************************************** + Group gpio + ***************************************/ + +/* Functions */ +gpio_set_output_level = 0x4fc00558; +gpio_get_input_level = 0x4fc0055c; +gpio_matrix_in = 0x4fc00560; +gpio_matrix_out = 0x4fc00564; +gpio_bypass_matrix_in = 0x4fc00568; +/* gpio_output_disable = 0x4fc0056c; */ +/* gpio_output_enable = 0x4fc00570; */ +gpio_pad_input_disable = 0x4fc00574; +gpio_pad_input_enable = 0x4fc00578; +gpio_pad_pulldown = 0x4fc0057c; +gpio_pad_pullup = 0x4fc00580; +gpio_pad_select_gpio = 0x4fc00584; +gpio_pad_set_drv = 0x4fc00588; +gpio_pad_unhold = 0x4fc0058c; +gpio_pad_hold = 0x4fc00590; +gpio_lppad_select_mux = 0x4fc00594; +gpio_ded_pad_set_drv = 0x4fc00598; +gpio_ded_pad_pullup = 0x4fc0059c; +gpio_ded_pad_pulldown = 0x4fc005a0; +gpio_ded_pad_hold = 0x4fc005a4; +gpio_ded_pad_unhold = 0x4fc005a8; + + +/*************************************** + Group interrupts + ***************************************/ + +/* Functions */ +esprv_intc_int_set_priority = 0x4fc005ac; +esprv_intc_int_set_threshold = 0x4fc005b0; +esprv_intc_int_enable = 0x4fc005b4; +esprv_intc_int_disable = 0x4fc005b8; +esprv_intc_int_set_type = 0x4fc005bc; +PROVIDE( intr_handler_set = 0x4fc005c0 ); +intr_matrix_set = 0x4fc005c4; +ets_intr_lock = 0x4fc005c8; +ets_intr_unlock = 0x4fc005cc; +ets_isr_attach = 0x4fc005d0; +ets_isr_mask = 0x4fc005d4; +ets_isr_unmask = 0x4fc005d8; + + +/*************************************** + Group crypto + ***************************************/ + +/* Functions */ +md5_vector = 0x4fc005dc; +MD5Init = 0x4fc005e0; +MD5Update = 0x4fc005e4; +MD5Final = 0x4fc005e8; +crc32_le = 0x4fc005ec; +crc16_le = 0x4fc005f0; +crc8_le = 0x4fc005f4; +crc32_be = 0x4fc005f8; +crc16_be = 0x4fc005fc; +crc8_be = 0x4fc00600; +esp_crc8 = 0x4fc00604; +ets_sha_enable = 0x4fc00608; +ets_sha_disable = 0x4fc0060c; +ets_sha_get_state = 0x4fc00610; +ets_sha_init = 0x4fc00614; +ets_sha_process = 0x4fc00618; +ets_sha_starts = 0x4fc0061c; +ets_sha_update = 0x4fc00620; +ets_sha_finish = 0x4fc00624; +ets_sha_clone = 0x4fc00628; +ets_hmac_enable = 0x4fc0062c; +ets_hmac_disable = 0x4fc00630; +ets_hmac_calculate_message = 0x4fc00634; +ets_hmac_calculate_downstream = 0x4fc00638; +ets_hmac_invalidate_downstream = 0x4fc0063c; +ets_jtag_enable_temporarily = 0x4fc00640; +ets_aes_enable = 0x4fc00644; +ets_aes_disable = 0x4fc00648; +ets_aes_setkey = 0x4fc0064c; +ets_aes_block = 0x4fc00650; +ets_aes_setkey_dec = 0x4fc00654; +ets_aes_setkey_enc = 0x4fc00658; +ets_bigint_enable = 0x4fc0065c; +ets_bigint_disable = 0x4fc00660; +ets_bigint_multiply = 0x4fc00664; +ets_bigint_modmult = 0x4fc00668; +ets_bigint_modexp = 0x4fc0066c; +ets_bigint_wait_finish = 0x4fc00670; +ets_bigint_getz = 0x4fc00674; +ets_ds_enable = 0x4fc00678; +ets_ds_disable = 0x4fc0067c; +ets_ds_start_sign = 0x4fc00680; +ets_ds_is_busy = 0x4fc00684; +ets_ds_finish_sign = 0x4fc00688; +ets_ds_encrypt_params = 0x4fc0068c; +ets_mgf1_sha256 = 0x4fc00690; +/* Data (.data, .bss, .rodata) */ +crc32_le_table_ptr = 0x4fc1fff8; +crc16_le_table_ptr = 0x4fc1fff4; +crc8_le_table_ptr = 0x4fc1fff0; +crc32_be_table_ptr = 0x4fc1ffec; +crc16_be_table_ptr = 0x4fc1ffe8; +crc8_be_table_ptr = 0x4fc1ffe4; + + +/*************************************** + Group efuse + ***************************************/ + +/* Functions */ +ets_efuse_read = 0x4fc00694; +ets_efuse_program = 0x4fc00698; +ets_efuse_clear_program_registers = 0x4fc0069c; +ets_efuse_write_key = 0x4fc006a0; +ets_efuse_get_read_register_address = 0x4fc006a4; +ets_efuse_get_key_purpose = 0x4fc006a8; +ets_efuse_key_block_unused = 0x4fc006ac; +ets_efuse_find_unused_key_block = 0x4fc006b0; +ets_efuse_rs_calculate = 0x4fc006b4; +ets_efuse_count_unused_key_blocks = 0x4fc006b8; +ets_efuse_secure_boot_enabled = 0x4fc006bc; +ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4fc006c0; +ets_efuse_cache_encryption_enabled = 0x4fc006c4; +ets_efuse_download_modes_disabled = 0x4fc006c8; +ets_efuse_find_purpose = 0x4fc006cc; +ets_efuse_force_send_resume = 0x4fc006d0; +ets_efuse_get_flash_delay_us = 0x4fc006d4; +ets_efuse_get_uart_print_control = 0x4fc006d8; +ets_efuse_direct_boot_mode_disabled = 0x4fc006dc; +ets_efuse_security_download_modes_enabled = 0x4fc006e0; +ets_efuse_jtag_disabled = 0x4fc006e4; +ets_efuse_usb_print_is_disabled = 0x4fc006e8; +ets_efuse_usb_download_mode_disabled = 0x4fc006ec; +ets_efuse_usb_device_disabled = 0x4fc006f0; +ets_efuse_get_km_huk_gen_state = 0x4fc006f4; +ets_efuse_get_km_deploy_only_once = 0x4fc006f8; +ets_efuse_get_force_use_km_key = 0x4fc006fc; +ets_efuse_xts_key_length_256 = 0x4fc00700; +ets_efuse_get_km_key_lock = 0x4fc00704; + + +/*************************************** + Group key_mgr + ***************************************/ + +/* Functions */ +esp_rom_check_recover_key = 0x4fc00708; +esp_rom_km_huk_conf = 0x4fc0070c; +esp_rom_km_huk_risk = 0x4fc00710; + + +/*************************************** + Group secureboot + ***************************************/ + +/* Functions */ +ets_emsa_pss_verify = 0x4fc00714; +ets_rsa_pss_verify = 0x4fc00718; +ets_ecdsa_verify = 0x4fc0071c; +ets_secure_boot_verify_bootloader_with_keys = 0x4fc00720; +ets_secure_boot_verify_signature = 0x4fc00724; +ets_secure_boot_read_key_digests = 0x4fc00728; +ets_secure_boot_revoke_public_key_digest = 0x4fc0072c; + + +/*************************************** + Group usb_device_uart + ***************************************/ + +/* Functions */ +usb_serial_device_rx_one_char = 0x4fc008a4; +usb_serial_device_rx_one_char_block = 0x4fc008a8; +usb_serial_device_tx_flush = 0x4fc008ac; +usb_serial_device_tx_one_char = 0x4fc008b0; + + +/*************************************** + Group usb_dwcotg_uart + ***************************************/ + +/* Functions */ +Uart_Init_USB = 0x4fc008b4; +usb_serial_otg_rx_one_char = 0x4fc008b8; +usb_serial_otg_rx_one_char_block = 0x4fc008bc; +usb_serial_otg_tx_flush = 0x4fc008c0; +usb_serial_otg_tx_one_char = 0x4fc008c4; +/* Data (.data, .bss, .rodata) */ +uart_acm_dev = 0x4ffbffd4; + + +/*************************************** + Group usb_dwcotg_module + ***************************************/ + +/* Functions */ +cdc_acm_class_handle_req = 0x4fc008c8; +cdc_acm_init = 0x4fc008cc; +cdc_acm_fifo_fill = 0x4fc008d0; +cdc_acm_rx_fifo_cnt = 0x4fc008d4; +cdc_acm_fifo_read = 0x4fc008d8; +cdc_acm_irq_tx_enable = 0x4fc008dc; +cdc_acm_irq_tx_disable = 0x4fc008e0; +cdc_acm_irq_state_enable = 0x4fc008e4; +cdc_acm_irq_state_disable = 0x4fc008e8; +cdc_acm_irq_tx_ready = 0x4fc008ec; +cdc_acm_irq_rx_enable = 0x4fc008f0; +cdc_acm_irq_rx_disable = 0x4fc008f4; +cdc_acm_irq_rx_ready = 0x4fc008f8; +cdc_acm_irq_is_pending = 0x4fc008fc; +cdc_acm_irq_callback_set = 0x4fc00900; +cdc_acm_line_ctrl_set = 0x4fc00904; +cdc_acm_line_ctrl_get = 0x4fc00908; +cdc_acm_poll_out = 0x4fc0090c; +chip_usb_dw_did_persist = 0x4fc00910; +chip_usb_dw_init = 0x4fc00914; +chip_usb_detach = 0x4fc00918; +chip_usb_dw_prepare_persist = 0x4fc0091c; +chip_usb_get_persist_flags = 0x4fc00920; +chip_usb_set_persist_flags = 0x4fc00924; +cpio_start = 0x4fc00928; +cpio_feed = 0x4fc0092c; +cpio_done = 0x4fc00930; +cpio_destroy = 0x4fc00934; +dfu_flash_init = 0x4fc00938; +dfu_flash_erase = 0x4fc0093c; +dfu_flash_program = 0x4fc00940; +dfu_flash_read = 0x4fc00944; +dfu_flash_attach = 0x4fc00948; +dfu_cpio_callback = 0x4fc0094c; +dfu_updater_get_err = 0x4fc00950; +dfu_updater_clear_err = 0x4fc00954; +dfu_updater_enable = 0x4fc00958; +dfu_updater_begin = 0x4fc0095c; +dfu_updater_feed = 0x4fc00960; +dfu_updater_end = 0x4fc00964; +dfu_updater_set_raw_addr = 0x4fc00968; +dfu_updater_flash_read = 0x4fc0096c; +usb_dc_prepare_persist = 0x4fc00970; +usb_dw_isr_handler = 0x4fc00974; +usb_dc_attach = 0x4fc00978; +usb_dc_detach = 0x4fc0097c; +usb_dc_reset = 0x4fc00980; +usb_dc_set_address = 0x4fc00984; +usb_dc_ep_check_cap = 0x4fc00988; +usb_dc_ep_configure = 0x4fc0098c; +usb_dc_ep_set_stall = 0x4fc00990; +usb_dc_ep_clear_stall = 0x4fc00994; +usb_dc_ep_halt = 0x4fc00998; +usb_dc_ep_is_stalled = 0x4fc0099c; +usb_dc_ep_enable = 0x4fc009a0; +usb_dc_ep_disable = 0x4fc009a4; +usb_dc_ep_flush = 0x4fc009a8; +usb_dc_ep_write_would_block = 0x4fc009ac; +usb_dc_ep_write = 0x4fc009b0; +usb_dc_ep_read_wait = 0x4fc009b4; +usb_dc_ep_read_continue = 0x4fc009b8; +usb_dc_ep_read = 0x4fc009bc; +usb_dc_ep_set_callback = 0x4fc009c0; +usb_dc_set_status_callback = 0x4fc009c4; +usb_dc_ep_mps = 0x4fc009c8; +usb_dc_check_poll_for_interrupts = 0x4fc009cc; +mac_addr_to_serial_str_desc = 0x4fc009d0; +usb_set_current_descriptor = 0x4fc009d4; +usb_get_descriptor = 0x4fc009d8; +usb_dev_resume = 0x4fc009dc; +usb_dev_get_configuration = 0x4fc009e0; +usb_set_config = 0x4fc009e4; +usb_deconfig = 0x4fc009e8; +usb_enable = 0x4fc009ec; +usb_disable = 0x4fc009f0; +usb_write_would_block = 0x4fc009f4; +usb_write = 0x4fc009f8; +usb_read = 0x4fc009fc; +usb_ep_set_stall = 0x4fc00a00; +usb_ep_clear_stall = 0x4fc00a04; +usb_ep_read_wait = 0x4fc00a08; +usb_ep_read_continue = 0x4fc00a0c; +usb_transfer_ep_callback = 0x4fc00a10; +usb_transfer = 0x4fc00a14; +usb_cancel_transfer = 0x4fc00a18; +usb_transfer_sync = 0x4fc00a1c; +usb_dfu_set_detach_cb = 0x4fc00a20; +dfu_class_handle_req = 0x4fc00a24; +dfu_status_cb = 0x4fc00a28; +dfu_custom_handle_req = 0x4fc00a2c; +usb_dfu_init = 0x4fc00a30; +usb_dfu_force_detach = 0x4fc00a34; +usb_dev_deinit = 0x4fc00a38; +usb_dw_ctrl_deinit = 0x4fc00a3c; +/* Data (.data, .bss, .rodata) */ +s_usb_osglue = 0x4ffbffc8; + + +/*************************************** + Group recovery_bootloader + ***************************************/ + +/* Functions */ +ets_get_bootloader_offset = 0x4fc00a40; +ets_set_bootloader_offset = 0x4fc00a44; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld new file mode 100644 index 00000000000..7dcac301e9e --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32p4.rom.libgcc.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 + * + * Compatible with ROM where ECO version equal or greater to 5. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group libgccdf + ***************************************/ + +/* Functions */ +__absvdi2 = 0x4fc00730; +__absvsi2 = 0x4fc00734; +__adddf3 = 0x4fc00738; +__addvdi3 = 0x4fc0073c; +__addvsi3 = 0x4fc00740; +__ashldi3 = 0x4fc00744; +__ashrdi3 = 0x4fc00748; +__bswapdi2 = 0x4fc0074c; +__bswapsi2 = 0x4fc00750; +__clear_cache = 0x4fc00754; +__clrsbdi2 = 0x4fc00758; +__clrsbsi2 = 0x4fc0075c; +__clzdi2 = 0x4fc00760; +__clzsi2 = 0x4fc00764; +__cmpdi2 = 0x4fc00768; +__ctzdi2 = 0x4fc0076c; +__ctzsi2 = 0x4fc00770; +__divdc3 = 0x4fc00774; +__divdf3 = 0x4fc00778; +__divdi3 = 0x4fc0077c; +__divsc3 = 0x4fc00780; +__divsi3 = 0x4fc00784; +__eqdf2 = 0x4fc00788; +__extendsfdf2 = 0x4fc0078c; +__ffsdi2 = 0x4fc00790; +__ffssi2 = 0x4fc00794; +__fixdfdi = 0x4fc00798; +__fixdfsi = 0x4fc0079c; +__fixsfdi = 0x4fc007a0; +__fixunsdfsi = 0x4fc007a4; +__fixunssfdi = 0x4fc007a8; +__fixunssfsi = 0x4fc007ac; +__floatdidf = 0x4fc007b0; +__floatdisf = 0x4fc007b4; +__floatsidf = 0x4fc007b8; +__floatundidf = 0x4fc007bc; +__floatundisf = 0x4fc007c0; +__floatunsidf = 0x4fc007c4; +__gcc_bcmp = 0x4fc007c8; +__gedf2 = 0x4fc007cc; +__gtdf2 = 0x4fc007d0; +__ledf2 = 0x4fc007d4; +__lshrdi3 = 0x4fc007d8; +__ltdf2 = 0x4fc007dc; +__moddi3 = 0x4fc007e0; +__modsi3 = 0x4fc007e4; +__muldc3 = 0x4fc007e8; +__muldf3 = 0x4fc007ec; +__muldi3 = 0x4fc007f0; +__mulsc3 = 0x4fc007f4; +__mulsi3 = 0x4fc007f8; +__mulvdi3 = 0x4fc007fc; +__mulvsi3 = 0x4fc00800; +__nedf2 = 0x4fc00804; +__negdf2 = 0x4fc00808; +__negdi2 = 0x4fc0080c; +__negvdi2 = 0x4fc00810; +__negvsi2 = 0x4fc00814; +__paritysi2 = 0x4fc00818; +__popcountdi2 = 0x4fc0081c; +__popcountsi2 = 0x4fc00820; +__powidf2 = 0x4fc00824; +__subdf3 = 0x4fc00828; +__subvdi3 = 0x4fc0082c; +__subvsi3 = 0x4fc00830; +__ucmpdi2 = 0x4fc00834; +__udivdi3 = 0x4fc00838; +__udivmoddi4 = 0x4fc0083c; +__udivsi3 = 0x4fc00840; +__udiv_w_sdiv = 0x4fc00844; +__umoddi3 = 0x4fc00848; +__umodsi3 = 0x4fc0084c; +__unorddf2 = 0x4fc00850; +__extenddftf2 = 0x4fc00854; +__trunctfdf2 = 0x4fc00858; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld new file mode 100644 index 00000000000..05749d8a4d5 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld @@ -0,0 +1,101 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32p4.rom.rvfp.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 + * + * Compatible with ROM where ECO version equal or greater to 5. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rvfplibdf + ***************************************/ + +/* Functions */ +__adddf3 = 0x4fc0085c; +__eqdf2 = 0x4fc00860; +__fixdfdi = 0x4fc00864; +__fixdfsi = 0x4fc00868; +__fixunsdfsi = 0x4fc00870; +__floatdidf = 0x4fc00878; +__floatsidf = 0x4fc0087c; +__floatundidf = 0x4fc00880; +__floatunsidf = 0x4fc00884; +__gedf2 = 0x4fc00888; +__gtdf2 = 0x4fc0088c; +__ledf2 = 0x4fc00890; +__ltdf2 = 0x4fc00894; +__muldf3 = 0x4fc00898; +__nedf2 = 0x4fc0089c; +__subdf3 = 0x4fc008a0; + +/*************************************** + Group libgcc +***************************************/ + +/* Functions */ +__absvdi2 = 0x4fc00730; +__absvsi2 = 0x4fc00734; +__addvdi3 = 0x4fc0073c; +__addvsi3 = 0x4fc00740; +__ashldi3 = 0x4fc00744; +__ashrdi3 = 0x4fc00748; +__bswapdi2 = 0x4fc0074c; +__bswapsi2 = 0x4fc00750; +__clear_cache = 0x4fc00754; +__clrsbdi2 = 0x4fc00758; +__clrsbsi2 = 0x4fc0075c; +__clzdi2 = 0x4fc00760; +__clzsi2 = 0x4fc00764; +__cmpdi2 = 0x4fc00768; +__ctzdi2 = 0x4fc0076c; +__ctzsi2 = 0x4fc00770; +__divdc3 = 0x4fc00774; +__divdf3 = 0x4fc00778; +__divdi3 = 0x4fc0077c; +__divsc3 = 0x4fc00780; +__divsi3 = 0x4fc00784; +__extendsfdf2 = 0x4fc0078c; +__ffsdi2 = 0x4fc00790; +__ffssi2 = 0x4fc00794; +__fixsfdi = 0x4fc007a0; +__fixunssfdi = 0x4fc007a8; +__fixunssfsi = 0x4fc007ac; +__floatdisf = 0x4fc007b4; +__floatundisf = 0x4fc007c0; +__gcc_bcmp = 0x4fc007c8; +__lshrdi3 = 0x4fc007d8; +__moddi3 = 0x4fc007e0; +__modsi3 = 0x4fc007e4; +__muldc3 = 0x4fc007e8; +__muldi3 = 0x4fc007f0; +__mulsc3 = 0x4fc007f4; +__mulsi3 = 0x4fc007f8; +__mulvdi3 = 0x4fc007fc; +__mulvsi3 = 0x4fc00800; +__negdf2 = 0x4fc00808; +__negdi2 = 0x4fc0080c; +__negvdi2 = 0x4fc00810; +__negvsi2 = 0x4fc00814; +__paritysi2 = 0x4fc00818; +__popcountdi2 = 0x4fc0081c; +__popcountsi2 = 0x4fc00820; +__powidf2 = 0x4fc00824; +__subvdi3 = 0x4fc0082c; +__subvsi3 = 0x4fc00830; +__ucmpdi2 = 0x4fc00834; +__udivdi3 = 0x4fc00838; +__udivmoddi4 = 0x4fc0083c; +__udivsi3 = 0x4fc00840; +__udiv_w_sdiv = 0x4fc00844; +__umoddi3 = 0x4fc00848; +__umodsi3 = 0x4fc0084c; +__unorddf2 = 0x4fc00850; +__extenddftf2 = 0x4fc00854; +__trunctfdf2 = 0x4fc00858; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld new file mode 100644 index 00000000000..b9950412e06 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld @@ -0,0 +1,585 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32p4.rom.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group common + ***************************************/ + +/* Functions */ +rtc_get_reset_reason = 0x4fc00018; +rtc_get_wakeup_cause = 0x4fc0001c; +pmu_enable_unhold_pads = 0x4fc00020; +ets_printf = 0x4fc00024; +ets_install_putc1 = 0x4fc00028; +ets_install_putc2 = 0x4fc0002c; +ets_install_uart_printf = 0x4fc00030; +ets_install_usb_printf = 0x4fc00034; +ets_get_printf_channel = 0x4fc00038; +ets_delay_us = 0x4fc0003c; +ets_get_cpu_frequency = 0x4fc00040; +ets_update_cpu_frequency = 0x4fc00044; +ets_install_lock = 0x4fc00048; +UartRxString = 0x4fc0004c; +UartGetCmdLn = 0x4fc00050; +uart_tx_one_char = 0x4fc00054; +uart_tx_one_char2 = 0x4fc00058; +uart_tx_one_char3 = 0x4fc0005c; +uart_rx_one_char = 0x4fc00060; +uart_rx_one_char_block = 0x4fc00064; +uart_rx_intr_handler = 0x4fc00068; +uart_rx_readbuff = 0x4fc0006c; +uartAttach = 0x4fc00070; +uart_tx_flush = 0x4fc00074; +uart_tx_wait_idle = 0x4fc00078; +uart_div_modify = 0x4fc0007c; +ets_write_char_uart = 0x4fc00080; +uart_tx_switch = 0x4fc00084; +uart_buff_switch = 0x4fc00088; +roundup2 = 0x4fc0008c; +multofup = 0x4fc00090; +software_reset = 0x4fc00094; +software_reset_cpu = 0x4fc00098; +ets_clk_assist_debug_clock_enable = 0x4fc0009c; +clear_super_wdt_reset_flag = 0x4fc000a0; +disable_default_watchdog = 0x4fc000a4; +ets_set_appcpu_boot_addr = 0x4fc000a8; +send_packet = 0x4fc000ac; +recv_packet = 0x4fc000b0; +GetUartDevice = 0x4fc000b4; +UartDwnLdProc = 0x4fc000b8; +GetSecurityInfoProc = 0x4fc000bc; +Uart_Init = 0x4fc000c0; +ets_set_user_start = 0x4fc000c4; +/* Data (.data, .bss, .rodata) */ +ets_rom_layout_p = 0x4fc1fffc; +ets_ops_table_ptr = 0x4ff3fff4; +g_saved_pc = 0x4ff3fff8; + + +/*************************************** + Group miniz + ***************************************/ + +/* Functions */ +mz_adler32 = 0x4fc000c8; +mz_free = 0x4fc000cc; +tdefl_compress = 0x4fc000d0; +tdefl_compress_buffer = 0x4fc000d4; +tdefl_compress_mem_to_heap = 0x4fc000d8; +tdefl_compress_mem_to_mem = 0x4fc000dc; +tdefl_compress_mem_to_output = 0x4fc000e0; +tdefl_get_adler32 = 0x4fc000e4; +tdefl_get_prev_return_status = 0x4fc000e8; +tdefl_init = 0x4fc000ec; +tdefl_write_image_to_png_file_in_memory = 0x4fc000f0; +tdefl_write_image_to_png_file_in_memory_ex = 0x4fc000f4; +tinfl_decompress = 0x4fc000f8; +tinfl_decompress_mem_to_callback = 0x4fc000fc; +tinfl_decompress_mem_to_heap = 0x4fc00100; +tinfl_decompress_mem_to_mem = 0x4fc00104; + + +/*************************************** + Group spi_extmem_common + ***************************************/ + +/* Functions */ +esp_rom_spi_cmd_config = 0x4fc00108; +esp_rom_spi_cmd_start = 0x4fc0010c; +esp_rom_spi_set_op_mode = 0x4fc00110; +esp_rom_spi_set_dtr_swap_mode = 0x4fc00114; + + +/*************************************** + Group spiflash_legacy + ***************************************/ + +/* Functions */ +esp_rom_spiflash_wait_idle = 0x4fc00118; +esp_rom_spiflash_write_encrypted = 0x4fc0011c; +esp_rom_spiflash_write_encrypted_dest = 0x4fc00120; +esp_rom_spiflash_write_encrypted_enable = 0x4fc00124; +esp_rom_spiflash_write_encrypted_disable = 0x4fc00128; +esp_rom_spiflash_erase_chip = 0x4fc0012c; +_esp_rom_spiflash_erase_sector = 0x4fc00130; +_esp_rom_spiflash_erase_block = 0x4fc00134; +_esp_rom_spiflash_write = 0x4fc00138; +_esp_rom_spiflash_read = 0x4fc0013c; +_esp_rom_spiflash_unlock = 0x4fc00140; +_SPIEraseArea = 0x4fc00144; +_SPI_write_enable = 0x4fc00148; +esp_rom_spiflash_erase_sector = 0x4fc0014c; +esp_rom_spiflash_erase_block = 0x4fc00150; +esp_rom_spiflash_write = 0x4fc00154; +esp_rom_spiflash_read = 0x4fc00158; +esp_rom_spiflash_unlock = 0x4fc0015c; +SPIEraseArea = 0x4fc00160; +SPI_write_enable = 0x4fc00164; +esp_rom_spiflash_config_param = 0x4fc00168; +esp_rom_spiflash_read_user_cmd = 0x4fc0016c; +esp_rom_spiflash_select_qio_pins = 0x4fc00170; +esp_rom_spi_flash_auto_sus_res = 0x4fc00174; +esp_rom_spi_flash_send_resume = 0x4fc00178; +esp_rom_spi_flash_update_id = 0x4fc0017c; +esp_rom_spiflash_config_clk = 0x4fc00180; +esp_rom_spiflash_config_readmode = 0x4fc00184; +esp_rom_spiflash_read_status = 0x4fc00188; +esp_rom_spiflash_read_statushigh = 0x4fc0018c; +esp_rom_spiflash_write_status = 0x4fc00190; +esp_rom_spiflash_write_disable = 0x4fc00194; +spi_cache_mode_switch = 0x4fc00198; +spi_common_set_dummy_output = 0x4fc0019c; +spi_common_set_flash_cs_timing = 0x4fc001a0; +esp_rom_spi_set_address_bit_len = 0x4fc001a4; +SPILock = 0x4fc001a8; +SPIMasterReadModeCnfig = 0x4fc001ac; +SPI_Common_Command = 0x4fc001b0; +SPI_WakeUp = 0x4fc001b4; +SPI_block_erase = 0x4fc001b8; +SPI_chip_erase = 0x4fc001bc; +SPI_init = 0x4fc001c0; +SPI_page_program = 0x4fc001c4; +SPI_read_data = 0x4fc001c8; +SPI_sector_erase = 0x4fc001cc; +SelectSpiFunction = 0x4fc001d0; +SetSpiDrvs = 0x4fc001d4; +Wait_SPI_Idle = 0x4fc001d8; +spi_dummy_len_fix = 0x4fc001dc; +Disable_QMode = 0x4fc001e0; +Enable_QMode = 0x4fc001e4; +spi_flash_attach = 0x4fc001e8; +spi_flash_get_chip_size = 0x4fc001ec; +spi_flash_guard_set = 0x4fc001f0; +spi_flash_guard_get = 0x4fc001f4; +spi_flash_read_encrypted = 0x4fc001f8; +/* Data (.data, .bss, .rodata) */ +rom_spiflash_legacy_funcs = 0x4ff3ffec; +rom_spiflash_legacy_data = 0x4ff3ffe8; +g_flash_guard_ops = 0x4ff3fff0; + + +/*************************************** + Group cache + ***************************************/ + +/* Functions */ +Cache_Get_L1_ICache_Line_Size = 0x4fc003c4; +Cache_Get_L1_DCache_Line_Size = 0x4fc003c8; +Cache_Get_L2_Cache_Line_Size = 0x4fc003cc; +Cache_Get_Mode = 0x4fc003d0; +Cache_Set_L2_Cache_Mode = 0x4fc003d4; +Cache_Address_Through_Cache = 0x4fc003d8; +ROM_Boot_Cache_Init = 0x4fc003dc; +Cache_Sync_Addr = 0x4fc003e0; +Cache_Invalidate_Addr = 0x4fc003e4; +Cache_Invalidate_Addr_Gid = 0x4fc003e8; +Cache_Clean_Addr = 0x4fc003ec; +Cache_Clean_Addr_Gid = 0x4fc003f0; +Cache_WriteBack_Addr = 0x4fc003f4; +Cache_WriteBack_Addr_Gid = 0x4fc003f8; +Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; +Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; +Cache_Invalidate_All = 0x4fc00404; +Cache_Invalidate_All_Gid = 0x4fc00408; +Cache_Clean_All = 0x4fc0040c; +Cache_Clean_All_Gid = 0x4fc00410; +Cache_WriteBack_All = 0x4fc00414; +Cache_WriteBack_All_Gid = 0x4fc00418; +Cache_WriteBack_Invalidate_All = 0x4fc0041c; +Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; +Cache_Mask_All = 0x4fc00424; +Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; +Cache_Resume_L1_CORE0_ICache_Autoload = 0x4fc0042c; +Cache_Suspend_L1_CORE1_ICache_Autoload = 0x4fc00430; +Cache_Resume_L1_CORE1_ICache_Autoload = 0x4fc00434; +Cache_Suspend_L1_DCache_Autoload = 0x4fc00438; +Cache_Resume_L1_DCache_Autoload = 0x4fc0043c; +Cache_Suspend_L2_Cache_Autoload = 0x4fc00440; +Cache_Resume_L2_Cache_Autoload = 0x4fc00444; +Cache_Start_L1_CORE0_ICache_Preload = 0x4fc00448; +Cache_L1_CORE0_ICache_Preload_Done = 0x4fc0044c; +Cache_End_L1_CORE0_ICache_Preload = 0x4fc00450; +Cache_Start_L1_CORE1_ICache_Preload = 0x4fc00454; +Cache_L1_CORE1_ICache_Preload_Done = 0x4fc00458; +Cache_End_L1_CORE1_ICache_Preload = 0x4fc0045c; +Cache_Start_L1_DCache_Preload = 0x4fc00460; +Cache_L1_DCache_Preload_Done = 0x4fc00464; +Cache_End_L1_DCache_Preload = 0x4fc00468; +Cache_Start_L2_Cache_Preload = 0x4fc0046c; +Cache_L2_Cache_Preload_Done = 0x4fc00470; +Cache_End_L2_Cache_Preload = 0x4fc00474; +Cache_Config_L1_CORE0_ICache_Autoload = 0x4fc00478; +Cache_Enable_L1_CORE0_ICache_Autoload = 0x4fc0047c; +Cache_Disable_L1_CORE0_ICache_Autoload = 0x4fc00480; +Cache_Config_L1_CORE1_ICache_Autoload = 0x4fc00484; +Cache_Enable_L1_CORE1_ICache_Autoload = 0x4fc00488; +Cache_Disable_L1_CORE1_ICache_Autoload = 0x4fc0048c; +Cache_Config_L1_DCache_Autoload = 0x4fc00490; +Cache_Enable_L1_DCache_Autoload = 0x4fc00494; +Cache_Disable_L1_DCache_Autoload = 0x4fc00498; +Cache_Config_L2_Cache_Autoload = 0x4fc0049c; +Cache_Enable_L2_Cache_Autoload = 0x4fc004a0; +Cache_Disable_L2_Cache_Autoload = 0x4fc004a4; +Cache_Enable_L1_CORE0_ICache_PreLock = 0x4fc004a8; +Cache_Disable_L1_CORE0_ICache_PreLock = 0x4fc004ac; +Cache_Enable_L1_CORE1_ICache_PreLock = 0x4fc004b0; +Cache_Disable_L1_CORE1_ICache_PreLock = 0x4fc004b4; +Cache_Enable_L1_DCache_PreLock = 0x4fc004b8; +Cache_Disable_L1_DCache_PreLock = 0x4fc004bc; +Cache_Enable_L2_Cache_PreLock = 0x4fc004c0; +Cache_Disable_L2_Cache_PreLock = 0x4fc004c4; +Cache_Lock_Addr = 0x4fc004c8; +Cache_Unlock_Addr = 0x4fc004cc; +Cache_Disable_L1_CORE0_ICache = 0x4fc004d0; +Cache_Enable_L1_CORE0_ICache = 0x4fc004d4; +Cache_Suspend_L1_CORE0_ICache = 0x4fc004d8; +Cache_Resume_L1_CORE0_ICache = 0x4fc004dc; +Cache_Disable_L1_CORE1_ICache = 0x4fc004e0; +Cache_Enable_L1_CORE1_ICache = 0x4fc004e4; +Cache_Suspend_L1_CORE1_ICache = 0x4fc004e8; +Cache_Resume_L1_CORE1_ICache = 0x4fc004ec; +Cache_Disable_L1_DCache = 0x4fc004f0; +Cache_Enable_L1_DCache = 0x4fc004f4; +Cache_Suspend_L1_DCache = 0x4fc004f8; +Cache_Resume_L1_DCache = 0x4fc004fc; +Cache_Disable_L2_Cache = 0x4fc00500; +Cache_Enable_L2_Cache = 0x4fc00504; +Cache_Suspend_L2_Cache = 0x4fc00508; +Cache_Resume_L2_Cache = 0x4fc0050c; +Cache_FLASH_MMU_Init = 0x4fc00510; +Cache_PSRAM_MMU_Init = 0x4fc00514; +Cache_FLASH_MMU_Set = 0x4fc00518; +Cache_FLASH_MMU_Set_Secure = 0x4fc0051c; +Cache_PSRAM_MMU_Set = 0x4fc00520; +Cache_PSRAM_MMU_Set_Secure = 0x4fc00524; +Cache_Count_Flash_Pages = 0x4fc00528; +Cache_Flash_To_SPIRAM_Copy = 0x4fc0052c; +Cache_Travel_Tag_Memory = 0x4fc00530; +Cache_Travel_Tag_Memory2 = 0x4fc00534; +Cache_Get_Virtual_Addr = 0x4fc00538; +Cache_Set_IDROM_MMU_Size = 0x4fc0053c; +flash2spiram_instruction_offset = 0x4fc00540; +flash2spiram_rodata_offset = 0x4fc00544; +flash_instr_rodata_start_page = 0x4fc00548; +flash_instr_rodata_end_page = 0x4fc0054c; +Cache_Set_IDROM_MMU_Info = 0x4fc00550; +Cache_Get_IROM_MMU_End = 0x4fc00554; +Cache_Get_DROM_MMU_End = 0x4fc00558; +/* Data (.data, .bss, .rodata) */ +rom_cache_op_cb = 0x4ff3ffdc; +rom_cache_internal_table_ptr = 0x4ff3ffd8; + + +/*************************************** + Group clock + ***************************************/ + +/* Functions */ +ets_clk_get_xtal_freq = 0x4fc0055c; +ets_clk_get_cpu_freq = 0x4fc00560; + + +/*************************************** + Group gpio + ***************************************/ + +/* Functions */ +gpio_set_output_level = 0x4fc00564; +gpio_get_input_level = 0x4fc00568; +gpio_matrix_in = 0x4fc0056c; +gpio_matrix_out = 0x4fc00570; +gpio_bypass_matrix_in = 0x4fc00574; +/* gpio_output_disable = 0x4fc00578; */ +/* gpio_output_enable = 0x4fc0057c; */ +gpio_pad_input_disable = 0x4fc00580; +gpio_pad_input_enable = 0x4fc00584; +gpio_pad_pulldown = 0x4fc00588; +gpio_pad_pullup = 0x4fc0058c; +gpio_pad_select_gpio = 0x4fc00590; +gpio_pad_set_drv = 0x4fc00594; +gpio_pad_unhold = 0x4fc00598; +gpio_pad_hold = 0x4fc0059c; +gpio_lppad_select_mux = 0x4fc005a0; +gpio_ded_pad_set_drv = 0x4fc005a4; +gpio_ded_pad_pullup = 0x4fc005a8; +gpio_ded_pad_pulldown = 0x4fc005ac; +gpio_ded_pad_hold = 0x4fc005b0; +gpio_ded_pad_unhold = 0x4fc005b4; + + +/*************************************** + Group interrupts + ***************************************/ + +/* Functions */ +esprv_intc_int_set_priority = 0x4fc005b8; +esprv_intc_int_set_threshold = 0x4fc005bc; +esprv_intc_int_enable = 0x4fc005c0; +esprv_intc_int_disable = 0x4fc005c4; +PROVIDE( intr_handler_set = 0x4fc005cc ); +intr_matrix_set = 0x4fc005d0; +ets_intr_lock = 0x4fc005d4; +ets_intr_unlock = 0x4fc005d8; +ets_isr_attach = 0x4fc005dc; +ets_isr_mask = 0x4fc005e0; +ets_isr_unmask = 0x4fc005e4; + + +/*************************************** + Group crypto + ***************************************/ + +/* Functions */ +md5_vector = 0x4fc005e8; +MD5Init = 0x4fc005ec; +MD5Update = 0x4fc005f0; +MD5Final = 0x4fc005f4; +crc32_le = 0x4fc005f8; +crc16_le = 0x4fc005fc; +crc8_le = 0x4fc00600; +crc32_be = 0x4fc00604; +crc16_be = 0x4fc00608; +crc8_be = 0x4fc0060c; +esp_crc8 = 0x4fc00610; +ets_sha_enable = 0x4fc00614; +ets_sha_disable = 0x4fc00618; +ets_sha_get_state = 0x4fc0061c; +ets_sha_init = 0x4fc00620; +ets_sha_process = 0x4fc00624; +ets_sha_starts = 0x4fc00628; +ets_sha_update = 0x4fc0062c; +ets_sha_finish = 0x4fc00630; +ets_sha_clone = 0x4fc00634; +ets_hmac_enable = 0x4fc00638; +ets_hmac_disable = 0x4fc0063c; +ets_hmac_calculate_message = 0x4fc00640; +ets_hmac_calculate_downstream = 0x4fc00644; +ets_hmac_invalidate_downstream = 0x4fc00648; +ets_jtag_enable_temporarily = 0x4fc0064c; +ets_aes_enable = 0x4fc00650; +ets_aes_disable = 0x4fc00654; +ets_aes_setkey = 0x4fc00658; +ets_aes_block = 0x4fc0065c; +ets_aes_setkey_dec = 0x4fc00660; +ets_aes_setkey_enc = 0x4fc00664; +ets_bigint_enable = 0x4fc00668; +ets_bigint_disable = 0x4fc0066c; +ets_bigint_multiply = 0x4fc00670; +ets_bigint_modmult = 0x4fc00674; +ets_bigint_modexp = 0x4fc00678; +ets_bigint_wait_finish = 0x4fc0067c; +ets_bigint_getz = 0x4fc00680; +ets_ds_enable = 0x4fc00684; +ets_ds_disable = 0x4fc00688; +ets_ds_start_sign = 0x4fc0068c; +ets_ds_is_busy = 0x4fc00690; +ets_ds_finish_sign = 0x4fc00694; +ets_ds_encrypt_params = 0x4fc00698; +ets_mgf1_sha256 = 0x4fc0069c; +/* Data (.data, .bss, .rodata) */ +crc32_le_table_ptr = 0x4fc1fff8; +crc16_le_table_ptr = 0x4fc1fff4; +crc8_le_table_ptr = 0x4fc1fff0; +crc32_be_table_ptr = 0x4fc1ffec; +crc16_be_table_ptr = 0x4fc1ffe8; +crc8_be_table_ptr = 0x4fc1ffe4; + + +/*************************************** + Group efuse + ***************************************/ + +/* Functions */ +ets_efuse_read = 0x4fc006a0; +ets_efuse_program = 0x4fc006a4; +ets_efuse_clear_program_registers = 0x4fc006a8; +ets_efuse_write_key = 0x4fc006ac; +ets_efuse_get_read_register_address = 0x4fc006b0; +ets_efuse_get_key_purpose = 0x4fc006b4; +ets_efuse_key_block_unused = 0x4fc006b8; +ets_efuse_find_unused_key_block = 0x4fc006bc; +ets_efuse_rs_calculate = 0x4fc006c0; +ets_efuse_count_unused_key_blocks = 0x4fc006c4; +ets_efuse_secure_boot_enabled = 0x4fc006c8; +ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4fc006cc; +ets_efuse_cache_encryption_enabled = 0x4fc006d0; +ets_efuse_download_modes_disabled = 0x4fc006d4; +ets_efuse_find_purpose = 0x4fc006d8; +ets_efuse_force_send_resume = 0x4fc006dc; +ets_efuse_get_flash_delay_us = 0x4fc006e0; +ets_efuse_get_uart_print_control = 0x4fc006e4; +ets_efuse_direct_boot_mode_disabled = 0x4fc006e8; +ets_efuse_security_download_modes_enabled = 0x4fc006ec; +ets_efuse_jtag_disabled = 0x4fc006f0; +ets_efuse_usb_print_is_disabled = 0x4fc006f4; +ets_efuse_usb_download_mode_disabled = 0x4fc006f8; +ets_efuse_usb_device_disabled = 0x4fc006fc; +ets_efuse_get_km_huk_gen_state = 0x4fc00700; +ets_efuse_get_km_deploy_only_once = 0x4fc00704; +ets_efuse_get_force_use_km_key = 0x4fc00708; +ets_efuse_xts_key_length_256 = 0x4fc0070c; +ets_efuse_get_km_key_lock = 0x4fc00710; + + +/*************************************** + Group key_mgr + ***************************************/ + +/* Functions */ +esp_rom_check_recover_key = 0x4fc00714; +esp_rom_km_huk_conf = 0x4fc00718; +esp_rom_km_huk_risk = 0x4fc0071c; + + +/*************************************** + Group secureboot + ***************************************/ + +/* Functions */ +ets_emsa_pss_verify = 0x4fc00720; +ets_rsa_pss_verify = 0x4fc00724; +ets_ecdsa_verify = 0x4fc00728; +ets_secure_boot_verify_bootloader_with_keys = 0x4fc0072c; +ets_secure_boot_verify_signature = 0x4fc00730; +ets_secure_boot_read_key_digests = 0x4fc00734; +ets_secure_boot_revoke_public_key_digest = 0x4fc00738; + + +/*************************************** + Group usb_device_uart + ***************************************/ + +/* Functions */ +usb_serial_device_rx_one_char = 0x4fc008b0; +usb_serial_device_rx_one_char_block = 0x4fc008b4; +usb_serial_device_tx_flush = 0x4fc008b8; +usb_serial_device_tx_one_char = 0x4fc008bc; + + +/*************************************** + Group usb_dwcotg_uart + ***************************************/ + +/* Functions */ +Uart_Init_USB = 0x4fc008c0; +usb_serial_otg_rx_one_char = 0x4fc008c4; +usb_serial_otg_rx_one_char_block = 0x4fc008c8; +usb_serial_otg_tx_flush = 0x4fc008cc; +usb_serial_otg_tx_one_char = 0x4fc008d0; +/* Data (.data, .bss, .rodata) */ +uart_acm_dev = 0x4ff3ffd4; + + +/*************************************** + Group usb_dwcotg_module + ***************************************/ + +/* Functions */ +cdc_acm_class_handle_req = 0x4fc008d4; +cdc_acm_init = 0x4fc008d8; +cdc_acm_fifo_fill = 0x4fc008dc; +cdc_acm_rx_fifo_cnt = 0x4fc008e0; +cdc_acm_fifo_read = 0x4fc008e4; +cdc_acm_irq_tx_enable = 0x4fc008e8; +cdc_acm_irq_tx_disable = 0x4fc008ec; +cdc_acm_irq_state_enable = 0x4fc008f0; +cdc_acm_irq_state_disable = 0x4fc008f4; +cdc_acm_irq_tx_ready = 0x4fc008f8; +cdc_acm_irq_rx_enable = 0x4fc008fc; +cdc_acm_irq_rx_disable = 0x4fc00900; +cdc_acm_irq_rx_ready = 0x4fc00904; +cdc_acm_irq_is_pending = 0x4fc00908; +cdc_acm_irq_callback_set = 0x4fc0090c; +cdc_acm_line_ctrl_set = 0x4fc00910; +cdc_acm_line_ctrl_get = 0x4fc00914; +cdc_acm_poll_out = 0x4fc00918; +chip_usb_dw_did_persist = 0x4fc0091c; +chip_usb_dw_init = 0x4fc00920; +chip_usb_detach = 0x4fc00924; +chip_usb_dw_prepare_persist = 0x4fc00928; +chip_usb_get_persist_flags = 0x4fc0092c; +chip_usb_set_persist_flags = 0x4fc00930; +cpio_start = 0x4fc00934; +cpio_feed = 0x4fc00938; +cpio_done = 0x4fc0093c; +cpio_destroy = 0x4fc00940; +dfu_flash_init = 0x4fc00944; +dfu_flash_erase = 0x4fc00948; +dfu_flash_program = 0x4fc0094c; +dfu_flash_read = 0x4fc00950; +dfu_flash_attach = 0x4fc00954; +dfu_cpio_callback = 0x4fc00958; +dfu_updater_get_err = 0x4fc0095c; +dfu_updater_clear_err = 0x4fc00960; +dfu_updater_enable = 0x4fc00964; +dfu_updater_begin = 0x4fc00968; +dfu_updater_feed = 0x4fc0096c; +dfu_updater_end = 0x4fc00970; +dfu_updater_set_raw_addr = 0x4fc00974; +dfu_updater_flash_read = 0x4fc00978; +usb_dc_prepare_persist = 0x4fc0097c; +usb_dw_isr_handler = 0x4fc00980; +usb_dc_attach = 0x4fc00984; +usb_dc_detach = 0x4fc00988; +usb_dc_reset = 0x4fc0098c; +usb_dc_set_address = 0x4fc00990; +usb_dc_ep_check_cap = 0x4fc00994; +usb_dc_ep_configure = 0x4fc00998; +usb_dc_ep_set_stall = 0x4fc0099c; +usb_dc_ep_clear_stall = 0x4fc009a0; +usb_dc_ep_halt = 0x4fc009a4; +usb_dc_ep_is_stalled = 0x4fc009a8; +usb_dc_ep_enable = 0x4fc009ac; +usb_dc_ep_disable = 0x4fc009b0; +usb_dc_ep_flush = 0x4fc009b4; +usb_dc_ep_write_would_block = 0x4fc009b8; +usb_dc_ep_write = 0x4fc009bc; +usb_dc_ep_read_wait = 0x4fc009c0; +usb_dc_ep_read_continue = 0x4fc009c4; +usb_dc_ep_read = 0x4fc009c8; +usb_dc_ep_set_callback = 0x4fc009cc; +usb_dc_set_status_callback = 0x4fc009d0; +usb_dc_ep_mps = 0x4fc009d4; +usb_dc_check_poll_for_interrupts = 0x4fc009d8; +mac_addr_to_serial_str_desc = 0x4fc009dc; +usb_set_current_descriptor = 0x4fc009e0; +usb_get_descriptor = 0x4fc009e4; +usb_dev_resume = 0x4fc009e8; +usb_dev_get_configuration = 0x4fc009ec; +usb_set_config = 0x4fc009f0; +usb_deconfig = 0x4fc009f4; +usb_enable = 0x4fc009f8; +usb_disable = 0x4fc009fc; +usb_write_would_block = 0x4fc00a00; +usb_write = 0x4fc00a04; +usb_read = 0x4fc00a08; +usb_ep_set_stall = 0x4fc00a0c; +usb_ep_clear_stall = 0x4fc00a10; +usb_ep_read_wait = 0x4fc00a14; +usb_ep_read_continue = 0x4fc00a18; +usb_transfer_ep_callback = 0x4fc00a1c; +usb_transfer = 0x4fc00a20; +usb_cancel_transfer = 0x4fc00a24; +usb_transfer_sync = 0x4fc00a28; +usb_dfu_set_detach_cb = 0x4fc00a2c; +dfu_class_handle_req = 0x4fc00a30; +dfu_status_cb = 0x4fc00a34; +dfu_custom_handle_req = 0x4fc00a38; +usb_dfu_init = 0x4fc00a3c; +usb_dfu_force_detach = 0x4fc00a40; +usb_dev_deinit = 0x4fc00a44; +usb_dw_ctrl_deinit = 0x4fc00a48; +/* Data (.data, .bss, .rodata) */ +s_usb_osglue = 0x4ff3ffc8; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld new file mode 100644 index 00000000000..3b969ade5a9 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32p4.rom.libgcc.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group libgccdf + ***************************************/ + +/* Functions */ +__absvdi2 = 0x4fc0073c; +__absvsi2 = 0x4fc00740; +__adddf3 = 0x4fc00744; +__addvdi3 = 0x4fc00748; +__addvsi3 = 0x4fc0074c; +__ashldi3 = 0x4fc00750; +__ashrdi3 = 0x4fc00754; +__bswapdi2 = 0x4fc00758; +__bswapsi2 = 0x4fc0075c; +__clear_cache = 0x4fc00760; +__clrsbdi2 = 0x4fc00764; +__clrsbsi2 = 0x4fc00768; +__clzdi2 = 0x4fc0076c; +__clzsi2 = 0x4fc00770; +__cmpdi2 = 0x4fc00774; +__ctzdi2 = 0x4fc00778; +__ctzsi2 = 0x4fc0077c; +__divdc3 = 0x4fc00780; +__divdf3 = 0x4fc00784; +__divdi3 = 0x4fc00788; +__divsc3 = 0x4fc0078c; +__divsi3 = 0x4fc00790; +__eqdf2 = 0x4fc00794; +__extendsfdf2 = 0x4fc00798; +__ffsdi2 = 0x4fc0079c; +__ffssi2 = 0x4fc007a0; +__fixdfdi = 0x4fc007a4; +__fixdfsi = 0x4fc007a8; +__fixsfdi = 0x4fc007ac; +__fixunsdfsi = 0x4fc007b0; +__fixunssfdi = 0x4fc007b4; +__fixunssfsi = 0x4fc007b8; +__floatdidf = 0x4fc007bc; +__floatdisf = 0x4fc007c0; +__floatsidf = 0x4fc007c4; +__floatundidf = 0x4fc007c8; +__floatundisf = 0x4fc007cc; +__floatunsidf = 0x4fc007d0; +__gcc_bcmp = 0x4fc007d4; +__gedf2 = 0x4fc007d8; +__gtdf2 = 0x4fc007dc; +__ledf2 = 0x4fc007e0; +__lshrdi3 = 0x4fc007e4; +__ltdf2 = 0x4fc007e8; +__moddi3 = 0x4fc007ec; +__modsi3 = 0x4fc007f0; +__muldc3 = 0x4fc007f4; +__muldf3 = 0x4fc007f8; +__muldi3 = 0x4fc007fc; +__mulsc3 = 0x4fc00800; +__mulsi3 = 0x4fc00804; +__mulvdi3 = 0x4fc00808; +__mulvsi3 = 0x4fc0080c; +__nedf2 = 0x4fc00810; +__negdf2 = 0x4fc00814; +__negdi2 = 0x4fc00818; +__negvdi2 = 0x4fc0081c; +__negvsi2 = 0x4fc00820; +__paritysi2 = 0x4fc00824; +__popcountdi2 = 0x4fc00828; +__popcountsi2 = 0x4fc0082c; +__powidf2 = 0x4fc00830; +__subdf3 = 0x4fc00834; +__subvdi3 = 0x4fc00838; +__subvsi3 = 0x4fc0083c; +__ucmpdi2 = 0x4fc00840; +__udivdi3 = 0x4fc00844; +__udivmoddi4 = 0x4fc00848; +__udivsi3 = 0x4fc0084c; +__udiv_w_sdiv = 0x4fc00850; +__umoddi3 = 0x4fc00854; +__umodsi3 = 0x4fc00858; +__unorddf2 = 0x4fc0085c; +__extenddftf2 = 0x4fc00860; +__trunctfdf2 = 0x4fc00864; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld new file mode 100644 index 00000000000..bb28d141915 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld @@ -0,0 +1,116 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32p4.rom.rvfp.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rvfplibdf + ***************************************/ +/* + * These functions cannot work when compiling with floating point ABI + * implementation assumes argument is passed in a0, but floats will be passed + * in the floating point registers instead + * + * __fixsfdi = 0x4fc00878; + * __fixunssfdi = 0x4fc00880; + */ + +/* Functions */ +__adddf3 = 0x4fc00868; +__eqdf2 = 0x4fc0086c; +__fixdfdi = 0x4fc00870; +__fixdfsi = 0x4fc00874; +__fixunsdfsi = 0x4fc0087c; +__floatdidf = 0x4fc00884; +__floatsidf = 0x4fc00888; +__floatundidf = 0x4fc0088c; +__floatunsidf = 0x4fc00890; +__gedf2 = 0x4fc00894; +__gtdf2 = 0x4fc00898; +__ledf2 = 0x4fc0089c; +__ltdf2 = 0x4fc008a0; +__muldf3 = 0x4fc008a4; +__nedf2 = 0x4fc008a8; +__subdf3 = 0x4fc008ac; + +/*************************************** + Group libgcc +***************************************/ + +/* Not part of the original ROM interface, but RVFP versions cannot work with float-abi */ +__fixsfdi = 0x4fc007ac; +__fixunssfdi = 0x4fc007b4; + +/* Functions */ +__absvdi2 = 0x4fc0073c; +__absvsi2 = 0x4fc00740; +__addvdi3 = 0x4fc00748; +__addvsi3 = 0x4fc0074c; +__ashldi3 = 0x4fc00750; +__ashrdi3 = 0x4fc00754; +__bswapdi2 = 0x4fc00758; +__bswapsi2 = 0x4fc0075c; +__clear_cache = 0x4fc00760; +__clrsbdi2 = 0x4fc00764; +__clrsbsi2 = 0x4fc00768; +__clzdi2 = 0x4fc0076c; +__clzsi2 = 0x4fc00770; +__cmpdi2 = 0x4fc00774; +__ctzdi2 = 0x4fc00778; +__ctzsi2 = 0x4fc0077c; +__divdc3 = 0x4fc00780; +__divdf3 = 0x4fc00784; +__divdi3 = 0x4fc00788; +__divsc3 = 0x4fc0078c; +__divsi3 = 0x4fc00790; +__extendsfdf2 = 0x4fc00798; +__ffsdi2 = 0x4fc0079c; +__ffssi2 = 0x4fc007a0; +__fixunssfsi = 0x4fc007b8; +__floatdisf = 0x4fc007c0; +__floatundisf = 0x4fc007cc; +__gcc_bcmp = 0x4fc007d4; +__lshrdi3 = 0x4fc007e4; +__moddi3 = 0x4fc007ec; +__modsi3 = 0x4fc007f0; +__muldc3 = 0x4fc007f4; +__muldi3 = 0x4fc007fc; +__mulsc3 = 0x4fc00800; +__mulsi3 = 0x4fc00804; +__mulvdi3 = 0x4fc00808; +__mulvsi3 = 0x4fc0080c; +__negdf2 = 0x4fc00814; +__negdi2 = 0x4fc00818; +__negvdi2 = 0x4fc0081c; +__negvsi2 = 0x4fc00820; +__paritysi2 = 0x4fc00824; +__popcountdi2 = 0x4fc00828; +__popcountsi2 = 0x4fc0082c; +__powidf2 = 0x4fc00830; +__subvdi3 = 0x4fc00838; +__subvsi3 = 0x4fc0083c; +__ucmpdi2 = 0x4fc00840; +__udivdi3 = 0x4fc00844; +__udivmoddi4 = 0x4fc00848; +__udivsi3 = 0x4fc0084c; +__udiv_w_sdiv = 0x4fc00850; +__umoddi3 = 0x4fc00854; +__umodsi3 = 0x4fc00858; +__unorddf2 = 0x4fc0085c; +__extenddftf2 = 0x4fc00860; +__trunctfdf2 = 0x4fc00864; +/*************************************** + Group libgcc +***************************************/ + +/* Functions */ diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.version.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.version.ld new file mode 100644 index 00000000000..6a0c65c2702 --- /dev/null +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.version.ld @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* ROM version variables for esp32p4 + * + * These addresses should be compatible with any ROM version for this chip. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +_rom_chip_id = 0x4fc00010; +_rom_eco_version = 0x4fc00014; diff --git a/esp-rom-sys/libs/esp32p4/unused b/esp-rom-sys/libs/esp32p4/unused new file mode 100644 index 00000000000..e69de29bb2d From e32739a14a2ebc21d076a7342307ca6cf10f5cf1 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 13 Apr 2026 02:08:40 +0900 Subject: [PATCH 02/27] Add esp32p4 feature and update memory.x for P4X (chip rev v3.x) - Add esp32p4 PAC dependency (v0.2, from esp-pacs at fc3e6d4) - Add esp32p4 feature with CLIC-48, LP core, RTC RAM support (matching esp32c5/c61 pattern for RISC-V CLIC chips) - Update memory.x linker script: - Conservative RAM origin at 0x4FF40000 (avoids ROM reserved 256 KB) - Verified against esp-idf SOC_IRAM_LOW/HIGH, SOC_DIRAM_ROM_RESERVE_HIGH - Note L2MEM cached region change in v3.x (bottom-up vs top-down) - Add rt feature forwarding for esp32p4 PAC Target: ESP32-P4NRW16X / ESP32-P4NRW32X (chip revision v3.0/v3.1) NOT for NRND variants (ESP32-P4NRW32 without X suffix). References: - TRM v0.5 (Pre-release), Table 1.4-1 CPU Address Map - Datasheet v0.5, Table 1-1 Series Comparison - Chip Revision v3.x User Guide v1.0 (2026.03) - esp-idf components/soc/esp32p4/include/soc/soc.h --- esp-hal/Cargo.toml | 16 ++++++++++ esp-hal/ld/esp32p4/memory.x | 58 +++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index 24aef9f4c6e..b19ea0e2bbb 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -110,6 +110,7 @@ esp32c6 = { version = "0.22", features = ["critical-section", "rt"], optional = esp32c61 = { version = "0.1", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32h2 = { version = "0.18", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32s2 = { version = "0.30", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } +esp32p4 = { version = "0.2", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32s3 = { version = "0.34", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } [target.'cfg(target_arch = "riscv32")'.dependencies] @@ -154,6 +155,7 @@ rt = [ "esp32c2?/rt", "esp32c3?/rt", "esp32c6?/rt", + "esp32p4?/rt", "esp32h2?/rt", "esp32s2?/rt", "esp32s3?/rt", @@ -231,6 +233,20 @@ esp32c6 = [ "esp-sync/esp32c6", "esp-metadata-generated/esp32c6", ] +## ESP32-P4 (chip revision v3.x / eco5 only, RISC-V dual-core HP + LP core) +## NOTE: This targets P4X (ESP32-P4NRW16X/32X) with chip revision >= v3.0. +## NRND variants (without X suffix) are NOT supported. +## Based on TRM v0.5 (Pre-release) and Chip Revision v3.x User Guide v1.0. +esp32p4 = [ + "dep:esp32p4", + "esp-riscv-rt/rtc-ram", + "esp-riscv-rt/clic-48", + "procmacros/rtc-fast", + "procmacros/has-lp-core", + "esp-rom-sys/esp32p4", + "esp-sync/esp32p4", + "esp-metadata-generated/esp32p4", +] ## esp32c61 = [ "dep:esp32c61", diff --git a/esp-hal/ld/esp32p4/memory.x b/esp-hal/ld/esp32p4/memory.x index b972e30be3e..e074ec4de0e 100644 --- a/esp-hal/ld/esp32p4/memory.x +++ b/esp-hal/ld/esp32p4/memory.x @@ -1,26 +1,42 @@ +/* ESP32-P4X (chip revision v3.x / eco5) Memory Layout + * + * Source: esp-idf soc.h, TRM v0.5, Chip Revision v3.x User Guide v1.0 + * Target: ESP32-P4NRW16X / ESP32-P4NRW32X only (NOT NRND variants) + * + * WARNING: Chip revision v3.x changed L2MEM cached region mapping + * from top-down to bottom-up (vs v1.x). This linker script is + * specifically for v3.x silicon. + * + * Memory map verified against esp-idf: + * SOC_IRAM_LOW = 0x4FF00000 + * SOC_IRAM_HIGH = 0x4FFC0000 (768 KB total L2MEM) + * SOC_DIRAM_ROM_RESERVE_HIGH = 0x4FF40000 (ROM uses first 256 KB) + * SOC_RTC_IRAM_LOW = 0x50108000 + * SOC_RTC_IRAM_HIGH = 0x50110000 (32 KB LP SRAM) + * SOC_EXTRAM_LOW = 0x48000000 (PSRAM, up to 64 MB via cache) + */ + MEMORY { - /* MEMORY_MAP = [ - [0x00000000, 0x00010000, "PADDING"], - [0x40000000, 0x4C000000, "DROM"], - [0x4FF00000, 0x4FFA0000, "DRAM"], - [0x4FF00000, 0x4FFA0000, "BYTE_ACCESSIBLE"], - [0x4FC00000, 0x4FC20000, "DROM_MASK"], - [0x4FC00000, 0x4FC20000, "IROM_MASK"], - [0x40000000, 0x4C000000, "IROM"], - [0x4FF00000, 0x4FFA0000, "IRAM"], - [0x50108000, 0x50110000, "RTC_IRAM"], - [0x50108000, 0x50110000, "RTC_DRAM"], - [0x600FE000, 0x60100000, "MEM_INTERNAL2"], - ] */ - - /* 768K of on soc RAM */ - RAM : ORIGIN = 0x4FF00000, LENGTH = 0xC0000 + /* 768 KB HP L2MEM (on-chip SRAM) + * Full range: 0x4FF00000 - 0x4FFC0000 + * ROM bootloader reserves 0x4FF00000 - 0x4FF40000 (256 KB) + * Usable for application: 0x4FF40000 - 0x4FFC0000 (512 KB) + * + * NOTE: For bare-metal without ROM bootloader, the full 768 KB + * may be available. Adjust ORIGIN/LENGTH accordingly. + * Current setting: conservative, avoids ROM reserved region. + */ + RAM : ORIGIN = 0x4FF40000, LENGTH = 512K - /* External flash */ - /* Instruction and Data ROM */ + /* External flash (XIP via cache) + * Mapped at 0x40000000, up to 64 MB + * +0x20 offset to skip flash header + */ ROM : ORIGIN = 0x40000000 + 0x20, LENGTH = 0x400000 - 0x20 - /* RTC fast memory (executable). Persists over deep sleep. */ - RTC_FAST : ORIGIN = 0x50108000, LENGTH = 32K /*- ESP_BOOTLOADER_RESERVE_RTC*/ -} \ No newline at end of file + /* LP SRAM (32 KB, persists over deep sleep) + * Used by LP core and RTC fast memory + */ + RTC_FAST : ORIGIN = 0x50108000, LENGTH = 32K +} From a19cdff499f662c563cdf89ed6b0da1b9c96f97a Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Tue, 21 Apr 2026 00:01:08 +0900 Subject: [PATCH 03/27] ESP32-P4X v3.x alignment: clocks, CLIC, PSRAM HEX, Zcmp workaround - Linker scripts (ld/esp32p4/*): RAM ends at 0x4FFAE000 per v3.x ROM reserve. - Regen esp-metadata(-generated) for esp32p4: SoC capability flags consistent. - CLIC / interrupt layer: consolidated int_ctrl regs; mintthresh run-level. - Clock tree (src/soc/esp32p4 + rtc_cntl): CPLL/SPLL/MPLL aligned to esp-idf. - New: src/psram/esp32p4.rs (AP HEX mode) and src/soc/esp32p4/gpio.rs (LP GPIO). - esp-sync/raw.rs: RV32 Zcmp hardware-bug workaround (mintthresh=0xff bracket around critical sections), mirrors esp-idf commit c27c33a83. #[cfg(esp32p4)]. - Misc PAC-name compat + xtask clippy auto-fix. Validated on P4X EV Board V1.7, silicon v3.2/ECO7: esp_hal::init -> embassy-net Runner -> IP101GRI MDIO alive. --- esp-backtrace/Cargo.toml | 1 + esp-bootloader-esp-idf/Cargo.toml | 2 + esp-bootloader-esp-idf/src/lib.rs | 13 +- esp-bootloader-esp-idf/src/partitions.rs | 8 + esp-hal/README.md | 112 +- esp-hal/ld/esp32p4/esp32p4.x | 135 +- esp-hal/ld/esp32p4/linkall.x | 9 + esp-hal/ld/esp32p4/memory.x | 25 +- esp-hal/src/analog/adc/riscv.rs | 22 + esp-hal/src/clock/mod.rs | 34 +- esp-hal/src/dma/gdma/ahb_v2.rs | 19 +- esp-hal/src/dma/gdma/mod.rs | 10 +- esp-hal/src/dma/mod.rs | 2 +- esp-hal/src/efuse/esp32p4/mod.rs | 47 +- esp-hal/src/efuse/mod.rs | 1 + esp-hal/src/gpio/interrupt.rs | 9 + esp-hal/src/gpio/mod.rs | 11 +- esp-hal/src/i2c/master/mod.rs | 9 + esp-hal/src/interrupt/mod.rs | 76 +- esp-hal/src/interrupt/riscv.rs | 18 + esp-hal/src/interrupt/riscv/clic.rs | 98 +- esp-hal/src/lib.rs | 36 +- esp-hal/src/psram/esp32p4.rs | 475 ++ esp-hal/src/psram/mod.rs | 1 + esp-hal/src/rtc_cntl/mod.rs | 156 + esp-hal/src/rtc_cntl/rtc/esp32p4.rs | 1357 +---- esp-hal/src/rtc_cntl/sleep/esp32p4.rs | 1081 +--- esp-hal/src/rtc_cntl/sleep/mod.rs | 1 + esp-hal/src/soc/esp32p4/clocks.rs | 493 +- esp-hal/src/soc/esp32p4/gpio.rs | 138 + esp-hal/src/soc/esp32p4/mod.rs | 12 +- esp-hal/src/soc/esp32p4/regi2c.rs | 135 +- esp-hal/src/soc/mod.rs | 1 + esp-hal/src/spi/master/mod.rs | 10 +- esp-hal/src/system.rs | 368 ++ esp-hal/src/uart/mod.rs | 29 +- esp-metadata-generated/Cargo.toml | 1 + .../src/_build_script_utils.rs | 572 +- .../src/_generated_esp32p4.rs | 5281 +++++++++-------- esp-metadata-generated/src/lib.rs | 2 + esp-metadata/devices/esp32p4.toml | 873 ++- esp-metadata/src/lib.rs | 5 + esp-println/Cargo.toml | 1 + esp-println/src/lib.rs | 19 + esp-rom-sys/Cargo.toml | 3 + esp-rom-sys/ld/esp32p4/rom/additional.ld | 2 + esp-rom-sys/src/rom/mod.rs | 2 +- esp-rom-sys/src/syscall/mod.rs | 3 +- esp-sync/Cargo.toml | 2 + esp-sync/src/raw.rs | 37 +- xtask-mcp-macros/src/lib.rs | 30 +- xtask/src/cargo.rs | 25 +- xtask/src/commands/build.rs | 2 +- xtask/src/commands/mod.rs | 6 +- xtask/src/commands/release/bump_version.rs | 6 +- xtask/src/commands/run.rs | 2 +- xtask/src/documentation.rs | 11 +- xtask/src/firmware.rs | 2 +- xtask/src/lib.rs | 48 +- xtask/src/main.rs | 25 +- 60 files changed, 6553 insertions(+), 5361 deletions(-) create mode 100644 esp-hal/src/psram/esp32p4.rs create mode 100644 esp-hal/src/soc/esp32p4/gpio.rs diff --git a/esp-backtrace/Cargo.toml b/esp-backtrace/Cargo.toml index b652d62cc6c..a5fc0a855bd 100644 --- a/esp-backtrace/Cargo.toml +++ b/esp-backtrace/Cargo.toml @@ -61,6 +61,7 @@ esp32c5 = ["esp-println?/esp32c5", "esp-metadata-generated/esp32c5"] esp32c6 = ["esp-println?/esp32c6", "esp-metadata-generated/esp32c6"] esp32c61 = ["esp-println?/esp32c61", "esp-metadata-generated/esp32c61"] esp32h2 = ["esp-println?/esp32h2", "esp-metadata-generated/esp32h2"] +esp32p4 = ["esp-println?/esp32p4", "esp-metadata-generated/esp32p4"] esp32s2 = ["esp-println?/esp32s2", "esp-metadata-generated/esp32s2", "semihosting?/openocd-semihosting"] esp32s3 = ["esp-println?/esp32s3", "esp-metadata-generated/esp32s3", "semihosting?/openocd-semihosting", "print-float-registers"] diff --git a/esp-bootloader-esp-idf/Cargo.toml b/esp-bootloader-esp-idf/Cargo.toml index bd7906551be..d989a1b0b64 100644 --- a/esp-bootloader-esp-idf/Cargo.toml +++ b/esp-bootloader-esp-idf/Cargo.toml @@ -83,6 +83,8 @@ esp32c61 = ["esp-rom-sys/esp32c61", "esp-metadata-generated/esp32c61", "esp-ha ## esp32h2 = ["esp-rom-sys/esp32h2", "esp-metadata-generated/esp32h2", "esp-hal/esp32h2"] ## +esp32p4 = ["esp-rom-sys/esp32p4", "esp-metadata-generated/esp32p4", "esp-hal/esp32p4", "dep:crc", "dep:md-5"] +## esp32 = ["esp-rom-sys/esp32", "esp-metadata-generated/esp32", "esp-hal/esp32"] ## esp32s2 = ["esp-rom-sys/esp32s2", "esp-metadata-generated/esp32s2", "esp-hal/esp32s2"] diff --git a/esp-bootloader-esp-idf/src/lib.rs b/esp-bootloader-esp-idf/src/lib.rs index bf426e5183a..ade87236be3 100644 --- a/esp-bootloader-esp-idf/src/lib.rs +++ b/esp-bootloader-esp-idf/src/lib.rs @@ -101,16 +101,21 @@ // MUST be the first module mod fmt; -#[cfg(not(feature = "std"))] +// P4 ROM does not have md5/crc functions (rom_crc_le/rom_md5_bsd flags not set). +// Use software crypto for P4, ROM crypto for other chips. +// Ref: esp-rom-sys rom/mod.rs -- pub mod crc gated on rom_crc_le +// P4 ROM does not have md5/crc functions (rom_crc_le/rom_md5_bsd flags not set). +// Use software crypto (non_rom module) for P4 and std builds. +#[cfg(all(not(feature = "std"), not(feature = "esp32p4")))] mod rom; -#[cfg(not(feature = "std"))] +#[cfg(all(not(feature = "std"), not(feature = "esp32p4")))] pub(crate) use rom as crypto; -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "esp32p4"))] mod non_rom; #[cfg(embedded_test)] pub use crypto::Crc32 as Crc32ForTesting; -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "esp32p4"))] pub(crate) use non_rom as crypto; pub mod partitions; diff --git a/esp-bootloader-esp-idf/src/partitions.rs b/esp-bootloader-esp-idf/src/partitions.rs index 810c806302f..4fd09be92e2 100644 --- a/esp-bootloader-esp-idf/src/partitions.rs +++ b/esp-bootloader-esp-idf/src/partitions.rs @@ -336,6 +336,14 @@ impl<'a> PartitionTable<'a> { let paddr = unsafe { ((0x600c5000 as *const u32).read_volatile() & 0xff) << 16 }; + } else if #[cfg(feature = "esp32p4")] { + // P4: SPI_MEM_C (SPI0) at 0x5008C000 + // Ref: esp-idf reg_base.h -- DR_REG_FLASH_SPI0_BASE = 0x5008C000 + // TODO(P4X): verify MSPI register for partition physical address read + let paddr = unsafe { + ((0x5008C000 + 0x380) as *mut u32).write_volatile(0); + (((0x5008C000 + 0x37c) as *const u32).read_volatile() & 0xff) << 16 + }; } else if #[cfg(any(feature = "esp32c5", feature = "esp32c6", feature = "esp32c61", feature = "esp32h2"))] { let paddr = unsafe { ((0x60002000 + 0x380) as *mut u32).write_volatile(0); diff --git a/esp-hal/README.md b/esp-hal/README.md index 61db62a4cde..97a807f62fb 100644 --- a/esp-hal/README.md +++ b/esp-hal/README.md @@ -56,62 +56,62 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a -| Driver | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ------------------------- |:-----:|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:| -| ADC | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| AES | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| ASSIST_DEBUG | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | -| Analog Voltage Comparator | | | | [❌][5168] [^1] | | | | | | -| Bit Scrambler | | | | [❌][5170] [^1] | | | | | | -| Bluetooth | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | -| Camera interface | ❌ | | | | | | | ❌ | ⚒️ | -| DAC | ⚒️ | | | | | | | ⚒️ | | -| Dedicated GPIO | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| DMA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| DS | | | ❌ | [❌][5159] [^1] | ❌ | | ❌ | ❌ | ❌ | -| ECC | | ⚒️ | | ⚒️ | ⚒️ | | ⚒️ | | | -| Ethernet | ❌ | | | | | | | | | -| ETM | | | | [❌][5167] [^1] | ⚒️ | | ⚒️ | | | -| GPIO | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ✔️ | ✔️ | -| HMAC | | | ⚒️ | [❌][5166] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| I2C master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | -| I2C slave | ❌ | | ❌ | [❌][5156] [^1] | ❌ | | ❌ | ❌ | ❌ | -| I2S | ⚒️ | | ⚒️ | [❌][5172] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| IEEE 802.15.4 | | | | ⚒️ | ⚒️ | | ⚒️ | | | -| Interrupts | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| IOMUX | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| Key Manager | | | | [❌][5171] [^1] | | | | | | -| LEDC | ⚒️ | ⚒️ | ⚒️ | [❌][5161] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| LP I2C master | | | | ⚒️ | ⚒️ | | | | | -| LP UART | | | | [❌][5155] [^1] | ⚒️ | | | | | -| MCPWM | ⚒️ | | | [❌][5154] [^1] | ⚒️ | | ⚒️ | | ⚒️ | -| PARL_IO | | | | ⚒️ | ⚒️ | | ⚒️ | | | -| PCNT | ⚒️ | | | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| PHY | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| PSRAM | ⚒️ | | | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | -| RGB display | ⚒️ | | | | | | | ❌ | ⚒️ | -| RMT | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| RNG | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| RSA | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| RTC Timekeeping | ⚒️ | ⚒️ | ⚒️ | [❌][5162] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| SDIO host | ⚒️ | | | | | | | | ⚒️ | -| SDIO slave | ⚒️ | | | [❌][5169] [^1] | ⚒️ | | | | | -| SHA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| Light/deep sleep | ⚒️ | ⚒️ | ⚒️ | [❌][5165] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| SPI master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | -| SPI slave | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| SYSTIMER | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| Temperature sensor | ⚒️ | ⚒️ | ⚒️ | [❌][5153] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| Timers | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| Touch | ⚒️ | | | [❌][5164] [^1] | | | | [❌][1905] [^1] | [❌][1905] [^1] | -| TWAI / CAN / CANFD | ⚒️ | | ⚒️ | [❌][5163] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| UART | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | -| UHCI | ❌ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ❌ | ⚒️ | -| ULP (FSM) | ⚒️ | | | | | | | ⚒️ | ⚒️ | -| ULP (RISC-V) | | | | [❌][5160] [^1] | ⚒️ | | | ⚒️ | ⚒️ | -| USB OTG FS | | | | | | | | ⚒️ | ⚒️ | -| USB Serial/JTAG | | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | -| WIFI | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | +| Driver | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ------------------------- |:-----:|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:|:--------:| +| ADC | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| AES | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| ASSIST_DEBUG | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | | ⚒️ | +| Analog Voltage Comparator | | | | [❌][5168] [^1] | | | | | | | +| Bit Scrambler | | | | [❌][5170] [^1] | | | | | | | +| Bluetooth | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | ⚒️ | +| Camera interface | ❌ | | | | | | | | ❌ | ⚒️ | +| DAC | ⚒️ | | | | | | | | ⚒️ | | +| Dedicated GPIO | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| DMA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| DS | | | ❌ | [❌][5159] [^1] | ❌ | | ❌ | | ❌ | ❌ | +| ECC | | ⚒️ | | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | | +| Ethernet | ❌ | | | | | | | | | | +| ETM | | | | [❌][5167] [^1] | ⚒️ | | ⚒️ | | | | +| GPIO | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ✔️ | +| HMAC | | | ⚒️ | [❌][5166] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| I2C master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | +| I2C slave | ❌ | | ❌ | [❌][5156] [^1] | ❌ | | ❌ | | ❌ | ❌ | +| I2S | ⚒️ | | ⚒️ | [❌][5172] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| IEEE 802.15.4 | | | | ⚒️ | ⚒️ | | ⚒️ | | | | +| Interrupts | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| IOMUX | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| Key Manager | | | | [❌][5171] [^1] | | | | | | | +| LEDC | ⚒️ | ⚒️ | ⚒️ | [❌][5161] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| LP I2C master | | | | ⚒️ | ⚒️ | | | | | | +| LP UART | | | | [❌][5155] [^1] | ⚒️ | | | | | | +| MCPWM | ⚒️ | | | [❌][5154] [^1] | ⚒️ | | ⚒️ | | | ⚒️ | +| PARL_IO | | | | ⚒️ | ⚒️ | | ⚒️ | | | | +| PCNT | ⚒️ | | | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| PHY | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| PSRAM | ⚒️ | | | ⚒️ | | ⚒️ | | | ⚒️ | ⚒️ | +| RGB display | ⚒️ | | | | | | | | ❌ | ⚒️ | +| RMT | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| RNG | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | +| RSA | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| RTC Timekeeping | ⚒️ | ⚒️ | ⚒️ | [❌][5162] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| SDIO host | ⚒️ | | | | | | | | | ⚒️ | +| SDIO slave | ⚒️ | | | [❌][5169] [^1] | ⚒️ | | | | | | +| SHA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| Light/deep sleep | ⚒️ | ⚒️ | ⚒️ | [❌][5165] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| SPI master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | +| SPI slave | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | +| SYSTIMER | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| Temperature sensor | ⚒️ | ⚒️ | ⚒️ | [❌][5153] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| Timers | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | +| Touch | ⚒️ | | | [❌][5164] [^1] | | | | | [❌][1905] [^1] | [❌][1905] [^1] | +| TWAI / CAN / CANFD | ⚒️ | | ⚒️ | [❌][5163] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| UART | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | +| UHCI | ❌ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ❌ | ⚒️ | +| ULP (FSM) | ⚒️ | | | | | | | | ⚒️ | ⚒️ | +| ULP (RISC-V) | | | | [❌][5160] [^1] | ⚒️ | | | | ⚒️ | ⚒️ | +| USB OTG FS | | | | | | | | | ⚒️ | ⚒️ | +| USB Serial/JTAG | | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | ⚒️ | +| WIFI | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | ⚒️ | ⚒️ | * Empty cell: Not available * ❌: Not supported diff --git a/esp-hal/ld/esp32p4/esp32p4.x b/esp-hal/ld/esp32p4/esp32p4.x index 552d4aa7e8a..7f00a9c8b3e 100644 --- a/esp-hal/ld/esp32p4/esp32p4.x +++ b/esp-hal/ld/esp32p4/esp32p4.x @@ -20,6 +20,110 @@ PROVIDE(ExceptionHandler = DefaultExceptionHandler); one additional interrupt ID: */ PROVIDE(interrupt0 = DefaultHandler); +/* ESP32-P4 peripheral interrupt handlers (99 sources from PAC). + Each maps to DefaultHandler unless overridden by the application. + Ref: esp32p4 PAC lib.rs __EXTERNAL_INTERRUPTS vector table + TRM v0.5 Ch 14 (Interrupt Matrix) */ +PROVIDE(LP_WDT = DefaultHandler); +PROVIDE(LP_TIMER0 = DefaultHandler); +PROVIDE(LP_TIMER1 = DefaultHandler); +PROVIDE(PMU0 = DefaultHandler); +PROVIDE(PMU1 = DefaultHandler); +PROVIDE(LP_ANA = DefaultHandler); +PROVIDE(LP_ADC = DefaultHandler); +PROVIDE(LP_GPIO = DefaultHandler); +PROVIDE(LP_I2C0 = DefaultHandler); +PROVIDE(LP_I2S0 = DefaultHandler); +PROVIDE(LP_TOUCH = DefaultHandler); +PROVIDE(LP_TSENS = DefaultHandler); +PROVIDE(LP_UART = DefaultHandler); +PROVIDE(LP_SYS = DefaultHandler); +PROVIDE(LP_HUK = DefaultHandler); +PROVIDE(USB_DEVICE = DefaultHandler); +PROVIDE(DMA = DefaultHandler); +PROVIDE(SPI2 = DefaultHandler); +PROVIDE(SPI3 = DefaultHandler); +PROVIDE(I2S0 = DefaultHandler); +PROVIDE(I2S1 = DefaultHandler); +PROVIDE(I2S2 = DefaultHandler); +PROVIDE(UHCI0 = DefaultHandler); +PROVIDE(UART0 = DefaultHandler); +PROVIDE(UART1 = DefaultHandler); +PROVIDE(UART2 = DefaultHandler); +PROVIDE(UART3 = DefaultHandler); +PROVIDE(UART4 = DefaultHandler); +PROVIDE(PWM0 = DefaultHandler); +PROVIDE(PWM1 = DefaultHandler); +PROVIDE(TWAI0 = DefaultHandler); +PROVIDE(TWAI1 = DefaultHandler); +PROVIDE(TWAI2 = DefaultHandler); +PROVIDE(RMT = DefaultHandler); +PROVIDE(I2C0 = DefaultHandler); +PROVIDE(I2C1 = DefaultHandler); +PROVIDE(TG0_T0_LEVEL = DefaultHandler); +PROVIDE(TG0_T1_LEVEL = DefaultHandler); +PROVIDE(TG0_WDT_LEVEL = DefaultHandler); +PROVIDE(TG1_T0_LEVEL = DefaultHandler); +PROVIDE(TG1_T1_LEVEL = DefaultHandler); +PROVIDE(TG1_WDT_LEVEL = DefaultHandler); +PROVIDE(LEDC = DefaultHandler); +PROVIDE(SYSTIMER_TARGET0 = DefaultHandler); +PROVIDE(SYSTIMER_TARGET1 = DefaultHandler); +PROVIDE(SYSTIMER_TARGET2 = DefaultHandler); +PROVIDE(AHB_PDMA_IN_CH0 = DefaultHandler); +PROVIDE(AHB_PDMA_IN_CH1 = DefaultHandler); +PROVIDE(AHB_PDMA_IN_CH2 = DefaultHandler); +PROVIDE(AHB_PDMA_OUT_CH0 = DefaultHandler); +PROVIDE(AHB_PDMA_OUT_CH1 = DefaultHandler); +PROVIDE(AHB_PDMA_OUT_CH2 = DefaultHandler); +PROVIDE(AXI_PDMA_IN_CH0 = DefaultHandler); +PROVIDE(AXI_PDMA_IN_CH1 = DefaultHandler); +PROVIDE(AXI_PDMA_IN_CH2 = DefaultHandler); +PROVIDE(AXI_PDMA_OUT_CH0 = DefaultHandler); +PROVIDE(AXI_PDMA_OUT_CH1 = DefaultHandler); +PROVIDE(AXI_PDMA_OUT_CH2 = DefaultHandler); +PROVIDE(RSA = DefaultHandler); +PROVIDE(AES = DefaultHandler); +PROVIDE(SHA = DefaultHandler); +PROVIDE(ECC = DefaultHandler); +PROVIDE(GPIO = DefaultHandler); +PROVIDE(GPIO_INT1 = DefaultHandler); +PROVIDE(GPIO_INT2 = DefaultHandler); +PROVIDE(GPIO_INT3 = DefaultHandler); +PROVIDE(GPIO_PAD_COMP = DefaultHandler); +PROVIDE(FROM_CPU_INTR0 = DefaultHandler); +PROVIDE(FROM_CPU_INTR1 = DefaultHandler); +PROVIDE(FROM_CPU_INTR2 = DefaultHandler); +PROVIDE(FROM_CPU_INTR3 = DefaultHandler); +PROVIDE(CACHE = DefaultHandler); +PROVIDE(CSI_BRIDGE = DefaultHandler); +PROVIDE(DSI_BRIDGE = DefaultHandler); +PROVIDE(CSI = DefaultHandler); +PROVIDE(DSI = DefaultHandler); +PROVIDE(JPEG = DefaultHandler); +PROVIDE(PPA = DefaultHandler); +PROVIDE(ISP = DefaultHandler); +PROVIDE(I3C = DefaultHandler); +PROVIDE(I3C_SLV = DefaultHandler); +PROVIDE(HP_SYS = DefaultHandler); +PROVIDE(PCNT = DefaultHandler); +PROVIDE(PAU = DefaultHandler); +PROVIDE(PARLIO_RX = DefaultHandler); +PROVIDE(PARLIO_TX = DefaultHandler); +PROVIDE(H264_DMA2D_OUT_CH0 = DefaultHandler); +PROVIDE(H264_DMA2D_OUT_CH1 = DefaultHandler); +PROVIDE(H264_DMA2D_OUT_CH2 = DefaultHandler); +PROVIDE(H264_DMA2D_OUT_CH3 = DefaultHandler); +PROVIDE(H264_DMA2D_OUT_CH4 = DefaultHandler); +PROVIDE(H264_DMA2D_IN_CH0 = DefaultHandler); +PROVIDE(H264_DMA2D_IN_CH1 = DefaultHandler); +PROVIDE(H264_DMA2D_IN_CH2 = DefaultHandler); +PROVIDE(H264_DMA2D_IN_CH3 = DefaultHandler); +PROVIDE(H264_DMA2D_IN_CH4 = DefaultHandler); +PROVIDE(H264_DMA2D_IN_CH5 = DefaultHandler); +PROVIDE(H264_REG = DefaultHandler); +PROVIDE(ASSIST_DEBUG = DefaultHandler); + PROVIDE(__post_init = default_post_init); /* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ @@ -37,19 +141,12 @@ PROVIDE(_mp_hook = default_mp_hook); By default uses the riscv crates default trap handler but by providing the `_start_trap` symbol external crates can override. */ -PROVIDE(_start_trap = default_start_trap); +PROVIDE(_start_trap = _default_start_trap); /* Must be called __global_pointer$ for linker relaxations to work. */ PROVIDE(__global_pointer$ = _data_start + 0x800); -SECTIONS { - .trap : ALIGN(4) - { - KEEP(*(.trap)); - *(.trap.*); - } > RWTEXT -} -INSERT BEFORE .rwtext; +/* NOTE: .trap section is generated by build.rs in rwtext.x, not duplicated here. */ SECTIONS { /** @@ -62,13 +159,23 @@ SECTIONS { } INSERT BEFORE .rodata; -/* Shared sections - ordering matters */ -INCLUDE "text.x" -INCLUDE "rwtext.x" +/* Shared sections - ordering matters. + rwtext.x and rwdata.x contain bare section directives that need a SECTIONS context. + We wrap them in SECTIONS {} blocks. */ +SECTIONS { + INCLUDE "rwtext.x" +} + +SECTIONS { + INCLUDE "rwdata.x" +} + INCLUDE "rodata.x" -INCLUDE "rwdata.x" +INCLUDE "text.x" INCLUDE "rtc_fast.x" INCLUDE "stack.x" +INCLUDE "metadata.x" +INCLUDE "eh_frame.x" /* End of Shared sections */ -INCLUDE "debug.x" \ No newline at end of file +_dram_data_start = ORIGIN(RAM) + SIZEOF(.trap) + SIZEOF(.rwtext); \ No newline at end of file diff --git a/esp-hal/ld/esp32p4/linkall.x b/esp-hal/ld/esp32p4/linkall.x index e542fd602de..485c40f2dd2 100644 --- a/esp-hal/ld/esp32p4/linkall.x +++ b/esp-hal/ld/esp32p4/linkall.x @@ -1,5 +1,6 @@ INCLUDE "memory.x" +/* esp-hal region aliases */ REGION_ALIAS("ROTEXT", ROM); REGION_ALIAS("RODATA", ROM); @@ -9,5 +10,13 @@ REGION_ALIAS("RWDATA", RAM); REGION_ALIAS("RTC_FAST_RWTEXT", RTC_FAST); REGION_ALIAS("RTC_FAST_RWDATA", RTC_FAST); +/* riscv-rt v0.16+ region aliases (required by upstream riscv-rt link.x) */ +REGION_ALIAS("REGION_TEXT", ROM); +REGION_ALIAS("REGION_RODATA", ROM); +REGION_ALIAS("REGION_DATA", RAM); +REGION_ALIAS("REGION_BSS", RAM); +REGION_ALIAS("REGION_HEAP", RAM); +REGION_ALIAS("REGION_STACK", RAM); + INCLUDE "esp32p4.x" INCLUDE "hal-defaults.x" \ No newline at end of file diff --git a/esp-hal/ld/esp32p4/memory.x b/esp-hal/ld/esp32p4/memory.x index e074ec4de0e..3b1c0b88fbe 100644 --- a/esp-hal/ld/esp32p4/memory.x +++ b/esp-hal/ld/esp32p4/memory.x @@ -1,6 +1,7 @@ -/* ESP32-P4X (chip revision v3.x / eco5) Memory Layout +/* ESP32-P4X (chip revision v3.x incl. v3.2 / eco7) Memory Layout * - * Source: esp-idf soc.h, TRM v0.5, Chip Revision v3.x User Guide v1.0 + * Source: esp-idf soc.h, TRM v0.5, Chip Revision v3.x User Guide v1.0, + * esp-idf 6.1 memory.ld (generated), esptool esp32p4.py * Target: ESP32-P4NRW16X / ESP32-P4NRW32X only (NOT NRND variants) * * WARNING: Chip revision v3.x changed L2MEM cached region mapping @@ -10,24 +11,28 @@ * Memory map verified against esp-idf: * SOC_IRAM_LOW = 0x4FF00000 * SOC_IRAM_HIGH = 0x4FFC0000 (768 KB total L2MEM) - * SOC_DIRAM_ROM_RESERVE_HIGH = 0x4FF40000 (ROM uses first 256 KB) + * SOC_DIRAM_ROM_RESERVE_HIGH = 0x4FF40000 (ROM uses first 256 KB, low end) * SOC_RTC_IRAM_LOW = 0x50108000 * SOC_RTC_IRAM_HIGH = 0x50110000 (32 KB LP SRAM) * SOC_EXTRAM_LOW = 0x48000000 (PSRAM, up to 64 MB via cache) + * + * CRITICAL (v3.x): ROM ALSO reserves the TOP of L2MEM for BSS/stack. + * esptool: BSS_UART_DEV_ADDR = 0x4FFBFEB0 for chip revision >= v3.0 + * esp-idf sram_seg ends at 0x4FFAEFC0 (leaves ~68KB at top for ROM) + * Writing into this region during Rust startup corrupts ROM UART + * state and the bootloader immediately prints "user code done" + * because the UART_DEV struct was trashed by _start's stack push. */ MEMORY { /* 768 KB HP L2MEM (on-chip SRAM) * Full range: 0x4FF00000 - 0x4FFC0000 - * ROM bootloader reserves 0x4FF00000 - 0x4FF40000 (256 KB) - * Usable for application: 0x4FF40000 - 0x4FFC0000 (512 KB) - * - * NOTE: For bare-metal without ROM bootloader, the full 768 KB - * may be available. Adjust ORIGIN/LENGTH accordingly. - * Current setting: conservative, avoids ROM reserved region. + * Low reserve (ROM bootloader): 0x4FF00000 - 0x4FF40000 (256 KB) + * High reserve (ROM BSS/stack, v3+): 0x4FFAE000 - 0x4FFC0000 (~72 KB) + * Usable for application: 0x4FF40000 - 0x4FFAE000 (440 KB) */ - RAM : ORIGIN = 0x4FF40000, LENGTH = 512K + RAM : ORIGIN = 0x4FF40000, LENGTH = 0x6E000 /* External flash (XIP via cache) * Mapped at 0x40000000, up to 64 MB diff --git a/esp-hal/src/analog/adc/riscv.rs b/esp-hal/src/analog/adc/riscv.rs index 2e412873067..244139e8c54 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -183,6 +183,18 @@ impl RegisterAccess for crate::peripherals::ADC1<'_> { regi2c::ADC_SAR1_DREF.write_field(1); } + // ESP32-P4 uses DREF value 4 (same as S2/S3) not 1. + // Ref: esp-idf esp32p4/adc_ll.h -- adc_ll_calibration_init() + // REGI2C_SAR_I2C (0x69) reg 2, bits [6:4] = DREF + #[cfg(esp32p4)] + fn calibration_init() { + use crate::soc::regi2c; + // REG2 bits [6:4] = ADC_SAR1_DREF; clear then set to 4 + let val = regi2c::regi2c_read(regi2c::REGI2C_SAR_I2C, 0, 2); + let new_val = (val & !(0x7 << 4)) | (4 << 4); + regi2c::regi2c_write(regi2c::REGI2C_SAR_I2C, 0, 2, new_val); + } + fn set_init_code(data: u16) { let [msb, lsb] = data.to_be_bytes(); @@ -260,6 +272,16 @@ impl RegisterAccess for crate::peripherals::ADC2<'_> { regi2c::ADC_SAR2_DREF.write_field(1); } + // ESP32-P4 uses DREF value 4 for ADC2 as well. + // REG5 bits [6:4] = ADC_SAR2_DREF + #[cfg(esp32p4)] + fn calibration_init() { + use crate::soc::regi2c; + let val = regi2c::regi2c_read(regi2c::REGI2C_SAR_I2C, 0, 5); + let new_val = (val & !(0x7 << 4)) | (4 << 4); + regi2c::regi2c_write(regi2c::REGI2C_SAR_I2C, 0, 5, new_val); + } + fn set_init_code(data: u16) { let [msb, lsb] = data.to_be_bytes(); diff --git a/esp-hal/src/clock/mod.rs b/esp-hal/src/clock/mod.rs index d999c11164c..73b8d35b8ba 100644 --- a/esp-hal/src/clock/mod.rs +++ b/esp-hal/src/clock/mod.rs @@ -45,6 +45,7 @@ //! ``` #![cfg_attr(not(feature = "rt"), expect(unused))] +use clocks::ClockTree; #[cfg(soc_has_clock_node_lp_slow_clk)] use clocks::LpSlowClkConfig; #[cfg(all(not(esp32s2), soc_has_clock_node_rtc_slow_clk))] @@ -100,6 +101,11 @@ impl CpuClock { Self::_160MHz } else if #[cfg(esp32h2)] { Self::_96MHz + } else if #[cfg(esp32p4)] { + // ESP32-P4 v3.x (eco5): max 400 MHz via CPLL + // Ref: TRM v0.5 Ch 2 -- HP CPU max frequency 400 MHz for v3.x + // esp-idf clk_tree_defs.h -- SOC_CPU_CLK_SRC_CPLL + Self::_400MHz } else { Self::_240MHz } @@ -200,6 +206,9 @@ static mut ACTIVE_CLOCKS: Option = None; impl Clocks { pub(crate) fn init(cpu_clock_config: ClockConfig) { ESP_HAL_LOCK.lock(|| { + // P4: init() disables all WDTs and resets PMU power domain force flags. + // Full PLL/clock tree config is NOT yet implemented -- relies on ROM bootloader. + // Ref: esp-idf pmu_init.c, bootloader_esp32p4.c, TRM v0.5 Ch 16 crate::rtc_cntl::rtc::init(); let config = Self::configure(cpu_clock_config); @@ -521,12 +530,24 @@ impl Clocks { /// The CPU clock frequency. pub fn cpu_clock() -> Rate { - Clocks::get().cpu_clock + // P4: ClockConfig is empty (no clock node framework yet). + // Return the actual configured frequency from CPLL init. + // Ref: esp-idf rtc_clk.c -- default is 400 MHz for eco5 (v3.x) + // TRM v0.5 Ch 12 + #[cfg(esp32p4)] + { Rate::from_mhz(400) } + #[cfg(not(esp32p4))] + { Clocks::get().cpu_clock } } /// The XTAL clock frequency. pub fn xtal_clock() -> Rate { - Clocks::get().xtal_clock + // P4: 40 MHz external crystal (SOC_XTAL_FREQ_40M) + // Ref: esp-idf clk_tree_defs.h -- SOC_XTAL_FREQ_40M = 40 + #[cfg(esp32p4)] + { Rate::from_mhz(40) } + #[cfg(not(esp32p4))] + { Clocks::get().xtal_clock } } /// Read the calibrated RTC slow clock period from the STORE1 register. @@ -545,7 +566,14 @@ fn rtc_slow_cal_period() -> u64 { } } - LP_AON::regs().store1().read().bits() as u64 + // P4: store registers are in LP_SYS (mapped as LP_AON in esp-hal). + // LP_SYS has lp_store0..lp_store14 registers. + // Ref: esp-idf lp_system_reg.h -- LP_SYSTEM_REG_LP_STORE1_REG = RTC_SLOW_CLK_CAL_REG + // esp-idf esp_time_impl.c -- uses store2/store3 for boot time + #[cfg(esp32p4)] + { LP_AON::regs().lp_store1().read().bits() as u64 } + #[cfg(not(esp32p4))] + { LP_AON::regs().store1().read().bits() as u64 } } /// Convert RTC slow clock ticks to microseconds using the calibrated period. diff --git a/esp-hal/src/dma/gdma/ahb_v2.rs b/esp-hal/src/dma/gdma/ahb_v2.rs index 9403bca5454..42ad40fe86f 100644 --- a/esp-hal/src/dma/gdma/ahb_v2.rs +++ b/esp-hal/src/dma/gdma/ahb_v2.rs @@ -1,14 +1,25 @@ use super::*; use crate::RegisterToggle; +// P4: PAC "dma" module is DW_GDMA (DesignWare), "ahb_dma" is GDMA v2 (what we need). +// Other chips: PAC "dma" module IS the GDMA v2 module. +// Ref: esp-idf ahb_dma_ll.h vs dw_gdma_ll.h +cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + use pac::ahb_dma as gdma_pac; + } else { + use pac::dma as gdma_pac; + } +} + impl AnyGdmaTxChannel<'_> { #[inline(always)] - pub(super) fn ch(&self) -> &pac::dma::ch::CH { + pub(super) fn ch(&self) -> &gdma_pac::ch::CH { DMA::regs().ch(self.channel as usize) } #[inline(always)] - pub(super) fn int(&self) -> &pac::dma::out_int_ch::OUT_INT_CH { + pub(super) fn int(&self) -> &gdma_pac::out_int_ch::OUT_INT_CH { DMA::regs().out_int_ch(self.channel as usize) } } @@ -217,12 +228,12 @@ impl InterruptAccess for AnyGdmaTxChannel<'_> { impl AnyGdmaRxChannel<'_> { #[inline(always)] - fn ch(&self) -> &pac::dma::ch::CH { + fn ch(&self) -> &gdma_pac::ch::CH { DMA::regs().ch(self.channel as usize) } #[inline(always)] - fn int(&self) -> &pac::dma::in_int_ch::IN_INT_CH { + fn int(&self) -> &gdma_pac::in_int_ch::IN_INT_CH { DMA::regs().in_int_ch(self.channel as usize) } } diff --git a/esp-hal/src/dma/gdma/mod.rs b/esp-hal/src/dma/gdma/mod.rs index 1da09035905..f606fe242ef 100644 --- a/esp-hal/src/dma/gdma/mod.rs +++ b/esp-hal/src/dma/gdma/mod.rs @@ -233,7 +233,15 @@ const CHANNEL_COUNT: usize = cfg!(soc_has_dma_ch0) as usize + cfg!(soc_has_dma_ch4) as usize; cfg_if::cfg_if! { - if #[cfg(dma_separate_in_out_interrupts)] { + // ESP32-P4: AHB_DMA interrupt names are AHB_PDMA_IN_CHn / AHB_PDMA_OUT_CHn + if #[cfg(esp32p4)] { + #[cfg(soc_has_dma_ch0)] + impl_channel!(0, AHB_PDMA_IN_CH0, AHB_PDMA_OUT_CH0); + #[cfg(soc_has_dma_ch1)] + impl_channel!(1, AHB_PDMA_IN_CH1, AHB_PDMA_OUT_CH1); + #[cfg(soc_has_dma_ch2)] + impl_channel!(2, AHB_PDMA_IN_CH2, AHB_PDMA_OUT_CH2); + } else if #[cfg(dma_separate_in_out_interrupts)] { #[cfg(soc_has_dma_ch0)] impl_channel!(0, DMA_IN_CH0, DMA_OUT_CH0); #[cfg(soc_has_dma_ch1)] diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index 03c6efbc5b5..f9adbf63526 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -61,7 +61,7 @@ use enumset::{EnumSet, EnumSetType}; pub use self::buffers::*; #[cfg(dma_kind = "gdma")] pub use self::gdma::*; -#[cfg(any(dma_kind = "gdma", esp32s2))] // TODO +#[cfg(all(any(dma_kind = "gdma", esp32s2), dma_supports_mem2mem))] pub use self::m2m::*; #[cfg(dma_kind = "pdma")] pub use self::pdma::*; diff --git a/esp-hal/src/efuse/esp32p4/mod.rs b/esp-hal/src/efuse/esp32p4/mod.rs index 48dd08cc5c9..e519d8c9504 100644 --- a/esp-hal/src/efuse/esp32p4/mod.rs +++ b/esp-hal/src/efuse/esp32p4/mod.rs @@ -1,29 +1,34 @@ //! # Reading of eFuses (ESP32-P4) -pub use self::fields::*; -use crate::peripherals::pac::EFUSE; +use crate::peripherals::EFUSE; + +#[cfg_attr(not(feature = "unstable"), allow(dead_code))] mod fields; +#[instability::unstable] +pub use fields::*; -impl super::Efuse { - /// Get status of SPI boot encryption. - pub fn get_flash_encryption() -> bool { - (Self::read_field_le::(SPI_BOOT_CRYPT_CNT).count_ones() % 2) != 0 - } +/// Get status of SPI boot encryption. +#[instability::unstable] +pub fn flash_encryption() -> bool { + !super::read_field_le::(SPI_BOOT_CRYPT_CNT) + .count_ones() + .is_multiple_of(2) +} - /// Get the multiplier for the timeout value of the RWDT STAGE 0 register. - pub fn get_rwdt_multiplier() -> u8 { - Self::read_field_le::(WDT_DELAY_SEL) - } +/// Get the multiplier for the timeout value of the RWDT STAGE 0 register. +#[instability::unstable] +pub fn rwdt_multiplier() -> u8 { + super::read_field_le::(WDT_DELAY_SEL) +} - /// Returns the major hardware revision - pub fn major_chip_version() -> u8 { - Self::read_field_le(WAFER_VERSION_MAJOR) - } +/// Returns the major hardware revision +pub(crate) fn major_chip_version() -> u8 { + super::read_field_le(WAFER_VERSION_MAJOR) +} - /// Returns the minor hardware revision - pub fn minor_chip_version() -> u8 { - Self::read_field_le(WAFER_VERSION_MINOR) - } +/// Returns the minor hardware revision +pub(crate) fn minor_chip_version() -> u8 { + super::read_field_le(WAFER_VERSION_MINOR) } #[derive(Debug, Clone, Copy, strum::FromRepr)] @@ -45,7 +50,7 @@ pub(crate) enum EfuseBlock { impl EfuseBlock { pub(crate) fn address(self) -> *const u32 { use EfuseBlock::*; - let efuse = unsafe { &*EFUSE::PTR }; + let efuse = EFUSE::regs(); match self { Block0 => efuse.rd_wr_dis().as_ptr(), Block1 => efuse.rd_mac_sys_0().as_ptr(), @@ -60,4 +65,4 @@ impl EfuseBlock { Block10 => efuse.rd_sys_part2_data0().as_ptr(), } } -} \ No newline at end of file +} diff --git a/esp-hal/src/efuse/mod.rs b/esp-hal/src/efuse/mod.rs index 35739bdf2cb..cb6b0c8b67c 100644 --- a/esp-hal/src/efuse/mod.rs +++ b/esp-hal/src/efuse/mod.rs @@ -44,6 +44,7 @@ use portable_atomic::AtomicU8; #[cfg_attr(esp32c6, path = "esp32c6/mod.rs")] #[cfg_attr(esp32c61, path = "esp32c61/mod.rs")] #[cfg_attr(esp32h2, path = "esp32h2/mod.rs")] +#[cfg_attr(esp32p4, path = "esp32p4/mod.rs")] #[cfg_attr(esp32s2, path = "esp32s2/mod.rs")] #[cfg_attr(esp32s3, path = "esp32s3/mod.rs")] pub(crate) mod implem; diff --git a/esp-hal/src/gpio/interrupt.rs b/esp-hal/src/gpio/interrupt.rs index df7c0451c3e..76d2aa45de3 100644 --- a/esp-hal/src/gpio/interrupt.rs +++ b/esp-hal/src/gpio/interrupt.rs @@ -231,6 +231,15 @@ impl InterruptStatusRegisterAccess { Self::Bank0 => GPIO::regs().status().read().bits(), Self::Bank1 => GPIO::regs().status1().read().bits(), } + } else if #[cfg(esp32p4)] { + // P4 PAC: intr_0() (Core0 GPIO interrupt status) + // Ref: esp-idf gpio_ll.h -- gpio_ll_get_intr_status() + // TRM v0.5 Ch 11 -- GPIO_STATUS_INT_REG + match self { + Self::Bank0 => GPIO::regs().intr_0().read().bits(), + #[cfg(gpio_has_bank_1)] + Self::Bank1 => GPIO::regs().intr1_0().read().bits(), + } } else { match self { Self::Bank0 => GPIO::regs().pcpu_int().read().bits(), diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 3dd791380a3..29f6621eba4 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -371,7 +371,7 @@ pub trait RtcPin: Pin { fn rtc_number(&self) -> u8; /// Configure the pin - #[cfg(any(xtensa, esp32c6))] + #[cfg(any(xtensa, esp32c6, esp32p4))] #[doc(hidden)] fn rtc_set_config(&self, input_enable: bool, mux: bool, func: RtcFunction); @@ -383,7 +383,7 @@ pub trait RtcPin: Pin { /// /// The `level` argument needs to be a valid setting for the /// `rtc_cntl.gpio_wakeup.gpio_pinX_int_type`. - #[cfg(any(esp32c3, esp32c2, esp32c6))] + #[cfg(any(esp32c3, esp32c2, esp32c6, esp32p4))] #[doc(hidden)] unsafe fn apply_wakeup(&self, wakeup: bool, level: u8); } @@ -1671,6 +1671,9 @@ impl<'lt> AnyPin<'lt> { { /// Workaround to make D+ and D- work when the pin is assigned to /// the `USB_SERIAL_JTAG` peripheral by default. + // P4 uses dedicated pins (GPIO49/50) for USB, so USB_DM/USB_DP are + // not in the analog function table -> this inner fn is unused on P4. + #[allow(dead_code)] fn disable_usb_pads(_gpionum: u8) { crate::peripherals::USB_DEVICE::regs() .conf0() @@ -2266,7 +2269,7 @@ impl RtcPin for AnyPin<'_> { } } - #[cfg(any(xtensa, esp32c6))] + #[cfg(any(xtensa, esp32c6, esp32p4))] fn rtc_set_config(&self, input_enable: bool, mux: bool, func: RtcFunction) { for_each_rtcio_pin! { (self, target) => { RtcPin::rtc_set_config(&target, input_enable, mux, func) }; @@ -2279,7 +2282,7 @@ impl RtcPin for AnyPin<'_> { } } - #[cfg(any(esp32c2, esp32c3, esp32c6))] + #[cfg(any(esp32c2, esp32c3, esp32c6, esp32p4))] unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) { for_each_rtcio_pin! { (self, target) => { unsafe { RtcPin::apply_wakeup(&target, wakeup, level) } }; diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index e704c80729b..100fda22af0 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -3366,6 +3366,15 @@ fn write_fifo(register_block: &RegisterBlock, data: u8) { unsafe { fifo_ptr.write_volatile(data as u32); } + } else if #[cfg(esp32p4)] { + // P4: data register is read-only (RX FIFO only). TX uses txfifo_start_addr. + // PAC txfifo_start_addr is also read-only in SVD, use direct MMIO. + // Ref: esp-idf i2c_ll.h -- i2c_ll_write_txfifo() uses HAL_FORCE_MODIFY + // TRM v0.5 Ch 48 -- I2C_TXFIFO_START_ADDR (offset 0x100) + let base = register_block as *const _ as usize; + unsafe { + ((base + 0x100) as *mut u32).write_volatile(data as u32); + } } else { register_block .data() diff --git a/esp-hal/src/interrupt/mod.rs b/esp-hal/src/interrupt/mod.rs index c9f48f7dd93..66639a9d885 100644 --- a/esp-hal/src/interrupt/mod.rs +++ b/esp-hal/src/interrupt/mod.rs @@ -198,19 +198,45 @@ impl InterruptStatus { match Cpu::current() { Cpu::ProCpu => InterruptStatus { status: core::array::from_fn(|idx| { - INTERRUPT_CORE0::regs() - .core_0_intr_status(idx) - .read() - .bits() + // P4: Status registers at base + 0x200 (4 x 32-bit = 128 sources) + // Ref: esp-idf interrupt_core0_reg.h + // INTERRUPT_CORE0_INTR_STATUS_REG_0_REG = base + 0x200 + // INTERRUPT_CORE0_INTR_STATUS_REG_1_REG = base + 0x204 + // INTERRUPT_CORE0_INTR_STATUS_REG_2_REG = base + 0x208 + // INTERRUPT_CORE0_INTR_STATUS_REG_3_REG = base + 0x20c + // TRM v0.5 Ch 14 + #[cfg(esp32p4)] + { + let base = crate::soc::registers::INTERRUPT_MAP_BASE + 0x200; + unsafe { ((base as *const u32).add(idx)).read_volatile() } + } + #[cfg(not(esp32p4))] + { + INTERRUPT_CORE0::regs() + .core_0_intr_status(idx) + .read() + .bits() + } }), }, #[cfg(multi_core)] Cpu::AppCpu => InterruptStatus { status: core::array::from_fn(|idx| { - INTERRUPT_CORE1::regs() - .core_1_intr_status(idx) - .read() - .bits() + // P4 Core1: base + 0x800 + 0x200 + // Ref: esp-idf interrupt_core1_reg.h + // INTERRUPT_CORE1 = INTERRUPT_CORE0 + 0x800 + #[cfg(esp32p4)] + { + let base = crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU + 0x200; + unsafe { ((base as *const u32).add(idx)).read_volatile() } + } + #[cfg(not(esp32p4))] + { + INTERRUPT_CORE1::regs() + .core_1_intr_status(idx) + .read() + .bits() + } }), }, } @@ -352,6 +378,25 @@ pub fn disable(core: Cpu, interrupt: Interrupt) { } pub(super) fn map_raw(core: Cpu, interrupt: Interrupt, cpu_interrupt: u32) { + // P4: 120 individual INT_MAP registers at sequential 4-byte offsets from base. + // Each register has 6-bit field [5:0] for CPU interrupt line (0-63). + // Core0: base = 0x500D_6000, Core1: base = 0x500D_6800 + // Ref: esp-idf interrupt_core0_reg.h -- LP_RTC_INT_MAP_REG at offset 0x0, + // LP_WDT_INT_MAP_REG at offset 0x4, etc. + // TRM v0.5 Ch 14 + #[cfg(esp32p4)] + { + let base = match core { + Cpu::ProCpu => crate::soc::registers::INTERRUPT_MAP_BASE, + #[cfg(multi_core)] + Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU, + }; + unsafe { + let reg = (base as *mut u32).add(interrupt as usize); + reg.write_volatile(cpu_interrupt); + } + } + #[cfg(not(esp32p4))] match core { Cpu::ProCpu => { INTERRUPT_CORE0::regs() @@ -373,6 +418,21 @@ pub(crate) fn mapped_to(cpu: Cpu, interrupt: Interrupt) -> Option } pub(crate) fn mapped_to_raw(cpu: Cpu, interrupt: u32) -> Option { + // P4: read INT_MAP register directly. 6-bit field [5:0] = CPU interrupt line. + // Ref: esp-idf interrupt_core0_reg.h, TRM v0.5 Ch 14 + #[cfg(esp32p4)] + let cpu_intr = { + let base = match cpu { + Cpu::ProCpu => crate::soc::registers::INTERRUPT_MAP_BASE, + #[cfg(multi_core)] + Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU, + }; + unsafe { + let reg = (base as *const u32).add(interrupt as usize); + reg.read_volatile() & 0x3F // 6-bit field + } + }; + #[cfg(not(esp32p4))] let cpu_intr = match cpu { Cpu::ProCpu => INTERRUPT_CORE0::regs() .core_0_intr_map(interrupt as usize) diff --git a/esp-hal/src/interrupt/riscv.rs b/esp-hal/src/interrupt/riscv.rs index acfba33ee2d..ee76a45d73c 100644 --- a/esp-hal/src/interrupt/riscv.rs +++ b/esp-hal/src/interrupt/riscv.rs @@ -312,6 +312,16 @@ pub fn enable_direct( let clic = unsafe { crate::soc::pac::CLIC::steal() }; // Enable hardware vectoring + #[cfg(esp32p4)] + clic.int_ctrl(cpu_interrupt as usize).modify(|_, w| unsafe { + // P4: CLIC uses consolidated int_ctrl register (not separate int_attr). + // int_ctrl contains: int_ip[0], int_ie[8], int_attr_shv[16], + // int_attr_trig[17:18], int_attr_mode[22:23], int_ctl[24:31] + // Ref: esp-idf clic_reg.h, TRM v0.5 Ch 2/14 + w.int_attr_shv().set_bit(); + w.int_attr_trig().bits(0) // positive level + }); + #[cfg(not(esp32p4))] clic.int_attr(cpu_interrupt as usize).modify(|_, w| { w.shv().hardware(); w.trig().positive_level() @@ -409,6 +419,14 @@ fn cpu_wait_mode_on() -> bool { cfg_if::cfg_if! { if #[cfg(soc_has_pcr)] { crate::peripherals::PCR::regs().cpu_waiti_conf().read().cpu_wait_mode_force_on().bit_is_set() + } else if #[cfg(esp32p4)] { + // P4: CPU_WAITI_CTRL0_REG in HP_SYS_CLKRST (offset 0xf4) controls + // whether WFI gates the clock. Default: core0_waiti_icg_en=1 (enabled). + // This register is only in hw_ver3 (eco5+), not in current PAC. + // Ref: esp-idf hp_sys_clkrst_reg.h -- HP_SYS_CLKRST_CPU_WAITI_CTRL0_REG + // TRM v0.5 Ch 22 (v3.x addition) + // Return true (WFI clock gating active) -- matches default hardware state. + true } else { crate::peripherals::SYSTEM::regs() .cpu_per_conf() diff --git a/esp-hal/src/interrupt/riscv/clic.rs b/esp-hal/src/interrupt/riscv/clic.rs index 65fafca0c1a..839aee5f4a2 100644 --- a/esp-hal/src/interrupt/riscv/clic.rs +++ b/esp-hal/src/interrupt/riscv/clic.rs @@ -6,33 +6,73 @@ pub(super) fn init() { let clic = unsafe { CLIC::steal() }; // Set 3 level bits = 8 priority levels - clic.int_config() - .modify(|_, w| unsafe { w.mnlbits().bits(3) }); + // P4 PAC: int_config_nlbits() (not mnlbits()) + // Ref: esp-idf clic_reg.h -- CLIC_INT_CONFIG_REG, nlbits field + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + clic.int_config() + .modify(|_, w| unsafe { w.int_config_nlbits().bits(3) }); + } else { + clic.int_config() + .modify(|_, w| unsafe { w.mnlbits().bits(3) }); + } + } // Enable hardware vectoring - for int in clic.int_attr_iter() { - int.modify(|_, w| { - w.shv().hardware(); - w.trig().positive_level() - }); + // ESP32-P4 uses consolidated int_ctrl registers; C5/C61 use separate int_attr. + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + for int in clic.int_ctrl_iter() { + int.modify(|_, w| unsafe { + w.int_attr_shv().set_bit(); + w.int_attr_trig().bits(0) // positive level + }); + } + } else { + for int in clic.int_attr_iter() { + int.modify(|_, w| { + w.shv().hardware(); + w.trig().positive_level() + }); + } + } } } pub(super) fn enable_cpu_interrupt_raw(cpu_interrupt: u32) { // Lower 16 interrupts are reserved for CLINT, which is currently not implemented. let clic = unsafe { CLIC::steal() }; - clic.int_ie(cpu_interrupt as usize) - .write(|w| w.int_ie().set_bit()); + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + clic.int_ctrl(cpu_interrupt as usize) + .modify(|_, w| w.int_ie().set_bit()); + } else { + clic.int_ie(cpu_interrupt as usize) + .write(|w| w.int_ie().set_bit()); + } + } } pub(super) fn set_kind_raw(cpu_interrupt: u32, kind: InterruptKind) { // Lower 16 interrupts are reserved for CLINT, which is currently not implemented. let clic = unsafe { CLIC::steal() }; - clic.int_attr(cpu_interrupt as usize) - .modify(|_, w| match kind { - InterruptKind::Level => w.trig().positive_level(), - InterruptKind::Edge => w.trig().positive_edge(), - }); + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + clic.int_ctrl(cpu_interrupt as usize) + .modify(|_, w| unsafe { + w.int_attr_trig().bits(match kind { + InterruptKind::Level => 0, // positive level + InterruptKind::Edge => 1, // positive edge + }) + }); + } else { + clic.int_attr(cpu_interrupt as usize) + .modify(|_, w| match kind { + InterruptKind::Level => w.trig().positive_level(), + InterruptKind::Edge => w.trig().positive_edge(), + }); + } + } } pub(super) fn set_priority_raw(cpu_interrupt: u32, priority: Priority) { @@ -43,21 +83,41 @@ pub(super) fn set_priority_raw(cpu_interrupt: u32, priority: Priority) { ))); // The `ctl` field would only write the 3 programmable bits, but we have the correct final // value anyway so let's write it directly. - clic.int_ctl(cpu_interrupt as usize) - .write(|w| unsafe { w.bits(prio_bits) }); + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + clic.int_ctrl(cpu_interrupt as usize) + .modify(|_, w| unsafe { w.int_ctl().bits(prio_bits) }); + } else { + clic.int_ctl(cpu_interrupt as usize) + .write(|w| unsafe { w.bits(prio_bits) }); + } + } } pub(super) fn clear_raw(cpu_interrupt: u32) { // Lower 16 interrupts are reserved for CLINT, which is currently not implemented. let clic = unsafe { CLIC::steal() }; - clic.int_ip(cpu_interrupt as usize) - .write(|w| w.int_ip().clear_bit()); + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + clic.int_ctrl(cpu_interrupt as usize) + .modify(|_, w| w.int_ip().clear_bit()); + } else { + clic.int_ip(cpu_interrupt as usize) + .write(|w| w.int_ip().clear_bit()); + } + } } pub(super) fn cpu_interrupt_priority_raw(cpu_interrupt: u32) -> u8 { // Lower 16 interrupts are reserved for CLINT, which is currently not implemented. let clic = unsafe { CLIC::steal() }; - let prio_level = clic.int_ctl(cpu_interrupt as usize).read().bits() as usize; + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + let prio_level = clic.int_ctrl(cpu_interrupt as usize).read().int_ctl().bits() as usize; + } else { + let prio_level = clic.int_ctl(cpu_interrupt as usize).read().bits() as usize; + } + } bits_to_prio(prio_level) } diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index 46e7733397a..8cd16a77c94 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -721,13 +721,9 @@ pub fn init(config: Config) -> Peripherals { #[cfg(soc_cpu_has_branch_predictor)] { - // Enable branch predictor - // Note that the branch predictor will start cache requests and needs to be disabled when - // the cache is disabled. - // MHCR: CSR 0x7c1 - const MHCR_RS: u32 = 1 << 4; // R/W, address return stack set bit - const MHCR_BFE: u32 = 1 << 5; // R/W, allow predictive jump set bit - const MHCR_BTB: u32 = 1 << 12; // R/W, branch target prediction enable bit + const MHCR_RS: u32 = 1 << 4; + const MHCR_BFE: u32 = 1 << 5; + const MHCR_BTB: u32 = 1 << 12; unsafe { core::arch::asm!("csrrs x0, 0x7c1, {0}", in(reg) MHCR_RS | MHCR_BFE | MHCR_BTB); } @@ -743,35 +739,45 @@ pub fn init(config: Config) -> Peripherals { Clocks::init(config.clock_config()); - // RTC domain must be enabled before we try to disable let mut rtc = crate::rtc_cntl::Rtc::new(peripherals.LPWR.reborrow()); #[cfg(sleep_driver_supported)] - crate::rtc_cntl::sleep::RtcSleepConfig::base_settings(&rtc); + { + crate::rtc_cntl::sleep::RtcSleepConfig::base_settings(&rtc); + } - // Disable watchdog timers #[cfg(swd)] - rtc.swd.disable(); + { + rtc.swd.disable(); + } rtc.rwdt.disable(); #[cfg(timergroup_timg0)] - crate::timer::timg::Wdt::>::new().disable(); + { + crate::timer::timg::Wdt::>::new().disable(); + } #[cfg(timergroup_timg1)] - crate::timer::timg::Wdt::>::new().disable(); + { + crate::timer::timg::Wdt::>::new().disable(); + } crate::time::implem::time_init(); #[cfg(gpio_driver_supported)] - crate::gpio::interrupt::bind_default_interrupt_handler(); + { + crate::gpio::interrupt::bind_default_interrupt_handler(); + } unsafe { esp_rom_sys::init_syscall_table(); } #[cfg(all(riscv, write_vec_table_monitoring))] - crate::soc::setup_trap_section_protection(); + { + crate::soc::setup_trap_section_protection(); + } peripherals } diff --git a/esp-hal/src/psram/esp32p4.rs b/esp-hal/src/psram/esp32p4.rs new file mode 100644 index 00000000000..a418e435950 --- /dev/null +++ b/esp-hal/src/psram/esp32p4.rs @@ -0,0 +1,475 @@ +//! PSRAM driver for ESP32-P4X (chip revision v3.x / eco5). +//! +//! P4 PSRAM uses HEX (16-line) mode via dedicated MSPI2/3 controller. +//! Memory mapped at 0x4800_0000 - 0x4C00_0000 (64 MB via cache/MMU). +//! +//! Init sequence (from esp-idf esp_psram_impl_ap_hex.c): +//! 1. MPLL enable (400 MHz for 200MHz PSRAM bus clock) +//! 2. MSPI2/3 module clock enable + clock source = MPLL +//! 3. Bus clock divider (MPLL/2 = 200MHz) +//! 4. PSRAM read/write command config (HEX sync mode) +//! 5. Address, dummy, DDR mode config +//! 6. AXI access enable +//! 7. Cache/MMU page mapping +//! +//! Ref: esp-idf components/esp_psram/device/esp_psram_impl_ap_hex.c +//! esp-idf components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h +//! esp-idf components/soc/esp32p4/include/soc/regi2c_mpll.h +//! esp-idf components/hal/esp32p4/include/hal/mmu_ll.h +//! TRM v0.5 Ch 9 (System and Memory) + +/// PSRAM virtual address range (cached) +/// Ref: esp-idf ext_mem_defs.h -- SOC_IRAM_PSRAM_ADDRESS_LOW/HIGH +pub const PSRAM_VADDR_START: usize = 0x4800_0000; + +/// MMU page size (64 KB) +const MMU_PAGE_SIZE: usize = 0x10000; + +/// PSRAM configuration. +#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[instability::unstable] +pub struct PsramConfig { + /// Size of PSRAM to map + pub size: super::PsramSize, +} + +/// Initialize PSRAM. +/// +/// Ref: esp-idf esp_psram_impl_enable() in esp_psram_impl_ap_hex.c +pub(crate) fn init_psram(config: PsramConfig) { + // 1. Enable MPLL (400 MHz) for PSRAM clock + // Ref: esp-idf clk_tree_ll.h -- clk_ll_mpll_enable(), clk_ll_mpll_set_config() + // regi2c_mpll.h -- I2C_MPLL = 0x63 + configure_mpll(400); + + // 2. Enable PSRAM controller clock and select MPLL source + // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_enable_module_clock() + // HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_en = 1 + // HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_src_sel = 1 (MPLL) + let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + // Ref: esp-idf clk_gate_ll.h -- psram_ctrlr_ll_enable_module_clock() + clkrst.peri_clk_ctrl00().modify(|_, w| unsafe { + w.psram_pll_clk_en().set_bit(); + w.psram_core_clk_en().set_bit(); + w.psram_clk_src_sel().bits(1) // 1 = MPLL + }); + + // 3. Set bus clock divider: MPLL(400MHz) / 2 = 200MHz PSRAM bus + // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_set_bus_clock() + // SPI_MEM_S_SRAM_CLK_REG: SCLKCNT_N=1, SCLKCNT_H=0, SCLKCNT_L=1 + // TODO(P4X): These registers are in SPIMEM2 which may not be in PAC. + // Using direct MMIO for now. + // PSRAM MSPI controller base + // Ref: esp-idf reg_base.h -- DR_REG_PSRAM_MSPI0_BASE = 0x5008_E000 + const PSRAM_MSPI_BASE: u32 = 0x5008_E000; + + // 3a. Set PSRAM bus clock divider: MPLL(400MHz) / 2 = 200MHz + // Ref: SPI_MEM_S_SRAM_CLK_REG offset from PSRAM_MSPI_BASE + // sclkcnt_n=1, sclkcnt_h=0, sclkcnt_l=1 + // TODO(P4X): verify exact register offset for SRAM_CLK_REG + // const SRAM_CLK_OFFSET: u32 = ...; // need to find from spi_mem_s_reg.h + + // 3b. Configure PSRAM read/write commands for HEX sync mode + // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_set_rd_cmd/wr_cmd() + // SPI_MEM_S_CACHE_SCTRL_REG: cache_sram_usr_rcmd, cache_sram_usr_wcmd + // SPI_MEM_S_SRAM_DRD_CMD_REG: cmd_bitlen=15, cmd_value=0x0000 (sync read) + // SPI_MEM_S_SRAM_DWR_CMD_REG: cmd_bitlen=15, cmd_value=0x8080 (sync write) + + // 3c. Set address length (32-bit) and dummy cycles + // SPI_MEM_S_CACHE_SCTRL_REG: sram_addr_bitlen=31 (32-bit) + // rdummy_cyclelen=13 (14-1 at 200MHz), wdummy_cyclelen=6 (7-1) + + // 3d. Enable DDR mode + // SPI_MEM_S_SMEM_DDR_REG: smem_ddr_en=1 + + // 3e. Enable HEX data lines + // SPI_MEM_S_SRAM_CMD_REG: sdin_hex=1, sdout_hex=1 + + // 3f. Enable AXI access + // SPI_MEM_S_CACHE_FCTRL_REG: axi_req_en=1 + + // 4. Configure PSRAM MSPI controller + // Ref: esp-idf psram_ctrlr_ll.h, spi_mem_s_reg.h + // PSRAM_MSPI_BASE = 0x5008_E000 + configure_psram_mspi(PSRAM_MSPI_BASE); + + // 5. Map PSRAM via MMU (0x48000000 virtual -> physical) + // Ref: esp-idf mmu_ll.h -- mmu_ll_write_entry() + mmu_map_psram(PSRAM_MSPI_BASE, config); + + // Determine PSRAM size + let psram_size = match config.size { + super::PsramSize::AutoDetect => psram_detect_size(PSRAM_MSPI_BASE), + super::PsramSize::Size(s) => s, + }; + + // Set PSRAM range (virtual address space) + if psram_size > 0 { + let start = PSRAM_VADDR_START; + let end = start + psram_size; + unsafe { super::set_psram_range(start..end) }; + } + + // TODO(P4X): Full PSRAM init needs: + // - SPIMEM2 read/write command configuration (HEX sync mode) + // - Address bitlen (32-bit), dummy cycles (14 read, 7 write at 200MHz) + // - CS timing, DDR mode enable + // - HEX data line mode (sdin_hex, sdout_hex) + // - AXI access enable (mem_axi_req_en) + // - Cache/MMU page mapping (SPI_MEM_S_MMU_ITEM_INDEX/CONTENT) + // - AP HEX PSRAM mode register initialization (MR0-MR8) + // - Timing calibration + // + // Without these, PSRAM memory at 0x48000000 is NOT accessible. + // The ROM bootloader may have already initialized PSRAM if esp-idf + // 2nd-stage bootloader was used. +} + +/// Detect PSRAM size by reading mode register MR2 via MSPI direct SPI command. +/// +/// AP HEX PSRAM MR2 format (bits [2:0] = density): +/// 0x1 = 32 Mbit (4 MB) +/// 0x3 = 64 Mbit (8 MB) +/// 0x5 = 128 Mbit (16 MB) +/// 0x7 = 256 Mbit (32 MB) +/// +/// Read sequence: issue SPI command 0x40 (read MR), address 0x2 (MR2 index), +/// capture 8-bit MISO response. +/// +/// Safety: if the MSPI controller is not in a known-good state or the command +/// hangs, we fall back to 32 MB (EV Board default). This is conservative but +/// avoids bricking on chips without PSRAM populated. +/// +/// Ref: esp-idf esp_psram_impl_ap_hex.c -- psram_detect_size() +/// TRM v0.5 Ch 9 (MSPI) -- USER/CMD/ADDR/MISO registers +fn psram_detect_size(mspi_base: u32) -> usize { + const SPI_CMD: u32 = 0x00; + const SPI_ADDR: u32 = 0x04; + const SPI_USER: u32 = 0x18; + const SPI_USER1: u32 = 0x1C; + const SPI_USER2: u32 = 0x20; + const SPI_MISO_DLEN: u32 = 0x28; + const SPI_W0: u32 = 0x58; + + // USER: usr_command=bit31, usr_addr=bit30, usr_miso=bit28 + const USR_COMMAND: u32 = 1 << 31; + const USR_ADDR: u32 = 1 << 30; + const USR_MISO: u32 = 1 << 28; + // CMD: usr=bit18 + const CMD_USR: u32 = 1 << 18; + + unsafe { + // Command: 0x40 (read MR), command bitlen=7 (8-1) + ((mspi_base + SPI_USER2) as *mut u32).write_volatile((7 << 28) | 0x40); + // Address: MR2 index = 0x2, address bitlen=7 (8-1) in USER1 bits [31:26] + ((mspi_base + SPI_USER1) as *mut u32).write_volatile(7 << 26); + ((mspi_base + SPI_ADDR) as *mut u32).write_volatile(0x2); + // MISO length: 8-1 = 7 bits + ((mspi_base + SPI_MISO_DLEN) as *mut u32).write_volatile(7); + // Enable command + address + MISO phases + ((mspi_base + SPI_USER) as *mut u32).write_volatile(USR_COMMAND | USR_ADDR | USR_MISO); + + // Trigger transaction + ((mspi_base + SPI_CMD) as *mut u32).write_volatile(CMD_USR); + + // Wait for completion with timeout + let mut timeout = 100_000u32; + while ((mspi_base + SPI_CMD) as *const u32).read_volatile() & CMD_USR != 0 { + timeout -= 1; + if timeout == 0 { + // Timeout -> fall back to default (EV Board = 32 MB) + return 32 * 1024 * 1024; + } + } + + // Read MR2 response from W0 register (low 8 bits) + let mr2 = ((mspi_base + SPI_W0) as *const u32).read_volatile() & 0xFF; + + // Decode density field [2:0] + match mr2 & 0x7 { + 0x1 => 4 * 1024 * 1024, // 32 Mbit = 4 MB + 0x3 => 8 * 1024 * 1024, // 64 Mbit = 8 MB + 0x5 => 16 * 1024 * 1024, // 128 Mbit = 16 MB + 0x7 => 32 * 1024 * 1024, // 256 Mbit = 32 MB + _ => { + // Unknown/invalid response -> fall back to EV Board default + 32 * 1024 * 1024 + } + } + } +} + +/// Map PSRAM physical pages into the virtual address space via MMU. +/// +/// Each MMU entry maps a 64 KB virtual page to a physical PSRAM page. +/// Virtual address range: 0x4800_0000 + page_idx * 0x10000 +/// +/// MMU entry format (SPI_MEM_S): +/// - Bit 15: MMU_VALID (1 = entry active) +/// - Bit 14: MMU_TYPE (0 = Flash, 1 = PSRAM) +/// - Bits [13:0]: Physical page number +/// +/// Ref: esp-idf mmu_ll.h -- mmu_ll_write_entry(), mmu_ll_check_valid_ext_vaddr() +/// esp-idf ext_mem_layout.h -- SOC_MMU_ENTRY_NUM, SOC_MMU_PAGE_SIZE +/// TRM v0.5 Ch 9 (System and Memory) -- MMU configuration +fn mmu_map_psram(mspi_base: u32, config: PsramConfig) { + const MMU_ITEM_INDEX: u32 = 0x380; + const MMU_ITEM_CONTENT: u32 = 0x37C; + const MMU_VALID: u32 = 1 << 15; + const MMU_TYPE_PSRAM: u32 = 1 << 14; + const MMU_INVALID_ENTRY: u32 = 0x4000; // bit 14 set, valid cleared = invalid + + let psram_size = match config.size { + super::PsramSize::AutoDetect => 32 * 1024 * 1024, // default 32 MB + super::PsramSize::Size(s) => s, + }; + + let page_count = psram_size / MMU_PAGE_SIZE; + + // Calculate the starting MMU entry index for PSRAM virtual address + // PSRAM virtual starts at 0x4800_0000. The MMU entry index depends on + // the overall virtual address map layout. For P4, PSRAM region starts + // at a fixed offset in the MMU table. + // Ref: esp-idf mmu_ll.h -- mmu_ll_get_entry_id() + // The formula: entry_id = (vaddr - SOC_MMU_VADDR_BASE) / MMU_PAGE_SIZE + // SOC_MMU_VADDR_BASE = 0x4000_0000 (flash mapping start) + // PSRAM at 0x4800_0000: entry_id = (0x4800_0000 - 0x4000_0000) / 0x10000 = 0x800 + const PSRAM_MMU_START_ENTRY: u32 = 0x800; + + // Disable data cache before modifying MMU + // Ref: esp-idf cache_ll.h -- cache_ll_l1_disable_cache() + cache_suspend(); + + unsafe { + let index_reg = (mspi_base + MMU_ITEM_INDEX) as *mut u32; + let content_reg = (mspi_base + MMU_ITEM_CONTENT) as *mut u32; + + for page in 0..page_count { + let entry_id = PSRAM_MMU_START_ENTRY + page as u32; + let content = MMU_VALID | MMU_TYPE_PSRAM | (page as u32 & 0x3FFF); + + // Write entry: set index, then write content + index_reg.write_volatile(entry_id); + content_reg.write_volatile(content); + } + } + + // Re-enable data cache + cache_resume(); +} + +/// Suspend L1 data cache for MMU/cache configuration. +/// +/// Must be paired with cache_resume(). +/// +/// Ref: esp-idf cache_ll.h -- cache_ll_l1_disable_cache() +/// L1_DCACHE_CTRL register: shut_dbus0, shut_dbus1, shut_dma bits +fn cache_suspend() { + let cache = unsafe { &*crate::pac::CACHE::PTR }; + cache + .l1_dcache_ctrl() + .modify(|_, w| w.l1_dcache_shut_dbus0().set_bit()); + + // Wait for cache to idle + while !cache + .l1_dcache_autoload_ctrl() + .read() + .l1_dcache_autoload_done() + .bit_is_set() + { + core::hint::spin_loop(); + } +} + +/// Resume L1 data cache after MMU/cache configuration. +/// +/// Ref: esp-idf cache_ll.h -- cache_ll_l1_enable_cache() +fn cache_resume() { + let cache = unsafe { &*crate::pac::CACHE::PTR }; + cache + .l1_dcache_ctrl() + .modify(|_, w| w.l1_dcache_shut_dbus0().clear_bit()); +} + +/// Invalidate L1 data cache for a given address range. +/// +/// Required after DMA transfers to ensure CPU sees fresh data. +/// +/// Ref: esp-idf cache_ll.h -- cache_ll_l1_invalidate_cache() +/// CACHE.sync_ctrl, sync_addr, sync_size +#[allow(dead_code)] +pub(crate) fn cache_invalidate(addr: u32, size: u32) { + let cache = unsafe { &*crate::pac::CACHE::PTR }; + + cache + .sync_addr() + .write(|w| unsafe { w.bits(addr) }); + cache + .sync_size() + .write(|w| unsafe { w.bits(size) }); + + // Trigger invalidate: sync_ctrl.invalidate_ena + cache + .sync_ctrl() + .modify(|_, w| w.invalidate_ena().set_bit()); + + // Wait for completion + while !cache + .sync_ctrl() + .read() + .sync_done() + .bit_is_set() + { + core::hint::spin_loop(); + } +} + +/// Write back L1 data cache for a given address range. +/// +/// Required before DMA transfers to ensure DMA sees latest CPU writes. +/// +/// Ref: esp-idf cache_ll.h -- cache_ll_l1_writeback_cache() +#[allow(dead_code)] +pub(crate) fn cache_writeback(addr: u32, size: u32) { + let cache = unsafe { &*crate::pac::CACHE::PTR }; + + cache + .sync_addr() + .write(|w| unsafe { w.bits(addr) }); + cache + .sync_size() + .write(|w| unsafe { w.bits(size) }); + + // Trigger writeback: sync_ctrl.writeback_ena + cache + .sync_ctrl() + .modify(|_, w| w.writeback_ena().set_bit()); + + while !cache + .sync_ctrl() + .read() + .sync_done() + .bit_is_set() + { + core::hint::spin_loop(); + } +} + +/// Configure MPLL to target frequency for PSRAM clock. +/// +/// Ref: esp-idf clk_tree_ll.h:475-519 -- clk_ll_mpll_set_config() +/// regi2c_mpll.h -- I2C_MPLL = 0x63 +fn configure_mpll(freq_mhz: u32) { + use crate::soc::regi2c; + + const I2C_MPLL: u8 = 0x63; + // Ref: esp-idf soc/esp32p4/include/soc/regi2c_mpll.h + const I2C_MPLL_DIV_REG_ADDR: u8 = 2; + const I2C_MPLL_DHREF: u8 = 3; + const I2C_MPLL_IR_CAL_RSTB: u8 = 5; + + // Enable MPLL power + // Ref: esp-idf clk_tree_ll.h -- clk_ll_mpll_enable() + // PMU.rf_pwc: mspi_phy_xpd + // LP_AON_CLKRST: hp_mpll_500m_clk_en + // TODO(P4X): PMU rf_pwc register access for MPLL power + + // Calculate divider: MPLL_freq = XTAL(40MHz) * (div+1) / (ref_div+1) + // For 400MHz: ref_div=1, div=19 -> 40*20/2 = 400MHz + // Ref: esp-idf clk_tree_ll.h:508 + let div_val: u8 = match freq_mhz { + 400 => (9 << 3) | 1, // div=9, ref_div=1 -> 40*10/2 = 200... needs recalc + 500 => (12 << 3) | 1, // div=12, ref_div=1 + _ => (9 << 3) | 1, // default 400MHz + }; + + // MPLL calibration sequence + // Ref: esp-idf clk_tree_ll.h:484-498 + // 1. Set DHREF bits [5:4] = 3 + let dhref = regi2c::regi2c_read(I2C_MPLL, 0, I2C_MPLL_DHREF); + regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_DHREF, dhref | (3 << 4)); + + // 2. Toggle IR_CAL_RSTB bit 5 + let rstb = regi2c::regi2c_read(I2C_MPLL, 0, I2C_MPLL_IR_CAL_RSTB); + regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_IR_CAL_RSTB, rstb & 0xDF); + regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_IR_CAL_RSTB, rstb | (1 << 5)); + + // 3. Write divider + regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_DIV_REG_ADDR, div_val); + + // 4. Run calibration + // Ref: HP_SYS_CLKRST.ana_pll_ctrl0.reg_mspi_cal_stop/end + let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + clkrst + .ana_pll_ctrl0() + .modify(|_, w| w.mspi_cal_stop().clear_bit()); + while !clkrst.ana_pll_ctrl0().read().mspi_cal_end().bit_is_set() { + core::hint::spin_loop(); + } + clkrst + .ana_pll_ctrl0() + .modify(|_, w| w.mspi_cal_stop().set_bit()); + + crate::rom::ets_delay_us(10); +} + +/// Configure PSRAM MSPI controller registers for HEX mode operation. +/// +/// Ref: esp-idf psram_ctrlr_ll.h, spi_mem_s_reg.h +/// All offsets relative to PSRAM_MSPI_BASE (0x5008_E000) +fn configure_psram_mspi(base: u32) { + // Register offsets from spi_mem_s_reg.h + const CACHE_FCTRL: u32 = 0x3C; + const CACHE_SCTRL: u32 = 0x40; + const SRAM_CMD: u32 = 0x44; + const SRAM_DRD_CMD: u32 = 0x48; + const SRAM_DWR_CMD: u32 = 0x4C; + const SMEM_DDR: u32 = 0xD8; + + unsafe { + // 1. Configure read command: 16-bit sync read (0x0000) + // SPI_MEM_S_CACHE_SCTRL: cache_sram_usr_rcmd=1 + // SPI_MEM_S_SRAM_DRD_CMD: cmd_bitlen=15, cmd_value=0 + let sctrl = (base + CACHE_SCTRL) as *mut u32; + let val = sctrl.read_volatile(); + let val = val | (1 << 20); // cache_sram_usr_rcmd = 1 + let val = val | (1 << 5); // cache_sram_usr_wcmd = 1 + // sram_addr_bitlen = 31 (32-bit address) + let val = (val & !(0x3F << 14)) | (31 << 14); + // usr_rd_sram_dummy = 1, sram_rdummy_cyclelen = 13 (14-1 for 200MHz) + let val = val | (1 << 22); // usr_rd_sram_dummy + let val = (val & !(0x3F << 6)) | (13 << 6); // rdummy_cyclelen + // cache_usr_saddr_4byte = 1 + let val = val | (1 << 24); + sctrl.write_volatile(val); + + // Read command: sync read 0x0000, bitlen=15 + let drd = (base + SRAM_DRD_CMD) as *mut u32; + drd.write_volatile((15 << 28) | 0x0000); // bitlen[31:28]=15, value[15:0]=0 + + // Write command: sync write 0x8080, bitlen=15 + let dwr = (base + SRAM_DWR_CMD) as *mut u32; + dwr.write_volatile((15 << 28) | 0x8080); + + // 2. Enable DDR mode + let ddr = (base + SMEM_DDR) as *mut u32; + let val = ddr.read_volatile(); + ddr.write_volatile(val | 1); // smem_ddr_en = 1 + + // 3. Enable HEX (16-line) data mode + let sram_cmd = (base + SRAM_CMD) as *mut u32; + let val = sram_cmd.read_volatile(); + // sdin_hex (bit 4) and sdout_hex (bit 5) -- exact bit positions need verification + // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_set_line_mode() + let val = val | (1 << 4) | (1 << 5); // HEX mode data lines + sram_cmd.write_volatile(val); + + // 4. Enable AXI access + let fctrl = (base + CACHE_FCTRL) as *mut u32; + let val = fctrl.read_volatile(); + let val = val | (1 << 0); // mem_axi_req_en = 1 + let val = val & !(1 << 1); // close_axi_inf_en = 0 + fctrl.write_volatile(val); + } +} diff --git a/esp-hal/src/psram/mod.rs b/esp-hal/src/psram/mod.rs index 11fe01c73ee..9d1e494daf9 100644 --- a/esp-hal/src/psram/mod.rs +++ b/esp-hal/src/psram/mod.rs @@ -47,6 +47,7 @@ use core::ops::Range; #[cfg_attr(esp32s2, path = "esp32s2.rs")] #[cfg_attr(esp32s3, path = "esp32s3.rs")] #[cfg_attr(any(esp32c5, esp32c61), path = "esp32c5_c61.rs")] +#[cfg_attr(esp32p4, path = "esp32p4.rs")] pub(crate) mod implem; pub use implem::*; diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index b76f923ff1e..75d96eca9b5 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -136,6 +136,7 @@ pub mod sleep; #[cfg_attr(esp32c6, path = "rtc/esp32c6.rs")] #[cfg_attr(esp32c61, path = "rtc/esp32c61.rs")] #[cfg_attr(esp32h2, path = "rtc/esp32h2.rs")] +#[cfg_attr(esp32p4, path = "rtc/esp32p4.rs")] #[cfg_attr(esp32s2, path = "rtc/esp32s2.rs")] #[cfg_attr(esp32s3, path = "rtc/esp32s3.rs")] pub(crate) mod rtc; @@ -414,6 +415,15 @@ impl<'d> Rtc<'d> { // ESP32-S3: TRM v1.5 chapter 8.3 // ESP32-H2: TRM v0.5 chapter 8.2.3 + // P4: store registers are in LP_SYS (mapped as LP_AON). + // Ref: esp-idf rom/rtc.h -- RTC_XTAL_FREQ_REG = LP_SYSTEM_REG_LP_STORE4_REG + // RTC_DISABLE_ROM_LOG = (1<<0)|(1<<16) + // esp-idf rtc_suppress_rom_log() uses LP_STORE4 + #[cfg(esp32p4)] + LP_AON::regs() + .lp_store4() + .modify(|r, w| unsafe { w.bits(r.bits() | Self::RTC_DISABLE_ROM_LOG) }); + #[cfg(not(esp32p4))] LP_AON::regs() .store4() .modify(|r, w| unsafe { w.bits(r.bits() | Self::RTC_DISABLE_ROM_LOG) }); @@ -487,6 +497,10 @@ pub enum RwdtStage { pub struct Rwdt(()); /// RTC Watchdog Timer driver. +/// +/// ESP32-P4 LP_WDT PAC uses different register names (config0 vs wdtconfig0, +/// lp_wdt vs wdt, etc.). P4-specific implementation is a TODO. +#[cfg(not(esp32p4))] impl Rwdt { /// Enable the watchdog timer instance. /// Watchdog starts with default settings (`stage 0` resets the system, the @@ -635,6 +649,139 @@ impl Rwdt { } } +/// ESP32-P4 LP_WDT implementation. +/// P4 PAC uses config0/config1/.../feed/wprotect (no "wdt" prefix), +/// and interrupt field is `lp_wdt` (not `wdt`). +/// Ref: esp-idf lp_wdt_reg.h, lpwdt_ll.h +/// TRM v0.5 Ch 19 (Watchdog Timers) +/// Write protection key: 0x50D8_3AA1 (same as other chips) +#[cfg(esp32p4)] +impl Rwdt { + /// Enable the watchdog timer instance. + pub fn enable(&mut self) { + self.set_enabled(true); + } + + /// Disable the watchdog timer instance. + pub fn disable(&mut self) { + self.set_enabled(false); + } + + /// Listen for interrupts on stage 0. + pub fn listen(&mut self) { + let rtc_cntl = LP_WDT::regs(); + self.set_write_protection(false); + // Ref: esp-idf lpwdt_ll.h -- lpwdt_ll_set_wdt_config0() + rtc_cntl + .config0() + .modify(|_, w| unsafe { w.wdt_stg0().bits(RwdtStageAction::Interrupt as u8) }); + // P4 PAC: int_ena().lp_wdt() (not .wdt()) + rtc_cntl.int_ena().modify(|_, w| w.lp_wdt().set_bit()); + self.set_write_protection(true); + } + + /// Stop listening for interrupts on stage 0. + pub fn unlisten(&mut self) { + let rtc_cntl = LP_WDT::regs(); + self.set_write_protection(false); + rtc_cntl + .config0() + .modify(|_, w| unsafe { w.wdt_stg0().bits(RwdtStageAction::ResetSystem as u8) }); + rtc_cntl.int_ena().modify(|_, w| w.lp_wdt().clear_bit()); + self.set_write_protection(true); + } + + /// Clear interrupt. + pub fn clear_interrupt(&mut self) { + self.set_write_protection(false); + LP_WDT::regs() + .int_clr() + .write(|w| w.lp_wdt().clear_bit_by_one()); + self.set_write_protection(true); + } + + /// Check if the interrupt is set. + pub fn is_interrupt_set(&self) -> bool { + LP_WDT::regs().int_st().read().lp_wdt().bit_is_set() + } + + /// Feed the watchdog timer. + pub fn feed(&mut self) { + self.set_write_protection(false); + // P4 PAC: feed().feed() (not wdtfeed().wdt_feed()) + LP_WDT::regs().feed().write(|w| w.feed().set_bit()); + self.set_write_protection(true); + } + + fn set_write_protection(&mut self, enable: bool) { + // Ref: esp-idf lpwdt_ll.h -- LP_WDT_WKEY_VALUE = 0x50D83AA1 + let wkey = if enable { 0u32 } else { 0x50D8_3AA1 }; + LP_WDT::regs() + .wprotect() + .write(|w| unsafe { w.bits(wkey) }); + } + + fn set_enabled(&mut self, enable: bool) { + let rtc_cntl = LP_WDT::regs(); + self.set_write_protection(false); + + if !enable { + rtc_cntl.config0().modify(|_, w| unsafe { w.bits(0) }); + } else { + rtc_cntl + .config0() + .write(|w| w.wdt_flashboot_mod_en().bit(false)); + rtc_cntl + .config0() + .modify(|_, w| w.wdt_en().bit(enable).wdt_pause_in_slp().bit(enable)); + unsafe { + rtc_cntl.config0().modify(|_, w| { + w.wdt_stg0().bits(RwdtStageAction::ResetSystem as u8); + w.wdt_cpu_reset_length().bits(7); + w.wdt_sys_reset_length().bits(7); + w.wdt_stg1().bits(RwdtStageAction::Off as u8); + w.wdt_stg2().bits(RwdtStageAction::Off as u8); + w.wdt_stg3().bits(RwdtStageAction::Off as u8); + w.wdt_en().set_bit() + }); + } + } + self.set_write_protection(true); + } + + /// Configure timeout value for the selected stage. + pub fn set_timeout(&mut self, stage: RwdtStage, timeout: Duration) { + let rtc_cntl = LP_WDT::regs(); + let timeout_raw = crate::clock::us_to_rtc_ticks(timeout.as_micros()) as u32; + self.set_write_protection(false); + + // P4 PAC: config1().wdt_stg0_hold(), config2().wdt_stg1_hold(), etc. + // Ref: esp-idf lp_wdt_struct.h + let timeout_raw = timeout_raw >> (1 + crate::efuse::rwdt_multiplier()); + match stage { + RwdtStage::Stage0 => rtc_cntl.config1().modify(|_, w| unsafe { w.wdt_stg0_hold().bits(timeout_raw) }), + RwdtStage::Stage1 => rtc_cntl.config2().modify(|_, w| unsafe { w.bits(timeout_raw) }), + RwdtStage::Stage2 => rtc_cntl.config3().modify(|_, w| unsafe { w.bits(timeout_raw) }), + RwdtStage::Stage3 => rtc_cntl.config4().modify(|_, w| unsafe { w.bits(timeout_raw) }), + }; + self.set_write_protection(true); + } + + /// Set the action for a specific stage. + pub fn set_stage_action(&mut self, stage: RwdtStage, action: RwdtStageAction) { + self.set_write_protection(false); + LP_WDT::regs().config0().modify(|_, w| unsafe { + match stage { + RwdtStage::Stage0 => w.wdt_stg0().bits(action as u8), + RwdtStage::Stage1 => w.wdt_stg1().bits(action as u8), + RwdtStage::Stage2 => w.wdt_stg2().bits(action as u8), + RwdtStage::Stage3 => w.wdt_stg3().bits(action as u8), + } + }); + self.set_write_protection(true); + } +} + /// Super Watchdog #[cfg(swd)] pub struct Swd(()); @@ -697,6 +844,15 @@ pub fn wakeup_cause() -> SleepSource { .read() .wakeup_cause() .bits(); + } else if #[cfg(esp32p4)] { + // P4: PMU_SLP_WAKEUP_STATUS0_REG (offset 0x144), field wakeup_cause [30:0] + // Ref: esp-idf pmu_reg.h -- PMU_SLP_WAKEUP_STATUS0_REG + // TRM v0.5 Ch 16 + let wakeup_cause_bits = crate::peripherals::PMU::regs() + .slp_wakeup_status0() + .read() + .wakeup_cause() + .bits(); } else { let wakeup_cause_bits = LPWR::regs().slp_wakeup_cause().read().wakeup_cause().bits(); } diff --git a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs index 82ed01c0339..0719016a9de 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs @@ -1,1032 +1,33 @@ -// Note: the PMU setup is based on esp-idf v5.1.2. Related code should be based -// on the same version until documentation is released and the code can be -// reasoned about. +//! RTC control for ESP32-P4X (chip revision v3.x / eco5). +//! +//! PMU power domain init and WDT disable for bare-metal boot. +//! +//! Register names validated against esp32p4 PAC (eco5) and esp-idf: +//! - esp-idf components/esp_hw_support/port/esp32p4/pmu_init.c +//! - esp-idf components/soc/esp32p4/register/hw_ver3/soc/pmu_reg.h +//! - TRM v0.5 Ch 16 (Low-Power Management) +//! - TRM v0.5 Ch 19 (Watchdog Timers) +//! +//! eco4 vs eco5 PMU difference: +//! eco4: power_pd_hpaon_cntl, power_pd_hpcpu_cntl, power_pd_hpwifi_cntl +//! eco5: power_pd_cnnt_cntl, power_pd_lpperi_cntl (hpaon/hpcpu/hpwifi removed) +//! Both: power_pd_top_cntl, power_pd_hpmem_cntl +//! +//! florianL21's original eco4 PMU code: esp32p4_florianl21_original.rs.bak use strum::FromRepr; -use crate::{ - clock::{RtcClock, RtcFastClock, RtcSlowClock}, - peripherals::{PMU, LPWR}, - rtc_cntl::RtcCalSel, - soc::{ - clocks::{ClockTree}, - regi2c, - }, -}; - -fn pmu_power_domain_force_default() { - // for bypass reserved power domain - - // PMU_HP_PD_TOP - PMU::regs().power_pd_top_cntl().modify(|_, w| { - w.force_top_reset().bit(false); // pmu_ll_hp_set_power_force_reset - w.force_top_iso().bit(false); // pmu_ll_hp_set_power_force_isolate - w.force_top_pu().bit(false); // pmu_ll_hp_set_power_force_power_up - w.force_top_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset - w.force_top_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate - w.force_top_pd().bit(false) // pmu_ll_hp_set_power_force_power_down - }); - - // PMU_HP_PD_HP_AON - PMU::regs().power_pd_hpaon_cntl().modify(|_, w| { - w.force_hp_aon_reset().bit(false); // pmu_ll_hp_set_power_force_reset - w.force_hp_aon_iso().bit(false); // pmu_ll_hp_set_power_force_isolate - w.force_hp_aon_pu().bit(false); // pmu_ll_hp_set_power_force_power_up - w.force_hp_aon_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset - w.force_hp_aon_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate - w.force_hp_aon_pd().bit(false) // pmu_ll_hp_set_power_force_power_down - }); - - // PMU_HP_PD_CPU - PMU::regs().power_pd_hpcpu_cntl().modify(|_, w| { - w.force_hp_cpu_reset().bit(false); // pmu_ll_hp_set_power_force_reset - w.force_hp_cpu_iso().bit(false); // pmu_ll_hp_set_power_force_isolate - w.force_hp_cpu_pu().bit(false); // pmu_ll_hp_set_power_force_power_up - w.force_hp_cpu_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset - w.force_hp_cpu_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate - w.force_hp_cpu_pd().bit(false) // pmu_ll_hp_set_power_force_power_down - }); - - // PMU_HP_PD_WIFI - PMU::regs().power_pd_hpwifi_cntl().modify(|_, w| { - w.force_hp_wifi_reset().bit(false); // pmu_ll_hp_set_power_force_reset - w.force_hp_wifi_iso().bit(false); // pmu_ll_hp_set_power_force_isolate - w.force_hp_wifi_pu().bit(false); // pmu_ll_hp_set_power_force_power_up - w.force_hp_wifi_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset - w.force_hp_wifi_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate - w.force_hp_wifi_pd().bit(false) // pmu_ll_hp_set_power_force_power_down - }); - - // Isolate all memory banks while sleeping, avoid memory leakage current - - PMU::regs().power_pd_mem_cntl().modify(|_, w| unsafe { - w.force_hp_mem_no_iso().bits(0) // pmu_ll_hp_set_memory_no_isolate - }); - - PMU::regs().power_pd_lpperi_cntl().modify(|_, w| { - w.force_lp_peri_reset().bit(false); // pmu_ll_lp_set_power_force_reset - w.force_lp_peri_iso().bit(false); // pmu_ll_lp_set_power_force_isolate - w.force_lp_peri_pu().bit(false); // pmu_ll_lp_set_power_force_power_up - w.force_lp_peri_no_reset().bit(false); // pmu_ll_lp_set_power_force_no_reset - w.force_lp_peri_no_iso().bit(false); // pmu_ll_lp_set_power_force_no_isolate - w.force_lp_peri_pd().bit(false) // pmu_ll_lp_set_power_force_power_down - }); -} - -fn modem_clock_domain_power_state_icg_map_init() { - todo!(); -} - -enum RtcSlowClockSource { - /// Select RC_SLOW_CLK as RTC_SLOW_CLK source - RcSlow = 0, - - /// Select XTAL32K_CLK as RTC_SLOW_CLK source - XTAL32K = 1, - - /// Select RC32K_CLK as RTC_SLOW_CLK source - RC32K = 2, - - /// Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source - OscSlow = 3, - - /// Invalid RTC_SLOW_CLK source - Invalid, -} - -impl RtcSlowClockSource { - fn current() -> Self { - // clk_ll_rtc_slow_get_src() - match LPWR::regs().lp_clk_conf().read().slow_clk_sel().bits() { - 0 => Self::RcSlow, - 1 => Self::XTAL32K, - 2 => Self::RC32K, - 3 => Self::OscSlow, - _ => Self::Invalid, - } - } -} - -#[allow(unused)] -enum ModemClockLpclkSource { - RcSlow = 0, - RcFast, - MainXtal, - RC32K, - XTAL32K, - EXT32K, -} - -impl From for ModemClockLpclkSource { - fn from(src: RtcSlowClockSource) -> Self { - match src { - RtcSlowClockSource::RcSlow => Self::RcSlow, - RtcSlowClockSource::XTAL32K => Self::XTAL32K, - RtcSlowClockSource::RC32K => Self::RC32K, - RtcSlowClockSource::OscSlow => Self::EXT32K, - _ => Self::RcSlow, - } - } -} - -fn modem_clock_hal_deselect_all_wifi_lpclk_source() { - todo!() -} - -fn modem_clock_hal_select_wifi_lpclk_source(src: ModemClockLpclkSource) { - todo!() -} - -fn modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider: u16) { - todo!() -} - -fn modem_clock_hal_enable_wifipwr_clock(enable: bool) { - todo!() -} - -// PHY, BT, IEEE802154 are not used by the init code so they are unimplemented -fn modem_clock_select_lp_clock_source_wifi(src: ModemClockLpclkSource, divider: u16) { - modem_clock_hal_deselect_all_wifi_lpclk_source(); - modem_clock_hal_select_wifi_lpclk_source(src); - modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider); - modem_clock_hal_enable_wifipwr_clock(true); -} - -const fn hp_retention_regdma_config(dir: u8, entry: u8) -> u8 { - (((dir) << 2) | (entry & 0x3)) & 0x7 -} - -const HP_CALI_DBIAS: u8 = 25; -const LP_CALI_DBIAS: u8 = 26; - -const ICG_MODEM_CODE_SLEEP: u8 = 0; -const ICG_MODEM_CODE_MODEM: u8 = 1; -const ICG_MODEM_CODE_ACTIVE: u8 = 2; - -const HP_SYSCLK_XTAL: u8 = 0; -const HP_SYSCLK_PLL: u8 = 1; - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_power_t.0 - pub struct HpDigPower(u32); - - pub bool, vdd_spi_pd_en, set_vdd_spi_pd_en: 21; - pub bool, mem_dslp , set_mem_dslp : 22; - pub u8, mem_pd_en , set_mem_pd_en : 26, 23; - pub bool, wifi_pd_en , set_wifi_pd_en : 27; - pub bool, cpu_pd_en , set_cpu_pd_en : 29; - pub bool, aon_pd_en , set_aon_pd_en : 30; - pub bool, top_pd_en , set_top_pd_en : 31; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_power_t.1 - pub struct HpClkPower(u32); - - pub bool, i2c_iso_en , set_i2c_iso_en : 26; - pub bool, i2c_retention, set_i2c_retention: 27; - pub bool, xpd_bb_i2c , set_xpd_bb_i2c : 28; - pub bool, xpd_bbpll_i2c, set_xpd_bbpll_i2c: 29; - pub bool, xpd_bbpll , set_xpd_bbpll : 30; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_power_t.2 - pub struct HpXtalPower(u32); - - pub bool, xpd_xtal , set_xpd_xtal : 31; -} - -#[derive(Clone, Copy, Default)] -// pmu_sleep_power_config_t.0 -pub struct HpSysPower { - // This is a best-guess assignment of the variants in the union `pmu_hp_power_t` union - // In esp-idf, all three fields are `pmu_hp_power_t` - pub dig_power: HpDigPower, - pub clk: HpClkPower, - pub xtal: HpXtalPower, -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_sys_cntl_reg_t - pub struct HpSysCntlReg(u32); - - pub bool, uart_wakeup_en , set_uart_wakeup_en : 24; - pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25; - pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26; - pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27; - pub bool, dig_pause_wdt , set_dig_pause_wdt : 28; - pub bool, dig_cpu_stall , set_dig_cpu_stall : 29; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_icg_modem_reg_t - pub struct HpIcgModem(u32); - - pub u8, code, set_code: 31, 30; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_sysclk_reg_t - pub struct HpSysclk(u32); - - pub bool, dig_sysclk_nodiv , set_dig_sysclk_nodiv : 26; - pub bool, icg_sysclk_en , set_icg_sysclk_en : 27; - pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28; - pub bool, icg_slp_sel , set_icg_slp_sel : 29; - pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30; -} - -// pmu_hp_system_clock_param_t -#[derive(Clone, Copy, Default)] -struct SystemClockParam { - icg_func: u32, - icg_apb: u32, - icg_modem: HpIcgModem, - sysclk: HpSysclk, -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_analog_t.0 - pub struct HpAnalogBias(u32); - - pub bool, xpd_bias , set_xpd_bias : 25; - pub u8, dbg_atten , set_dbg_atten : 29, 26; - pub bool, pd_cur , set_pd_cur : 30; - pub bool, bias_sleep, set_bias_sleep: 31; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_analog_t.1 - pub struct HpAnalogRegulator0(u32); - - // Only HP_ACTIVE modem under hp system is valid - pub u8, lp_dbias_vol , set_lp_dbias_vol : 8, 4; - // Only HP_ACTIVE modem under hp system is valid - pub u8, hp_dbias_vol , set_hp_dbias_vol : 13, 9; - // Only HP_ACTIVE modem under hp system is valid - pub bool, dbias_sel , set_dbias_sel : 14; - // Only HP_ACTIVE modem under hp system is valid - pub bool, dbias_init , set_dbias_init : 15; - - pub bool, slp_mem_xpd , set_slp_mem_xpd : 16; - pub bool, slp_logic_xpd , set_slp_logic_xpd : 17; - pub bool, xpd , set_xpd : 18; - pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19; - pub u8, slp_logic_dbias, set_slp_logic_dbias: 26, 23; - pub u8, dbias , set_dbias : 31, 27; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_analog_t.2 - pub struct HpAnalogRegulator1(u32); - - pub u32, drv_b , set_drv_b : 31, 8; -} - -#[derive(Clone, Copy, Default)] -// pmu_hp_analog_t -pub struct HpAnalog { - pub bias: HpAnalogBias, - pub regulator0: HpAnalogRegulator0, - pub regulator1: HpAnalogRegulator1, -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_backup_reg_t/active - pub struct HpActiveBackup(u32); - - pub u8, hp_sleep2active_backup_modem_clk_code, set_hp_sleep2active_backup_modem_clk_code: 5, 4; - pub u8, hp_modem2active_backup_modem_clk_code, set_hp_modem2active_backup_modem_clk_code: 7, 6; - pub bool, hp_active_retention_mode , set_hp_active_retention_mode : 10; - pub bool, hp_sleep2active_retention_en , set_hp_sleep2active_retention_en : 11; - pub bool, hp_modem2active_retention_en , set_hp_modem2active_retention_en : 12; - pub u8, hp_sleep2active_backup_clk_sel , set_hp_sleep2active_backup_clk_sel : 15, 14; - pub u8, hp_modem2active_backup_clk_sel , set_hp_modem2active_backup_clk_sel : 17, 16; - pub u8, hp_sleep2active_backup_mode , set_hp_sleep2active_backup_mode : 22, 20; - pub u8, hp_modem2active_backup_mode , set_hp_modem2active_backup_mode : 25, 23; - pub bool, hp_sleep2active_backup_en , set_hp_sleep2active_backup_en : 29; - pub bool, hp_modem2active_backup_en , set_hp_modem2active_backup_en : 30; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_backup_reg_t/modem - pub struct HpModemBackup(u32); - - pub u8, hp_sleep2modem_backup_modem_clk_code , set_hp_sleep2modem_backup_modem_clk_code : 5, 4; - pub bool, hp_modem_retention_mode , set_hp_modem_retention_mode : 10; - pub bool, hp_sleep2modem_retention_en , set_hp_sleep2modem_retention_en : 11; - pub u8, hp_sleep2modem_backup_clk_sel , set_hp_sleep2modem_backup_clk_sel : 15, 14; - pub u8, hp_sleep2modem_backup_mode , set_hp_sleep2modem_backup_mode : 22, 20; - pub bool, hp_sleep2modem_backup_en , set_hp_sleep2modem_backup_en : 29; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_hp_backup_reg_t/sleep - pub struct HpSleepBackup(u32); - - pub u8, hp_modem2sleep_backup_modem_clk_code , set_hp_modem2sleep_backup_modem_clk_code : 7, 6; - pub u8, hp_active2sleep_backup_modem_clk_code, set_hp_active2sleep_backup_modem_clk_code: 9, 8; - pub bool, hp_sleep_retention_mode , set_hp_sleep_retention_mode : 10; - pub bool, hp_modem2sleep_retention_en , set_hp_modem2sleep_retention_en : 12; - pub bool, hp_active2sleep_retention_en , set_hp_active2sleep_retention_en : 13; - pub u8, hp_modem2sleep_backup_clk_sel , set_hp_modem2sleep_backup_clk_sel : 17, 16; - pub u8, hp_active2sleep_backup_clk_sel , set_hp_active2sleep_backup_clk_sel : 19, 18; - pub u8, hp_modem2sleep_backup_mode , set_hp_modem2sleep_backup_mode : 25, 23; - pub u8, hp_active2sleep_backup_mode , set_hp_active2sleep_backup_mode : 28, 26; - pub bool, hp_modem2sleep_backup_en , set_hp_modem2sleep_backup_en : 30; - pub bool, hp_active2sleep_backup_en , set_hp_active2sleep_backup_en : 31; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // custom based on `PMU_ICG_FUNC_ENA_*` bitflag constants - pub struct HpBackupClk(u32); - - pub bool, gdma , set_gdma : 0; - pub bool, spi2 , set_spi2 : 1; - pub bool, i2s_rx , set_i2s_rx : 2; - pub bool, uart0 , set_uart0 : 3; - pub bool, uart1 , set_uart1 : 4; - pub bool, uhci , set_uhci : 5; - pub bool, usb_device , set_usb_device : 6; - pub bool, i2s_tx , set_i2s_tx : 7; - pub bool, regdma , set_regdma : 8; - pub bool, retention , set_retention : 9; - pub bool, mem_monitor , set_mem_monitor : 10; - pub bool, sdio_slave , set_sdio_slave : 11; - pub bool, tsens , set_tsens : 12; - pub bool, tg1 , set_tg1 : 13; - pub bool, tg0 , set_tg0 : 14; - pub bool, hpbus , set_hpbus : 15; - pub bool, soc_etm , set_soc_etm : 16; - pub bool, hpcore , set_hpcore : 17; - pub bool, systimer , set_systimer : 18; - pub bool, sec , set_sec : 19; - pub bool, saradc , set_saradc : 20; - pub bool, rmt , set_rmt : 21; - pub bool, pwm , set_pwm : 22; - pub bool, pvt_monitor , set_pvt_monitor : 23; - pub bool, parl_tx , set_parl_tx : 24; - pub bool, parl_rx , set_parl_rx : 25; - pub bool, mspi , set_mspi : 26; - pub bool, ledc , set_ledc : 27; - pub bool, iomux , set_iomux : 28; - pub bool, i2c , set_i2c : 29; - pub bool, can1 , set_can1 : 30; - pub bool, can0 , set_can0 : 31; -} - -macro_rules! hp_system_init { - ($state:ident => $s:ident) => { - paste::paste! { - unsafe { - // Default configuration of hp-system power in active, modem and sleep modes - PMU::regs().[<$state _dig_power >]().modify(|_, w| w.bits($s.power.dig_power.0)); - PMU::regs().[<$state _hp_ck_power >]().modify(|_, w| w.bits($s.power.clk.0)); - PMU::regs().[<$state _xtal >]().modify(|_, w| w - .[<$state _xpd_xtal >]().bit($s.power.xtal.xpd_xtal()) - ); - - // Default configuration of hp-system clock in active, modem and sleep modes - PMU::regs().[<$state _icg_hp_func >]().write(|w| w.bits($s.clock.icg_func)); - PMU::regs().[<$state _icg_hp_apb >]().write(|w| w.bits($s.clock.icg_apb)); - PMU::regs().[<$state _icg_modem >]().write(|w| w - .[<$state _dig_icg_modem_code >]().bits($s.clock.icg_modem.code()) - ); - PMU::regs().[<$state _sysclk >]().modify(|_, w| w - .[<$state _dig_sys_clk_no_div >]().bit($s.clock.sysclk.dig_sysclk_nodiv()) - .[<$state _icg_sys_clock_en >]().bit($s.clock.sysclk.icg_sysclk_en()) - .[<$state _sys_clk_slp_sel >]().bit($s.clock.sysclk.sysclk_slp_sel()) - .[<$state _icg_slp_sel >]().bit($s.clock.sysclk.icg_slp_sel()) - .[<$state _dig_sys_clk_sel >]().bits($s.clock.sysclk.dig_sysclk_sel()) - ); - - // Default configuration of hp-system digital sub-system in active, modem - // and sleep modes - PMU::regs().[<$state _hp_sys_cntl >]().modify(|_, w| w - .[<$state _uart_wakeup_en >]().bit($s.syscntl.uart_wakeup_en()) - .[<$state _lp_pad_hold_all >]().bit($s.syscntl.lp_pad_hold_all()) - .[<$state _hp_pad_hold_all >]().bit($s.syscntl.hp_pad_hold_all()) - .[<$state _dig_pad_slp_sel >]().bit($s.syscntl.dig_pad_slp_sel()) - .[<$state _dig_pause_wdt >]().bit($s.syscntl.dig_pause_wdt()) - .[<$state _dig_cpu_stall >]().bit($s.syscntl.dig_cpu_stall()) - ); - - // Default configuration of hp-system analog sub-system in active, modem and - // sleep modes - PMU::regs().[<$state _bias >]().modify(|_, w| w - .[<$state _xpd_bias >]().bit($s.anlg.bias.xpd_bias()) - .[<$state _dbg_atten >]().bits($s.anlg.bias.dbg_atten()) - .[<$state _pd_cur >]().bit($s.anlg.bias.pd_cur()) - .sleep().bit($s.anlg.bias.bias_sleep()) - ); - - PMU::regs().[<$state _hp_regulator0 >]().modify(|_, w| w - .[<$state _hp_regulator_slp_mem_xpd >]().bit($s.anlg.regulator0.slp_mem_xpd()) - .[<$state _hp_regulator_slp_logic_xpd >]().bit($s.anlg.regulator0.slp_logic_xpd()) - .[<$state _hp_regulator_xpd >]().bit($s.anlg.regulator0.xpd()) - .[<$state _hp_regulator_slp_mem_dbias >]().bits($s.anlg.regulator0.slp_mem_dbias()) - .[<$state _hp_regulator_slp_logic_dbias >]().bits($s.anlg.regulator0.slp_logic_dbias()) - .[<$state _hp_regulator_dbias >]().bits($s.anlg.regulator0.dbias()) - ); - - PMU::regs().[<$state _hp_regulator1 >]().modify(|_, w| w - .[<$state _hp_regulator_drv_b >]().bits($s.anlg.regulator1.drv_b()) - ); - - // Default configuration of hp-system retention sub-system in active, modem - // and sleep modes - PMU::regs().[<$state _backup >]().write(|w| w.bits($s.retention)); - PMU::regs().[<$state _backup_clk >]().write(|w| w.bits($s.backup_clk)); - } - } - }; -} - -struct HpSystemInit { - power: HpSysPower, - clock: SystemClockParam, - syscntl: HpSysCntlReg, - anlg: HpAnalog, - retention: u32, - backup_clk: u32, -} -impl HpSystemInit { - fn active() -> Self { - // pmu_hp_system_init_default - - let mut power = HpSysPower::default(); - power.dig_power.set_vdd_spi_pd_en(false); - power.dig_power.set_wifi_pd_en(false); - power.dig_power.set_cpu_pd_en(false); - power.dig_power.set_aon_pd_en(false); - power.dig_power.set_top_pd_en(false); - power.dig_power.set_mem_pd_en(0); - power.dig_power.set_mem_dslp(false); - - power.clk.set_i2c_iso_en(false); - power.clk.set_i2c_retention(false); - power.clk.set_xpd_bb_i2c(true); - power.clk.set_xpd_bbpll_i2c(true); - power.clk.set_xpd_bbpll(true); - - power.xtal.set_xpd_xtal(true); - - let mut clock = SystemClockParam { - icg_func: 0xffffffff, - icg_apb: 0xffffffff, - ..SystemClockParam::default() - }; - clock.icg_modem.set_code(ICG_MODEM_CODE_ACTIVE); - clock.sysclk.set_dig_sysclk_nodiv(false); - clock.sysclk.set_icg_sysclk_en(true); - clock.sysclk.set_sysclk_slp_sel(false); - clock.sysclk.set_icg_slp_sel(false); - clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL); - - let mut syscntl = HpSysCntlReg::default(); - syscntl.set_uart_wakeup_en(false); - syscntl.set_lp_pad_hold_all(false); - syscntl.set_hp_pad_hold_all(false); - syscntl.set_dig_pad_slp_sel(false); - syscntl.set_dig_pause_wdt(false); - syscntl.set_dig_cpu_stall(false); - - // PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT - let mut anlg = HpAnalog::default(); - anlg.bias.set_xpd_bias(true); - anlg.bias.set_dbg_atten(0x0); - anlg.bias.set_pd_cur(false); - anlg.bias.set_bias_sleep(false); - - // TODO: These 4 aren't applied currently? - anlg.regulator0.set_lp_dbias_vol(0xD); - anlg.regulator0.set_hp_dbias_vol(0x1C); - anlg.regulator0.set_dbias_sel(true); - anlg.regulator0.set_dbias_init(true); - - anlg.regulator0.set_slp_mem_xpd(false); - anlg.regulator0.set_slp_logic_xpd(false); - anlg.regulator0.set_xpd(true); - anlg.regulator0.set_slp_mem_dbias(0); - anlg.regulator0.set_slp_logic_dbias(0); - anlg.regulator0.set_dbias(HP_CALI_DBIAS); - - anlg.regulator1.set_drv_b(0); - - let mut retention = HpActiveBackup::default(); - retention.set_hp_sleep2active_backup_modem_clk_code(2); - retention.set_hp_modem2active_backup_modem_clk_code(2); - retention.set_hp_active_retention_mode(false); - retention.set_hp_sleep2active_retention_en(false); - retention.set_hp_modem2active_retention_en(false); - retention.set_hp_sleep2active_backup_clk_sel(0); - retention.set_hp_modem2active_backup_clk_sel(1); - retention.set_hp_sleep2active_backup_mode(hp_retention_regdma_config(0, 0)); - retention.set_hp_modem2active_backup_mode(hp_retention_regdma_config(0, 2)); - retention.set_hp_sleep2active_backup_en(false); - retention.set_hp_modem2active_backup_en(false); - - let mut backup_clk = HpBackupClk::default(); - backup_clk.set_regdma(true); - backup_clk.set_tg0(true); - backup_clk.set_tg1(true); - backup_clk.set_hpbus(true); - backup_clk.set_mspi(true); - backup_clk.set_iomux(true); - backup_clk.set_spi2(true); - backup_clk.set_uart0(true); - backup_clk.set_systimer(true); - - Self { - power, - clock, - syscntl, - anlg, - retention: retention.0, - backup_clk: backup_clk.0, - } - } - - fn modem() -> Self { - let mut power = HpSysPower::default(); - power.dig_power.set_vdd_spi_pd_en(false); - power.dig_power.set_wifi_pd_en(false); - power.dig_power.set_cpu_pd_en(true); - power.dig_power.set_aon_pd_en(false); - power.dig_power.set_top_pd_en(false); - power.dig_power.set_mem_pd_en(0); - power.dig_power.set_mem_dslp(false); - - power.clk.set_xpd_bb_i2c(true); - power.clk.set_xpd_bbpll_i2c(true); - power.clk.set_xpd_bbpll(true); - power.clk.set_i2c_iso_en(false); - power.clk.set_i2c_retention(false); - - power.xtal.set_xpd_xtal(true); - - let mut clock = SystemClockParam { - icg_func: 0, - icg_apb: 0, - ..SystemClockParam::default() - }; - clock.icg_modem.set_code(ICG_MODEM_CODE_MODEM); - clock.sysclk.set_dig_sysclk_nodiv(false); - clock.sysclk.set_icg_sysclk_en(true); - clock.sysclk.set_sysclk_slp_sel(true); - clock.sysclk.set_icg_slp_sel(true); - clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_PLL); - - let mut syscntl = HpSysCntlReg::default(); - syscntl.set_uart_wakeup_en(true); - syscntl.set_lp_pad_hold_all(false); - syscntl.set_hp_pad_hold_all(false); - syscntl.set_dig_pad_slp_sel(false); - syscntl.set_dig_pause_wdt(true); - syscntl.set_dig_cpu_stall(true); - - let mut anlg = HpAnalog::default(); - anlg.bias.set_xpd_bias(false); - anlg.bias.set_dbg_atten(0x0); - anlg.bias.set_pd_cur(false); - anlg.bias.set_bias_sleep(false); - - anlg.regulator0.set_slp_mem_xpd(false); - anlg.regulator0.set_slp_logic_xpd(false); - anlg.regulator0.set_xpd(true); - anlg.regulator0.set_slp_mem_dbias(0); - anlg.regulator0.set_slp_logic_dbias(0); - anlg.regulator0.set_dbias(HP_CALI_DBIAS); - - anlg.regulator1.set_drv_b(0); - - let mut retention = HpModemBackup::default(); - retention.set_hp_sleep2modem_backup_modem_clk_code(1); - retention.set_hp_modem_retention_mode(false); - retention.set_hp_sleep2modem_retention_en(false); - retention.set_hp_sleep2modem_backup_clk_sel(0); - retention.set_hp_sleep2modem_backup_mode(hp_retention_regdma_config(0, 1)); - retention.set_hp_sleep2modem_backup_en(false); - - let mut backup_clk = HpBackupClk::default(); - backup_clk.set_regdma(true); - backup_clk.set_tg0(true); - backup_clk.set_tg1(true); - backup_clk.set_hpbus(true); - backup_clk.set_mspi(true); - backup_clk.set_iomux(true); - backup_clk.set_spi2(true); - backup_clk.set_uart0(true); - backup_clk.set_systimer(true); - - Self { - power, - clock, - syscntl, - anlg, - retention: retention.0, - backup_clk: backup_clk.0, - } - } - - fn sleep() -> Self { - let mut power = HpSysPower::default(); - power.dig_power.set_vdd_spi_pd_en(true); - power.dig_power.set_mem_dslp(false); - power.dig_power.set_mem_pd_en(0); - power.dig_power.set_wifi_pd_en(true); - power.dig_power.set_cpu_pd_en(false); - power.dig_power.set_aon_pd_en(false); - power.dig_power.set_top_pd_en(false); - - power.clk.set_i2c_iso_en(true); - power.clk.set_i2c_retention(true); - power.clk.set_xpd_bb_i2c(true); - power.clk.set_xpd_bbpll_i2c(false); - power.clk.set_xpd_bbpll(false); - - power.xtal.set_xpd_xtal(false); - - let mut clock = SystemClockParam { - icg_func: 0, - icg_apb: 0, - ..SystemClockParam::default() - }; - clock.icg_modem.set_code(ICG_MODEM_CODE_SLEEP); - clock.sysclk.set_dig_sysclk_nodiv(false); - clock.sysclk.set_icg_sysclk_en(false); - clock.sysclk.set_sysclk_slp_sel(true); - clock.sysclk.set_icg_slp_sel(true); - clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL); - - let mut anlg = HpAnalog::default(); - anlg.bias.set_xpd_bias(false); - anlg.bias.set_dbg_atten(0x0); - anlg.bias.set_pd_cur(false); - anlg.bias.set_bias_sleep(false); - - anlg.regulator0.set_slp_mem_xpd(false); - anlg.regulator0.set_slp_logic_xpd(false); - anlg.regulator0.set_xpd(true); - anlg.regulator0.set_slp_mem_dbias(0); - anlg.regulator0.set_slp_logic_dbias(0); - anlg.regulator0.set_dbias(1); - - anlg.regulator1.set_drv_b(0); - - let mut retention = HpSleepBackup::default(); - retention.set_hp_modem2sleep_backup_modem_clk_code(0); - retention.set_hp_active2sleep_backup_modem_clk_code(2); - retention.set_hp_sleep_retention_mode(false); - retention.set_hp_modem2sleep_retention_en(false); - retention.set_hp_active2sleep_retention_en(false); - retention.set_hp_modem2sleep_backup_clk_sel(0); - retention.set_hp_active2sleep_backup_clk_sel(0); - retention.set_hp_modem2sleep_backup_mode(hp_retention_regdma_config(1, 1)); - retention.set_hp_active2sleep_backup_mode(hp_retention_regdma_config(1, 0)); - retention.set_hp_modem2sleep_backup_en(false); - retention.set_hp_active2sleep_backup_en(false); - - let mut backup_clk = HpBackupClk::default(); - backup_clk.set_regdma(true); - backup_clk.set_tg0(true); - backup_clk.set_tg1(true); - backup_clk.set_hpbus(true); - backup_clk.set_mspi(true); - backup_clk.set_iomux(true); - backup_clk.set_spi2(true); - backup_clk.set_uart0(true); - backup_clk.set_systimer(true); - - let mut syscntl = HpSysCntlReg::default(); - syscntl.set_uart_wakeup_en(true); - syscntl.set_lp_pad_hold_all(false); - syscntl.set_hp_pad_hold_all(false); - syscntl.set_dig_pad_slp_sel(true); - syscntl.set_dig_pause_wdt(true); - syscntl.set_dig_cpu_stall(true); - - Self { - power, - clock, - syscntl, - anlg, - retention: retention.0, - backup_clk: backup_clk.0, - } - } - - fn init_default() { - let active = Self::active(); - let modem = Self::modem(); - let sleep = Self::sleep(); - - hp_system_init!(hp_active => active); - hp_system_init!(hp_modem => modem); - hp_system_init!(hp_sleep => sleep); - - unsafe { - // Some PMU initial parameter configuration - PMU::regs() - .imm_modem_icg() - .write(|w| w.update_dig_icg_modem_en().bit(true)); - PMU::regs() - .imm_sleep_sysclk() - .write(|w| w.update_dig_icg_switch().bit(true)); - - const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2; - PMU::regs() - .slp_wakeup_cntl3() - .modify(|_, w| w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP)); - } - } -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_lp_power_t.0 - pub struct LpDigPower(u32); - - pub u32, mem_dslp , set_mem_dslp : 30; - pub u32, peri_pd_en, set_peri_pd_en: 31; - -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_lp_power_t.1 - pub struct LpClkPower(u32); - - pub u32, xpd_xtal32k, set_xpd_xtal32k: 28; - pub u32, xpd_rc32k , set_xpd_rc32k : 29; - pub u32, xpd_fosc , set_xpd_fosc : 30; - pub u32, pd_osc , set_pd_osc : 31; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_lp_power_t.2 - pub struct LpXtalPower(u32); - - pub bool, xpd_xtal , set_xpd_xtal : 31; -} - -#[derive(Clone, Copy, Default)] -// pmu_sleep_power_config_t.1 -pub struct LpSysPower { - // This is a best-guess assignment of the variants in the union `pmu_lp_power_t` union - // In esp-idf, all three fields are `pmu_lp_power_t` - pub dig_power: LpDigPower, - pub clk_power: LpClkPower, - pub xtal: LpXtalPower, -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_lp_analog_t.0 - pub struct LpAnalogBias(u32); - - pub bool, xpd_bias , set_xpd_bias : 25; - pub u8, dbg_atten , set_dbg_atten : 29, 26; - pub bool, pd_cur , set_pd_cur : 30; - pub bool, bias_sleep, set_bias_sleep: 31; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_lp_analog_t.1 - pub struct LpAnalogRegulator0(u32); - - pub bool, slp_xpd , set_slp_xpd : 21; - pub bool, xpd , set_xpd : 22; - pub u8, slp_dbias, set_slp_dbias: 26, 23; - pub u8, dbias , set_dbias : 31, 27; -} - -bitfield::bitfield! { - #[derive(Clone, Copy, Default)] - // pmu_lp_analog_t.2 - pub struct LpAnalogRegulator1(u32); - - pub u8, drv_b , set_drv_b : 31, 28; -} - -#[derive(Clone, Copy, Default)] -// pmu_lp_analog_t -pub struct LpAnalog { - pub bias: LpAnalogBias, - pub regulator0: LpAnalogRegulator0, - pub regulator1: LpAnalogRegulator1, -} - -macro_rules! lp_system_init { - ($state:ident => $s:ident) => { - paste::paste! { - unsafe { - // Default configuration of lp-system power in active and sleep modes - PMU::regs().[< $state _dig_power >]().modify(|_, w| w.bits($s.dig_power.0)); - PMU::regs().[< $state _ck_power >]().modify(|_, w| w.bits($s.clk_power.0)); - - // Default configuration of lp-system analog sub-system in active and sleep modes - PMU::regs().[< $state _regulator0 >]().modify(|_, w| w - .[< $state _regulator_slp_xpd >]().bit($s.analog_regulator0.slp_xpd()) - .[< $state _regulator_xpd >]().bit($s.analog_regulator0.xpd()) - .[< $state _regulator_slp_dbias >]().bits($s.analog_regulator0.slp_dbias()) - .[< $state _regulator_dbias >]().bits($s.analog_regulator0.dbias()) - ); - - PMU::regs().[< $state _regulator1 >]().modify(|_, w| w - .[< $state _regulator_drv_b >]().bits($s.analog_regulator1.drv_b()) - ); - } - } - }; -} - -struct LpSystemInit { - dig_power: LpDigPower, - clk_power: LpClkPower, - xtal: LpXtalPower, - bias: LpAnalogBias, - analog_regulator0: LpAnalogRegulator0, - analog_regulator1: LpAnalogRegulator1, -} -impl LpSystemInit { - fn active() -> Self { - let mut dig_power = LpDigPower::default(); - dig_power.set_peri_pd_en(false); - dig_power.set_mem_dslp(false); - - let mut clk_power = LpClkPower::default(); - clk_power.set_xpd_xtal32k(true); - clk_power.set_xpd_rc32k(true); - clk_power.set_xpd_fosc(true); - - let mut analog_regulator0 = LpAnalogRegulator0::default(); - analog_regulator0.set_slp_xpd(false); - analog_regulator0.set_xpd(true); - analog_regulator0.set_slp_dbias(0); - analog_regulator0.set_dbias(26); - - let mut analog_regulator1 = LpAnalogRegulator1::default(); - analog_regulator1.set_drv_b(0); - - Self { - dig_power, - clk_power, - xtal: LpXtalPower::default(), - bias: LpAnalogBias::default(), - analog_regulator0, - analog_regulator1, - } - } - - fn sleep() -> Self { - let mut dig_power = LpDigPower::default(); - dig_power.set_mem_dslp(true); - dig_power.set_peri_pd_en(false); - - let mut clk_power = LpClkPower::default(); - clk_power.set_xpd_xtal32k(false); - clk_power.set_xpd_rc32k(false); - clk_power.set_xpd_fosc(false); - clk_power.set_pd_osc(false); - - let mut xtal = LpXtalPower::default(); - xtal.set_xpd_xtal(false); - - let mut analog_bias = LpAnalogBias::default(); - analog_bias.set_xpd_bias(false); - analog_bias.set_dbg_atten(0); - analog_bias.set_pd_cur(true); - analog_bias.set_bias_sleep(true); - - let mut analog_regulator0 = LpAnalogRegulator0::default(); - analog_regulator0.set_slp_xpd(false); - analog_regulator0.set_xpd(true); - analog_regulator0.set_slp_dbias(0); - analog_regulator0.set_dbias(12); - - let mut analog_regulator1 = LpAnalogRegulator1::default(); - analog_regulator1.set_drv_b(0); - - Self { - dig_power, - clk_power, - xtal, - bias: analog_bias, - analog_regulator0, - analog_regulator1, - } - } - - fn init_default() { - let active = Self::active(); - let sleep = Self::sleep(); - - lp_system_init!(hp_sleep_lp => active); - lp_system_init!(lp_sleep_lp => sleep); - - PMU::regs() - .lp_sleep_xtal() - .modify(|_, w| w.lp_sleep_xpd_xtal().bit(sleep.xtal.xpd_xtal())); - - PMU::regs().lp_sleep_bias().modify(|_, w| unsafe { - w.lp_sleep_xpd_bias().bit(sleep.bias.xpd_bias()); // pmu_ll_lp_set_bias_xpd - w.lp_sleep_dbg_atten().bits(sleep.bias.dbg_atten()); // pmu_ll_lp_set_bias_dbg_atten - w.lp_sleep_pd_cur().bit(sleep.bias.pd_cur()); // pmu_ll_lp_set_bias_pd_cur - w.sleep().bit(sleep.bias.bias_sleep()) // pmu_ll_lp_set_bias_sleep - }); - } -} - -pub(crate) fn init() { - // pmu_init() - PMU::regs() - .rf_pwc() - .modify(|_, w| w.perif_i2c_rstb().set_bit().xpd_perif_i2c().set_bit()); - - // regi2c::I2C_DIG_REG_ENIF_RTC_DREG.write_field(1); - // regi2c::I2C_DIG_REG_ENIF_DIG_DREG.write_field(1); - // regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0); - // regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0); - - HpSystemInit::init_default(); - LpSystemInit::init_default(); - - pmu_power_domain_force_default(); - - // esp_perip_clk_init() - modem_clock_domain_power_state_icg_map_init(); - - // During system initialization, the low-power clock source of the modem - // (WiFi, BLE or Coexist) follows the configuration of the slow clock source - // of the system. If the WiFi, BLE or Coexist module needs a higher - // precision sleep clock (for example, the BLE needs to use the main XTAL - // oscillator (40 MHz) to provide the clock during the sleep process in some - // scenarios), the module needs to switch to the required clock source by - // itself. - // TODO - WIFI-5233 - let modem_lpclk_src = ModemClockLpclkSource::from(RtcSlowClockSource::current()); - - modem_clock_select_lp_clock_source_wifi(modem_lpclk_src, 0); - - RtcClock::set_fast_freq(RtcFastClock::RcFast); - RtcClock::set_slow_freq(RtcSlowClock::RcSlow); -} - -pub(crate) fn configure_clock() { - let cal_val = loop { - let res = RtcClock::calibrate(RtcCalSel::RtcMux, 1024); - if res != 0 { - break res; - } - }; - - LPWR::regs() - .store1() - .modify(|_, w| unsafe { w.bits(cal_val) }); - - modem_clk_domain_active_state_icg_map_preinit(); -} - -fn modem_clk_domain_active_state_icg_map_preinit() { - todo!() -} - -// Terminology: -// -// CPU Reset: Reset CPU core only, once reset done, CPU will execute from -// reset vector -// Core Reset: Reset the whole digital system except RTC sub-system -// System Reset: Reset the whole digital system, including RTC sub-system -// Chip Reset: Reset the whole chip, including the analog part +use crate::peripherals::{LP_WDT, PMU, TIMG0, TIMG1}; /// SOC Reset Reason. +/// Ref: esp-idf components/soc/esp32p4/include/soc/reset_reasons.h #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] +#[repr(usize)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SocResetReason { /// Power on reset - /// - /// In ESP-IDF this value (0x01) can *also* be `ChipBrownOut` or - /// `ChipSuperWdt`, however that is not really compatible with Rust-style - /// enums. ChipPowerOn = 0x01, - /// Software resets the digital core by RTC_CNTL_SW_SYS_RST + /// Software resets the digital core CoreSw = 0x03, /// Deep sleep reset the digital core CoreDeepSleep = 0x05, @@ -1040,7 +41,7 @@ pub enum SocResetReason { CoreRtcWdt = 0x09, /// Main watch dog 0 resets CPU 0 Cpu0Mwdt0 = 0x0B, - /// Software resets CPU 0 by RTC_CNTL_SW_PROCPU_RST + /// Software resets CPU 0 Cpu0Sw = 0x0C, /// RTC watch dog resets CPU 0 Cpu0RtcWdt = 0x0D, @@ -1062,23 +63,303 @@ pub enum SocResetReason { Cpu0JtagCpu = 0x18, } -// #[derive(Clone, Copy)] -// pub(crate) struct SavedClockConfig { -// /// The clock from which CPU clock is derived -// old_soc_root_clk: Option, -// } +/// Clear all force flags on PMU power domains to allow normal power management. +/// +/// eco5 power domains (verified against PAC): +/// - TOP: power_pd_top_cntl (system top-level) +/// - CNNT: power_pd_cnnt_cntl (connectivity, eco5 new -- replaces hpaon/hpcpu/hpwifi) +/// - HPMEM: power_pd_hpmem_cntl (HP memory) +/// - LPPERI: power_pd_lpperi_cntl (LP peripherals, eco5 new) +/// +/// Ref: esp-idf pmu_init.c -- pmu_hp_system_init() +/// esp-idf pmu_reg.h -- PMU_POWER_PD_*_CNTL_REG +fn pmu_power_domain_force_default() { + let pmu = PMU::regs(); + + // PMU_HP_PD_TOP + // Ref: esp-idf pmu_init.c, pmu_ll.h -- pmu_ll_hp_set_power_force_* + pmu.power_pd_top_cntl().modify(|_, w| { + w.force_top_reset().bit(false); + w.force_top_iso().bit(false); + w.force_top_pu().bit(false); + w.force_top_no_reset().bit(false); + w.force_top_no_iso().bit(false); + w.force_top_pd().bit(false) + }); + + // PMU_HP_PD_CNNT (eco5: replaces hpaon + hpcpu + hpwifi from eco4) + // Ref: esp-idf pmu_reg.h -- PMU_POWER_PD_CNNT_CNTL_REG + pmu.power_pd_cnnt_cntl().modify(|_, w| { + w.force_cnnt_reset().bit(false); + w.force_cnnt_iso().bit(false); + w.force_cnnt_pu().bit(false); + w.force_cnnt_no_reset().bit(false); + w.force_cnnt_no_iso().bit(false); + w.force_cnnt_pd().bit(false) + }); + + // PMU_HP_PD_HPMEM + // Ref: esp-idf pmu_reg.h -- PMU_POWER_PD_HPMEM_CNTL_REG + pmu.power_pd_hpmem_cntl().modify(|_, w| { + w.force_hp_mem_reset().bit(false); + w.force_hp_mem_iso().bit(false); + w.force_hp_mem_pu().bit(false); + w.force_hp_mem_no_reset().bit(false); + w.force_hp_mem_no_iso().bit(false); + w.force_hp_mem_pd().bit(false) + }); + + // PMU_LP_PD_LPPERI (eco5 new) + // Ref: esp-idf pmu_reg.h -- PMU_POWER_PD_LPPERI_CNTL_REG + pmu.power_pd_lpperi_cntl().modify(|_, w| { + w.force_lp_peri_reset().bit(false); + w.force_lp_peri_iso().bit(false); + w.force_lp_peri_pu().bit(false); + w.force_lp_peri_no_reset().bit(false); + w.force_lp_peri_no_iso().bit(false); + w.force_lp_peri_pd().bit(false) + }); +} + +/// Minimal init for bare-metal boot: disable all watchdogs and set power domains. +/// +/// This is the minimum needed for the chip to not reset itself during startup. +/// Full clock configuration (PLL, CPU freq) is handled separately. +/// +/// Ref: esp-idf bootloader_esp32p4.c -- bootloader_super_wdt_auto_feed(), +/// bootloader_clock_configure(), esp_rtc_init() +/// TRM v0.5 Ch 19 (WDT), Ch 16 (Power Management) +pub(crate) fn init() { + // 1. Clear all PMU power domain force flags + pmu_power_domain_force_default(); + + // 2. Disable TIMG0 watchdog + // Ref: esp-idf wdt_hal.c -- wdt_hal_init(), wdt_hal_disable() + // TIMG WDT write protect key: 0x50D8_3AA1 + // TRM v0.5 Ch 19 -- TIMG0_WDTWPROTECT_REG, TIMG0_WDTCONFIG0_REG + let tg0 = TIMG0::regs(); + tg0.wdtwprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); + tg0.wdtconfig0().modify(|_, w| w.wdt_en().clear_bit()); + tg0.wdtwprotect().write(|w| unsafe { w.bits(0) }); + + // 3. Disable TIMG1 watchdog + let tg1 = TIMG1::regs(); + tg1.wdtwprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); + tg1.wdtconfig0().modify(|_, w| w.wdt_en().clear_bit()); + tg1.wdtwprotect().write(|w| unsafe { w.bits(0) }); + + // 4. Disable LP_WDT (Low-Power Watchdog) + // Ref: esp-idf lpwdt_ll.h -- LP_WDT write protect key: 0x50D8_3AA1 + // P4 PAC: config0() (not wdtconfig0()), wprotect() (not wdtwprotect()) + // TRM v0.5 Ch 19 -- LP_WDT_CONFIG0_REG + let lp_wdt = LP_WDT::regs(); + lp_wdt.wprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); + lp_wdt.config0().modify(|_, w| unsafe { w.bits(0) }); + lp_wdt.wprotect().write(|w| unsafe { w.bits(0) }); + + // 5. Disable SWD (Super Watchdog) by enabling auto-feed + // Ref: esp-idf bootloader_esp32p4.c -- bootloader_super_wdt_auto_feed() + // LP_WDT SWD write protect key: 0x50D8_3AA1 (same key) + // TRM v0.5 Ch 19 -- LP_WDT_SWD_CONFIG_REG + lp_wdt + .swd_wprotect() + .write(|w| unsafe { w.bits(0x50D8_3AA1) }); + lp_wdt + .swd_config() + .modify(|_, w| w.swd_auto_feed_en().set_bit()); + lp_wdt.swd_wprotect().write(|w| unsafe { w.bits(0) }); + + // 6. Clear DCDC switch force flags + // Ref: esp-idf pmu_init.c -- pmu_ll_set_dcdc_switch_force_power_up/down + // PMU_POWER_DCDC_SWITCH_REG (offset 0x10c) + let pmu = PMU::regs(); + pmu.power_dcdc_switch().modify(|_, w| { + w.force_dcdc_switch_pu().bit(false); + w.force_dcdc_switch_pd().bit(false) + }); + + // 7. Enable CPLL (400 MHz) and SPLL (480 MHz) + // Ref: esp-idf rtc_clk.c:401 -- rtc_clk_cpu_freq_set_config() + // esp-idf clk_tree_ll.h:375 -- clk_ll_cpll_set_config() + // esp-idf clk_tree_ll.h:430 -- clk_ll_spll_set_config() + // TRM v0.5 Ch 12 (Reset and Clock) + cpll_configure(400); + spll_configure(480); + + // 8. Set CPU divider to 1 (400 MHz CPU), MEM divider 2, APB divider 2 + // Ref: esp-idf rtc_clk.c:262 -- case 400: mem_divider=2, apb_divider=2 + // esp-idf clk_tree_ll.h -- clk_ll_cpu_set_divider() + let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + + // Set CPU divider: cpu_clk_div_num = divider - 1 = 0 + // Ref: HP_SYS_CLKRST.root_clk_ctrl0.reg_cpu_clk_div_num + clkrst.root_clk_ctrl0().modify(|_, w| unsafe { + w.cpu_clk_div_num().bits(0); // CPU: /1 = 400 MHz + w.cpu_clk_div_numerator().bits(0); + w.cpu_clk_div_denominator().bits(0) + }); + // Trigger clock divider update + clkrst + .root_clk_ctrl0() + .modify(|_, w| w.soc_clk_div_update().set_bit()); + while clkrst + .root_clk_ctrl0() + .read() + .soc_clk_div_update() + .bit_is_set() + { + core::hint::spin_loop(); + } -// impl SavedClockConfig { -// pub(crate) fn save(clocks: &ClockTree) -> Self { -// let old_soc_root_clk = clocks.soc_root_clk(); + // 9. Switch CPU clock source from XTAL to CPLL + // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_CPLL) + // LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel: 0=XTAL, 1=CPLL, 2=RC_FAST + crate::peripherals::LP_AON_CLKRST::regs() + .lp_aonclkrst_hp_clk_ctrl() + .modify(|_, w| unsafe { w.lp_aonclkrst_hp_root_clk_src_sel().bits(1) }); // 1 = CPLL +} + +/// Configure CPLL for the given frequency (360 or 400 MHz). +/// +/// eco5 (v3.x) uses different I2C register values than eco4 (v1.x). +/// Ref: esp-idf clk_tree_ll.h:375-425 -- clk_ll_cpll_set_config() +/// esp-idf regi2c_cpll.h -- I2C_CPLL_OC_REF_DIV, I2C_CPLL_OC_DIV_7_0, I2C_CPLL_OC_DCUR +/// TRM v0.5 Ch 12 -- CPLL configuration +fn cpll_configure(freq_mhz: u32) { + use crate::soc::regi2c; + + // I2C CPLL register addresses + // Ref: esp-idf soc/esp32p4/include/soc/regi2c_cpll.h + const I2C_CPLL: u8 = 0x67; // CPLL slave address + const I2C_CPLL_OC_REF_DIV: u8 = 2; + const I2C_CPLL_OC_DIV_7_0: u8 = 3; + const I2C_CPLL_OC_DCUR: u8 = 6; + + // 1. Enable CPLL power + // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpll_enable() + // PMU.imm_hp_ck_power: tie_high_xpd_pll, tie_high_xpd_pll_i2c + // Note: PAC uses "pll" not "cpll" (eco4 PAC, single PLL) + let pmu = PMU::regs(); + // PAC: tie_high_xpd_pll is 4-bit field (one bit per PLL: CPLL/SPLL/MPLL/PLLA). + // Set all bits to enable all PLLs. Same for pll_i2c. + // Ref: esp-idf pmu_reg.h -- PMU_TIE_HIGH_XPD_CPLL (BIT27) etc. + pmu.imm_hp_ck_power().write(|w| unsafe { + w.tie_high_xpd_pll().bits(0xF); + w.tie_high_xpd_pll_i2c().bits(0xF) + }); + // Enable global CPLL ICG (clock gating) + // Ref: PMU.imm_hp_ck_power.tie_high_global_cpll_icg + // Note: this field may not exist in eco4 PAC; use direct bit write if needed + // For now, the PLL is enabled via xpd_pll above. + + // 2. Configure CPLL via I2C analog registers + // eco5 values (v3.x): div7_0 = 10 (400MHz), 9 (360MHz) with 40MHz XTAL + // Ref: esp-idf clk_tree_ll.h:400-410 -- !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 path + let div7_0: u8 = match freq_mhz { + 400 => 10, // eco5: 400 MHz + 360 => 9, // eco5: 360 MHz + _ => 10, // default to 400 MHz + }; -// SavedClockConfig { old_soc_root_clk } -// } + // OC_REF_DIV + DCHGP: (oc_enb_fcal << 7) | (dchgp << 4) | div_ref = 0x50 + // Ref: esp-idf clk_tree_ll.h:414 + let lref: u8 = 0x50; // dchgp=5, div_ref=0, oc_enb_fcal=0 + + // OC_DCUR: (dlref_sel << 6) | (dhref_sel << 4) | dcur = 0x73 + // Ref: esp-idf clk_tree_ll.h:421 + let dcur: u8 = 0x73; // dlref_sel=1, dhref_sel=3, dcur=3 + + regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_REF_DIV, lref); + regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_DIV_7_0, div7_0); + regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_DCUR, dcur); + + // 3. Run CPLL calibration + // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpll_calibration_start/stop/is_done + // HP_SYS_CLKRST.ana_pll_ctrl0.cpu_pll_cal_stop + let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + + // Start calibration: set cpu_pll_cal_stop = 0 + clkrst + .ana_pll_ctrl0() + .modify(|_, w| w.cpu_pll_cal_stop().clear_bit()); + + // Wait for calibration to complete + while !clkrst + .ana_pll_ctrl0() + .read() + .cpu_pll_cal_end() + .bit_is_set() + { + core::hint::spin_loop(); + } + + // Stop calibration: set cpu_pll_cal_stop = 1 + clkrst + .ana_pll_ctrl0() + .modify(|_, w| w.cpu_pll_cal_stop().set_bit()); + + // Small delay for PLL to stabilize + crate::rom::ets_delay_us(10); +} + +/// Configure SPLL (System PLL) for the given frequency (480 MHz typical). +/// +/// SPLL provides peripheral clocks: PLL_F240M/160M/120M/80M/20M. +/// Ref: esp-idf clk_tree_ll.h:430-480 -- clk_ll_spll_set_config() +/// esp-idf regi2c_syspll.h -- I2C_SYS_PLL_OC_REF_DIV, I2C_SYS_PLL_OC_DIV_7_0 +/// TRM v0.5 Ch 12 -- SPLL configuration +fn spll_configure(freq_mhz: u32) { + use crate::soc::regi2c; + + // I2C SPLL register addresses + // Ref: esp-idf soc/esp32p4/include/soc/regi2c_syspll.h + const I2C_SPLL: u8 = regi2c::REGI2C_SYS_PLL; + const I2C_SPLL_OC_REF_DIV: u8 = 2; + const I2C_SPLL_OC_DIV_7_0: u8 = 3; + const I2C_SPLL_OC_DCUR: u8 = 6; + + // PLL power already enabled in cpll_configure (PMU xpd_pll bits(0xF) enables all PLLs) + + // Configure SPLL via I2C analog registers + // eco5 values: div7_0 = (freq_mhz / 40) - 1, same formula as CPLL + // Ref: esp-idf clk_tree_ll.h:460 -- !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 path + let div7_0: u8 = match freq_mhz { + 480 => 11, // 480 MHz: (480/40) - 1 = 11 + 240 => 5, // 240 MHz: (240/40) - 1 = 5 + _ => 11, // default to 480 MHz + }; + + // Same OC_REF_DIV and OC_DCUR values as CPLL + // Ref: esp-idf clk_tree_ll.h:468-475 + let lref: u8 = 0x50; // dchgp=5, div_ref=0, oc_enb_fcal=0 + let dcur: u8 = 0x73; // dlref_sel=1, dhref_sel=3, dcur=3 + + regi2c::regi2c_write(I2C_SPLL, 0, I2C_SPLL_OC_REF_DIV, lref); + regi2c::regi2c_write(I2C_SPLL, 0, I2C_SPLL_OC_DIV_7_0, div7_0); + regi2c::regi2c_write(I2C_SPLL, 0, I2C_SPLL_OC_DCUR, dcur); + + // Run SPLL calibration + // Ref: esp-idf clk_tree_ll.h -- clk_ll_spll_calibration_start/stop/is_done + // HP_SYS_CLKRST.ana_pll_ctrl0.sys_pll_cal_stop + let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + + clkrst + .ana_pll_ctrl0() + .modify(|_, w| w.sys_pll_cal_stop().clear_bit()); + + while !clkrst + .ana_pll_ctrl0() + .read() + .sys_pll_cal_end() + .bit_is_set() + { + core::hint::spin_loop(); + } + + clkrst + .ana_pll_ctrl0() + .modify(|_, w| w.sys_pll_cal_stop().set_bit()); + + crate::rom::ets_delay_us(10); +} -// // rtc_clk_cpu_freq_set_config -// pub(crate) fn restore(self, clocks: &mut ClockTree) { -// if let Some(old_soc_root_clk) = self.old_soc_root_clk { -// // crate::soc::clocks::configure_soc_root_clk(clocks, old_soc_root_clk); -// } -// } -// } diff --git a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs index 9bac1c24a24..0277416bb1b 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs @@ -1,1064 +1,17 @@ -use core::ops::Not; - -use crate::{ - clock::Clock, - efuse::Efuse, - gpio::RtcFunction, - rtc_cntl::{ - Rtc, - RtcCalSel, - RtcClock, - rtc::{HpAnalog, HpSysCntlReg, HpSysPower, LpAnalog, LpSysPower, SavedClockConfig}, - sleep::{ - Ext1WakeupSource, - TimerWakeupSource, - WakeFromLpCoreWakeupSource, - WakeSource, - WakeTriggers, - WakeupLevel, - }, - }, - soc::clocks::ClockTree, -}; - -impl WakeSource for TimerWakeupSource { - fn apply( - &self, - rtc: &Rtc<'_>, - triggers: &mut WakeTriggers, - _sleep_config: &mut RtcSleepConfig, - ) { - triggers.set_timer(true); - - let lp_timer = unsafe { &*esp32p4::LP_TIMER::ptr() }; - let clock_freq = RtcClock::slow_freq(); - // TODO: maybe add sleep time adjustment like idf - // TODO: maybe add check to prevent overflow? - let clock_hz = clock_freq.frequency().as_hz() as u64; - let ticks = self.duration.as_micros() as u64 * clock_hz / 1_000_000u64; - // "alarm" time in slow rtc ticks - let now = rtc.time_since_boot_raw(); - let time_in_ticks = now + ticks; - unsafe { - lp_timer.tar0_high().write(|w| { - w.main_timer_tar_high0() - .bits(((time_in_ticks >> 32) & 0xffff) as u16) - }); - lp_timer.tar0_low().write(|w| { - w.main_timer_tar_low0() - .bits((time_in_ticks & 0xffffffff) as u32) - }); - lp_timer - .int_clr() - .write(|w| w.soc_wakeup().clear_bit_by_one()); - lp_timer - .tar0_high() - .modify(|_, w| w.main_timer_tar_en0().set_bit()); - } - } -} - -impl Ext1WakeupSource<'_, '_> { - /// Returns the currently configured wakeup pins. - fn wakeup_pins() -> u8 { - unsafe { lp_aon().ext_wakeup_cntl().read().ext_wakeup_sel().bits() } - } - - fn wake_io_reset() { - use crate::gpio::RtcPin; - - fn uninit_pin(pin: impl RtcPin, wakeup_pins: u8) { - if wakeup_pins & (1 << pin.number()) != 0 { - pin.rtcio_pad_hold(false); - pin.rtc_set_config(false, false, RtcFunction::Rtc); - } - } - - let wakeup_pins = Ext1WakeupSource::wakeup_pins(); - uninit_pin(unsafe { crate::peripherals::GPIO0::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO1::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO2::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO3::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO4::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO5::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO6::steal() }, wakeup_pins); - uninit_pin(unsafe { crate::peripherals::GPIO7::steal() }, wakeup_pins); - } -} - -impl WakeSource for Ext1WakeupSource<'_, '_> { - fn apply( - &self, - _rtc: &Rtc<'_>, - triggers: &mut WakeTriggers, - _sleep_config: &mut RtcSleepConfig, - ) { - // We don't have to keep the LP domain powered if we hold the wakeup pin states. - triggers.set_ext1(true); - - // set pins to RTC function - let mut pins = self.pins.borrow_mut(); - let mut pin_mask = 0u8; - let mut level_mask = 0u8; - for (pin, level) in pins.iter_mut() { - pin_mask |= 1 << pin.number(); - level_mask |= match level { - WakeupLevel::High => 1 << pin.number(), - WakeupLevel::Low => 0, - }; - - pin.rtc_set_config(true, true, RtcFunction::Rtc); - pin.rtcio_pad_hold(true); - } - - unsafe { - // clear previous wakeup status - lp_aon() - .ext_wakeup_cntl() - .modify(|_, w| w.ext_wakeup_status_clr().set_bit()); - - // set pin + level register fields - lp_aon().ext_wakeup_cntl().modify(|r, w| { - w.ext_wakeup_sel() - .bits(r.ext_wakeup_sel().bits() | pin_mask) - .ext_wakeup_lv() - .bits(r.ext_wakeup_lv().bits() & !pin_mask | level_mask) - }); - } - } -} - -impl Drop for Ext1WakeupSource<'_, '_> { - fn drop(&mut self) { - // should we have saved the pin configuration first? - // set pin back to IO_MUX (input_enable and func have no effect when pin is sent - // to IO_MUX) - let mut pins = self.pins.borrow_mut(); - for (pin, _level) in pins.iter_mut() { - pin.rtc_set_config(true, false, RtcFunction::Rtc); - } - } -} - -impl WakeSource for WakeFromLpCoreWakeupSource { - fn apply( - &self, - _rtc: &Rtc<'_>, - triggers: &mut WakeTriggers, - _sleep_config: &mut RtcSleepConfig, - ) { - triggers.set_lp_core(true); - } -} - -/// Configuration for controlling the behavior during sleep modes. -#[derive(Clone, Copy)] -// pmu_sleep_analog_config_t -pub struct AnalogSleepConfig { - /// High-power system configuration. - pub hp_sys: HpAnalog, - // pub lp_sys_active: LpAnalog, // unused - /// Low-power system analog configuration. - pub lp_sys_sleep: LpAnalog, -} - -impl AnalogSleepConfig { - fn defaults_deep_sleep() -> Self { - Self { - // PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT - hp_sys: { - let mut cfg = HpAnalog::default(); - - cfg.bias.set_pd_cur(false); - cfg.bias.set_bias_sleep(false); - cfg.regulator0.set_xpd(false); - cfg.bias.set_dbg_atten(0); - - cfg - }, - // lp_sys_active: LpAnalog::default(), - lp_sys_sleep: { - let mut cfg = LpAnalog::default(); - - cfg.regulator1.set_drv_b(0); - cfg.bias.set_pd_cur(true); - cfg.bias.set_bias_sleep(true); - cfg.regulator0.set_slp_xpd(false); - cfg.regulator0.set_slp_dbias(0); - cfg.regulator0.set_xpd(true); - cfg.bias.set_dbg_atten(12); - cfg.regulator0.set_dbias(23); // 0.7V - - cfg - }, - } - } - - fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self { - let mut this = Self { - // PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT - hp_sys: { - let mut cfg = HpAnalog::default(); - - cfg.regulator1.set_drv_b(0); - cfg.bias.set_pd_cur(true); - cfg.bias.set_bias_sleep(true); - cfg.regulator0.set_xpd(true); - cfg.bias.set_dbg_atten(0); - cfg.regulator0.set_dbias(1); // 0.6V - - cfg - }, - // lp_sys_active: LpAnalog::default(), - lp_sys_sleep: { - let mut cfg = LpAnalog::default(); - - cfg.regulator1.set_drv_b(0); - cfg.bias.set_pd_cur(true); - cfg.bias.set_bias_sleep(true); - cfg.regulator0.set_slp_xpd(false); - cfg.regulator0.set_slp_dbias(0); - cfg.regulator0.set_xpd(true); - cfg.bias.set_dbg_atten(0); - cfg.regulator0.set_dbias(12); // 0.7V - - cfg - }, - }; - - if !pd_flags.pd_xtal() { - this.hp_sys.bias.set_pd_cur(false); - this.hp_sys.bias.set_bias_sleep(false); - this.hp_sys.regulator0.set_dbias(25); - - this.lp_sys_sleep.bias.set_pd_cur(false); - this.lp_sys_sleep.bias.set_bias_sleep(false); - this.lp_sys_sleep.regulator0.set_dbias(26); - } - - this - } - - fn apply(&self) { - // pmu_sleep_analog_init - - unsafe { - // HP SLEEP (hp_sleep_*) - pmu().hp_sleep_bias().modify(|_, w| { - w.hp_sleep_dbg_atten() // pmu_ll_hp_set_dbg_atten - .bits(self.hp_sys.bias.dbg_atten()) - .hp_sleep_pd_cur() // pmu_ll_hp_set_current_power_off - .bit(self.hp_sys.bias.pd_cur()) - .sleep() // pmu_ll_hp_set_bias_sleep_enable - .bit(self.hp_sys.bias.bias_sleep()) - }); - pmu().hp_sleep_hp_regulator0().modify(|_, w| { - w.hp_sleep_hp_regulator_xpd() // pmu_ll_hp_set_regulator_xpd - .bit(self.hp_sys.regulator0.xpd()) - .hp_sleep_hp_regulator_dbias() // pmu_ll_hp_set_regulator_dbias - .bits(self.hp_sys.regulator0.dbias()) - }); - pmu().hp_sleep_hp_regulator1().modify(|_, w| { - w.hp_sleep_hp_regulator_drv_b() // pmu_ll_hp_set_regulator_driver_bar - .bits(self.hp_sys.regulator1.drv_b()) - }); - - // LP SLEEP (lp_sleep_*) - pmu().lp_sleep_bias().modify(|_, w| { - w.lp_sleep_dbg_atten() // pmu_ll_lp_set_dbg_atten - .bits(self.lp_sys_sleep.bias.dbg_atten()) - .lp_sleep_pd_cur() // pmu_ll_lp_set_current_power_off - .bit(self.lp_sys_sleep.bias.pd_cur()) - .sleep() // pmu_ll_lp_set_bias_sleep_enable - .bit(self.lp_sys_sleep.bias.bias_sleep()) - }); - - pmu().lp_sleep_lp_regulator0().modify(|_, w| { - w.lp_sleep_lp_regulator_slp_xpd() // pmu_ll_lp_set_regulator_slp_xpd - .bit(self.lp_sys_sleep.regulator0.slp_xpd()) - .lp_sleep_lp_regulator_xpd() // pmu_ll_lp_set_regulator_xpd - .bit(self.lp_sys_sleep.regulator0.xpd()) - .lp_sleep_lp_regulator_slp_dbias() // pmu_ll_lp_set_regulator_sleep_dbias - .bits(self.lp_sys_sleep.regulator0.slp_dbias()) - .lp_sleep_lp_regulator_dbias() // pmu_ll_lp_set_regulator_dbias - .bits(self.lp_sys_sleep.regulator0.dbias()) - }); - - pmu().lp_sleep_lp_regulator1().modify(|_, w| { - w.lp_sleep_lp_regulator_drv_b() // pmu_ll_lp_set_regulator_driver_bar - .bits(self.lp_sys_sleep.regulator1.drv_b()) - }); - } - } -} - -/// Configuration for controlling the behavior of digital peripherals during -/// sleep modes. -#[derive(Clone, Copy)] -// pmu_sleep_digital_config_t -pub struct DigitalSleepConfig { - /// High-power system control register configuration. - pub syscntl: HpSysCntlReg, -} - -impl DigitalSleepConfig { - fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self { - Self { - // PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT - syscntl: { - let mut cfg = HpSysCntlReg::default(); - - cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not()); - - cfg - }, - } - } - - fn apply(&self) { - // pmu_sleep_digital_init - unsafe { - pmu().hp_sleep_hp_sys_cntl().modify(|_, w| { - w.hp_sleep_dig_pad_slp_sel() - .bit(self.syscntl.dig_pad_slp_sel()) - }) - }; - } -} - -/// Configuration for controlling the power settings of high-power and low-power -/// systems during sleep modes. -#[derive(Clone, Copy)] -// pmu_sleep_power_config_t -pub struct PowerSleepConfig { - /// Power configuration for the high-power system during sleep. - pub hp_sys: HpSysPower, - /// Power configuration for the low-power system when it is active. - pub lp_sys_active: LpSysPower, - /// Power configuration for the low-power system when it is in sleep mode. - pub lp_sys_sleep: LpSysPower, -} - -impl PowerSleepConfig { - fn defaults(pd_flags: PowerDownFlags) -> Self { - let mut this = Self { - hp_sys: HpSysPower::default(), - lp_sys_active: LpSysPower::default(), - lp_sys_sleep: LpSysPower::default(), - }; - this.apply_flags(pd_flags); - this - } - - fn apply_flags(&mut self, pd_flags: PowerDownFlags) { - // PMU_SLEEP_POWER_CONFIG_DEFAULT - self.hp_sys - .dig_power - .set_vdd_spi_pd_en(pd_flags.pd_vddsdio()); - self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem()); - self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu()); - self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon()); - self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top()); - - self.hp_sys.clk.set_i2c_iso_en(true); - self.hp_sys.clk.set_i2c_retention(true); - - self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not()); - - self.lp_sys_active.clk_power.set_xpd_xtal32k(true); - self.lp_sys_active.clk_power.set_xpd_rc32k(true); - self.lp_sys_active.clk_power.set_xpd_fosc(true); - - self.lp_sys_sleep - .dig_power - .set_peri_pd_en(pd_flags.pd_lp_periph()); - self.lp_sys_sleep.dig_power.set_mem_dslp(true); - - self.lp_sys_sleep - .clk_power - .set_xpd_xtal32k(pd_flags.pd_xtal32k().not()); - self.lp_sys_sleep - .clk_power - .set_xpd_rc32k(pd_flags.pd_rc32k().not()); - self.lp_sys_sleep - .clk_power - .set_xpd_fosc(pd_flags.pd_rc_fast().not()); - - self.lp_sys_sleep - .xtal - .set_xpd_xtal(pd_flags.pd_xtal().not()); - } - - fn apply(&self) { - // pmu_sleep_power_init - - unsafe { - // HP SLEEP (hp_sleep_*) - pmu() - .hp_sleep_dig_power() - .modify(|_, w| w.bits(self.hp_sys.dig_power.0)); - pmu() - .hp_sleep_hp_ck_power() - .modify(|_, w| w.bits(self.hp_sys.clk.0)); - pmu() - .hp_sleep_xtal() - .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal())); - - // LP ACTIVE (hp_sleep_lp_*) - pmu() - .hp_sleep_lp_dig_power() - .modify(|_, w| w.bits(self.lp_sys_active.dig_power.0)); - pmu() - .hp_sleep_lp_ck_power() - .modify(|_, w| w.bits(self.lp_sys_active.clk_power.0)); - - // LP SLEEP (lp_sleep_*) - pmu() - .lp_sleep_lp_dig_power() - .modify(|_, w| w.bits(self.lp_sys_sleep.dig_power.0)); - pmu() - .lp_sleep_lp_ck_power() - .modify(|_, w| w.bits(self.lp_sys_sleep.clk_power.0)); - pmu() - .lp_sleep_xtal() - .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal())); - } - } -} - -/// Parameters for high-power system configurations during sleep modes. -#[derive(Clone, Copy)] -// pmu_hp_param_t -pub struct HpParam { - /// Number of cycles to wait for the modem to wake up. - pub modem_wakeup_wait_cycle: u32, - /// Number of cycles to wait for the analog component stabilization. - pub analog_wait_target_cycle: u16, - /// Number of cycles to wait for the digital power-down sequence. - pub digital_power_down_wait_cycle: u16, - /// Number of cycles to wait for the digital power supply to stabilize. - pub digital_power_supply_wait_cycle: u16, - /// Number of cycles to wait for the digital power-up sequence. - pub digital_power_up_wait_cycle: u16, - /// Number of cycles to wait for the PLL to stabilize. - pub pll_stable_wait_cycle: u16, - /// Number of cycles to wait for modifying the ICG control. - pub modify_icg_cntl_wait_cycle: u8, - /// Number of cycles to wait for switching the ICG coйntrol. - pub switch_icg_cntl_wait_cycle: u8, - /// Minimum sleep time measured in slow clock cycles. - pub min_slp_slow_clk_cycle: u8, -} - -/// Parameters for low-power system configurations during sleep modes. -#[derive(Clone, Copy)] -// pmu_lp_param_t -pub struct LpParam { - /// Number of cycles to wait for the digital power supply to stabilize. - pub digital_power_supply_wait_cycle: u16, - /// Minimum sleep time measured in slow clock cycles. - pub min_slp_slow_clk_cycle: u8, - /// Number of cycles to wait for the analog component stabilization. - pub analog_wait_target_cycle: u8, - /// Number of cycles to wait for the digital power-down sequence. - pub digital_power_down_wait_cycle: u8, - /// Number of cycles to wait for the digital power-up sequence. - pub digital_power_up_wait_cycle: u8, -} - -/// Parameters for high-power and low-power system configurations during sleep -/// modes. -#[derive(Clone, Copy)] -// pmu_hp_lp_param_t -pub struct HpLpParam { - /// Union of two u16 variants - pub xtal_stable_wait_cycle: u16, -} - -/// Configuration of parameters for sleep modes -#[derive(Clone, Copy)] -// pmu_sleep_param_config_t -pub struct ParamSleepConfig { - /// Configuration of high-power system parameters. - pub hp_sys: HpParam, - /// Configuration of low-power system parameters. - pub lp_sys: LpParam, - /// Shared configuration parameters for high-power and low-power systems. - pub hp_lp: HpLpParam, -} -impl ParamSleepConfig { - const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self { - hp_sys: HpParam { - min_slp_slow_clk_cycle: 10, - analog_wait_target_cycle: 2419, - digital_power_supply_wait_cycle: 32, - digital_power_up_wait_cycle: 32, - modem_wakeup_wait_cycle: 20700, - pll_stable_wait_cycle: 2, - - digital_power_down_wait_cycle: 0, - modify_icg_cntl_wait_cycle: 0, - switch_icg_cntl_wait_cycle: 0, - }, - lp_sys: LpParam { - min_slp_slow_clk_cycle: 10, - analog_wait_target_cycle: 23, - digital_power_supply_wait_cycle: 32, - digital_power_up_wait_cycle: 32, - - digital_power_down_wait_cycle: 0, - }, - hp_lp: HpLpParam { - xtal_stable_wait_cycle: 30, - }, - }; - - fn apply(&self) { - // pmu_sleep_param_init - - unsafe { - pmu().slp_wakeup_cntl3().modify(|_, w| { - w.hp_min_slp_val() // pmu_ll_hp_set_min_sleep_cycle - .bits(self.hp_sys.min_slp_slow_clk_cycle) - .lp_min_slp_val() // pmu_ll_lp_set_min_sleep_cycle - .bits(self.lp_sys.min_slp_slow_clk_cycle) - }); - - pmu().slp_wakeup_cntl7().modify(|_, w| { - w.ana_wait_target() // pmu_ll_hp_set_analog_wait_target_cycle - .bits(self.hp_sys.analog_wait_target_cycle) - }); - - pmu().power_wait_timer0().modify(|_, w| { - w.dg_hp_wait_timer() // pmu_ll_hp_set_digital_power_supply_wait_cycle - .bits(self.hp_sys.digital_power_supply_wait_cycle) - .dg_hp_powerup_timer() // pmu_ll_hp_set_digital_power_up_wait_cycle - .bits(self.hp_sys.digital_power_up_wait_cycle) - }); - - pmu().power_wait_timer1().modify(|_, w| { - w.dg_lp_wait_timer() // pmu_ll_lp_set_digital_power_supply_wait_cycle - .bits(self.lp_sys.digital_power_supply_wait_cycle) - .dg_lp_powerup_timer() // pmu_ll_lp_set_digital_power_up_wait_cycle - .bits(self.lp_sys.digital_power_up_wait_cycle) - }); - - pmu().slp_wakeup_cntl5().modify(|_, w| { - w.lp_ana_wait_target() // pmu_ll_lp_set_analog_wait_target_cycle - .bits(self.lp_sys.analog_wait_target_cycle) - .modem_wait_target() // pmu_ll_hp_set_modem_wakeup_wait_cycle - .bits(self.hp_sys.modem_wakeup_wait_cycle) - }); - pmu().power_ck_wait_cntl().modify(|_, w| { - w.wait_xtl_stable() // pmu_ll_hp_set_xtal_stable_wait_cycle - .bits(self.hp_lp.xtal_stable_wait_cycle) - .wait_pll_stable() // pmu_ll_hp_set_pll_stable_wait_cycle - .bits(self.hp_sys.pll_stable_wait_cycle) - }); - } - } - - fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self { - let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT; - - // pmu_sleep_param_config_default - param.hp_sys.min_slp_slow_clk_cycle = - config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8; - param.hp_sys.analog_wait_target_cycle = - config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16; - param.hp_sys.digital_power_supply_wait_cycle = - config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16; - param.hp_sys.digital_power_up_wait_cycle = - config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16; - param.hp_sys.pll_stable_wait_cycle = - config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16; - - let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags); - - let modem_wakeup_wait_time_us = (config.sleep_time_adjustment - + MachineConstants::MODEM_STATE_SKIP_TIME_US - + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US) - .saturating_sub(hw_wait_time_us); - param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us); - - param.lp_sys.min_slp_slow_clk_cycle = - config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8; - param.lp_sys.analog_wait_target_cycle = - config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8; - param.lp_sys.digital_power_supply_wait_cycle = - config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16; - param.lp_sys.digital_power_up_wait_cycle = - config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8; - - // This looks different from esp-idf but it is the same: - // Both `xtal_stable_wait_cycle` and `xtal_stable_wait_slow_clk_cycle` are - // u16 variants of the same union - param.hp_lp.xtal_stable_wait_cycle = if pd_xtal { - config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16 - } else { - config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16 - }; - - param - } -} - -#[derive(Clone, Copy)] -struct SleepTimeConfig { - sleep_time_adjustment: u32, - // TODO: esp-idf does some calibration here to determine slowclk_period - slowclk_period: u32, - fastclk_period: u32, -} - -const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160; - -impl SleepTimeConfig { - const RTC_CLK_CAL_FRACT: u32 = 19; - - fn rtc_clk_cal_fast(mut slowclk_cycles: u32) -> u32 { - let xtal_freq = 40; // esp-idf has a very complicated way of determining this - - // The Fosc CLK of calibration circuit is divided by 32 for ECO1. - // So we need to divide the calibrate cycles of the FOSC for ECO1 and above - // chips by 32 to avoid excessive calibration time. - if Efuse::chip_revision() >= 1 { - slowclk_cycles /= 32; - } - - let xtal_cycles = RtcClock::calibrate_internal(RtcCalSel::RcFast, slowclk_cycles) as u64; - - let divider: u64 = xtal_freq as u64 * slowclk_cycles as u64; - let period_64: u64 = ((xtal_cycles << Self::RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; - (period_64 & (u32::MAX as u64)) as u32 - } - - fn new(_deep: bool) -> Self { - // https://github.com/espressif/esp-idf/commit/e1d24ebd7f43c7c7ded183bc8800b20af3bf014b - - // Calibrate rtc slow clock - // TODO: do an actual calibration instead of a read - let slowclk_period = unsafe { lp_aon().store1().read().data().bits() }; - - // Calibrate rtc fast clock, only PMU supported chips sleep process is needed. - const FAST_CLK_SRC_CAL_CYCLES: u32 = 2048; - let fastclk_period = Self::rtc_clk_cal_fast(FAST_CLK_SRC_CAL_CYCLES); - - Self { - sleep_time_adjustment: 0, - slowclk_period, - fastclk_period, - } - } - - fn light_sleep(pd_flags: PowerDownFlags) -> Self { - const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56; - - let mut this = Self::new(false); - - let sw = LIGHT_SLEEP_TIME_OVERHEAD_US; // TODO - let hw = this.pmu_sleep_calculate_hw_wait_time(pd_flags); - - this.sleep_time_adjustment = sw + hw; - - this - } - - fn deep_sleep() -> Self { - let mut this = Self::new(true); - - this.sleep_time_adjustment = 250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; - - this - } - - fn us_to_slowclk(&self, us: u32) -> u32 { - (us << Self::RTC_CLK_CAL_FRACT) / self.slowclk_period - } - - fn slowclk_to_us(&self, rtc_cycles: u32) -> u32 { - (rtc_cycles * self.slowclk_period) >> Self::RTC_CLK_CAL_FRACT - } - - fn us_to_fastclk(&self, us: u32) -> u32 { - (us << Self::RTC_CLK_CAL_FRACT) / self.fastclk_period - } - - fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 { - // LP core hardware wait time, microsecond - let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE); - let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE); - let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() { - MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US - } else { - self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE) - }; - - let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US - + MachineConstants::LP_ANALOG_WAIT_TIME_US - + lp_clk_power_on_wait_time_us - + lp_wakeup_wait_time_us - + lp_clk_switch_time_us - + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US - + MachineConstants::LP_POWER_UP_WAIT_TIME_US; - - // HP core hardware wait time, microsecond - let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US - + MachineConstants::HP_POWER_UP_WAIT_TIME_US; - let hp_regdma_wait_time_us = u32::max( - MachineConstants::HP_REGDMA_S2M_WORK_TIME_US - + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US, - MachineConstants::HP_REGDMA_S2A_WORK_TIME_US, - ); - let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US - + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US; - - let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US - + u32::max( - hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us, - hp_clock_wait_time_us, - ); - - #[rustfmt::skip] // ASCII art - // When the SOC wakeup (lp timer or GPIO wakeup) and Modem wakeup (Beacon wakeup) complete, - // the soc wakeup will be delayed until the RF is turned on in Modem state. - // - // modem wakeup TBTT, RF on by HW - // | | - // \|/ \|/ - // PMU_HP_ACTIVE /------ - // PMU_HP_MODEM /------------////////////////// - // PMU_HP_SLEEP ----------------------////////////////// - // /|\ /|\ /|\ /|\ /|\ /|\ - // |<- some hw wait ->| | | |<- M2A switch ->| - // | slow cycles & | soc wakeup | | - // | FOSC cycles |<- S2M switch ->| | - // | | - // |<-- PMU guard time, also the maximum time for the SOC -->| - // | wake-up delay | - // - const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true; - - let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP { - ( - MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US, - MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US, - ) - } else { - (0, 0) - }; - - lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us - } -} - -/// Configuration for the RTC sleep behavior. -#[derive(Clone, Copy)] -// pmu_sleep_config_t + deep sleep flag + pd flags -pub struct RtcSleepConfig { - /// Deep Sleep flag - pub deep: bool, - /// Power Down flags - pub pd_flags: PowerDownFlags, -} - -impl Default for RtcSleepConfig { - fn default() -> Self { - // from pmu_sleep_param_config_default - // sleep flags will be applied by wakeup methods and apply - - Self { - deep: false, - pd_flags: PowerDownFlags(0), - } - } -} - -unsafe fn pmu<'a>() -> &'a esp32p4::pmu::RegisterBlock { - unsafe { &*esp32p4::PMU::ptr() } -} - -unsafe fn lp_aon<'a>() -> &'a esp32p4::lp_aon_clkrst::RegisterBlock { - unsafe { &*esp32p4::LP_AON_CLKRST::ptr() } -} - -bitfield::bitfield! { - #[derive(Clone, Copy)] - /// Power domains to be powered down during sleep - pub struct PowerDownFlags(u32); - - /// Controls the power-down status of the top power domain. - pub u32, pd_top , set_pd_top : 0; - /// Controls the power-down status of the VDD_SDIO power domain. - pub u32, pd_vddsdio , set_pd_vddsdio : 1; - /// Controls the power-down status of the modem power domain. - pub u32, pd_modem , set_pd_modem : 2; - /// Controls the power-down status of the high-performance peripheral power domain. - pub u32, pd_hp_periph, set_pd_hp_periph: 3; - /// Controls the power-down status of the CPU power domain. - pub u32, pd_cpu , set_pd_cpu : 4; - /// Controls the power-down status of the high-performance always-on domain. - pub u32, pd_hp_aon , set_pd_hp_aon : 5; - /// Controls the power-down status of memory group 0. - pub u32, pd_mem_g0 , set_pd_mem_g0 : 6; - /// Controls the power-down status of memory group 1. - pub u32, pd_mem_g1 , set_pd_mem_g1 : 7; - /// Controls the power-down status of memory group 2. - pub u32, pd_mem_g2 , set_pd_mem_g2 : 8; - /// Controls the power-down status of memory group 3. - pub u32, pd_mem_g3 , set_pd_mem_g3 : 9; - /// Controls the power-down status of the crystal oscillator. - pub u32, pd_xtal , set_pd_xtal : 10; - /// Controls the power-down status of the fast RC oscillator. - pub u32, pd_rc_fast , set_pd_rc_fast : 11; - /// Controls the power-down status of the 32kHz crystal oscillator. - pub u32, pd_xtal32k , set_pd_xtal32k : 12; - /// Controls the power-down status of the 32kHz RC oscillator. - pub u32, pd_rc32k , set_pd_rc32k : 13; - /// Controls the power-down status of the low-power peripheral domain. - pub u32, pd_lp_periph, set_pd_lp_periph: 14; -} - -impl PowerDownFlags { - /// Checks whether all memory groups (G0, G1, G2, G3) are powered down. - pub fn pd_mem(self) -> bool { - self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3() - } - - /// Sets the power-down status for all memory groups (G0, G1, G2, G3) at - /// once. - pub fn set_pd_mem(&mut self, value: bool) { - self.set_pd_mem_g0(value); - self.set_pd_mem_g1(value); - self.set_pd_mem_g2(value); - self.set_pd_mem_g3(value); - } -} - -// Constants defined in `PMU_SLEEP_MC_DEFAULT()` -struct MachineConstants; -impl MachineConstants { - const LP_MIN_SLP_TIME_US: u32 = 450; - const LP_WAKEUP_WAIT_CYCLE: u32 = 4; - const LP_ANALOG_WAIT_TIME_US: u32 = 154; - const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250; - const LP_CLK_SWITCH_CYCLE: u32 = 1; - const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1; - const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2; - const LP_POWER_UP_WAIT_TIME_US: u32 = 2; - - const HP_MIN_SLP_TIME_US: u32 = 450; - const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 150; - const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124; - const HP_ANALOG_WAIT_TIME_US: u32 = 154; - const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2; - const HP_POWER_UP_WAIT_TIME_US: u32 = 2; - const HP_REGDMA_S2M_WORK_TIME_US: u32 = 172; - const HP_REGDMA_S2A_WORK_TIME_US: u32 = 480; - const HP_REGDMA_M2A_WORK_TIME_US: u32 = 278; - // Unused, but defined in esp-idf. May be needed later. - // const HP_REGDMA_A2S_WORK_TIME_US: u32 = 382; - const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 70; - // Unused, but defined in esp-idf. May be needed later. - // const HP_REGDMA_RF_OFF_WORK_TIME_US: u32 = 23; - const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250; - const HP_PLL_WAIT_STABLE_TIME_US: u32 = 1; - - const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US - + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US - + Self::LP_MIN_SLP_TIME_US; -} - -impl RtcSleepConfig { - /// Returns whether the device is in deep sleep mode. - pub fn deep_slp(&self) -> bool { - self.deep - } - - /// Configures the device for deep sleep mode with ultra-low power settings. - pub fn deep() -> Self { - // Set up for ultra-low power sleep. Wakeup sources may modify these settings. - Self { - deep: true, - ..Self::default() - } - } - - pub(crate) fn base_settings(_rtc: &Rtc<'_>) { - Self::wake_io_reset(); - } - - fn wake_io_reset() { - // loosely based on esp_deep_sleep_wakeup_io_reset - Ext1WakeupSource::wake_io_reset(); - } - - /// Finalize power-down flags, apply configuration based on the flags. - pub(crate) fn apply(&mut self) { - if self.deep { - // force-disable certain power domains - self.pd_flags.set_pd_top(true); - self.pd_flags.set_pd_vddsdio(true); - self.pd_flags.set_pd_modem(true); - self.pd_flags.set_pd_hp_periph(true); - self.pd_flags.set_pd_cpu(true); - self.pd_flags.set_pd_mem(true); - self.pd_flags.set_pd_xtal(true); - self.pd_flags.set_pd_hp_aon(true); - self.pd_flags.set_pd_lp_periph(true); - self.pd_flags.set_pd_xtal32k(true); - self.pd_flags.set_pd_rc32k(true); - self.pd_flags.set_pd_rc_fast(true); - } - } - - /// Configures wakeup options and enters sleep. - /// - /// This function does not return if deep sleep is requested. - pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) { - const PMU_EXT0_WAKEUP_EN: u32 = 1 << 0; - const PMU_EXT1_WAKEUP_EN: u32 = 1 << 1; - const PMU_GPIO_WAKEUP_EN: u32 = 1 << 2; - const PMU_LP_TIMER_WAKEUP_EN: u32 = 1 << 4; - const PMU_WIFI_SOC_WAKEUP_EN: u32 = 1 << 5; - const PMU_UART0_WAKEUP_EN: u32 = 1 << 6; - const PMU_UART1_WAKEUP_EN: u32 = 1 << 7; - const PMU_SDIO_WAKEUP_EN: u32 = 1 << 8; - const PMU_BLE_SOC_WAKEUP_EN: u32 = 1 << 10; - const PMU_LP_CORE_WAKEUP_EN: u32 = 1 << 11; - const PMU_USB_WAKEUP_EN: u32 = 1 << 14; - const MODEM_REJECT: u32 = 1 << 16; - - const RTC_SLEEP_REJECT_MASK: u32 = PMU_EXT0_WAKEUP_EN - | PMU_EXT1_WAKEUP_EN - | PMU_GPIO_WAKEUP_EN - | PMU_LP_TIMER_WAKEUP_EN - | PMU_WIFI_SOC_WAKEUP_EN - | PMU_UART0_WAKEUP_EN - | PMU_UART1_WAKEUP_EN - | PMU_SDIO_WAKEUP_EN - | PMU_BLE_SOC_WAKEUP_EN - | PMU_LP_CORE_WAKEUP_EN - | PMU_USB_WAKEUP_EN; - - let wakeup_mask = wakeup_triggers.0 as u32; - let reject_mask = if self.deep { - 0 - } else { - // TODO: MODEM_REJECT if s_sleep_modem.wifi.phy_link != NULL - let reject_mask = RTC_SLEEP_REJECT_MASK | MODEM_REJECT; - wakeup_mask & reject_mask - }; - - let cpu_freq_config = ClockTree::with(|clocks| { - let cpu_freq_config = SavedClockConfig::save(clocks); - crate::soc::clocks::configure_soc_root_clk( - clocks, - crate::soc::clocks::SocRootClkConfig::Xtal, - ); - cpu_freq_config - }); - - // pmu_sleep_config_default + pmu_sleep_init. - - let power = PowerSleepConfig::defaults(self.pd_flags); - power.apply(); - - // Needs to happen after rtc_clk_cpu_freq_set_xtal - let config = if self.deep { - SleepTimeConfig::deep_sleep() - } else { - SleepTimeConfig::light_sleep(self.pd_flags) - }; - - let mut param = - ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal()); - - if self.deep { - const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500; - param.lp_sys.analog_wait_target_cycle = - config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8; - - AnalogSleepConfig::defaults_deep_sleep().apply(); - } else { - AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply(); - DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply(); - } - - param.apply(); - - // like esp-idf pmu_sleep_start() - - unsafe { - // lp_aon_hal_inform_wakeup_type - tells ROM which wakeup stub to run - lp_aon() - .store9() - .modify(|r, w| w.bits(r.bits() & !0x01 | self.deep as u32)); - - // pmu_ll_hp_set_wakeup_enable - pmu().slp_wakeup_cntl2().write(|w| w.bits(wakeup_mask)); - - // pmu_ll_hp_set_reject_enable - pmu().slp_wakeup_cntl1().modify(|_, w| { - w.slp_reject_en() - .bit(true) - .sleep_reject_ena() - .bits(reject_mask) - }); - - // pmu_ll_hp_clear_reject_cause - pmu() - .slp_wakeup_cntl4() - .write(|w| w.slp_reject_cause_clr().bit(true)); - - pmu().int_clr().write(|w| { - w.sw() // pmu_ll_hp_clear_sw_intr_status - .clear_bit_by_one() - .soc_sleep_reject() // pmu_ll_hp_clear_reject_intr_status - .clear_bit_by_one() - .soc_wakeup() // pmu_ll_hp_clear_wakeup_intr_status - .clear_bit_by_one() - }); - - // misc_modules_sleep_prepare - - // TODO: IDF-7370 - #[cfg(not(soc_has_pmu))] - if !(self.deep && wakeup_triggers.touch) { - APB_SARADC::regs() - .ctrl() - .modify(|_, w| w.saradc2_pwdet_drv().bit(false)); - } - - // Start entry into sleep mode - - // pmu_ll_hp_set_sleep_enable - pmu().slp_wakeup_cntl0().write(|w| w.sleep_req().bit(true)); - - // In pd_cpu lightsleep and deepsleep mode, we never get here - loop { - let int_raw = pmu().int_raw().read(); - if int_raw.soc_wakeup().bit_is_set() || int_raw.soc_sleep_reject().bit_is_set() { - break; - } - } - } - - // esp-idf returns if the sleep was rejected, we don't return anything - - ClockTree::with(|clocks| { - cpu_freq_config.restore(clocks); - }); - } - - /// Cleans up after sleep - pub(crate) fn finish_sleep(&self) { - // like esp-idf pmu_sleep_finish() - // In "pd_cpu lightsleep" and "deepsleep" modes we never get here - - // esp-idf returns if the sleep was rejected, we do nothing - // pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev) - - Self::wake_io_reset(); - } -} +//! Sleep mode for ESP32-P4X (chip revision v3.x / eco5). +//! +//! Current status: Not implemented. Sleep mode requires PMU eco5 registers +//! which have different layouts from eco4. +//! +//! The original florianL21 sleep code (1064 lines) is preserved as +//! esp32p4_florianl21_original.rs.bak in this directory. +//! It references types and PMU registers that don't exist in current PAC: +//! - crate::clock::Clock, crate::efuse::Efuse (old API pattern) +//! - PMU hp_active/hp_modem/hp_sleep register groups +//! +//! TODO(P4X): Implement sleep mode once PMU eco5 registers are validated. +//! Ref: esp-idf pmu_sleep.c, pmu_eco5_struct.h +//! TRM v0.5 Ch 16 (Low-Power Management) +//! .investigation/ESP32P4_ECO5_PERIPHERAL_AUDIT.md + +// florianL21 original: see esp32p4_florianl21_original.rs.bak (1064 lines) diff --git a/esp-hal/src/rtc_cntl/sleep/mod.rs b/esp-hal/src/rtc_cntl/sleep/mod.rs index d6b455131ee..3381759edaf 100644 --- a/esp-hal/src/rtc_cntl/sleep/mod.rs +++ b/esp-hal/src/rtc_cntl/sleep/mod.rs @@ -31,6 +31,7 @@ use crate::rtc_cntl::Rtc; #[cfg_attr(esp32c6, path = "esp32c6.rs")] #[cfg_attr(esp32c2, path = "esp32c2.rs")] #[cfg_attr(esp32h2, path = "esp32h2.rs")] +#[cfg_attr(esp32p4, path = "esp32p4.rs")] mod sleep_impl; pub use sleep_impl::*; diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index b09cdbfbe02..a9825cf40fd 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -1,52 +1,86 @@ -//! Clock tree definitions and implementations for ESP32-C6. +//! Clock tree for ESP32-P4X (chip revision v3.x / eco5). //! -//! Remarks: -//! - Enabling a clock node assumes it has first been configured. Some fixed clock nodes don't need -//! to be configured. -//! - Some information may be assumed, e.g. the possibility to disable watchdog timers before clock -//! configuration. -//! - Internal RC oscillators (136k RC_SLOW and 17.5M RC_FAST) are not calibrated here, this system -//! can only give a rough estimate of their frequency. They can be calibrated separately using a -//! known crystal frequency. -//! - Some of the SOC capabilities are not implemented: I2S external pad clock source, external 32k -//! oscillator, LP_DYN_FAST_CLK, APB_DECREASE_DIV (which seems unnecessary to model), -//! PCR_CPU_HS_120M_FORCE. -#![allow(dead_code, reason = "Some of this is bound to be unused")] - -// TODO: This is a temporary place for this, should probably be moved into clocks_ll. - -use crate::peripherals::{LP_AON_CLKRST, PMU, SYSTEM}; +//! CPLL: 400 MHz (eco5 default), 360 MHz (conservative) +//! SPLL: 480 MHz (peripheral clocks) +//! MPLL: 400 MHz (PSRAM, media) +//! XTAL: 40 MHz +//! +//! Clock hierarchy: XTAL -> CPLL -> CPU_ROOT -> CPU/APB dividers +//! SPLL -> PLL_F240M/160M/120M/80M/20M (peripheral clocks) +//! +//! Ref: esp-idf rtc_clk.c, clk_tree_ll.h, clk_tree_defs.h +//! TRM v0.5 Ch 12 (Reset and Clock) +#![allow(dead_code, reason = "Clock functions called from generated macro code")] define_clock_tree_types!(); -/// Clock configuration options. +/// CPU clock frequency presets for ESP32-P4X (eco5 / chip revision v3.x). +/// Ref: esp-idf rtc_clk.c:240 -- !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 path +/// TRM v0.5 Ch 2 -- HP CPU max frequency 400 MHz for v3.x #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[allow( - clippy::enum_variant_names, - reason = "MHz suffix indicates physical unit." -)] #[non_exhaustive] pub enum CpuClock { - /// 360 MHz CPU clock + /// 400 MHz CPU clock (eco5 / v3.x maximum) + /// CPLL -> CPU_ROOT -> CPU/1, APB divider /4 = 100MHz #[default] - _360MHz = 360, + _400MHz = 400, + + /// 360 MHz CPU clock (conservative) + _360MHz = 360, + + /// 200 MHz CPU clock (low power) + /// CPLL -> CPU_ROOT -> CPU/2, APB /2 = 100MHz + _200MHz = 200, + + /// 100 MHz CPU clock (ultra low power) + /// CPLL -> CPU_ROOT -> CPU/4, APB /1 = 100MHz + _100MHz = 100, } impl CpuClock { + // Preset: 400 MHz CPU, 100 MHz APB + // Ref: esp-idf rtc_clk.c:262 -- case 400: cpu=1, mem=2, apb=2 + const PRESET_400: ClockConfig = ClockConfig { + cpu_root_clk: Some(CpuRootClkConfig::Cpll), + cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 400 MHz + apb_clk: Some(ApbClkConfig::new(3)), // /4 = 100 MHz + lp_fast_clk: Some(LpFastClkConfig::RcFast), + lp_slow_clk: Some(LpSlowClkConfig::RcSlow), + }; + const PRESET_360: ClockConfig = ClockConfig { - xtal_clk: None, - apb_clk: Some(ApbClkConfig::new(0)), + cpu_root_clk: Some(CpuRootClkConfig::Cpll), + cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 360 MHz (CPLL at 360) + apb_clk: Some(ApbClkConfig::new(3)), // /4 = 90 MHz + lp_fast_clk: Some(LpFastClkConfig::RcFast), + lp_slow_clk: Some(LpSlowClkConfig::RcSlow), + }; + + const PRESET_200: ClockConfig = ClockConfig { + cpu_root_clk: Some(CpuRootClkConfig::Cpll), + cpu_clk: Some(CpuClkConfig::new(1)), // /2 = 200 MHz + apb_clk: Some(ApbClkConfig::new(1)), // /2 = 100 MHz + lp_fast_clk: Some(LpFastClkConfig::RcFast), + lp_slow_clk: Some(LpSlowClkConfig::RcSlow), + }; + + const PRESET_100: ClockConfig = ClockConfig { + cpu_root_clk: Some(CpuRootClkConfig::Cpll), + cpu_clk: Some(CpuClkConfig::new(3)), // /4 = 100 MHz + apb_clk: Some(ApbClkConfig::new(0)), // /1 = 100 MHz lp_fast_clk: Some(LpFastClkConfig::RcFast), lp_slow_clk: Some(LpSlowClkConfig::RcSlow), - ..Default::default() }; } impl From for ClockConfig { fn from(value: CpuClock) -> ClockConfig { match value { + CpuClock::_400MHz => CpuClock::PRESET_400, CpuClock::_360MHz => CpuClock::PRESET_360, + CpuClock::_200MHz => CpuClock::PRESET_200, + CpuClock::_100MHz => CpuClock::PRESET_100, } } } @@ -60,286 +94,193 @@ impl Default for ClockConfig { impl ClockConfig { pub(crate) fn try_get_preset(self) -> Option { match self { + v if v == CpuClock::PRESET_400 => Some(CpuClock::_400MHz), v if v == CpuClock::PRESET_360 => Some(CpuClock::_360MHz), + v if v == CpuClock::PRESET_200 => Some(CpuClock::_200MHz), + v if v == CpuClock::PRESET_100 => Some(CpuClock::_100MHz), _ => None, } } - pub(crate) fn configure(mut self) { - if self.xtal_clk.is_none() { - self.xtal_clk = Some(XtalClkConfig::_40); - } + pub(crate) fn configure(self) { self.apply(); } } -// XTAL_CLK - -fn configure_xtal_clk_impl(_clocks: &mut ClockTree, _config: XtalClkConfig) { - // The stored configuration affects PLL settings instead. -} - -// CPLL_CLK - -fn enable_cpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_cpll_clk_impl(_clocks: &mut ClockTree, _config: CpllClkConfig) { - todo!() -} - -// RC_FAST_CLK - -fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, en: bool) { - HP_SYS_CLKRST::regs().hp_rst_en1().modify(|_,w| w.rst_en_uart0_core().bit(en)) - PMU::regs() - .hp_sleep_lp_ck_power() - .modify(|_, w| w.hp_sleep_xpd_fosc_clk().bit(en)); - // TODO: Should the digital clock gate be a different clock node? - LP_AON_CLKRST::regs() - .clk_to_hp() - .modify(|_, w| w.icg_hp_fosc().bit(en)); - crate::rom::ets_delay_us(5); -} - -// MPLL_CLK - -fn enable_mpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_mpll_clk_impl(_clocks: &mut ClockTree, _config: MpllClkConfig) { - todo!() -} - -// SPLL_CLK - -fn enable_spll_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_spll_clk_impl(_clocks: &mut ClockTree, _config: SpllClkConfig) { - todo!() -} - -// XTAL32K_CLK +// ============================================================ +// Clock node implementation functions (called from generated macro) +// These must match the function names that define_clock_tree_types!() expects. +// ============================================================ -fn enable_xtal32k_clk_impl(_clocks: &mut ClockTree, en: bool) { - LP_AON_CLKRST::regs().xtal32k().write(|w| unsafe { - w.dac_xtal32k().bits(3); - w.dres_xtal32k().bits(3); - w.dgm_xtal32k().bits(3); - w.dbuf_xtal32k().bit(true) +// CPU_ROOT_CLK (mux: XTAL / CPLL / RC_FAST) +fn configure_cpu_root_clk_impl( + _clocks: &mut ClockTree, + _old_selector: Option, + new_selector: CpuRootClkConfig, +) { + // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_src() + // LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel: 0=XTAL, 1=CPLL, 2=RC_FAST + let sel = match new_selector { + CpuRootClkConfig::Xtal => 0, + CpuRootClkConfig::Cpll => 1, + CpuRootClkConfig::RcFast => 2, + }; + crate::peripherals::LP_AON_CLKRST::regs() + .lp_aonclkrst_hp_clk_ctrl() + .modify(|_, w| unsafe { w.lp_aonclkrst_hp_root_clk_src_sel().bits(sel) }); +} + +// CPU_CLK divider +fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _old_config: Option, new_config: CpuClkConfig) { + // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_divider() + // HP_SYS_CLKRST.root_clk_ctrl0.cpu_clk_div_num = divider - 1 + let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + clkrst.root_clk_ctrl0().modify(|_, w| unsafe { + w.cpu_clk_div_num().bits(new_config.divisor as u8); + w.cpu_clk_div_numerator().bits(0); + w.cpu_clk_div_denominator().bits(0) }); - - PMU::regs() - .hp_sleep_lp_ck_power() - .modify(|_, w| w.hp_sleep_xpd_xtal32k().bit(en)); - - // Enable for digital part - // TODO: Should the digital clock gate be a different clock node? - LP_AON_CLKRST::regs() - .clk_to_hp() - .modify(|_, w| w.icg_hp_xtal32k().bit(en)); -} - -// RC_SLOW_CLK - -fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, en: bool) { - if en { - // SCK_DCAP value controls tuning of 136k clock. The higher the value of DCAP, the lower the - // frequency. There is no separate enable bit, just make sure the calibration value is set. - // const RTC_CNTL_SCK_DCAP_DEFAULT: u8 = 128; - // crate::soc::regi2c::I2C_DIG_REG_SCK_DCAP.write_reg(RTC_CNTL_SCK_DCAP_DEFAULT); + // Trigger divider update + clkrst.root_clk_ctrl0().modify(|_, w| w.soc_clk_div_update().set_bit()); + while clkrst.root_clk_ctrl0().read().soc_clk_div_update().bit_is_set() { + core::hint::spin_loop(); } - - PMU::regs() - .hp_sleep_lp_ck_power() - .modify(|_, w| w.hp_sleep_xpd_rc32k().bit(en)); - - // Enable for digital part - LP_AON_CLKRST::regs() - .clk_to_hp() - .modify(|_, w| w.icg_hp_osc32k().bit(en)); } -// OSC_SLOW_CLK - -fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { - // TODO: - // gpio_ll_input_enable(&GPIO, SOC_EXT_OSC_SLOW_GPIO_NUM); - // REG_SET_BIT(LP_AON_GPIO_HOLD0_REG, BIT(SOC_EXT_OSC_SLOW_GPIO_NUM)); - todo!(); - - // No need to configure anything else for OSC_SLOW_CLK -} - -// PLL_LP_CLK - -fn enable_pll_lp_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_pll_lp_clk_impl(_clocks: &mut ClockTree, _config: PllLpClkConfig) { - todo!() +// APB_CLK divider +fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn configure_apb_clk_impl(_clocks: &mut ClockTree, _old_config: Option, _new_config: ApbClkConfig) { + // TODO(P4X): APB divider register in HP_SYS_CLKRST + // For now, APB freq is derived from CPU freq via divider } -// ROOT_CLK - -fn configure_root_clk_impl( +// LP_FAST_CLK mux +fn configure_lp_fast_clk_impl( _clocks: &mut ClockTree, - _old_selector: Option, - _new_selector: RootClkConfig, + _old_selector: Option, + new_selector: LpFastClkConfig, ) { - todo!() -} - -// CPU_CLK - -fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _new_config: CpuClkConfig) { - todo!() -} - -// MEM_CLK - -fn enable_mem_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_mem_clk_impl(_clocks: &mut ClockTree, _new_config: MemClkConfig) { - todo!() -} - -// SYS_CLK - -fn enable_sys_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -fn configure_sys_clk_impl(_clocks: &mut ClockTree, _new_config: SysClkConfig) { - todo!() -} - -// APB_CLK - -fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) { - // Nothing to do. -} - -fn configure_apb_clk_impl(_clocks: &mut ClockTree, _new_config: ApbClkConfig) { - todo!() -} - -// PLL_F50M_CLK - -fn enable_pll_f50m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// PLL_F25M_CLK - -fn enable_pll_f25m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// PLL_F240M_CLK - -fn enable_pll_f240m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// PLL_F160M_CLK - -fn enable_pll_f160m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// PLL_F120M_CLK - -fn enable_pll_f120m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// PLL_F80M_CLK - -fn enable_pll_f80m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// PLL_F20M_CLK - -fn enable_pll_f20m_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} - -// LP_SLOW_CLK - + // Ref: esp-idf clk_tree_ll.h -- clk_ll_rtc_fast_set_src() + crate::peripherals::LP_AON_CLKRST::regs() + .lp_aonclkrst_lp_clk_conf() + .modify(|_, w| unsafe { + w.lp_aonclkrst_fast_clk_sel().bits(match new_selector { + LpFastClkConfig::RcFast => 0, + LpFastClkConfig::XtalD2 => 1, + }) + }); +} + +// LP_SLOW_CLK mux fn configure_lp_slow_clk_impl( _clocks: &mut ClockTree, _old_selector: Option, new_selector: LpSlowClkConfig, ) { - LP_AON_CLKRST::regs().lp_clk_conf().modify(|_, w| unsafe { - w.slow_clk_sel().bits(match new_selector { - LpSlowClkConfig::Xtal32kClk => 1, - LpSlowClkConfig::RcSlow => 0, - LpSlowClkConfig::OscSlow => 2, - }) - }); -} - -// LP_FAST_CLK + // Ref: esp-idf clk_tree_ll.h -- clk_ll_rtc_slow_set_src() + crate::peripherals::LP_AON_CLKRST::regs() + .lp_aonclkrst_lp_clk_conf() + .modify(|_, w| unsafe { + w.lp_aonclkrst_slow_clk_sel().bits(match new_selector { + LpSlowClkConfig::RcSlow => 0, + LpSlowClkConfig::Xtal32k => 1, + LpSlowClkConfig::Rc32k => 2, + LpSlowClkConfig::OscSlow => 3, + }) + }); +} + +// ============================================================ +// Per-instance clock impl for UART (called on UartInstance enum) +// Ref: esp-idf uart_ll.h, hp_sys_clkrst_reg.h +// ============================================================ + +impl UartInstance { + fn enable_function_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { + // UART function clock enable is handled by peripheral clock gates in system.rs + } -fn configure_lp_fast_clk_impl( - _clocks: &mut ClockTree, - _old_selector: Option, - new_selector: LpFastClkConfig, -) { - LP_AON_CLKRST::regs().lp_clk_conf().modify(|_, w| { - w.fast_clk_sel().bit(match new_selector { - LpFastClkConfig::RcFastClk => false, - LpFastClkConfig::XtalD2Clk => true, - }) - }); -} + fn configure_function_clock_impl( + self, + _clocks: &mut ClockTree, + _old_config: Option, + _new_config: UartFunctionClockConfig, + ) { + // TODO(P4X): Configure UART clock source selection + // HP_SYS_CLKRST PERI_CLK_CTRL110-114 for UART0-4 + // Ref: esp-idf clk_tree_ll.h -- clk_ll_uart_set_sclk() + } -// LP_DYN_SLOW_CLK + fn enable_baud_rate_generator_impl(self, _clocks: &mut ClockTree, _en: bool) { + // Baud rate generator is always on when UART is enabled + } -fn configure_lp_dyn_slow_clk_impl( - _clocks: &mut ClockTree, - _old_selector: Option, - _new_selector: LpDynSlowClkConfig, -) { - todo!() + fn configure_baud_rate_generator_impl( + self, + _clocks: &mut ClockTree, + _old_config: Option, + _new_config: UartBaudRateGeneratorConfig, + ) { + // Baud rate is configured directly in UART registers, not here + } } -// LP_DYN_FAST_CLK +// ============================================================ +// Per-instance clock impl for TIMG +// Ref: esp-idf timer_ll.h +// ============================================================ -fn configure_lp_dyn_fast_clk_impl( - _clocks: &mut ClockTree, - _old_selector: Option, - _new_selector: LpDynFastClkConfig, -) { - todo!() -} +impl TimgInstance { + fn enable_function_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { + // TIMG function clock is managed by peripheral clock gates + } -// LP_PERI_CLK + fn configure_function_clock_impl( + self, + _clocks: &mut ClockTree, + _old_config: Option, + _new_config: TimgFunctionClockConfig, + ) { + // TODO(P4X): Configure TIMG clock source + // HP_SYS_CLKRST PERI_CLK_CTRL20/21 + } -fn enable_lp_peri_clk_impl(_clocks: &mut ClockTree, _en: bool) { - todo!() -} + fn enable_wdt_clock_impl(self, _clocks: &mut ClockTree, _en: bool) {} -fn configure_lp_peri_clk_impl(_clocks: &mut ClockTree, _new_config: LpPeriClkConfig) { - todo!() + fn configure_wdt_clock_impl( + self, + _clocks: &mut ClockTree, + _old_config: Option, + _new_config: TimgWdtClockConfig, + ) { + // TODO(P4X): Configure TIMG WDT clock source + } } -// XTAL_D2_CLK - -fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) { - // Nothing to do, the divider is always on. -} \ No newline at end of file +// ============================================================ +// System clock impl functions +// ============================================================ + +// Mux enable stubs (mux nodes need enable functions too) +fn enable_cpu_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_lp_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_lp_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {} + +// Source clock enable/disable stubs (PLLs, oscillators) +fn enable_cpll_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_spll_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_mpll_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_xtal32k_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_rc32k_clk_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f20m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f80m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f120m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f160m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f240m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f25m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_pll_f50m_impl(_clocks: &mut ClockTree, _en: bool) {} +fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) {} diff --git a/esp-hal/src/soc/esp32p4/gpio.rs b/esp-hal/src/soc/esp32p4/gpio.rs new file mode 100644 index 00000000000..6eb9be309c4 --- /dev/null +++ b/esp-hal/src/soc/esp32p4/gpio.rs @@ -0,0 +1,138 @@ +//! ESP32-P4 LP GPIO (RtcPin) implementation. +//! +//! P4 LP GPIO uses named registers (pin0, pin1, ...) instead of indexed pin(n). +//! LP_IO_MUX uses pad0, pad1, ... with different field names from other chips. +//! +//! LP pins: GPIO0-5, GPIO12-23 (16 pins total, mapped to LP_GPIO pin0-pin15) +//! GPIO0-5 -> LP pin 0-5 +//! GPIO12-23 -> LP pin 6-17 (offset by 6) +//! +//! Ref: esp-idf rtc_io_ll.h for P4 +//! TRM v0.5 Ch 11 (GPIO) -- LP_IO_MUX section +//! P4 PAC: lp_gpio (0x5012_A000), lp_io_mux (0x5012_B000) + +/// LP GPIO base address (from PAC) +const LP_GPIO_BASE: u32 = 0x5012_A000; +/// LP IO MUX base address (from PAC) +const LP_IO_MUX_BASE: u32 = 0x5012_B000; + +/// Convert GPIO number to LP pin index. +/// GPIO0-5 -> LP pin 0-5 +/// GPIO12-23 -> LP pin 6-17 +#[allow(dead_code)] // used by p4_rtc_pin! macro expansions and future LP wakeup code +const fn gpio_to_lp_pin(gpio: u8) -> Option { + match gpio { + 0..=5 => Some(gpio), + 12..=23 => Some(gpio - 6), + _ => None, + } +} + +/// Implement RtcPin for a P4 LP-capable GPIO. +/// Uses direct MMIO because P4 LP_GPIO PAC has named registers (pin0, pin1, ...) +/// and LP_IO_MUX has different field names from other chips. +macro_rules! p4_rtc_pin { + ($($gpio_num:literal => $lp_pin:literal),+ $(,)?) => { + $( + impl $crate::gpio::RtcPin for paste::paste!($crate::peripherals::[]<'_>) { + unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) { + // LP_GPIO.PINn register: wakeup_enable + int_type + // Ref: P4 PAC lp_gpio/pin0.rs -- reg_gpio_pin0_wakeup_enable, int_type + // Each PINn register is at LP_GPIO_BASE + 0x20 + n*4 + unsafe { + let pin_reg = (LP_GPIO_BASE + 0x20 + $lp_pin * 4) as *mut u32; + let val = pin_reg.read_volatile(); + let val = (val & !(0x7 << 7)) | ((level as u32 & 0x7) << 7); + let val = if wakeup { val | (1 << 10) } else { val & !(1 << 10) }; + pin_reg.write_volatile(val); + } + } + + fn rtcio_pad_hold(&self, enable: bool) { + // LP_AON (LP_SYS) doesn't have gpio_hold for P4. + // P4 uses LP_IO_MUX pad hold instead. + // Ref: esp-idf rtc_io_ll.h -- rtcio_ll_force_hold_enable() + // For now, no-op. TODO(P4X): implement LP pad hold + let _ = enable; + } + + fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) { + unsafe { + // LP_IO_MUX.PADn register + // pad0 at offset 0x08, pad1 at 0x0C, etc. + let pad_reg = (LP_IO_MUX_BASE + 0x08 + $lp_pin * 4) as *mut u32; + let mut val = pad_reg.read_volatile(); + + // reg_padN_mux_sel: bit 3 (1=LP mode, 0=IO MUX mode) + if mux { val |= 1 << 3; } else { val &= !(1 << 3); } + + // reg_padN_fun_ie: bit 8 (input enable) + if input_enable { val |= 1 << 8; } else { val &= !(1 << 8); } + + // reg_padN_fun_sel: bits [5:4] (function select) + val = (val & !(0x3 << 4)) | (((func as u32) & 0x3) << 4); + + // reg_padN_slp_sel: bit 6 (0=normal operation) + val &= !(1 << 6); + + pad_reg.write_volatile(val); + } + } + } + + impl $crate::gpio::RtcPinWithResistors for paste::paste!($crate::peripherals::[]<'_>) { + fn rtcio_pullup(&self, enable: bool) { + unsafe { + let pad_reg = (LP_IO_MUX_BASE + 0x08 + $lp_pin * 4) as *mut u32; + let val = pad_reg.read_volatile(); + // reg_padN_rue: bit 2 (pullup enable) + if enable { + pad_reg.write_volatile(val | (1 << 2)); + } else { + pad_reg.write_volatile(val & !(1 << 2)); + } + } + } + + fn rtcio_pulldown(&self, enable: bool) { + unsafe { + let pad_reg = (LP_IO_MUX_BASE + 0x08 + $lp_pin * 4) as *mut u32; + let val = pad_reg.read_volatile(); + // reg_padN_rde: bit 1 (pulldown enable) + if enable { + pad_reg.write_volatile(val | (1 << 1)); + } else { + pad_reg.write_volatile(val & !(1 << 1)); + } + } + } + } + )+ + }; +} + +// GPIO0-5 -> LP pin 0-5 +p4_rtc_pin! { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, +} + +// GPIO12-23 -> LP pin 6-17 +p4_rtc_pin! { + 12 => 6, + 13 => 7, + 14 => 8, + 15 => 9, + 16 => 10, + 17 => 11, + 18 => 12, + 19 => 13, + 20 => 14, + 21 => 15, + 22 => 16, + 23 => 17, +} diff --git a/esp-hal/src/soc/esp32p4/mod.rs b/esp-hal/src/soc/esp32p4/mod.rs index 55ec1a9eac0..3f1bdaece03 100644 --- a/esp-hal/src/soc/esp32p4/mod.rs +++ b/esp-hal/src/soc/esp32p4/mod.rs @@ -1,5 +1,5 @@ // pub mod efuse; -// pub mod gpio; +pub mod gpio; // pub mod peripherals; crate::unstable_module! { @@ -10,13 +10,23 @@ pub(crate) mod regi2c; pub(crate) use esp32p4 as pac; +// P4 DMA module alias: pac::dma is DW_GDMA, but esp-hal GDMA driver expects AHB_DMA layout. +// Provide `pac::dma` alias pointing to `pac::ahb_dma` module for GDMA driver compatibility. +// This is necessary because ahb_v2.rs uses `pac::dma::ch::CH` type directly. +#[allow(unused)] +pub(crate) mod dma_compat { + pub use super::pac::ahb_dma::*; +} + pub(crate) mod registers { pub const INTERRUPT_MAP_BASE: u32 = 0x500D_6000; pub const INTERRUPT_MAP_BASE_APP_CPU: u32 = 0x500D_6800; } pub(crate) mod constants { + #[allow(dead_code)] // used by other chips; reserved for future P4 DRAM boundary checks pub const SOC_DRAM_LOW: u32 = 0x4FF0_0000; + #[allow(dead_code)] pub const SOC_DRAM_HIGH: u32 = 0x4FFC_0000; } diff --git a/esp-hal/src/soc/esp32p4/regi2c.rs b/esp-hal/src/soc/esp32p4/regi2c.rs index 9023c56ac2b..770481bc1e4 100644 --- a/esp-hal/src/soc/esp32p4/regi2c.rs +++ b/esp-hal/src/soc/esp32p4/regi2c.rs @@ -1,9 +1,140 @@ +//! I2C analog register access for ESP32-P4. +//! +//! Used for PLL configuration (CPLL, SPLL, MPLL) and other analog peripherals. +//! Accesses the LP_I2C_ANA_MST peripheral which bridges to internal analog I2C bus. +//! +//! Ref: esp-idf components/esp_hal_regi2c/esp32p4/regi2c_impl.c +//! esp-idf components/soc/esp32p4/register/hw_ver3/soc/lp_i2c_ana_mst_reg.h +//! TRM v0.5 Ch 49 (Analog I2C Controller) +// I2C slave addresses for analog blocks +// Ref: esp-idf regi2c_impl.c lines 57-81 +#[allow(dead_code)] +pub(crate) const REGI2C_DIG_REG: u8 = 0x6d; +#[allow(dead_code)] +pub(crate) const REGI2C_CPU_PLL: u8 = 0x67; +#[allow(dead_code)] +pub(crate) const REGI2C_SDIO_PLL: u8 = 0x62; +#[allow(dead_code)] +pub(crate) const REGI2C_BIAS: u8 = 0x6a; +#[allow(dead_code)] +pub(crate) const REGI2C_MSPI: u8 = 0x63; +#[allow(dead_code)] +pub(crate) const REGI2C_SYS_PLL: u8 = 0x66; +#[allow(dead_code)] +pub(crate) const REGI2C_PLLA: u8 = 0x6f; +#[allow(dead_code)] +pub(crate) const REGI2C_SAR_I2C: u8 = 0x69; +// Master select bits in ANA_CONF2 register +// Ref: esp-idf regi2c_impl.c lines 21-28 +const REGI2C_DIG_REG_MST_SEL: u16 = 1 << 10; +const REGI2C_PLL_CPU_MST_SEL: u16 = 1 << 11; +#[allow(dead_code)] +const REGI2C_PLL_SDIO_MST_SEL: u16 = 1 << 6; +#[allow(dead_code)] +const REGI2C_BIAS_MST_SEL: u16 = 1 << 12; +#[allow(dead_code)] +const REGI2C_MSPI_XTAL_MST_SEL: u16 = 1 << 9; +#[allow(dead_code)] +const REGI2C_PLL_SYS_MST_SEL: u16 = 1 << 5; +#[allow(dead_code)] +const REGI2C_PLLA_MST_SEL: u16 = 1 << 8; +#[allow(dead_code)] +const REGI2C_SAR_I2C_MST_SEL: u16 = 1 << 7; + +/// I2C control register bit fields +/// Ref: esp-idf regi2c_impl.c lines 32-55 +const REGI2C_RTC_BUSY_BIT: u32 = 1 << 25; +const REGI2C_RTC_WR_CNTL_BIT: u32 = 1 << 24; +const REGI2C_RTC_DATA_SHIFT: u32 = 16; +const REGI2C_RTC_DATA_MASK: u32 = 0xFF; +const REGI2C_RTC_ADDR_SHIFT: u32 = 8; +const REGI2C_RTC_ADDR_MASK: u32 = 0xFF; +const REGI2C_RTC_SLAVE_ID_SHIFT: u32 = 0; +const REGI2C_RTC_SLAVE_ID_MASK: u32 = 0xFF; + +/// LP_I2C_ANA_MST base address (from PAC: 0x5012_4000) +/// I2C0_CTRL_REG is at offset 0x14 +const LP_I2C_ANA_MST_BASE: u32 = 0x5012_4000; +const LP_I2C_ANA_MST_I2C0_CTRL_REG: u32 = LP_I2C_ANA_MST_BASE + 0x14; +const LP_I2C_ANA_MST_ANA_CONF1_REG: u32 = LP_I2C_ANA_MST_BASE + 0x04; +const LP_I2C_ANA_MST_ANA_CONF2_REG: u32 = LP_I2C_ANA_MST_BASE + 0x08; + +/// Select the I2C master for the given analog block. +/// Ref: esp-idf regi2c_impl.c:83-117 -- regi2c_enable_block() +fn regi2c_enable_block(block: u8) { + // Clear both conf registers first + // Ref: esp-idf regi2c_impl.c:86-87 + unsafe { + (LP_I2C_ANA_MST_ANA_CONF2_REG as *mut u32).write_volatile(0); + (LP_I2C_ANA_MST_ANA_CONF1_REG as *mut u32).write_volatile(0); + } + + // Set the master select bit for this block + let sel_bit: u32 = match block { + REGI2C_DIG_REG => REGI2C_DIG_REG_MST_SEL as u32, + REGI2C_CPU_PLL => REGI2C_PLL_CPU_MST_SEL as u32, + REGI2C_SDIO_PLL => REGI2C_PLL_SDIO_MST_SEL as u32, + REGI2C_BIAS => REGI2C_BIAS_MST_SEL as u32, + REGI2C_MSPI => REGI2C_MSPI_XTAL_MST_SEL as u32, + REGI2C_SYS_PLL => REGI2C_PLL_SYS_MST_SEL as u32, + REGI2C_PLLA => REGI2C_PLLA_MST_SEL as u32, + REGI2C_SAR_I2C => REGI2C_SAR_I2C_MST_SEL as u32, + _ => return, + }; + + unsafe { + let reg = LP_I2C_ANA_MST_ANA_CONF2_REG as *mut u32; + reg.write_volatile(reg.read_volatile() | sel_bit); + } +} + +/// Wait for I2C bus to become idle. +#[inline] +fn wait_i2c_idle() { + unsafe { + let reg = LP_I2C_ANA_MST_I2C0_CTRL_REG as *const u32; + while reg.read_volatile() & REGI2C_RTC_BUSY_BIT != 0 { + core::hint::spin_loop(); + } + } +} + +/// Read an analog I2C register. +/// Ref: esp-idf regi2c_impl.c:119-132 -- _regi2c_impl_read() pub(crate) fn regi2c_read(block: u8, _host_id: u8, reg_add: u8) -> u8 { - todo!() + regi2c_enable_block(block); + wait_i2c_idle(); + + // Build read command: slave_id[7:0] | addr[15:8] + let cmd = ((block as u32 & REGI2C_RTC_SLAVE_ID_MASK) << REGI2C_RTC_SLAVE_ID_SHIFT) + | ((reg_add as u32 & REGI2C_RTC_ADDR_MASK) << REGI2C_RTC_ADDR_SHIFT); + + unsafe { + (LP_I2C_ANA_MST_I2C0_CTRL_REG as *mut u32).write_volatile(cmd); + } + wait_i2c_idle(); + + // Read data from bits [23:16] + let val = unsafe { (LP_I2C_ANA_MST_I2C0_CTRL_REG as *const u32).read_volatile() }; + ((val >> REGI2C_RTC_DATA_SHIFT) & REGI2C_RTC_DATA_MASK) as u8 } +/// Write an analog I2C register. +/// Ref: esp-idf regi2c_impl.c:151-164 -- _regi2c_impl_write() pub(crate) fn regi2c_write(block: u8, _host_id: u8, reg_add: u8, data: u8) { - todo!() + regi2c_enable_block(block); + wait_i2c_idle(); + + // Build write command: slave_id[7:0] | addr[15:8] | data[23:16] | wr_cntl[24] + let cmd = ((block as u32 & REGI2C_RTC_SLAVE_ID_MASK) << REGI2C_RTC_SLAVE_ID_SHIFT) + | ((reg_add as u32 & REGI2C_RTC_ADDR_MASK) << REGI2C_RTC_ADDR_SHIFT) + | REGI2C_RTC_WR_CNTL_BIT + | ((data as u32 & REGI2C_RTC_DATA_MASK) << REGI2C_RTC_DATA_SHIFT); + + unsafe { + (LP_I2C_ANA_MST_I2C0_CTRL_REG as *mut u32).write_volatile(cmd); + } + wait_i2c_idle(); } diff --git a/esp-hal/src/soc/mod.rs b/esp-hal/src/soc/mod.rs index dbc7597acad..08ab358f810 100644 --- a/esp-hal/src/soc/mod.rs +++ b/esp-hal/src/soc/mod.rs @@ -15,6 +15,7 @@ use crate::efuse::ChipRevision; #[cfg_attr(esp32c6, path = "esp32c6/mod.rs")] #[cfg_attr(esp32c61, path = "esp32c61/mod.rs")] #[cfg_attr(esp32h2, path = "esp32h2/mod.rs")] +#[cfg_attr(esp32p4, path = "esp32p4/mod.rs")] #[cfg_attr(esp32s2, path = "esp32s2/mod.rs")] #[cfg_attr(esp32s3, path = "esp32s3/mod.rs")] mod implementation; diff --git a/esp-hal/src/spi/master/mod.rs b/esp-hal/src/spi/master/mod.rs index 21cd2d449cc..156be04430c 100644 --- a/esp-hal/src/spi/master/mod.rs +++ b/esp-hal/src/spi/master/mod.rs @@ -2396,7 +2396,15 @@ impl Driver { fn update(&self) { cfg_if::cfg_if! { - if #[cfg(not(any(esp32, esp32s2)))] { + if #[cfg(esp32p4)] { + // P4 PAC: cmd.update() is write-only (no read method). + // Write update bit and wait a short time instead of polling. + // Ref: esp-idf spi_ll.h -- spi_ll_update_conf() + let reg_block = self.regs(); + reg_block.cmd().modify(|_, w| w.update().set_bit()); + // Small delay for SPI register sync + for _ in 0..10 { core::hint::spin_loop(); } + } else if #[cfg(not(any(esp32, esp32s2)))] { let reg_block = self.regs(); reg_block.cmd().modify(|_, w| w.update().set_bit()); diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index bc9cb3e5ee1..f17d2810fd3 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -11,8 +11,369 @@ cfg_if::cfg_if! { } // Implements the Peripheral enum based on esp-metadata/device.soc/peripheral_clocks +// ESP32-P4: manual Peripheral enum with HP_SYS_CLKRST clock gate registers. +// The generated macro produces an empty #[repr(u8)] enum (no clock nodes in metadata). +// This manual definition covers all 43 peripherals with their enable/reset registers. +// Ref: esp-idf clk_gate_ll.h, hp_sys_clkrst_reg.h, TRM v0.5 Ch 12/22. +#[cfg(not(esp32p4))] implement_peripheral_clocks!(); +/// ESP32-P4 peripheral clock gates and resets. +/// +/// All controlled via HP_SYS_CLKRST registers: +/// SOC_CLK_CTRL0 (0x14): Flash/PSRAM/GDMA system clocks +/// SOC_CLK_CTRL1 (0x18): Peripheral system clocks +/// SOC_CLK_CTRL2 (0x1c): APB clocks +/// HP_RST_EN0 (0xc0): Core/cache/DMA resets +/// HP_RST_EN1 (0xc4): Timer/UART/I2C/misc resets +/// HP_RST_EN2 (0xc8): SPI/I2S/crypto/misc resets +/// PERI_CLK_CTRLxx: Per-peripheral clock dividers and enables +/// +/// Ref: esp-idf clk_gate_ll.h, hp_sys_clkrst_reg.h +/// TRM v0.5 Ch 12 (Reset and Clock), Ch 22 (System Registers) +#[cfg(esp32p4)] +mod _p4_peripheral_clocks { + use crate::peripherals::HP_SYS_CLKRST; + + #[doc(hidden)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(u8)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + #[allow(non_camel_case_types)] + pub enum Peripheral { + // -- UARTs (5x) -- SOC_CLK_CTRL1 sys + SOC_CLK_CTRL2 apb + HP_RST_EN1 + Uart0 = 0, + Uart1 = 1, + Uart2 = 2, + Uart3 = 3, + Uart4 = 4, + // -- SPI (2x) -- SOC_CLK_CTRL1 sys + SOC_CLK_CTRL2 apb + HP_RST_EN2 + Spi2 = 5, + Spi3 = 6, + // -- I2C (2x) -- SOC_CLK_CTRL2 apb + HP_RST_EN1 + I2c0 = 7, + I2c1 = 8, + // -- I2S (3x) -- SOC_CLK_CTRL2 apb + HP_RST_EN2 + I2s0 = 9, + I2s1 = 10, + I2s2 = 11, + // -- Timers -- SOC_CLK_CTRL2 apb + HP_RST_EN1 + Systimer = 12, + Timg0 = 13, + Timg1 = 14, + // -- GPIO/IOMUX -- PERI_CLK_CTRL26 + HP_RST_EN1 + Iomux = 15, + // -- PWM/Counter -- SOC_CLK_CTRL2 apb + HP_RST_EN1 + Ledc = 16, + Pcnt = 17, + Mcpwm0 = 18, + Mcpwm1 = 19, + Rmt = 20, + // -- CAN (TWAI) -- SOC_CLK_CTRL2 apb + HP_RST_EN1 + Twai0 = 21, + Twai1 = 22, + Twai2 = 23, + // -- USB -- SOC_CLK_CTRL1 sys + UsbOtg11 = 24, // Full-Speed + UsbOtg20 = 25, // High-Speed + UsbDevice = 26, // Serial/JTAG + // -- Connectivity -- SOC_CLK_CTRL1 sys + Emac = 27, + Sdmmc = 28, + Uhci = 29, + // -- Crypto -- SOC_CLK_CTRL1 crypto_sys + HP_RST_EN2 + Aes = 30, + Sha = 31, + Rsa = 32, + Ecc = 33, + Ecdsa = 34, + Hmac = 35, + Ds = 36, + // -- DMA -- SOC_CLK_CTRL1 sys + HP_RST_EN0/1 + // P4 has 3 DMA controllers: + // AHB_DMA (AHB PDMA): GDMA v2 compatible, used by esp-hal as "Dma" + // DW_GDMA (DesignWare GDMA): different register layout, not used by esp-hal + // AXI_DMA (AXI PDMA): AXI bus DMA + Dma = 37, // maps to AHB_DMA (GDMA v2 compatible) + Gdma = 38, // DW_GDMA (DesignWare GDMA) -- NOT esp-hal compatible + AhbPdma = 39, // alias for Dma (legacy) + AxiPdma = 40, + // -- ADC -- SOC_CLK_CTRL2 apb + HP_RST_EN2 + Adc = 41, + // -- Parallel IO -- SOC_CLK_CTRL1 sys + SOC_CLK_CTRL2 apb + HP_RST_EN2 + Parlio = 42, + // -- Camera/Display -- SOC_CLK_CTRL1 sys + HP_RST_EN2 + LcdCam = 43, + } + + impl Peripheral { + // NOTE (ESP32-P4): UsbDevice (USB-JTAG-Serial) kept enabled when the + // esp-println `jtag-serial` backend or the esp-hal `usb_serial_jtag` + // console driver is the boot log channel. Disabling its clock during + // init silences all subsequent println output and looks like a hang. + // TODO: gate this on a console feature; for now we keep it always on + // because the EV board and probe firmware both use USB-JTAG-Serial. + pub const KEEP_ENABLED: &[Peripheral] = + &[Peripheral::Systimer, Peripheral::Iomux, Peripheral::UsbDevice]; + pub const COUNT: usize = Self::ALL.len(); + pub const ALL: &[Self] = &[ + Self::Uart0, Self::Uart1, Self::Uart2, Self::Uart3, Self::Uart4, + Self::Spi2, Self::Spi3, + Self::I2c0, Self::I2c1, + Self::I2s0, Self::I2s1, Self::I2s2, + Self::Systimer, Self::Timg0, Self::Timg1, + Self::Iomux, + Self::Ledc, Self::Pcnt, Self::Mcpwm0, Self::Mcpwm1, Self::Rmt, + Self::Twai0, Self::Twai1, Self::Twai2, + Self::UsbOtg11, Self::UsbOtg20, Self::UsbDevice, + Self::Emac, Self::Sdmmc, Self::Uhci, + Self::Aes, Self::Sha, Self::Rsa, Self::Ecc, Self::Ecdsa, Self::Hmac, Self::Ds, + Self::Dma, Self::Gdma, Self::AhbPdma, Self::AxiPdma, + Self::Adc, Self::Parlio, Self::LcdCam, + ]; + } + + /// Enable or disable peripheral clock. + /// Ref: esp-idf clk_gate_ll.h -- *_ll_enable_bus_clock() functions + /// esp-idf hp_sys_clkrst_reg.h + /// TRM v0.5 Ch 12 + pub(crate) unsafe fn enable_internal_racey(peripheral: Peripheral, enable: bool) { + let c = HP_SYS_CLKRST::regs(); + match peripheral { + // -- UARTs: sys_clk + apb_clk -- + Peripheral::Uart0 => { + c.soc_clk_ctrl1().modify(|_, w| w.uart0_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.uart0_apb_clk_en().bit(enable)); + } + Peripheral::Uart1 => { + c.soc_clk_ctrl1().modify(|_, w| w.uart1_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.uart1_apb_clk_en().bit(enable)); + } + Peripheral::Uart2 => { + c.soc_clk_ctrl1().modify(|_, w| w.uart2_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.uart2_apb_clk_en().bit(enable)); + } + Peripheral::Uart3 => { + c.soc_clk_ctrl1().modify(|_, w| w.uart3_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.uart3_apb_clk_en().bit(enable)); + } + Peripheral::Uart4 => { + c.soc_clk_ctrl1().modify(|_, w| w.uart4_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.uart4_apb_clk_en().bit(enable)); + } + // -- SPI: sys_clk + apb_clk -- + Peripheral::Spi2 => { + c.soc_clk_ctrl1().modify(|_, w| w.gpspi2_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.gpspi2_apb_clk_en().bit(enable)); + } + Peripheral::Spi3 => { + c.soc_clk_ctrl1().modify(|_, w| w.gpspi3_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.gpspi3_apb_clk_en().bit(enable)); + } + // -- I2C: apb_clk only -- + Peripheral::I2c0 => { + c.soc_clk_ctrl2().modify(|_, w| w.i2c0_apb_clk_en().bit(enable)); + } + Peripheral::I2c1 => { + c.soc_clk_ctrl2().modify(|_, w| w.i2c1_apb_clk_en().bit(enable)); + } + // -- I2S: apb_clk -- + Peripheral::I2s0 => { + c.soc_clk_ctrl2().modify(|_, w| w.i2s0_apb_clk_en().bit(enable)); + } + Peripheral::I2s1 => { + c.soc_clk_ctrl2().modify(|_, w| w.i2s1_apb_clk_en().bit(enable)); + } + Peripheral::I2s2 => { + c.soc_clk_ctrl2().modify(|_, w| w.i2s2_apb_clk_en().bit(enable)); + } + // -- Timers -- + Peripheral::Systimer => { + c.soc_clk_ctrl2().modify(|_, w| w.systimer_apb_clk_en().bit(enable)); + c.peri_clk_ctrl21().modify(|_, w| w.systimer_clk_en().bit(enable)); + } + Peripheral::Timg0 => { + c.soc_clk_ctrl2().modify(|_, w| w.timergrp0_apb_clk_en().bit(enable)); + } + Peripheral::Timg1 => { + c.soc_clk_ctrl2().modify(|_, w| w.timergrp1_apb_clk_en().bit(enable)); + } + // -- GPIO/IOMUX -- + Peripheral::Iomux => { + c.peri_clk_ctrl26().modify(|_, w| w.iomux_clk_en().bit(enable)); + } + // -- PWM/Counter -- + Peripheral::Ledc => { + // Note: LEDC uses SOC_CLK_CTRL3 in esp-idf, but PAC may differ + // Ref: esp-idf clk_gate_ll.h -- _ledc_ll_enable_bus_clock + // For now just reset control + } + Peripheral::Pcnt => { + c.soc_clk_ctrl2().modify(|_, w| w.pcnt_apb_clk_en().bit(enable)); + } + Peripheral::Mcpwm0 => { + c.soc_clk_ctrl2().modify(|_, w| w.mcpwm0_apb_clk_en().bit(enable)); + } + Peripheral::Mcpwm1 => { + c.soc_clk_ctrl2().modify(|_, w| w.mcpwm1_apb_clk_en().bit(enable)); + } + Peripheral::Rmt => { + c.soc_clk_ctrl2().modify(|_, w| w.rmt_sys_clk_en().bit(enable)); + } + // -- TWAI (CAN) -- + Peripheral::Twai0 => { + c.soc_clk_ctrl2().modify(|_, w| w.twai0_apb_clk_en().bit(enable)); + } + Peripheral::Twai1 => { + c.soc_clk_ctrl2().modify(|_, w| w.twai1_apb_clk_en().bit(enable)); + } + Peripheral::Twai2 => { + c.soc_clk_ctrl2().modify(|_, w| w.twai2_apb_clk_en().bit(enable)); + } + // -- USB -- + Peripheral::UsbOtg11 => { + c.soc_clk_ctrl1().modify(|_, w| w.usb_otg11_sys_clk_en().bit(enable)); + } + Peripheral::UsbOtg20 => { + c.soc_clk_ctrl1().modify(|_, w| w.usb_otg20_sys_clk_en().bit(enable)); + } + Peripheral::UsbDevice => { + c.soc_clk_ctrl2().modify(|_, w| w.usb_device_apb_clk_en().bit(enable)); + } + // -- Connectivity -- + Peripheral::Emac => { + c.soc_clk_ctrl1().modify(|_, w| w.emac_sys_clk_en().bit(enable)); + } + Peripheral::Sdmmc => { + c.soc_clk_ctrl1().modify(|_, w| w.sdmmc_sys_clk_en().bit(enable)); + } + Peripheral::Uhci => { + c.soc_clk_ctrl1().modify(|_, w| w.uhci_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.uhci_apb_clk_en().bit(enable)); + } + // -- Crypto (shared sys clock) -- + Peripheral::Aes | Peripheral::Sha | Peripheral::Rsa | + Peripheral::Ecc | Peripheral::Ecdsa | Peripheral::Hmac | Peripheral::Ds => { + c.soc_clk_ctrl1().modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + // -- DMA -- + // Dma = AHB_DMA (GDMA v2 compatible, used by esp-hal) + Peripheral::Dma => { + c.soc_clk_ctrl1().modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); + } + // Gdma = DW_GDMA (DesignWare, NOT used by esp-hal DMA driver) + Peripheral::Gdma => { + c.soc_clk_ctrl1().modify(|_, w| w.gdma_sys_clk_en().bit(enable)); + } + Peripheral::AhbPdma => { + c.soc_clk_ctrl1().modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); + } + Peripheral::AxiPdma => { + c.soc_clk_ctrl1().modify(|_, w| w.axi_pdma_sys_clk_en().bit(enable)); + } + // -- ADC -- + Peripheral::Adc => { + c.soc_clk_ctrl2().modify(|_, w| w.adc_apb_clk_en().bit(enable)); + } + // -- Parallel IO -- + Peripheral::Parlio => { + c.soc_clk_ctrl1().modify(|_, w| w.parlio_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2().modify(|_, w| w.parlio_apb_clk_en().bit(enable)); + } + // -- LCD/Camera -- + Peripheral::LcdCam => { + // LCD_CAM uses SOC_CLK_CTRL3 which may not be in PAC + // Ref: esp-idf clk_gate_ll.h -- _lcdcam_ll_enable_bus_clock + } + } + } + + /// Assert or de-assert peripheral reset. + /// Ref: esp-idf hp_sys_clkrst_reg.h -- HP_RST_EN0/1/2 + /// TRM v0.5 Ch 12 + #[allow(clippy::single_match)] + pub(crate) unsafe fn assert_peri_reset_racey(peripheral: Peripheral, reset: bool) { + let c = HP_SYS_CLKRST::regs(); + match peripheral { + // -- UARTs: HP_RST_EN1 (core + apb reset) -- + Peripheral::Uart0 => { c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart0_core().bit(reset).rst_en_uart0_apb().bit(reset) + }); } + Peripheral::Uart1 => { c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart1_core().bit(reset).rst_en_uart1_apb().bit(reset) + }); } + Peripheral::Uart2 => { c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart2_core().bit(reset).rst_en_uart2_apb().bit(reset) + }); } + Peripheral::Uart3 => { c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart3_core().bit(reset).rst_en_uart3_apb().bit(reset) + }); } + Peripheral::Uart4 => { c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart4_core().bit(reset).rst_en_uart4_apb().bit(reset) + }); } + // -- SPI: HP_RST_EN2 -- + Peripheral::Spi2 => { c.hp_rst_en2().modify(|_, w| w.rst_en_spi2().bit(reset)); } + Peripheral::Spi3 => { c.hp_rst_en2().modify(|_, w| w.rst_en_spi3().bit(reset)); } + // -- I2C: HP_RST_EN1 -- + Peripheral::I2c0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_i2c0().bit(reset)); } + Peripheral::I2c1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_i2c1().bit(reset)); } + // -- I2S: HP_RST_EN2 -- + Peripheral::I2s0 => { c.hp_rst_en2().modify(|_, w| w.rst_en_i2s0_apb().bit(reset)); } + Peripheral::I2s1 => { c.hp_rst_en2().modify(|_, w| w.rst_en_i2s1_apb().bit(reset)); } + Peripheral::I2s2 => { c.hp_rst_en2().modify(|_, w| w.rst_en_i2s2_apb().bit(reset)); } + // -- Timers: HP_RST_EN1 -- + Peripheral::Systimer => { c.hp_rst_en1().modify(|_, w| w.rst_en_stimer().bit(reset)); } + Peripheral::Timg0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_timergrp0().bit(reset)); } + Peripheral::Timg1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_timergrp1().bit(reset)); } + // -- IOMUX: HP_RST_EN1 -- + Peripheral::Iomux => { c.hp_rst_en1().modify(|_, w| w.rst_en_iomux().bit(reset)); } + // -- PWM/Counter: HP_RST_EN1 -- + Peripheral::Ledc => { c.hp_rst_en1().modify(|_, w| w.rst_en_ledc().bit(reset)); } + Peripheral::Pcnt => { c.hp_rst_en1().modify(|_, w| w.rst_en_pcnt().bit(reset)); } + Peripheral::Mcpwm0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_pwm0().bit(reset)); } + Peripheral::Mcpwm1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_pwm1().bit(reset)); } + Peripheral::Rmt => { c.hp_rst_en1().modify(|_, w| w.rst_en_rmt().bit(reset)); } + // -- TWAI: HP_RST_EN1 (named can0/1/2) -- + Peripheral::Twai0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_can0().bit(reset)); } + Peripheral::Twai1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_can1().bit(reset)); } + Peripheral::Twai2 => { c.hp_rst_en1().modify(|_, w| w.rst_en_can2().bit(reset)); } + // -- USB: reset via LP domain registers, not HP_RST_EN -- + Peripheral::UsbOtg11 | Peripheral::UsbOtg20 | Peripheral::UsbDevice => { return; } + // -- Connectivity -- + Peripheral::Emac => { return; } // EMAC reset via dedicated register, not HP_RST_EN + Peripheral::Sdmmc => { return; } // SDMMC reset not in HP_RST_EN + Peripheral::Uhci => { c.hp_rst_en1().modify(|_, w| w.rst_en_uhci().bit(reset)); } + // -- Crypto: HP_RST_EN2 -- + Peripheral::Aes => { c.hp_rst_en2().modify(|_, w| w.rst_en_aes().bit(reset)); } + Peripheral::Sha => { c.hp_rst_en2().modify(|_, w| w.rst_en_sha().bit(reset)); } + Peripheral::Rsa => { c.hp_rst_en2().modify(|_, w| w.rst_en_rsa().bit(reset)); } + Peripheral::Ecc => { c.hp_rst_en2().modify(|_, w| w.rst_en_ecc().bit(reset)); } + Peripheral::Ecdsa => { c.hp_rst_en2().modify(|_, w| w.rst_en_ecdsa().bit(reset)); } + Peripheral::Hmac => { c.hp_rst_en2().modify(|_, w| w.rst_en_hmac().bit(reset)); } + Peripheral::Ds => { c.hp_rst_en2().modify(|_, w| w.rst_en_ds().bit(reset)); } + // -- DMA: HP_RST_EN0/1 -- + Peripheral::Dma => { c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); } + Peripheral::Gdma => { c.hp_rst_en0().modify(|_, w| w.rst_en_gdma().bit(reset)); } + Peripheral::AhbPdma => { c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); } + Peripheral::AxiPdma => { c.hp_rst_en1().modify(|_, w| w.rst_en_axi_pdma().bit(reset)); } + // -- ADC: HP_RST_EN2 -- + Peripheral::Adc => { c.hp_rst_en2().modify(|_, w| w.rst_en_adc().bit(reset)); } + // -- Parallel IO: HP_RST_EN2 -- + Peripheral::Parlio => { c.hp_rst_en2().modify(|_, w| { + w.rst_en_parlio().bit(reset) + .rst_en_parlio_rx().bit(reset) + .rst_en_parlio_tx().bit(reset) + }); } + // -- LCD/Camera: HP_RST_EN2 -- + Peripheral::LcdCam => { c.hp_rst_en2().modify(|_, w| w.rst_en_lcdcam().bit(reset)); } + } + } +} + +#[cfg(esp32p4)] +pub use _p4_peripheral_clocks::*; + +#[cfg(not(esp32p4))] impl Peripheral { pub const fn try_from(value: u8) -> Option { if value >= Peripheral::COUNT as u8 { @@ -23,6 +384,13 @@ impl Peripheral { } } +#[cfg(esp32p4)] +impl Peripheral { + pub const fn try_from(_value: u8) -> Option { + None + } +} + struct RefCounts { counts: [usize; Peripheral::COUNT], } diff --git a/esp-hal/src/uart/mod.rs b/esp-hal/src/uart/mod.rs index e7db05af1c8..37b63a14137 100644 --- a/esp-hal/src/uart/mod.rs +++ b/esp-hal/src/uart/mod.rs @@ -1100,7 +1100,7 @@ impl<'d> UartRx<'d, Async> { } cfg_if::cfg_if! { - if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { let reg_en = self.regs().tout_conf(); } else { let reg_en = self.regs().conf1(); @@ -2042,7 +2042,8 @@ where /// Configures the AT-CMD detection settings #[instability::unstable] pub fn set_at_cmd(&mut self, config: AtCmdConfig) { - #[cfg(not(any(esp32, esp32s2)))] + // P4: sclk_en is controlled by HP_SYS_CLKRST, not UART clk_conf register + #[cfg(not(any(esp32, esp32s2, esp32p4)))] self.regs() .clk_conf() .modify(|_, w| w.sclk_en().clear_bit()); @@ -2070,7 +2071,7 @@ where .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) }); } - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(any(esp32, esp32s2, esp32p4)))] self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit()); sync_regs(self.regs()); @@ -3306,7 +3307,7 @@ impl Info { cfg_if::cfg_if! { if #[cfg(esp32)] { let reg_thrhd = register_block.conf1(); - } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { let reg_thrhd = register_block.tout_conf(); } else { let reg_thrhd = register_block.mem_conf(); @@ -3316,7 +3317,7 @@ impl Info { } cfg_if::cfg_if! { - if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { let reg_en = register_block.tout_conf(); } else { let reg_en = register_block.conf1(); @@ -3339,7 +3340,7 @@ impl Info { let source_config = ClockConfig::new( config.clock_source, - #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] + #[cfg(any(uart_has_sclk_divider, soc_has_pcr, esp32p4))] 0, ); let clk = clock.function_clock_config_frequency(clocks, source_config); @@ -3357,7 +3358,7 @@ impl Info { // TODO: this block should only prepare the new clock config, and it should // be applied only after validating the resulting baud rate. cfg_if::cfg_if! { - if #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] { + if #[cfg(any(uart_has_sclk_divider, soc_has_pcr, esp32p4))] { const MAX_DIV: u32 = property!("clock_tree.uart.baud_rate_generator.integral").1; let clk_div = clk.div_ceil(MAX_DIV).div_ceil(config.baudrate); debug!("SCLK: {} divider: {}", clk, clk_div); @@ -3459,7 +3460,7 @@ impl Info { xoff_threshold, } => { cfg_if::cfg_if! { - if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit()); self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)}); self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) }); @@ -3478,7 +3479,7 @@ impl Info { } SwFlowControl::Disabled => { cfg_if::cfg_if! { - if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { let reg = self.regs().swfc_conf0(); } else { let reg = self.regs().flow_conf(); @@ -3508,7 +3509,7 @@ impl Info { cfg_if::cfg_if! { if #[cfg(esp32)] { self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) }); - } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) }); } else { self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) }); @@ -3517,7 +3518,7 @@ impl Info { } cfg_if::cfg_if! { - if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] { + if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2, esp32p4))] { self.regs().hwfc_conf().modify(|_, w| { w.rx_flow_en().bit(enable) }); @@ -3749,6 +3750,10 @@ crate::any_peripheral! { Uart1(crate::peripherals::UART1<'d>), #[cfg(soc_has_uart2)] Uart2(crate::peripherals::UART2<'d>), + #[cfg(soc_has_uart3)] + Uart3(crate::peripherals::UART3<'d>), + #[cfg(soc_has_uart4)] + Uart4(crate::peripherals::UART4<'d>), } } @@ -3790,7 +3795,7 @@ impl<'t> UartClockGuard<'t> { // Apply default SCLK configuration let sclk_config = ClockConfig::new( Default::default(), - #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] + #[cfg(any(uart_has_sclk_divider, soc_has_pcr, esp32p4))] 0, ); clock.configure_function_clock(clocks, sclk_config); diff --git a/esp-metadata-generated/Cargo.toml b/esp-metadata-generated/Cargo.toml index 8cf001a2d45..30c1a785c70 100644 --- a/esp-metadata-generated/Cargo.toml +++ b/esp-metadata-generated/Cargo.toml @@ -27,5 +27,6 @@ esp32c5 = ["_device-selected"] esp32c6 = ["_device-selected"] esp32c61 = ["_device-selected"] esp32h2 = ["_device-selected"] +esp32p4 = ["_device-selected"] esp32s2 = ["_device-selected"] esp32s3 = ["_device-selected"] diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index ae275870854..4309ef21d73 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -43,6 +43,7 @@ pub enum Chip { Esp32c6, Esp32c61, Esp32h2, + Esp32p4, Esp32s2, Esp32s3, } @@ -57,11 +58,12 @@ impl core::str::FromStr for Chip { "esp32c6" => Ok(Self::Esp32c6), "esp32c61" => Ok(Self::Esp32c61), "esp32h2" => Ok(Self::Esp32h2), + "esp32p4" => Ok(Self::Esp32p4), "esp32s2" => Ok(Self::Esp32s2), "esp32s3" => Ok(Self::Esp32s3), _ => Err(alloc::format!( "Unknown chip {s}. Possible options: esp32, esp32c2, esp32c3, esp32c5, esp32c6, \ - esp32c61, esp32h2, esp32s2, esp32s3" + esp32c61, esp32h2, esp32p4, esp32s2, esp32s3" )), } } @@ -79,6 +81,7 @@ impl Chip { ("CARGO_FEATURE_ESP32C6", Self::Esp32c6), ("CARGO_FEATURE_ESP32C61", Self::Esp32c61), ("CARGO_FEATURE_ESP32H2", Self::Esp32h2), + ("CARGO_FEATURE_ESP32P4", Self::Esp32p4), ("CARGO_FEATURE_ESP32S2", Self::Esp32s2), ("CARGO_FEATURE_ESP32S3", Self::Esp32s3), ]; @@ -88,7 +91,8 @@ impl Chip { if chip.is_some() { return Err( "Expected exactly one of the following features to be enabled: esp32, \ - esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3", + esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32p4, esp32s2, \ + esp32s3", ); } chip = Some(c); @@ -98,7 +102,7 @@ impl Chip { Some(chip) => Ok(chip), None => Err( "Expected exactly one of the following features to be enabled: esp32, esp32c2, \ - esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3", + esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32p4, esp32s2, esp32s3", ), } } @@ -126,6 +130,7 @@ impl Chip { Self::Esp32c6 => "esp32c6", Self::Esp32c61 => "esp32c61", Self::Esp32h2 => "esp32h2", + Self::Esp32p4 => "esp32p4", Self::Esp32s2 => "esp32s2", Self::Esp32s3 => "esp32s3", } @@ -180,6 +185,7 @@ impl Chip { Self::Esp32c6, Self::Esp32c61, Self::Esp32h2, + Self::Esp32p4, Self::Esp32s2, Self::Esp32s3, ] @@ -3983,6 +3989,532 @@ impl Chip { }, ], }, + Self::Esp32p4 => Config { + architecture: "riscv", + target: "riscv32imafc-unknown-none-elf", + symbols: &[ + "esp32p4", + "riscv", + "multi_core", + "soc_has_efuse", + "soc_has_gpio", + "soc_has_hp_sys", + "soc_has_hp_sys_clkrst", + "soc_has_interrupt_core0", + "soc_has_interrupt_core1", + "soc_has_clic", + "soc_has_io_mux", + "soc_has_lp_aon", + "soc_has_lp_aon_clkrst", + "soc_has_lp_sys", + "soc_has_lp_wdt", + "soc_has_lpwr", + "soc_has_pmu", + "soc_has_systimer", + "soc_has_timg0", + "soc_has_timg1", + "soc_has_uart0", + "soc_has_uart1", + "soc_has_uart2", + "soc_has_uart3", + "soc_has_uart4", + "soc_has_spi2", + "soc_has_spi3", + "soc_has_i2c0", + "soc_has_i2c1", + "soc_has_twai0", + "soc_has_twai1", + "soc_has_twai2", + "soc_has_psram", + "soc_has_dma", + "soc_has_dma_ch0", + "soc_has_dma_ch1", + "soc_has_dma_ch2", + "soc_has_usb_device", + "soc_has_sdhost", + "soc_has_ledc", + "soc_has_mcpwm0", + "soc_has_mcpwm1", + "soc_has_pcnt", + "soc_has_rmt", + "soc_has_adc", + "soc_has_aes", + "soc_has_sha", + "soc_has_rsa", + "soc_has_ecc", + "very_large_intr_status", + "spi_octal", + "adc_driver_supported", + "aes_driver_supported", + "dma_driver_supported", + "ecc_driver_supported", + "gpio_driver_supported", + "i2c_master_driver_supported", + "interrupts_driver_supported", + "rsa_driver_supported", + "sha_driver_supported", + "soc_driver_supported", + "spi_master_driver_supported", + "systimer_driver_supported", + "twai_driver_supported", + "uart_driver_supported", + "usb_serial_jtag_driver_supported", + "i2c_master_i2c0", + "i2c_master_i2c1", + "spi_master_spi2", + "spi_master_spi3", + "uart_uart0", + "uart_uart1", + "uart_uart2", + "uart_uart3", + "uart_uart4", + "aes_dma", + "aes_has_split_text_registers", + "dma_kind=\"gdma\"", + "dma_separate_in_out_interrupts", + "dma_max_priority=\"5\"", + "dma_max_priority_is_set", + "dma_gdma_version=\"2\"", + "dma_gdma_version_is_set", + "ecc_separate_jacobian_point_memory", + "ecc_has_modular_arithmetic", + "ecc_has_point_addition", + "ecc_has_curve_p192", + "ecc_has_curve_p256", + "ecc_has_curve_p384", + "gpio_has_bank_1", + "gpio_gpio_function=\"1\"", + "gpio_constant_0_input=\"62\"", + "gpio_constant_1_input=\"63\"", + "gpio_func_in_sel_offset=\"0\"", + "gpio_input_signal_max=\"203\"", + "gpio_output_signal_max=\"256\"", + "i2c_master_has_fsm_timeouts", + "i2c_master_has_hw_bus_clear", + "i2c_master_has_bus_timeout_enable", + "i2c_master_max_bus_timeout=\"31\"", + "i2c_master_ll_intr_mask=\"262143\"", + "i2c_master_fifo_size=\"32\"", + "interrupts_status_registers=\"3\"", + "interrupt_controller=\"clic\"", + "rsa_size_increment=\"32\"", + "rsa_memory_size_bytes=\"384\"", + "sha_dma", + "soc_cpu_has_csr_pc", + "soc_rc_fast_clk_default=\"20000000\"", + "soc_rc_fast_clk_default_is_set", + "soc_has_clock_node_xtal_clk", + "soc_has_clock_node_cpll_clk", + "soc_has_clock_node_spll_clk", + "soc_has_clock_node_mpll_clk", + "soc_has_clock_node_rc_fast_clk", + "soc_has_clock_node_xtal32k_clk", + "soc_has_clock_node_osc_slow_clk", + "soc_has_clock_node_rc_slow_clk", + "soc_has_clock_node_rc32k_clk", + "soc_has_clock_node_pll_f20m", + "soc_has_clock_node_pll_f80m", + "soc_has_clock_node_pll_f120m", + "soc_has_clock_node_pll_f160m", + "soc_has_clock_node_pll_f240m", + "soc_has_clock_node_pll_f25m", + "soc_has_clock_node_pll_f50m", + "soc_has_clock_node_xtal_d2_clk", + "soc_has_clock_node_cpu_root_clk", + "soc_has_clock_node_cpu_clk", + "soc_has_clock_node_apb_clk", + "soc_has_clock_node_lp_fast_clk", + "soc_has_clock_node_lp_slow_clk", + "soc_has_clock_node_uart_function_clock", + "soc_has_clock_node_uart_baud_rate_generator", + "soc_has_clock_node_timg_function_clock", + "soc_has_clock_node_timg_wdt_clock", + "has_dram_region", + "has_dram2_uninit_region", + "spi_master_supports_dma", + "uart_ram_size=\"128\"", + ], + cfgs: &[ + "cargo:rustc-cfg=esp32p4", + "cargo:rustc-cfg=riscv", + "cargo:rustc-cfg=multi_core", + "cargo:rustc-cfg=soc_has_efuse", + "cargo:rustc-cfg=soc_has_gpio", + "cargo:rustc-cfg=soc_has_hp_sys", + "cargo:rustc-cfg=soc_has_hp_sys_clkrst", + "cargo:rustc-cfg=soc_has_interrupt_core0", + "cargo:rustc-cfg=soc_has_interrupt_core1", + "cargo:rustc-cfg=soc_has_clic", + "cargo:rustc-cfg=soc_has_io_mux", + "cargo:rustc-cfg=soc_has_lp_aon", + "cargo:rustc-cfg=soc_has_lp_aon_clkrst", + "cargo:rustc-cfg=soc_has_lp_sys", + "cargo:rustc-cfg=soc_has_lp_wdt", + "cargo:rustc-cfg=soc_has_lpwr", + "cargo:rustc-cfg=soc_has_pmu", + "cargo:rustc-cfg=soc_has_systimer", + "cargo:rustc-cfg=soc_has_timg0", + "cargo:rustc-cfg=soc_has_timg1", + "cargo:rustc-cfg=soc_has_uart0", + "cargo:rustc-cfg=soc_has_uart1", + "cargo:rustc-cfg=soc_has_uart2", + "cargo:rustc-cfg=soc_has_uart3", + "cargo:rustc-cfg=soc_has_uart4", + "cargo:rustc-cfg=soc_has_spi2", + "cargo:rustc-cfg=soc_has_spi3", + "cargo:rustc-cfg=soc_has_i2c0", + "cargo:rustc-cfg=soc_has_i2c1", + "cargo:rustc-cfg=soc_has_twai0", + "cargo:rustc-cfg=soc_has_twai1", + "cargo:rustc-cfg=soc_has_twai2", + "cargo:rustc-cfg=soc_has_psram", + "cargo:rustc-cfg=soc_has_dma", + "cargo:rustc-cfg=soc_has_dma_ch0", + "cargo:rustc-cfg=soc_has_dma_ch1", + "cargo:rustc-cfg=soc_has_dma_ch2", + "cargo:rustc-cfg=soc_has_usb_device", + "cargo:rustc-cfg=soc_has_sdhost", + "cargo:rustc-cfg=soc_has_ledc", + "cargo:rustc-cfg=soc_has_mcpwm0", + "cargo:rustc-cfg=soc_has_mcpwm1", + "cargo:rustc-cfg=soc_has_pcnt", + "cargo:rustc-cfg=soc_has_rmt", + "cargo:rustc-cfg=soc_has_adc", + "cargo:rustc-cfg=soc_has_aes", + "cargo:rustc-cfg=soc_has_sha", + "cargo:rustc-cfg=soc_has_rsa", + "cargo:rustc-cfg=soc_has_ecc", + "cargo:rustc-cfg=very_large_intr_status", + "cargo:rustc-cfg=spi_octal", + "cargo:rustc-cfg=adc_driver_supported", + "cargo:rustc-cfg=aes_driver_supported", + "cargo:rustc-cfg=dma_driver_supported", + "cargo:rustc-cfg=ecc_driver_supported", + "cargo:rustc-cfg=gpio_driver_supported", + "cargo:rustc-cfg=i2c_master_driver_supported", + "cargo:rustc-cfg=interrupts_driver_supported", + "cargo:rustc-cfg=rsa_driver_supported", + "cargo:rustc-cfg=sha_driver_supported", + "cargo:rustc-cfg=soc_driver_supported", + "cargo:rustc-cfg=spi_master_driver_supported", + "cargo:rustc-cfg=systimer_driver_supported", + "cargo:rustc-cfg=twai_driver_supported", + "cargo:rustc-cfg=uart_driver_supported", + "cargo:rustc-cfg=usb_serial_jtag_driver_supported", + "cargo:rustc-cfg=i2c_master_i2c0", + "cargo:rustc-cfg=i2c_master_i2c1", + "cargo:rustc-cfg=spi_master_spi2", + "cargo:rustc-cfg=spi_master_spi3", + "cargo:rustc-cfg=uart_uart0", + "cargo:rustc-cfg=uart_uart1", + "cargo:rustc-cfg=uart_uart2", + "cargo:rustc-cfg=uart_uart3", + "cargo:rustc-cfg=uart_uart4", + "cargo:rustc-cfg=aes_dma", + "cargo:rustc-cfg=aes_has_split_text_registers", + "cargo:rustc-cfg=dma_kind=\"gdma\"", + "cargo:rustc-cfg=dma_separate_in_out_interrupts", + "cargo:rustc-cfg=dma_max_priority=\"5\"", + "cargo:rustc-cfg=dma_max_priority_is_set", + "cargo:rustc-cfg=dma_gdma_version=\"2\"", + "cargo:rustc-cfg=dma_gdma_version_is_set", + "cargo:rustc-cfg=ecc_separate_jacobian_point_memory", + "cargo:rustc-cfg=ecc_has_modular_arithmetic", + "cargo:rustc-cfg=ecc_has_point_addition", + "cargo:rustc-cfg=ecc_has_curve_p192", + "cargo:rustc-cfg=ecc_has_curve_p256", + "cargo:rustc-cfg=ecc_has_curve_p384", + "cargo:rustc-cfg=gpio_has_bank_1", + "cargo:rustc-cfg=gpio_gpio_function=\"1\"", + "cargo:rustc-cfg=gpio_constant_0_input=\"62\"", + "cargo:rustc-cfg=gpio_constant_1_input=\"63\"", + "cargo:rustc-cfg=gpio_func_in_sel_offset=\"0\"", + "cargo:rustc-cfg=gpio_input_signal_max=\"203\"", + "cargo:rustc-cfg=gpio_output_signal_max=\"256\"", + "cargo:rustc-cfg=i2c_master_has_fsm_timeouts", + "cargo:rustc-cfg=i2c_master_has_hw_bus_clear", + "cargo:rustc-cfg=i2c_master_has_bus_timeout_enable", + "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", + "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", + "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=interrupts_status_registers=\"3\"", + "cargo:rustc-cfg=interrupt_controller=\"clic\"", + "cargo:rustc-cfg=rsa_size_increment=\"32\"", + "cargo:rustc-cfg=rsa_memory_size_bytes=\"384\"", + "cargo:rustc-cfg=sha_dma", + "cargo:rustc-cfg=soc_cpu_has_csr_pc", + "cargo:rustc-cfg=soc_rc_fast_clk_default=\"20000000\"", + "cargo:rustc-cfg=soc_rc_fast_clk_default_is_set", + "cargo:rustc-cfg=soc_has_clock_node_xtal_clk", + "cargo:rustc-cfg=soc_has_clock_node_cpll_clk", + "cargo:rustc-cfg=soc_has_clock_node_spll_clk", + "cargo:rustc-cfg=soc_has_clock_node_mpll_clk", + "cargo:rustc-cfg=soc_has_clock_node_rc_fast_clk", + "cargo:rustc-cfg=soc_has_clock_node_xtal32k_clk", + "cargo:rustc-cfg=soc_has_clock_node_osc_slow_clk", + "cargo:rustc-cfg=soc_has_clock_node_rc_slow_clk", + "cargo:rustc-cfg=soc_has_clock_node_rc32k_clk", + "cargo:rustc-cfg=soc_has_clock_node_pll_f20m", + "cargo:rustc-cfg=soc_has_clock_node_pll_f80m", + "cargo:rustc-cfg=soc_has_clock_node_pll_f120m", + "cargo:rustc-cfg=soc_has_clock_node_pll_f160m", + "cargo:rustc-cfg=soc_has_clock_node_pll_f240m", + "cargo:rustc-cfg=soc_has_clock_node_pll_f25m", + "cargo:rustc-cfg=soc_has_clock_node_pll_f50m", + "cargo:rustc-cfg=soc_has_clock_node_xtal_d2_clk", + "cargo:rustc-cfg=soc_has_clock_node_cpu_root_clk", + "cargo:rustc-cfg=soc_has_clock_node_cpu_clk", + "cargo:rustc-cfg=soc_has_clock_node_apb_clk", + "cargo:rustc-cfg=soc_has_clock_node_lp_fast_clk", + "cargo:rustc-cfg=soc_has_clock_node_lp_slow_clk", + "cargo:rustc-cfg=soc_has_clock_node_uart_function_clock", + "cargo:rustc-cfg=soc_has_clock_node_uart_baud_rate_generator", + "cargo:rustc-cfg=soc_has_clock_node_timg_function_clock", + "cargo:rustc-cfg=soc_has_clock_node_timg_wdt_clock", + "cargo:rustc-cfg=has_dram_region", + "cargo:rustc-cfg=has_dram2_uninit_region", + "cargo:rustc-cfg=spi_master_supports_dma", + "cargo:rustc-cfg=uart_ram_size=\"128\"", + ], + memory_layout: &MemoryLayout { + regions: &[ + ( + "dram", + MemoryRegion { + address_range: 0x4FF40000..0x4FFC0000, + }, + ), + ( + "dram2_uninit", + MemoryRegion { + address_range: 0x4FF00000..0x4FF40000, + }, + ), + ], + }, + pins: &[ + PinInfo { + pin: 0, + limitations: &[], + }, + PinInfo { + pin: 1, + limitations: &[], + }, + PinInfo { + pin: 2, + limitations: &["jtag"], + }, + PinInfo { + pin: 3, + limitations: &["jtag"], + }, + PinInfo { + pin: 4, + limitations: &["jtag"], + }, + PinInfo { + pin: 5, + limitations: &["jtag"], + }, + PinInfo { + pin: 6, + limitations: &[], + }, + PinInfo { + pin: 7, + limitations: &[], + }, + PinInfo { + pin: 8, + limitations: &[], + }, + PinInfo { + pin: 9, + limitations: &[], + }, + PinInfo { + pin: 10, + limitations: &[], + }, + PinInfo { + pin: 11, + limitations: &[], + }, + PinInfo { + pin: 12, + limitations: &[], + }, + PinInfo { + pin: 13, + limitations: &[], + }, + PinInfo { + pin: 14, + limitations: &[], + }, + PinInfo { + pin: 15, + limitations: &[], + }, + PinInfo { + pin: 16, + limitations: &[], + }, + PinInfo { + pin: 17, + limitations: &[], + }, + PinInfo { + pin: 18, + limitations: &[], + }, + PinInfo { + pin: 19, + limitations: &[], + }, + PinInfo { + pin: 20, + limitations: &[], + }, + PinInfo { + pin: 21, + limitations: &[], + }, + PinInfo { + pin: 22, + limitations: &[], + }, + PinInfo { + pin: 23, + limitations: &[], + }, + PinInfo { + pin: 24, + limitations: &["usb_jtag"], + }, + PinInfo { + pin: 25, + limitations: &["usb_jtag"], + }, + PinInfo { + pin: 26, + limitations: &["usb_jtag"], + }, + PinInfo { + pin: 27, + limitations: &["usb_jtag"], + }, + PinInfo { + pin: 28, + limitations: &[], + }, + PinInfo { + pin: 29, + limitations: &[], + }, + PinInfo { + pin: 30, + limitations: &[], + }, + PinInfo { + pin: 31, + limitations: &[], + }, + PinInfo { + pin: 32, + limitations: &["strapping"], + }, + PinInfo { + pin: 33, + limitations: &["strapping"], + }, + PinInfo { + pin: 34, + limitations: &["strapping"], + }, + PinInfo { + pin: 35, + limitations: &["strapping"], + }, + PinInfo { + pin: 36, + limitations: &["strapping"], + }, + PinInfo { + pin: 37, + limitations: &["strapping"], + }, + PinInfo { + pin: 38, + limitations: &["strapping"], + }, + PinInfo { + pin: 39, + limitations: &[], + }, + PinInfo { + pin: 40, + limitations: &[], + }, + PinInfo { + pin: 41, + limitations: &[], + }, + PinInfo { + pin: 42, + limitations: &[], + }, + PinInfo { + pin: 43, + limitations: &[], + }, + PinInfo { + pin: 44, + limitations: &[], + }, + PinInfo { + pin: 45, + limitations: &[], + }, + PinInfo { + pin: 46, + limitations: &[], + }, + PinInfo { + pin: 47, + limitations: &[], + }, + PinInfo { + pin: 48, + limitations: &[], + }, + PinInfo { + pin: 49, + limitations: &[], + }, + PinInfo { + pin: 50, + limitations: &[], + }, + PinInfo { + pin: 51, + limitations: &[], + }, + PinInfo { + pin: 52, + limitations: &[], + }, + PinInfo { + pin: 53, + limitations: &[], + }, + PinInfo { + pin: 54, + limitations: &[], + }, + ], + }, Self::Esp32s2 => Config { architecture: "xtensa", target: "xtensa-esp32s2-none-elf", @@ -5728,6 +6260,27 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_pll_f48m_clk)"); println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_pll_lp_clk)"); println!("cargo:rustc-check-cfg=cfg(timergroup_rc_fast_calibration_tick_enable)"); + println!("cargo:rustc-check-cfg=cfg(esp32p4)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_hp_sys_clkrst)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_interrupt_core1)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clic)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_lp_aon_clkrst)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_lp_sys)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_uart3)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_uart4)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_twai2)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_adc)"); + println!("cargo:rustc-check-cfg=cfg(very_large_intr_status)"); + println!("cargo:rustc-check-cfg=cfg(spi_octal)"); + println!("cargo:rustc-check-cfg=cfg(uart_uart3)"); + println!("cargo:rustc-check-cfg=cfg(uart_uart4)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_cpll_clk)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_spll_clk)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_mpll_clk)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_rc32k_clk)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_pll_f25m)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_pll_f50m)"); + println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_cpu_root_clk)"); println!("cargo:rustc-check-cfg=cfg(esp32s2)"); println!("cargo:rustc-check-cfg=cfg(soc_has_dedicated_gpio)"); println!("cargo:rustc-check-cfg=cfg(soc_has_pms)"); @@ -5746,7 +6299,6 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_ref_tick_ck8m)"); println!("cargo:rustc-check-cfg=cfg(spi_master_has_octal)"); println!("cargo:rustc-check-cfg=cfg(esp32s3)"); - println!("cargo:rustc-check-cfg=cfg(soc_has_interrupt_core1)"); println!("cargo:rustc-check-cfg=cfg(soc_has_lcd_cam)"); println!("cargo:rustc-check-cfg=cfg(soc_has_peri_backup)"); println!("cargo:rustc-check-cfg=cfg(soc_has_rtc_cntl)"); @@ -5763,13 +6315,16 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(dma_kind, values(\"pdma\",\"gdma\"))"); println!("cargo:rustc-check-cfg=cfg(gpio_gpio_function, values(\"2\",\"1\"))"); println!( - "cargo:rustc-check-cfg=cfg(gpio_constant_0_input, values(\"48\",\"31\",\"96\",\"60\"))" + "cargo:rustc-check-cfg=cfg(gpio_constant_0_input, \ + values(\"48\",\"31\",\"96\",\"60\",\"62\"))" + ); + println!( + "cargo:rustc-check-cfg=cfg(gpio_constant_1_input, values(\"56\",\"30\",\"64\",\"63\"))" ); - println!("cargo:rustc-check-cfg=cfg(gpio_constant_1_input, values(\"56\",\"30\",\"64\"))"); println!("cargo:rustc-check-cfg=cfg(gpio_func_in_sel_offset, values(\"0\"))"); println!( "cargo:rustc-check-cfg=cfg(gpio_input_signal_max, \ - values(\"206\",\"100\",\"116\",\"124\",\"242\",\"255\"))" + values(\"206\",\"100\",\"116\",\"124\",\"203\",\"242\",\"255\"))" ); println!("cargo:rustc-check-cfg=cfg(gpio_output_signal_max, values(\"256\",\"128\"))"); println!( @@ -5797,7 +6352,8 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(rsa_size_increment, values(\"512\",\"32\"))"); println!("cargo:rustc-check-cfg=cfg(rsa_memory_size_bytes, values(\"512\",\"384\"))"); println!( - "cargo:rustc-check-cfg=cfg(soc_rc_fast_clk_default, values(\"8500000\",\"17500000\"))" + "cargo:rustc-check-cfg=cfg(soc_rc_fast_clk_default, \ + values(\"8500000\",\"17500000\",\"20000000\"))" ); println!("cargo:rustc-check-cfg=cfg(uart_ram_size, values(\"128\"))"); println!("cargo:rustc-check-cfg=cfg(wifi_mac_version, values(\"1\",\"3\",\"2\"))"); diff --git a/esp-metadata-generated/src/_generated_esp32p4.rs b/esp-metadata-generated/src/_generated_esp32p4.rs index d72087812ea..01f06c5dadd 100644 --- a/esp-metadata-generated/src/_generated_esp32p4.rs +++ b/esp-metadata-generated/src/_generated_esp32p4.rs @@ -17,6 +17,22 @@ macro_rules! chip { "esp32p4" }; } +/// The pretty name of the chip as `&str` +/// +/// # Example +/// +/// ```rust, no_run +/// use esp_hal::chip; +/// let chip_name = chip_pretty!(); +#[doc = concat!("assert_eq!(chip_name, ", chip_pretty!(), ")")] +/// ``` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! chip_pretty { + () => { + "ESP32-P4" + }; +} /// The properties of this chip and its drivers. #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] @@ -36,27 +52,57 @@ macro_rules! property { ("trm") => { "https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf" }; - ("soc.cpu_has_csr_pc") => { + ("aes.dma") => { true }; - ("soc.cpu_has_prv_mode") => { + ("aes.has_split_text_registers") => { + true + }; + ("aes.endianness_configurable") => { false }; - ("soc.rc_fast_clk_default") => { - 20000000 + ("dma.kind") => { + "gdma" }; - ("soc.rc_fast_clk_default", str) => { - stringify!(20000000) + ("dma.supports_mem2mem") => { + false + }; + ("dma.can_access_psram") => { + false + }; + ("dma.separate_in_out_interrupts") => { + true }; - ("soc.rc_slow_clock") => { - 150000 + ("dma.max_priority") => { + 5 }; - ("soc.rc_slow_clock", str) => { - stringify!(150000) + ("dma.max_priority", str) => { + stringify!(5) }; - ("gpio.has_bank_1") => { + ("dma.gdma_version") => { + 2 + }; + ("dma.gdma_version", str) => { + stringify!(2) + }; + ("ecc.zero_extend_writes") => { + false + }; + ("ecc.separate_jacobian_point_memory") => { + true + }; + ("ecc.has_memory_clock_gate") => { false }; + ("ecc.supports_enhanced_security") => { + false + }; + ("ecc.mem_block_size") => { + 48 + }; + ("gpio.has_bank_1") => { + true + }; ("gpio.gpio_function") => { 1 }; @@ -64,16 +110,16 @@ macro_rules! property { stringify!(1) }; ("gpio.constant_0_input") => { - 60 + 62 }; ("gpio.constant_0_input", str) => { - stringify!(60) + stringify!(62) }; ("gpio.constant_1_input") => { - 56 + 63 }; ("gpio.constant_1_input", str) => { - stringify!(56) + stringify!(63) }; ("gpio.remap_iomux_pin_registers") => { false @@ -85,16 +131,16 @@ macro_rules! property { stringify!(0) }; ("gpio.input_signal_max") => { - 255 + 203 }; ("gpio.input_signal_max", str) => { - stringify!(255) + stringify!(203) }; ("gpio.output_signal_max") => { - 255 + 256 }; ("gpio.output_signal_max", str) => { - stringify!(255) + stringify!(256) }; ("i2c_master.has_fsm_timeouts") => { true @@ -109,22 +155,22 @@ macro_rules! property { false }; ("i2c_master.can_estimate_nack_reason") => { - true + false }; ("i2c_master.has_conf_update") => { - true + false }; ("i2c_master.has_reliable_fsm_reset") => { - true + false }; ("i2c_master.has_arbitration_en") => { - true + false }; ("i2c_master.has_tx_fifo_watermark") => { - true + false }; ("i2c_master.bus_timeout_is_exponential") => { - true + false }; ("i2c_master.max_bus_timeout") => { 31 @@ -145,23 +191,74 @@ macro_rules! property { stringify!(32) }; ("interrupts.status_registers") => { - 4 + 3 }; ("interrupts.status_registers", str) => { - stringify!(4) + stringify!(3) + }; + ("interrupts.disabled_interrupt") => { + 0 + }; + ("rsa.size_increment") => { + 32 + }; + ("rsa.size_increment", str) => { + stringify!(32) }; - ("sleep.light_sleep") => { + ("rsa.memory_size_bytes") => { + 384 + }; + ("rsa.memory_size_bytes", str) => { + stringify!(384) + }; + ("sha.dma") => { true }; - ("sleep.deep_sleep") => { + ("soc.cpu_has_branch_predictor") => { + false + }; + ("soc.cpu_has_csr_pc") => { true }; - ("timergroup.timg_has_timer1") => { + ("soc.multi_core_enabled") => { false }; - ("timergroup.timg_has_divcnt_rst") => { + ("soc.rc_fast_clk_default") => { + 20000000 + }; + ("soc.rc_fast_clk_default", str) => { + stringify!(20000000) + }; + ("clock_tree.cpu_clk.divisor") => { + (0, 255) + }; + ("clock_tree.apb_clk.divisor") => { + (0, 255) + }; + ("clock_tree.uart.function_clock.div_num") => { + (0, 255) + }; + ("clock_tree.uart.baud_rate_generator.fractional") => { + (0, 15) + }; + ("clock_tree.uart.baud_rate_generator.integral") => { + (0, 4095) + }; + ("spi_master.supports_dma") => { true }; + ("spi_master.has_octal") => { + false + }; + ("spi_master.has_app_interrupts") => { + false + }; + ("spi_master.has_dma_segmented_transfer") => { + false + }; + ("spi_master.has_clk_pre_div") => { + false + }; ("uart.ram_size") => { 128 }; @@ -169,7 +266,446 @@ macro_rules! property { stringify!(128) }; ("uart.peripheral_controls_mem_clk") => { - true + false + }; + ("uart.has_sclk_divider") => { + false + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_aes_key_length { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_aes_key_length { $(($pattern) => $code;)* ($other : + tt) => {} } _for_each_inner_aes_key_length!((128)); + _for_each_inner_aes_key_length!((256)); _for_each_inner_aes_key_length!((128, 0, + 4)); _for_each_inner_aes_key_length!((256, 2, 6)); + _for_each_inner_aes_key_length!((bits(128), (256))); + _for_each_inner_aes_key_length!((modes(128, 0, 4), (256, 2, 6))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_ecc_working_mode { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_ecc_working_mode { $(($pattern) => $code;)* ($other + : tt) => {} } _for_each_inner_ecc_working_mode!((0, AffinePointMultiplication)); + _for_each_inner_ecc_working_mode!((2, AffinePointVerification)); + _for_each_inner_ecc_working_mode!((3, AffinePointVerificationAndMultiplication)); + _for_each_inner_ecc_working_mode!((4, JacobianPointMultiplication)); + _for_each_inner_ecc_working_mode!((5, AffinePointAddition)); + _for_each_inner_ecc_working_mode!((6, JacobianPointVerification)); + _for_each_inner_ecc_working_mode!((7, + AffinePointVerificationAndJacobianPointMultiplication)); + _for_each_inner_ecc_working_mode!((8, ModularAddition)); + _for_each_inner_ecc_working_mode!((all(0, AffinePointMultiplication), (2, + AffinePointVerification), (3, AffinePointVerificationAndMultiplication), (4, + JacobianPointMultiplication), (5, AffinePointAddition), (6, + JacobianPointVerification), (7, + AffinePointVerificationAndJacobianPointMultiplication), (8, ModularAddition))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_ecc_curve { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_ecc_curve { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_ecc_curve!((0, P192, 192)); + _for_each_inner_ecc_curve!((1, P256, 256)); _for_each_inner_ecc_curve!((2, P384, + 384)); _for_each_inner_ecc_curve!((all(0, P192, 192), (1, P256, 256), (2, P384, + 384))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_interrupt { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_interrupt { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_interrupt!(([disabled 0] 0)); + _for_each_inner_interrupt!(([reserved 0] 1)); + _for_each_inner_interrupt!(([reserved 1] 2)); + _for_each_inner_interrupt!(([reserved 2] 3)); + _for_each_inner_interrupt!(([reserved 3] 4)); + _for_each_inner_interrupt!(([reserved 4] 5)); + _for_each_inner_interrupt!(([reserved 5] 6)); + _for_each_inner_interrupt!(([reserved 6] 7)); + _for_each_inner_interrupt!(([reserved 7] 8)); + _for_each_inner_interrupt!(([reserved 8] 9)); + _for_each_inner_interrupt!(([reserved 9] 10)); + _for_each_inner_interrupt!(([reserved 10] 11)); + _for_each_inner_interrupt!(([reserved 11] 12)); + _for_each_inner_interrupt!(([reserved 12] 13)); + _for_each_inner_interrupt!(([reserved 13] 14)); + _for_each_inner_interrupt!(([reserved 14] 15)); + _for_each_inner_interrupt!(([vector 0] 16)); _for_each_inner_interrupt!(([vector + 1] 17)); _for_each_inner_interrupt!(([vector 2] 18)); + _for_each_inner_interrupt!(([vector 3] 19)); _for_each_inner_interrupt!(([vector + 4] 20)); _for_each_inner_interrupt!(([vector 5] 21)); + _for_each_inner_interrupt!(([vector 6] 22)); _for_each_inner_interrupt!(([vector + 7] 23)); _for_each_inner_interrupt!(([direct_bindable 0] 24)); + _for_each_inner_interrupt!(([direct_bindable 1] 25)); + _for_each_inner_interrupt!(([direct_bindable 2] 26)); + _for_each_inner_interrupt!(([direct_bindable 3] 27)); + _for_each_inner_interrupt!(([direct_bindable 4] 28)); + _for_each_inner_interrupt!(([direct_bindable 5] 29)); + _for_each_inner_interrupt!(([direct_bindable 6] 30)); + _for_each_inner_interrupt!(([direct_bindable 7] 31)); + _for_each_inner_interrupt!(([direct_bindable 8] 32)); + _for_each_inner_interrupt!(([direct_bindable 9] 33)); + _for_each_inner_interrupt!(([direct_bindable 10] 34)); + _for_each_inner_interrupt!(([direct_bindable 11] 35)); + _for_each_inner_interrupt!(([direct_bindable 12] 36)); + _for_each_inner_interrupt!(([direct_bindable 13] 37)); + _for_each_inner_interrupt!(([direct_bindable 14] 38)); + _for_each_inner_interrupt!(([direct_bindable 15] 39)); + _for_each_inner_interrupt!(([direct_bindable 16] 40)); + _for_each_inner_interrupt!(([direct_bindable 17] 41)); + _for_each_inner_interrupt!(([direct_bindable 18] 42)); + _for_each_inner_interrupt!(([direct_bindable 19] 43)); + _for_each_inner_interrupt!(([direct_bindable 20] 44)); + _for_each_inner_interrupt!(([direct_bindable 21] 45)); + _for_each_inner_interrupt!(([direct_bindable 22] 46)); + _for_each_inner_interrupt!(([direct_bindable 23] 47)); + _for_each_inner_interrupt!((all([disabled 0] 0), ([reserved 0] 1), ([reserved 1] + 2), ([reserved 2] 3), ([reserved 3] 4), ([reserved 4] 5), ([reserved 5] 6), + ([reserved 6] 7), ([reserved 7] 8), ([reserved 8] 9), ([reserved 9] 10), + ([reserved 10] 11), ([reserved 11] 12), ([reserved 12] 13), ([reserved 13] 14), + ([reserved 14] 15), ([vector 0] 16), ([vector 1] 17), ([vector 2] 18), ([vector + 3] 19), ([vector 4] 20), ([vector 5] 21), ([vector 6] 22), ([vector 7] 23), + ([direct_bindable 0] 24), ([direct_bindable 1] 25), ([direct_bindable 2] 26), + ([direct_bindable 3] 27), ([direct_bindable 4] 28), ([direct_bindable 5] 29), + ([direct_bindable 6] 30), ([direct_bindable 7] 31), ([direct_bindable 8] 32), + ([direct_bindable 9] 33), ([direct_bindable 10] 34), ([direct_bindable 11] 35), + ([direct_bindable 12] 36), ([direct_bindable 13] 37), ([direct_bindable 14] 38), + ([direct_bindable 15] 39), ([direct_bindable 16] 40), ([direct_bindable 17] 41), + ([direct_bindable 18] 42), ([direct_bindable 19] 43), ([direct_bindable 20] 44), + ([direct_bindable 21] 45), ([direct_bindable 22] 46), ([direct_bindable 23] + 47))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_classified_interrupt { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_classified_interrupt { $(($pattern) => $code;)* + ($other : tt) => {} } _for_each_inner_classified_interrupt!(([direct_bindable 0] + 24)); _for_each_inner_classified_interrupt!(([direct_bindable 1] 25)); + _for_each_inner_classified_interrupt!(([direct_bindable 2] 26)); + _for_each_inner_classified_interrupt!(([direct_bindable 3] 27)); + _for_each_inner_classified_interrupt!(([direct_bindable 4] 28)); + _for_each_inner_classified_interrupt!(([direct_bindable 5] 29)); + _for_each_inner_classified_interrupt!(([direct_bindable 6] 30)); + _for_each_inner_classified_interrupt!(([direct_bindable 7] 31)); + _for_each_inner_classified_interrupt!(([direct_bindable 8] 32)); + _for_each_inner_classified_interrupt!(([direct_bindable 9] 33)); + _for_each_inner_classified_interrupt!(([direct_bindable 10] 34)); + _for_each_inner_classified_interrupt!(([direct_bindable 11] 35)); + _for_each_inner_classified_interrupt!(([direct_bindable 12] 36)); + _for_each_inner_classified_interrupt!(([direct_bindable 13] 37)); + _for_each_inner_classified_interrupt!(([direct_bindable 14] 38)); + _for_each_inner_classified_interrupt!(([direct_bindable 15] 39)); + _for_each_inner_classified_interrupt!(([direct_bindable 16] 40)); + _for_each_inner_classified_interrupt!(([direct_bindable 17] 41)); + _for_each_inner_classified_interrupt!(([direct_bindable 18] 42)); + _for_each_inner_classified_interrupt!(([direct_bindable 19] 43)); + _for_each_inner_classified_interrupt!(([direct_bindable 20] 44)); + _for_each_inner_classified_interrupt!(([direct_bindable 21] 45)); + _for_each_inner_classified_interrupt!(([direct_bindable 22] 46)); + _for_each_inner_classified_interrupt!(([direct_bindable 23] 47)); + _for_each_inner_classified_interrupt!(([vector 0] 16)); + _for_each_inner_classified_interrupt!(([vector 1] 17)); + _for_each_inner_classified_interrupt!(([vector 2] 18)); + _for_each_inner_classified_interrupt!(([vector 3] 19)); + _for_each_inner_classified_interrupt!(([vector 4] 20)); + _for_each_inner_classified_interrupt!(([vector 5] 21)); + _for_each_inner_classified_interrupt!(([vector 6] 22)); + _for_each_inner_classified_interrupt!(([vector 7] 23)); + _for_each_inner_classified_interrupt!(([reserved 0] 1)); + _for_each_inner_classified_interrupt!(([reserved 1] 2)); + _for_each_inner_classified_interrupt!(([reserved 2] 3)); + _for_each_inner_classified_interrupt!(([reserved 3] 4)); + _for_each_inner_classified_interrupt!(([reserved 4] 5)); + _for_each_inner_classified_interrupt!(([reserved 5] 6)); + _for_each_inner_classified_interrupt!(([reserved 6] 7)); + _for_each_inner_classified_interrupt!(([reserved 7] 8)); + _for_each_inner_classified_interrupt!(([reserved 8] 9)); + _for_each_inner_classified_interrupt!(([reserved 9] 10)); + _for_each_inner_classified_interrupt!(([reserved 10] 11)); + _for_each_inner_classified_interrupt!(([reserved 11] 12)); + _for_each_inner_classified_interrupt!(([reserved 12] 13)); + _for_each_inner_classified_interrupt!(([reserved 13] 14)); + _for_each_inner_classified_interrupt!(([reserved 14] 15)); + _for_each_inner_classified_interrupt!((direct_bindable([direct_bindable 0] 24), + ([direct_bindable 1] 25), ([direct_bindable 2] 26), ([direct_bindable 3] 27), + ([direct_bindable 4] 28), ([direct_bindable 5] 29), ([direct_bindable 6] 30), + ([direct_bindable 7] 31), ([direct_bindable 8] 32), ([direct_bindable 9] 33), + ([direct_bindable 10] 34), ([direct_bindable 11] 35), ([direct_bindable 12] 36), + ([direct_bindable 13] 37), ([direct_bindable 14] 38), ([direct_bindable 15] 39), + ([direct_bindable 16] 40), ([direct_bindable 17] 41), ([direct_bindable 18] 42), + ([direct_bindable 19] 43), ([direct_bindable 20] 44), ([direct_bindable 21] 45), + ([direct_bindable 22] 46), ([direct_bindable 23] 47))); + _for_each_inner_classified_interrupt!((vector([vector 0] 16), ([vector 1] 17), + ([vector 2] 18), ([vector 3] 19), ([vector 4] 20), ([vector 5] 21), ([vector 6] + 22), ([vector 7] 23))); _for_each_inner_classified_interrupt!((reserved([reserved + 0] 1), ([reserved 1] 2), ([reserved 2] 3), ([reserved 3] 4), ([reserved 4] 5), + ([reserved 5] 6), ([reserved 6] 7), ([reserved 7] 8), ([reserved 8] 9), + ([reserved 9] 10), ([reserved 10] 11), ([reserved 11] 12), ([reserved 12] 13), + ([reserved 13] 14), ([reserved 14] 15))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_interrupt_priority { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_interrupt_priority { $(($pattern) => $code;)* + ($other : tt) => {} } _for_each_inner_interrupt_priority!((0, 1, Priority1, + Level1)); _for_each_inner_interrupt_priority!((1, 2, Priority2, Level2)); + _for_each_inner_interrupt_priority!((2, 3, Priority3, Level3)); + _for_each_inner_interrupt_priority!((3, 4, Priority4, Level4)); + _for_each_inner_interrupt_priority!((4, 5, Priority5, Level5)); + _for_each_inner_interrupt_priority!((5, 6, Priority6, Level6)); + _for_each_inner_interrupt_priority!((6, 7, Priority7, Level7)); + _for_each_inner_interrupt_priority!((7, 8, Priority8, Level8)); + _for_each_inner_interrupt_priority!((all(0, 1, Priority1, Level1), (1, 2, + Priority2, Level2), (2, 3, Priority3, Level3), (3, 4, Priority4, Level4), (4, 5, + Priority5, Level5), (5, 6, Priority6, Level6), (6, 7, Priority7, Level7), (7, 8, + Priority8, Level8))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_sw_interrupt { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_sw_interrupt { $(($pattern) => $code;)* ($other : + tt) => {} } _for_each_inner_sw_interrupt!((0, FROM_CPU_INTR0, + software_interrupt0)); _for_each_inner_sw_interrupt!((1, FROM_CPU_INTR1, + software_interrupt1)); _for_each_inner_sw_interrupt!((2, FROM_CPU_INTR2, + software_interrupt2)); _for_each_inner_sw_interrupt!((3, FROM_CPU_INTR3, + software_interrupt3)); _for_each_inner_sw_interrupt!((all(0, FROM_CPU_INTR0, + software_interrupt0), (1, FROM_CPU_INTR1, software_interrupt1), (2, + FROM_CPU_INTR2, software_interrupt2), (3, FROM_CPU_INTR3, software_interrupt3))); + }; +} +#[macro_export] +macro_rules! sw_interrupt_delay { + () => { + unsafe { + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + ::core::arch::asm!("nop"); + } + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_rsa_exponentiation { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_rsa_exponentiation { $(($pattern) => $code;)* + ($other : tt) => {} } _for_each_inner_rsa_exponentiation!((32)); + _for_each_inner_rsa_exponentiation!((64)); + _for_each_inner_rsa_exponentiation!((96)); + _for_each_inner_rsa_exponentiation!((128)); + _for_each_inner_rsa_exponentiation!((160)); + _for_each_inner_rsa_exponentiation!((192)); + _for_each_inner_rsa_exponentiation!((224)); + _for_each_inner_rsa_exponentiation!((256)); + _for_each_inner_rsa_exponentiation!((288)); + _for_each_inner_rsa_exponentiation!((320)); + _for_each_inner_rsa_exponentiation!((352)); + _for_each_inner_rsa_exponentiation!((384)); + _for_each_inner_rsa_exponentiation!((416)); + _for_each_inner_rsa_exponentiation!((448)); + _for_each_inner_rsa_exponentiation!((480)); + _for_each_inner_rsa_exponentiation!((512)); + _for_each_inner_rsa_exponentiation!((544)); + _for_each_inner_rsa_exponentiation!((576)); + _for_each_inner_rsa_exponentiation!((608)); + _for_each_inner_rsa_exponentiation!((640)); + _for_each_inner_rsa_exponentiation!((672)); + _for_each_inner_rsa_exponentiation!((704)); + _for_each_inner_rsa_exponentiation!((736)); + _for_each_inner_rsa_exponentiation!((768)); + _for_each_inner_rsa_exponentiation!((800)); + _for_each_inner_rsa_exponentiation!((832)); + _for_each_inner_rsa_exponentiation!((864)); + _for_each_inner_rsa_exponentiation!((896)); + _for_each_inner_rsa_exponentiation!((928)); + _for_each_inner_rsa_exponentiation!((960)); + _for_each_inner_rsa_exponentiation!((992)); + _for_each_inner_rsa_exponentiation!((1024)); + _for_each_inner_rsa_exponentiation!((1056)); + _for_each_inner_rsa_exponentiation!((1088)); + _for_each_inner_rsa_exponentiation!((1120)); + _for_each_inner_rsa_exponentiation!((1152)); + _for_each_inner_rsa_exponentiation!((1184)); + _for_each_inner_rsa_exponentiation!((1216)); + _for_each_inner_rsa_exponentiation!((1248)); + _for_each_inner_rsa_exponentiation!((1280)); + _for_each_inner_rsa_exponentiation!((1312)); + _for_each_inner_rsa_exponentiation!((1344)); + _for_each_inner_rsa_exponentiation!((1376)); + _for_each_inner_rsa_exponentiation!((1408)); + _for_each_inner_rsa_exponentiation!((1440)); + _for_each_inner_rsa_exponentiation!((1472)); + _for_each_inner_rsa_exponentiation!((1504)); + _for_each_inner_rsa_exponentiation!((1536)); + _for_each_inner_rsa_exponentiation!((1568)); + _for_each_inner_rsa_exponentiation!((1600)); + _for_each_inner_rsa_exponentiation!((1632)); + _for_each_inner_rsa_exponentiation!((1664)); + _for_each_inner_rsa_exponentiation!((1696)); + _for_each_inner_rsa_exponentiation!((1728)); + _for_each_inner_rsa_exponentiation!((1760)); + _for_each_inner_rsa_exponentiation!((1792)); + _for_each_inner_rsa_exponentiation!((1824)); + _for_each_inner_rsa_exponentiation!((1856)); + _for_each_inner_rsa_exponentiation!((1888)); + _for_each_inner_rsa_exponentiation!((1920)); + _for_each_inner_rsa_exponentiation!((1952)); + _for_each_inner_rsa_exponentiation!((1984)); + _for_each_inner_rsa_exponentiation!((2016)); + _for_each_inner_rsa_exponentiation!((2048)); + _for_each_inner_rsa_exponentiation!((2080)); + _for_each_inner_rsa_exponentiation!((2112)); + _for_each_inner_rsa_exponentiation!((2144)); + _for_each_inner_rsa_exponentiation!((2176)); + _for_each_inner_rsa_exponentiation!((2208)); + _for_each_inner_rsa_exponentiation!((2240)); + _for_each_inner_rsa_exponentiation!((2272)); + _for_each_inner_rsa_exponentiation!((2304)); + _for_each_inner_rsa_exponentiation!((2336)); + _for_each_inner_rsa_exponentiation!((2368)); + _for_each_inner_rsa_exponentiation!((2400)); + _for_each_inner_rsa_exponentiation!((2432)); + _for_each_inner_rsa_exponentiation!((2464)); + _for_each_inner_rsa_exponentiation!((2496)); + _for_each_inner_rsa_exponentiation!((2528)); + _for_each_inner_rsa_exponentiation!((2560)); + _for_each_inner_rsa_exponentiation!((2592)); + _for_each_inner_rsa_exponentiation!((2624)); + _for_each_inner_rsa_exponentiation!((2656)); + _for_each_inner_rsa_exponentiation!((2688)); + _for_each_inner_rsa_exponentiation!((2720)); + _for_each_inner_rsa_exponentiation!((2752)); + _for_each_inner_rsa_exponentiation!((2784)); + _for_each_inner_rsa_exponentiation!((2816)); + _for_each_inner_rsa_exponentiation!((2848)); + _for_each_inner_rsa_exponentiation!((2880)); + _for_each_inner_rsa_exponentiation!((2912)); + _for_each_inner_rsa_exponentiation!((2944)); + _for_each_inner_rsa_exponentiation!((2976)); + _for_each_inner_rsa_exponentiation!((3008)); + _for_each_inner_rsa_exponentiation!((3040)); + _for_each_inner_rsa_exponentiation!((3072)); + _for_each_inner_rsa_exponentiation!((all(32), (64), (96), (128), (160), (192), + (224), (256), (288), (320), (352), (384), (416), (448), (480), (512), (544), + (576), (608), (640), (672), (704), (736), (768), (800), (832), (864), (896), + (928), (960), (992), (1024), (1056), (1088), (1120), (1152), (1184), (1216), + (1248), (1280), (1312), (1344), (1376), (1408), (1440), (1472), (1504), (1536), + (1568), (1600), (1632), (1664), (1696), (1728), (1760), (1792), (1824), (1856), + (1888), (1920), (1952), (1984), (2016), (2048), (2080), (2112), (2144), (2176), + (2208), (2240), (2272), (2304), (2336), (2368), (2400), (2432), (2464), (2496), + (2528), (2560), (2592), (2624), (2656), (2688), (2720), (2752), (2784), (2816), + (2848), (2880), (2912), (2944), (2976), (3008), (3040), (3072))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_rsa_multiplication { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_rsa_multiplication { $(($pattern) => $code;)* + ($other : tt) => {} } _for_each_inner_rsa_multiplication!((32)); + _for_each_inner_rsa_multiplication!((64)); + _for_each_inner_rsa_multiplication!((96)); + _for_each_inner_rsa_multiplication!((128)); + _for_each_inner_rsa_multiplication!((160)); + _for_each_inner_rsa_multiplication!((192)); + _for_each_inner_rsa_multiplication!((224)); + _for_each_inner_rsa_multiplication!((256)); + _for_each_inner_rsa_multiplication!((288)); + _for_each_inner_rsa_multiplication!((320)); + _for_each_inner_rsa_multiplication!((352)); + _for_each_inner_rsa_multiplication!((384)); + _for_each_inner_rsa_multiplication!((416)); + _for_each_inner_rsa_multiplication!((448)); + _for_each_inner_rsa_multiplication!((480)); + _for_each_inner_rsa_multiplication!((512)); + _for_each_inner_rsa_multiplication!((544)); + _for_each_inner_rsa_multiplication!((576)); + _for_each_inner_rsa_multiplication!((608)); + _for_each_inner_rsa_multiplication!((640)); + _for_each_inner_rsa_multiplication!((672)); + _for_each_inner_rsa_multiplication!((704)); + _for_each_inner_rsa_multiplication!((736)); + _for_each_inner_rsa_multiplication!((768)); + _for_each_inner_rsa_multiplication!((800)); + _for_each_inner_rsa_multiplication!((832)); + _for_each_inner_rsa_multiplication!((864)); + _for_each_inner_rsa_multiplication!((896)); + _for_each_inner_rsa_multiplication!((928)); + _for_each_inner_rsa_multiplication!((960)); + _for_each_inner_rsa_multiplication!((992)); + _for_each_inner_rsa_multiplication!((1024)); + _for_each_inner_rsa_multiplication!((1056)); + _for_each_inner_rsa_multiplication!((1088)); + _for_each_inner_rsa_multiplication!((1120)); + _for_each_inner_rsa_multiplication!((1152)); + _for_each_inner_rsa_multiplication!((1184)); + _for_each_inner_rsa_multiplication!((1216)); + _for_each_inner_rsa_multiplication!((1248)); + _for_each_inner_rsa_multiplication!((1280)); + _for_each_inner_rsa_multiplication!((1312)); + _for_each_inner_rsa_multiplication!((1344)); + _for_each_inner_rsa_multiplication!((1376)); + _for_each_inner_rsa_multiplication!((1408)); + _for_each_inner_rsa_multiplication!((1440)); + _for_each_inner_rsa_multiplication!((1472)); + _for_each_inner_rsa_multiplication!((1504)); + _for_each_inner_rsa_multiplication!((1536)); + _for_each_inner_rsa_multiplication!((all(32), (64), (96), (128), (160), (192), + (224), (256), (288), (320), (352), (384), (416), (448), (480), (512), (544), + (576), (608), (640), (672), (704), (736), (768), (800), (832), (864), (896), + (928), (960), (992), (1024), (1056), (1088), (1120), (1152), (1184), (1216), + (1248), (1280), (1312), (1344), (1376), (1408), (1440), (1472), (1504), (1536))); + }; +} +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_sha_algorithm { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_sha_algorithm { $(($pattern) => $code;)* ($other : + tt) => {} } _for_each_inner_sha_algorithm!((Sha1, "SHA-1"(sizes : 64, 20, 8) + (insecure_against : "collision", "length extension"), 0)); + _for_each_inner_sha_algorithm!((Sha224, "SHA-224"(sizes : 64, 28, 8) + (insecure_against : "length extension"), 1)); + _for_each_inner_sha_algorithm!((Sha256, "SHA-256"(sizes : 64, 32, 8) + (insecure_against : "length extension"), 2)); + _for_each_inner_sha_algorithm!((algos(Sha1, "SHA-1"(sizes : 64, 20, 8) + (insecure_against : "collision", "length extension"), 0), (Sha224, + "SHA-224"(sizes : 64, 28, 8) (insecure_against : "length extension"), 1), + (Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against : "length extension"), + 2))); }; } #[macro_export] @@ -177,23 +713,15 @@ macro_rules! property { /// ```rust, no_run /// // XTAL_CLK /// -/// fn configure_xtal_clk_impl(_clocks: &mut ClockTree, _config: XtalClkConfig) { -/// todo!() -/// } -/// /// // CPLL_CLK /// /// fn enable_cpll_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// fn configure_cpll_clk_impl(_clocks: &mut ClockTree, _config: CpllClkConfig) { -/// todo!() -/// } -/// -/// // RC_FAST_CLK +/// // SPLL_CLK /// -/// fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_spll_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// @@ -203,17 +731,9 @@ macro_rules! property { /// todo!() /// } /// -/// fn configure_mpll_clk_impl(_clocks: &mut ClockTree, _config: MpllClkConfig) { -/// todo!() -/// } -/// -/// // SPLL_CLK -/// -/// fn enable_spll_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } +/// // RC_FAST_CLK /// -/// fn configure_spll_clk_impl(_clocks: &mut ClockTree, _config: SpllClkConfig) { +/// fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// @@ -223,702 +743,557 @@ macro_rules! property { /// todo!() /// } /// -/// // RC_SLOW_CLK -/// -/// fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// /// // OSC_SLOW_CLK /// /// fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_LP_CLK -/// -/// fn enable_pll_lp_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// -/// fn configure_pll_lp_clk_impl(_clocks: &mut ClockTree, _config: PllLpClkConfig) { -/// todo!() -/// } -/// -/// // ROOT_CLK +/// // RC_SLOW_CLK /// -/// fn configure_root_clk_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: RootClkConfig, -/// ) { +/// fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // CPU_CLK -/// -/// fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } +/// // RC32K_CLK /// -/// fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _new_config: CpuClkConfig) { +/// fn enable_rc32k_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // MEM_CLK -/// -/// fn enable_mem_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } +/// // PLL_F20M /// -/// fn configure_mem_clk_impl(_clocks: &mut ClockTree, _new_config: MemClkConfig) { +/// fn enable_pll_f20m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // SYS_CLK -/// -/// fn enable_sys_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } +/// // PLL_F80M /// -/// fn configure_sys_clk_impl(_clocks: &mut ClockTree, _new_config: SysClkConfig) { +/// fn enable_pll_f80m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // APB_CLK -/// -/// fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } +/// // PLL_F120M /// -/// fn configure_apb_clk_impl(_clocks: &mut ClockTree, _new_config: ApbClkConfig) { +/// fn enable_pll_f120m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F50M_CLK +/// // PLL_F160M /// -/// fn enable_pll_f50m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_pll_f160m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F25M_CLK +/// // PLL_F240M /// -/// fn enable_pll_f25m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_pll_f240m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F240M_CLK +/// // PLL_F25M /// -/// fn enable_pll_f240m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_pll_f25m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F160M_CLK +/// // PLL_F50M /// -/// fn enable_pll_f160m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_pll_f50m_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F120M_CLK +/// // XTAL_D2_CLK /// -/// fn enable_pll_f120m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F80M_CLK +/// // CPU_ROOT_CLK /// -/// fn enable_pll_f80m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_cpu_root_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // PLL_F20M_CLK -/// -/// fn enable_pll_f20m_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn configure_cpu_root_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_config: Option, +/// _new_config: CpuRootClkConfig, +/// ) { /// todo!() /// } /// -/// // LP_SLOW_CLK +/// // CPU_CLK /// -/// fn configure_lp_slow_clk_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: LpSlowClkConfig, -/// ) { +/// fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // LP_FAST_CLK -/// -/// fn configure_lp_fast_clk_impl( +/// fn configure_cpu_clk_impl( /// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: LpFastClkConfig, +/// _old_config: Option, +/// _new_config: CpuClkConfig, /// ) { /// todo!() /// } /// -/// // LP_DYN_SLOW_CLK +/// // APB_CLK /// -/// fn configure_lp_dyn_slow_clk_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: LpDynSlowClkConfig, -/// ) { +/// fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // LP_DYN_FAST_CLK -/// -/// fn configure_lp_dyn_fast_clk_impl( +/// fn configure_apb_clk_impl( /// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: LpDynFastClkConfig, +/// _old_config: Option, +/// _new_config: ApbClkConfig, /// ) { /// todo!() /// } /// -/// // LP_PERI_CLK -/// -/// fn enable_lp_peri_clk_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } +/// // LP_FAST_CLK /// -/// fn configure_lp_peri_clk_impl(_clocks: &mut ClockTree, _new_config: LpPeriClkConfig) { +/// fn enable_lp_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// // XTAL_D2_CLK -/// -/// fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn configure_lp_fast_clk_impl( +/// _clocks: &mut ClockTree, +/// _old_config: Option, +/// _new_config: LpFastClkConfig, +/// ) { /// todo!() /// } /// -/// // TIMG0_FUNCTION_CLOCK +/// // LP_SLOW_CLK /// -/// fn enable_timg0_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { +/// fn enable_lp_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) { /// todo!() /// } /// -/// fn configure_timg0_function_clock_impl( +/// fn configure_lp_slow_clk_impl( /// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Timg0FunctionClockConfig, +/// _old_config: Option, +/// _new_config: LpSlowClkConfig, /// ) { /// todo!() /// } /// -/// // TIMG1_FUNCTION_CLOCK -/// -/// fn enable_timg1_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() +/// impl TimgInstance { +/// // TIMG_FUNCTION_CLOCK +/// +/// fn enable_function_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_function_clock_impl( +/// self, +/// _clocks: &mut ClockTree, +/// _old_config: Option, +/// _new_config: TimgFunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // TIMG_WDT_CLOCK +/// +/// fn enable_wdt_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_wdt_clock_impl( +/// self, +/// _clocks: &mut ClockTree, +/// _old_config: Option, +/// _new_config: TimgWdtClockConfig, +/// ) { +/// todo!() +/// } /// } -/// -/// fn configure_timg1_function_clock_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Timg0FunctionClockConfig, -/// ) { -/// todo!() -/// } -/// -/// // UART0_FUNCTION_CLOCK -/// -/// fn enable_uart0_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// -/// fn configure_uart0_function_clock_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Uart0FunctionClockConfig, -/// ) { -/// todo!() -/// } -/// -/// // UART1_FUNCTION_CLOCK -/// -/// fn enable_uart1_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// -/// fn configure_uart1_function_clock_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Uart0FunctionClockConfig, -/// ) { -/// todo!() -/// } -/// -/// // UART2_FUNCTION_CLOCK -/// -/// fn enable_uart2_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// -/// fn configure_uart2_function_clock_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Uart0FunctionClockConfig, -/// ) { -/// todo!() -/// } -/// -/// // UART3_FUNCTION_CLOCK -/// -/// fn enable_uart3_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// -/// fn configure_uart3_function_clock_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Uart0FunctionClockConfig, -/// ) { -/// todo!() -/// } -/// -/// // UART4_FUNCTION_CLOCK -/// -/// fn enable_uart4_function_clock_impl(_clocks: &mut ClockTree, _en: bool) { -/// todo!() -/// } -/// -/// fn configure_uart4_function_clock_impl( -/// _clocks: &mut ClockTree, -/// _old_selector: Option, -/// _new_selector: Uart0FunctionClockConfig, -/// ) { -/// todo!() +/// impl UartInstance { +/// // UART_FUNCTION_CLOCK +/// +/// fn enable_function_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_function_clock_impl( +/// self, +/// _clocks: &mut ClockTree, +/// _old_config: Option, +/// _new_config: UartFunctionClockConfig, +/// ) { +/// todo!() +/// } +/// +/// // UART_BAUD_RATE_GENERATOR +/// +/// fn enable_baud_rate_generator_impl(self, _clocks: &mut ClockTree, _en: bool) { +/// todo!() +/// } +/// +/// fn configure_baud_rate_generator_impl( +/// self, +/// _clocks: &mut ClockTree, +/// _old_config: Option, +/// _new_config: UartBaudRateGeneratorConfig, +/// ) { +/// todo!() +/// } /// } /// ``` macro_rules! define_clock_tree_types { () => { - /// Selects the output frequency of `XTAL_CLK`. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum XtalClkConfig { - /// 40 MHz - _40, - } - impl XtalClkConfig { - pub fn value(&self) -> u32 { - match self { - XtalClkConfig::_40 => 40000000, - } - } - } - /// Selects the output frequency of `CPLL_CLK`. Depends on `XTAL_CLK`. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum CpllClkConfig { - /// 360 MHz - _360, - } - impl CpllClkConfig { - pub fn value(&self) -> u32 { - match self { - CpllClkConfig::_360 => 360000000, - } - } + pub enum TimgInstance { + Timg0 = 0, + Timg1 = 1, } - /// Selects the output frequency of `MPLL_CLK`. Depends on `XTAL_CLK`. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum MpllClkConfig { - /// 500 MHz - _500, - } - impl MpllClkConfig { - pub fn value(&self) -> u32 { - match self { - MpllClkConfig::_500 => 500000000, - } - } - } - /// Selects the output frequency of `SPLL_CLK`. Depends on `XTAL_CLK`. + pub enum UartInstance { + Uart0 = 0, + Uart1 = 1, + Uart2 = 2, + Uart3 = 3, + Uart4 = 4, + } + /// The list of clock signals that the `CPU_ROOT_CLK` multiplexer can output. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum SpllClkConfig { - /// 480 MHz - _480, - } - impl SpllClkConfig { - pub fn value(&self) -> u32 { - match self { - SpllClkConfig::_480 => 480000000, - } - } - } - /// Selects the output frequency of `PLL_LP_CLK`. Depends on `XTAL32K_CLK`. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum PllLpClkConfig { - /// 8 MHz - _8, - } - impl PllLpClkConfig { - pub fn value(&self) -> u32 { - match self { - PllLpClkConfig::_8 => 8000000, - } - } - } - /// The list of clock signals that the `ROOT_CLK` multiplexer can output. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum RootClkConfig { + pub enum CpuRootClkConfig { /// Selects `XTAL_CLK`. Xtal, + /// Selects `CPLL_CLK`. + Cpll, /// Selects `RC_FAST_CLK`. RcFast, - /// Selects `CPLL_CLK`. - Pll, } - /// Configures the `CPU_CLK` clock divider. + /// Configures the `CPU_CLK` clock node. /// - /// The output is calculated as `OUTPUT = ROOT_CLK / DIVISOR`. + /// The output is calculated as `OUTPUT = CPU_ROOT_CLK / (divisor + 1)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct CpuClkConfig(u32); + pub struct CpuClkConfig { + divisor: u32, + } impl CpuClkConfig { - /// Creates a new divider configuration. + /// Creates a new configuration for the CPU_CLK clock node. + /// + /// ## Panics + /// + /// Panics if the divisor value is outside the + /// valid range (0 ..= 255). pub const fn new(divisor: u32) -> Self { - Self(divisor) + ::core::assert!( + divisor <= 255, + "`CPU_CLK` divisor must be between 0 and 255 (inclusive)." + ); + Self { divisor } } - fn value(self) -> u32 { - self.0 + fn divisor(self) -> u32 { + self.divisor as u32 } } - /// Configures the `MEM_CLK` clock divider. + /// Configures the `APB_CLK` clock node. /// - /// The output is calculated as `OUTPUT = CPU_CLK / DIVISOR`. + /// The output is calculated as `OUTPUT = CPU_CLK / (divisor + 1)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct MemClkConfig(u32); - impl MemClkConfig { - /// Creates a new divider configuration. - pub const fn new(divisor: u32) -> Self { - Self(divisor) - } - fn value(self) -> u32 { - self.0 - } + pub struct ApbClkConfig { + divisor: u32, } - /// Configures the `SYS_CLK` clock divider. - /// - /// The output is calculated as `OUTPUT = MEM_CLK / DIVISOR`. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct SysClkConfig(u32); - impl SysClkConfig { - /// Creates a new divider configuration. + impl ApbClkConfig { + /// Creates a new configuration for the APB_CLK clock node. + /// + /// ## Panics + /// + /// Panics if the divisor value is outside the + /// valid range (0 ..= 255). pub const fn new(divisor: u32) -> Self { - Self(divisor) + ::core::assert!( + divisor <= 255, + "`APB_CLK` divisor must be between 0 and 255 (inclusive)." + ); + Self { divisor } } - fn value(self) -> u32 { - self.0 + fn divisor(self) -> u32 { + self.divisor as u32 } } - /// Configures the `APB_CLK` clock divider. - /// - /// The output is calculated as `OUTPUT = SYS_CLK / DIVISOR`. + /// The list of clock signals that the `LP_FAST_CLK` multiplexer can output. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct ApbClkConfig(u32); - impl ApbClkConfig { - /// Creates a new divider configuration. - pub const fn new(divisor: u32) -> Self { - Self(divisor) - } - fn value(self) -> u32 { - self.0 - } + pub enum LpFastClkConfig { + /// Selects `RC_FAST_CLK`. + RcFast, + /// Selects `XTAL_D2_CLK`. + XtalD2, } /// The list of clock signals that the `LP_SLOW_CLK` multiplexer can output. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum LpSlowClkConfig { - /// Selects `XTAL32K_CLK`. - Xtal32k, /// Selects `RC_SLOW_CLK`. RcSlow, + /// Selects `XTAL32K_CLK`. + Xtal32k, + /// Selects `RC32K_CLK`. + Rc32k, /// Selects `OSC_SLOW_CLK`. OscSlow, } - /// The list of clock signals that the `LP_FAST_CLK` multiplexer can output. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + /// The list of clock signals that the `TIMG0_FUNCTION_CLOCK` multiplexer can output. + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum LpFastClkConfig { + pub enum TimgFunctionClockConfig { + #[default] /// Selects `XTAL_CLK`. - Xtal, + XtalClk, /// Selects `RC_FAST_CLK`. - RcFast, - /// Selects `PLL_LP_CLK`. - Pll, + RcFastClk, + /// Selects `PLL_F80M`. + PllF80m, } - /// The list of clock signals that the `LP_DYN_SLOW_CLK` multiplexer can output. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + /// The list of clock signals that the `TIMG0_WDT_CLOCK` multiplexer can output. + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum LpDynSlowClkConfig { - /// Selects `LP_SLOW_CLK`. - LpSlow, - /// Selects `LP_FAST_CLK`. - LpFast, + pub enum TimgWdtClockConfig { + #[default] + /// Selects `XTAL_CLK`. + XtalClk, + /// Selects `PLL_F80M`. + PllF80m, + /// Selects `RC_FAST_CLK`. + RcFastClk, } - /// The list of clock signals that the `LP_DYN_FAST_CLK` multiplexer can output. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum LpDynFastClkConfig { - /// Selects `LP_SLOW_CLK`. - LpSlow, - /// Selects `LP_FAST_CLK`. - LpFast, + pub enum UartFunctionClockSclk { + #[default] + /// Selects `XTAL_CLK`. + Xtal, + /// Selects `PLL_F80M`. + PllF80m, + /// Selects `RC_FAST_CLK`. + RcFast, } - /// Configures the `LP_PERI_CLK` clock divider. + /// Configures the `UART0_FUNCTION_CLOCK` clock node. /// - /// The output is calculated as `OUTPUT = LP_DYN_FAST_CLK / DIVISOR`. + /// The output is calculated as `OUTPUT = sclk / (div_num + 1)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct LpPeriClkConfig(u32); - impl LpPeriClkConfig { - /// Creates a new divider configuration. + pub struct UartFunctionClockConfig { + sclk: UartFunctionClockSclk, + div_num: u32, + } + impl UartFunctionClockConfig { + /// Creates a new configuration for the FUNCTION_CLOCK clock node. /// - /// # Panics + /// ## Panics /// - /// Panics if the divisor value is outside the - /// valid range (0 ..= 31). - pub const fn new(divisor: u32) -> Self { + /// Panics if the div_num value is outside the + /// valid range (0 ..= 255). + pub const fn new(sclk: UartFunctionClockSclk, div_num: u32) -> Self { ::core::assert!( - divisor <= 31u32, - "`LP_PERI_CLK` divisor value must be between 0 and 31 (inclusive)." + div_num <= 255, + "`UART0_FUNCTION_CLOCK` div_num must be between 0 and 255 (inclusive)." ); - Self(divisor) + Self { sclk, div_num } } - fn value(self) -> u32 { - self.0 + fn sclk(self) -> UartFunctionClockSclk { + self.sclk + } + fn div_num(self) -> u32 { + self.div_num as u32 } } - /// The list of clock signals that the `TIMG0_FUNCTION_CLOCK` multiplexer can output. + /// Configures the `UART0_BAUD_RATE_GENERATOR` clock node. + /// + /// The output is calculated as `OUTPUT = (FUNCTION_CLOCK * 16) / (integral * 16 + + /// fractional)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum Timg0FunctionClockConfig { - /// Selects `PLL_F80M_CLK`. - Pll80, - /// Selects `RC_FAST_CLK`. - RcFast, - /// Selects `XTAL_CLK`. - Xtal, + pub struct UartBaudRateGeneratorConfig { + fractional: u32, + integral: u32, } - /// The list of clock signals that the `UART0_FUNCTION_CLOCK` multiplexer can output. - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum Uart0FunctionClockConfig { - /// Selects `PLL_F80M_CLK`. - Pll80, - /// Selects `RC_FAST_CLK`. - RcFast, - #[default] - /// Selects `XTAL_CLK`. - Xtal, + impl UartBaudRateGeneratorConfig { + /// Creates a new configuration for the BAUD_RATE_GENERATOR clock node. + /// + /// ## Panics + /// + /// Panics if the fractional value is outside the + /// valid range (0 ..= 15). + /// + /// Panics if the integral value is outside the + /// valid range (0 ..= 4095). + pub const fn new(fractional: u32, integral: u32) -> Self { + ::core::assert!( + fractional <= 15, + "`UART0_BAUD_RATE_GENERATOR` fractional must be between 0 and 15 (inclusive)." + ); + ::core::assert!( + integral <= 4095, + "`UART0_BAUD_RATE_GENERATOR` integral must be between 0 and 4095 (inclusive)." + ); + Self { + fractional, + integral, + } + } + fn fractional(self) -> u32 { + self.fractional as u32 + } + fn integral(self) -> u32 { + self.integral as u32 + } } /// Represents the device's clock tree. pub struct ClockTree { - xtal_clk: Option, - cpll_clk: Option, - mpll_clk: Option, - spll_clk: Option, - pll_lp_clk: Option, - root_clk: Option, + cpu_root_clk: Option, cpu_clk: Option, - mem_clk: Option, - sys_clk: Option, apb_clk: Option, - lp_slow_clk: Option, lp_fast_clk: Option, - lp_dyn_slow_clk: Option, - lp_dyn_fast_clk: Option, - lp_peri_clk: Option, - timg0_function_clock: Option, - timg1_function_clock: Option, - uart0_function_clock: Option, - uart1_function_clock: Option, - uart2_function_clock: Option, - uart3_function_clock: Option, - uart4_function_clock: Option, - rc_fast_clk_refcount: u32, - mpll_clk_refcount: u32, + lp_slow_clk: Option, + timg_function_clock: [Option; 2], + timg_wdt_clock: [Option; 2], + uart_function_clock: [Option; 5], + uart_baud_rate_generator: [Option; 5], spll_clk_refcount: u32, - xtal32k_clk_refcount: u32, + mpll_clk_refcount: u32, + rc_fast_clk_refcount: u32, + pll_f20m_refcount: u32, + pll_f80m_refcount: u32, + pll_f120m_refcount: u32, + pll_f160m_refcount: u32, + pll_f240m_refcount: u32, + pll_f25m_refcount: u32, + pll_f50m_refcount: u32, apb_clk_refcount: u32, - pll_f50m_clk_refcount: u32, - pll_f25m_clk_refcount: u32, - pll_f240m_clk_refcount: u32, - pll_f160m_clk_refcount: u32, - pll_f120m_clk_refcount: u32, - pll_f80m_clk_refcount: u32, - pll_f20m_clk_refcount: u32, - lp_peri_clk_refcount: u32, - xtal_d2_clk_refcount: u32, - timg0_function_clock_refcount: u32, - timg1_function_clock_refcount: u32, - uart0_function_clock_refcount: u32, - uart1_function_clock_refcount: u32, - uart2_function_clock_refcount: u32, - uart3_function_clock_refcount: u32, - uart4_function_clock_refcount: u32, + lp_fast_clk_refcount: u32, + lp_slow_clk_refcount: u32, + timg_function_clock_refcount: [u32; 2], + timg_wdt_clock_refcount: [u32; 2], + uart_function_clock_refcount: [u32; 5], + uart_baud_rate_generator_refcount: [u32; 5], } impl ClockTree { /// Locks the clock tree for exclusive access. pub fn with(f: impl FnOnce(&mut ClockTree) -> R) -> R { CLOCK_TREE.with(f) } - /// Returns the current configuration of the XTAL_CLK clock tree node - pub fn xtal_clk(&self) -> Option { - self.xtal_clk - } - /// Returns the current configuration of the CPLL_CLK clock tree node - pub fn cpll_clk(&self) -> Option { - self.cpll_clk - } - /// Returns the current configuration of the MPLL_CLK clock tree node - pub fn mpll_clk(&self) -> Option { - self.mpll_clk - } - /// Returns the current configuration of the SPLL_CLK clock tree node - pub fn spll_clk(&self) -> Option { - self.spll_clk - } - /// Returns the current configuration of the PLL_LP_CLK clock tree node - pub fn pll_lp_clk(&self) -> Option { - self.pll_lp_clk - } - /// Returns the current configuration of the ROOT_CLK clock tree node - pub fn root_clk(&self) -> Option { - self.root_clk + /// Returns the current configuration of the CPU_ROOT_CLK clock tree node + pub fn cpu_root_clk(&self) -> Option { + self.cpu_root_clk } /// Returns the current configuration of the CPU_CLK clock tree node pub fn cpu_clk(&self) -> Option { self.cpu_clk } - /// Returns the current configuration of the MEM_CLK clock tree node - pub fn mem_clk(&self) -> Option { - self.mem_clk - } - /// Returns the current configuration of the SYS_CLK clock tree node - pub fn sys_clk(&self) -> Option { - self.sys_clk - } /// Returns the current configuration of the APB_CLK clock tree node pub fn apb_clk(&self) -> Option { self.apb_clk } - /// Returns the current configuration of the LP_SLOW_CLK clock tree node - pub fn lp_slow_clk(&self) -> Option { - self.lp_slow_clk - } /// Returns the current configuration of the LP_FAST_CLK clock tree node pub fn lp_fast_clk(&self) -> Option { self.lp_fast_clk } - /// Returns the current configuration of the LP_DYN_SLOW_CLK clock tree node - pub fn lp_dyn_slow_clk(&self) -> Option { - self.lp_dyn_slow_clk - } - /// Returns the current configuration of the LP_DYN_FAST_CLK clock tree node - pub fn lp_dyn_fast_clk(&self) -> Option { - self.lp_dyn_fast_clk - } - /// Returns the current configuration of the LP_PERI_CLK clock tree node - pub fn lp_peri_clk(&self) -> Option { - self.lp_peri_clk + /// Returns the current configuration of the LP_SLOW_CLK clock tree node + pub fn lp_slow_clk(&self) -> Option { + self.lp_slow_clk } /// Returns the current configuration of the TIMG0_FUNCTION_CLOCK clock tree node - pub fn timg0_function_clock(&self) -> Option { - self.timg0_function_clock + pub fn timg0_function_clock(&self) -> Option { + self.timg_function_clock[TimgInstance::Timg0 as usize] + } + /// Returns the current configuration of the TIMG0_WDT_CLOCK clock tree node + pub fn timg0_wdt_clock(&self) -> Option { + self.timg_wdt_clock[TimgInstance::Timg0 as usize] } /// Returns the current configuration of the TIMG1_FUNCTION_CLOCK clock tree node - pub fn timg1_function_clock(&self) -> Option { - self.timg1_function_clock + pub fn timg1_function_clock(&self) -> Option { + self.timg_function_clock[TimgInstance::Timg1 as usize] + } + /// Returns the current configuration of the TIMG1_WDT_CLOCK clock tree node + pub fn timg1_wdt_clock(&self) -> Option { + self.timg_wdt_clock[TimgInstance::Timg1 as usize] } /// Returns the current configuration of the UART0_FUNCTION_CLOCK clock tree node - pub fn uart0_function_clock(&self) -> Option { - self.uart0_function_clock + pub fn uart0_function_clock(&self) -> Option { + self.uart_function_clock[UartInstance::Uart0 as usize] + } + /// Returns the current configuration of the UART0_BAUD_RATE_GENERATOR clock tree node + pub fn uart0_baud_rate_generator(&self) -> Option { + self.uart_baud_rate_generator[UartInstance::Uart0 as usize] } /// Returns the current configuration of the UART1_FUNCTION_CLOCK clock tree node - pub fn uart1_function_clock(&self) -> Option { - self.uart1_function_clock + pub fn uart1_function_clock(&self) -> Option { + self.uart_function_clock[UartInstance::Uart1 as usize] + } + /// Returns the current configuration of the UART1_BAUD_RATE_GENERATOR clock tree node + pub fn uart1_baud_rate_generator(&self) -> Option { + self.uart_baud_rate_generator[UartInstance::Uart1 as usize] } /// Returns the current configuration of the UART2_FUNCTION_CLOCK clock tree node - pub fn uart2_function_clock(&self) -> Option { - self.uart2_function_clock + pub fn uart2_function_clock(&self) -> Option { + self.uart_function_clock[UartInstance::Uart2 as usize] + } + /// Returns the current configuration of the UART2_BAUD_RATE_GENERATOR clock tree node + pub fn uart2_baud_rate_generator(&self) -> Option { + self.uart_baud_rate_generator[UartInstance::Uart2 as usize] } /// Returns the current configuration of the UART3_FUNCTION_CLOCK clock tree node - pub fn uart3_function_clock(&self) -> Option { - self.uart3_function_clock + pub fn uart3_function_clock(&self) -> Option { + self.uart_function_clock[UartInstance::Uart3 as usize] + } + /// Returns the current configuration of the UART3_BAUD_RATE_GENERATOR clock tree node + pub fn uart3_baud_rate_generator(&self) -> Option { + self.uart_baud_rate_generator[UartInstance::Uart3 as usize] } /// Returns the current configuration of the UART4_FUNCTION_CLOCK clock tree node - pub fn uart4_function_clock(&self) -> Option { - self.uart4_function_clock + pub fn uart4_function_clock(&self) -> Option { + self.uart_function_clock[UartInstance::Uart4 as usize] + } + /// Returns the current configuration of the UART4_BAUD_RATE_GENERATOR clock tree node + pub fn uart4_baud_rate_generator(&self) -> Option { + self.uart_baud_rate_generator[UartInstance::Uart4 as usize] } } static CLOCK_TREE: ::esp_sync::NonReentrantMutex = ::esp_sync::NonReentrantMutex::new(ClockTree { - xtal_clk: None, - cpll_clk: None, - mpll_clk: None, - spll_clk: None, - pll_lp_clk: None, - root_clk: None, + cpu_root_clk: None, cpu_clk: None, - mem_clk: None, - sys_clk: None, apb_clk: None, - lp_slow_clk: None, lp_fast_clk: None, - lp_dyn_slow_clk: None, - lp_dyn_fast_clk: None, - lp_peri_clk: None, - timg0_function_clock: None, - timg1_function_clock: None, - uart0_function_clock: None, - uart1_function_clock: None, - uart2_function_clock: None, - uart3_function_clock: None, - uart4_function_clock: None, - rc_fast_clk_refcount: 0, - mpll_clk_refcount: 0, + lp_slow_clk: None, + timg_function_clock: [None; 2], + timg_wdt_clock: [None; 2], + uart_function_clock: [None; 5], + uart_baud_rate_generator: [None; 5], spll_clk_refcount: 0, - xtal32k_clk_refcount: 0, + mpll_clk_refcount: 0, + rc_fast_clk_refcount: 0, + pll_f20m_refcount: 0, + pll_f80m_refcount: 0, + pll_f120m_refcount: 0, + pll_f160m_refcount: 0, + pll_f240m_refcount: 0, + pll_f25m_refcount: 0, + pll_f50m_refcount: 0, apb_clk_refcount: 0, - pll_f50m_clk_refcount: 0, - pll_f25m_clk_refcount: 0, - pll_f240m_clk_refcount: 0, - pll_f160m_clk_refcount: 0, - pll_f120m_clk_refcount: 0, - pll_f80m_clk_refcount: 0, - pll_f20m_clk_refcount: 0, - lp_peri_clk_refcount: 0, - xtal_d2_clk_refcount: 0, - timg0_function_clock_refcount: 0, - timg1_function_clock_refcount: 0, - uart0_function_clock_refcount: 0, - uart1_function_clock_refcount: 0, - uart2_function_clock_refcount: 0, - uart3_function_clock_refcount: 0, - uart4_function_clock_refcount: 0, + lp_fast_clk_refcount: 0, + lp_slow_clk_refcount: 0, + timg_function_clock_refcount: [0; 2], + timg_wdt_clock_refcount: [0; 2], + uart_function_clock_refcount: [0; 5], + uart_baud_rate_generator_refcount: [0; 5], }); - pub fn configure_xtal_clk(clocks: &mut ClockTree, config: XtalClkConfig) { - clocks.xtal_clk = Some(config); - configure_xtal_clk_impl(clocks, config); - } fn request_xtal_clk(_clocks: &mut ClockTree) {} fn release_xtal_clk(_clocks: &mut ClockTree) {} pub fn xtal_clk_frequency(clocks: &mut ClockTree) -> u32 { - unwrap!(clocks.xtal_clk).value() - } - pub fn configure_cpll_clk(clocks: &mut ClockTree, config: CpllClkConfig) { - clocks.cpll_clk = Some(config); - configure_cpll_clk_impl(clocks, config); + 40000000 } pub fn request_cpll_clk(clocks: &mut ClockTree) { trace!("Requesting CPLL_CLK"); @@ -933,28 +1308,26 @@ macro_rules! define_clock_tree_types { release_xtal_clk(clocks); } pub fn cpll_clk_frequency(clocks: &mut ClockTree) -> u32 { - unwrap!(clocks.cpll_clk).value() + 400000000 } - pub fn request_rc_fast_clk(clocks: &mut ClockTree) { - trace!("Requesting RC_FAST_CLK"); - if increment_reference_count(&mut clocks.rc_fast_clk_refcount) { - trace!("Enabling RC_FAST_CLK"); - enable_rc_fast_clk_impl(clocks, true); + pub fn request_spll_clk(clocks: &mut ClockTree) { + trace!("Requesting SPLL_CLK"); + if increment_reference_count(&mut clocks.spll_clk_refcount) { + trace!("Enabling SPLL_CLK"); + request_xtal_clk(clocks); + enable_spll_clk_impl(clocks, true); } } - pub fn release_rc_fast_clk(clocks: &mut ClockTree) { - trace!("Releasing RC_FAST_CLK"); - if decrement_reference_count(&mut clocks.rc_fast_clk_refcount) { - trace!("Disabling RC_FAST_CLK"); - enable_rc_fast_clk_impl(clocks, false); + pub fn release_spll_clk(clocks: &mut ClockTree) { + trace!("Releasing SPLL_CLK"); + if decrement_reference_count(&mut clocks.spll_clk_refcount) { + trace!("Disabling SPLL_CLK"); + enable_spll_clk_impl(clocks, false); + release_xtal_clk(clocks); } } - pub fn rc_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { - 20000000 - } - pub fn configure_mpll_clk(clocks: &mut ClockTree, config: MpllClkConfig) { - clocks.mpll_clk = Some(config); - configure_mpll_clk_impl(clocks, config); + pub fn spll_clk_frequency(clocks: &mut ClockTree) -> u32 { + 480000000 } pub fn request_mpll_clk(clocks: &mut ClockTree) { trace!("Requesting MPLL_CLK"); @@ -973,61 +1346,38 @@ macro_rules! define_clock_tree_types { } } pub fn mpll_clk_frequency(clocks: &mut ClockTree) -> u32 { - unwrap!(clocks.mpll_clk).value() - } - pub fn configure_spll_clk(clocks: &mut ClockTree, config: SpllClkConfig) { - clocks.spll_clk = Some(config); - configure_spll_clk_impl(clocks, config); + 400000000 } - pub fn request_spll_clk(clocks: &mut ClockTree) { - trace!("Requesting SPLL_CLK"); - if increment_reference_count(&mut clocks.spll_clk_refcount) { - trace!("Enabling SPLL_CLK"); - request_xtal_clk(clocks); - enable_spll_clk_impl(clocks, true); + pub fn request_rc_fast_clk(clocks: &mut ClockTree) { + trace!("Requesting RC_FAST_CLK"); + if increment_reference_count(&mut clocks.rc_fast_clk_refcount) { + trace!("Enabling RC_FAST_CLK"); + enable_rc_fast_clk_impl(clocks, true); } } - pub fn release_spll_clk(clocks: &mut ClockTree) { - trace!("Releasing SPLL_CLK"); - if decrement_reference_count(&mut clocks.spll_clk_refcount) { - trace!("Disabling SPLL_CLK"); - enable_spll_clk_impl(clocks, false); - release_xtal_clk(clocks); + pub fn release_rc_fast_clk(clocks: &mut ClockTree) { + trace!("Releasing RC_FAST_CLK"); + if decrement_reference_count(&mut clocks.rc_fast_clk_refcount) { + trace!("Disabling RC_FAST_CLK"); + enable_rc_fast_clk_impl(clocks, false); } } - pub fn spll_clk_frequency(clocks: &mut ClockTree) -> u32 { - unwrap!(clocks.spll_clk).value() + pub fn rc_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { + 20000000 } pub fn request_xtal32k_clk(clocks: &mut ClockTree) { trace!("Requesting XTAL32K_CLK"); - if increment_reference_count(&mut clocks.xtal32k_clk_refcount) { - trace!("Enabling XTAL32K_CLK"); - enable_xtal32k_clk_impl(clocks, true); - } + trace!("Enabling XTAL32K_CLK"); + enable_xtal32k_clk_impl(clocks, true); } pub fn release_xtal32k_clk(clocks: &mut ClockTree) { trace!("Releasing XTAL32K_CLK"); - if decrement_reference_count(&mut clocks.xtal32k_clk_refcount) { - trace!("Disabling XTAL32K_CLK"); - enable_xtal32k_clk_impl(clocks, false); - } + trace!("Disabling XTAL32K_CLK"); + enable_xtal32k_clk_impl(clocks, false); } pub fn xtal32k_clk_frequency(clocks: &mut ClockTree) -> u32 { 32768 } - pub fn request_rc_slow_clk(clocks: &mut ClockTree) { - trace!("Requesting RC_SLOW_CLK"); - trace!("Enabling RC_SLOW_CLK"); - enable_rc_slow_clk_impl(clocks, true); - } - pub fn release_rc_slow_clk(clocks: &mut ClockTree) { - trace!("Releasing RC_SLOW_CLK"); - trace!("Disabling RC_SLOW_CLK"); - enable_rc_slow_clk_impl(clocks, false); - } - pub fn rc_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { - 150000 - } pub fn request_osc_slow_clk(clocks: &mut ClockTree) { trace!("Requesting OSC_SLOW_CLK"); trace!("Enabling OSC_SLOW_CLK"); @@ -1041,775 +1391,707 @@ macro_rules! define_clock_tree_types { pub fn osc_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { 32768 } - pub fn configure_pll_lp_clk(clocks: &mut ClockTree, config: PllLpClkConfig) { - clocks.pll_lp_clk = Some(config); - configure_pll_lp_clk_impl(clocks, config); - } - pub fn request_pll_lp_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_LP_CLK"); - trace!("Enabling PLL_LP_CLK"); - request_xtal32k_clk(clocks); - enable_pll_lp_clk_impl(clocks, true); - } - pub fn release_pll_lp_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_LP_CLK"); - trace!("Disabling PLL_LP_CLK"); - enable_pll_lp_clk_impl(clocks, false); - release_xtal32k_clk(clocks); - } - pub fn pll_lp_clk_frequency(clocks: &mut ClockTree) -> u32 { - unwrap!(clocks.pll_lp_clk).value() - } - pub fn configure_root_clk(clocks: &mut ClockTree, new_selector: RootClkConfig) { - let old_selector = clocks.root_clk.replace(new_selector); - match new_selector { - RootClkConfig::Xtal => request_xtal_clk(clocks), - RootClkConfig::RcFast => request_rc_fast_clk(clocks), - RootClkConfig::Pll => request_cpll_clk(clocks), - } - configure_root_clk_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - RootClkConfig::Xtal => release_xtal_clk(clocks), - RootClkConfig::RcFast => release_rc_fast_clk(clocks), - RootClkConfig::Pll => release_cpll_clk(clocks), - } - } - } - fn request_root_clk(_clocks: &mut ClockTree) {} - fn release_root_clk(_clocks: &mut ClockTree) {} - pub fn root_clk_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.root_clk) { - RootClkConfig::Xtal => xtal_clk_frequency(clocks), - RootClkConfig::RcFast => rc_fast_clk_frequency(clocks), - RootClkConfig::Pll => cpll_clk_frequency(clocks), - } - } - pub fn configure_cpu_clk(clocks: &mut ClockTree, config: CpuClkConfig) { - clocks.cpu_clk = Some(config); - configure_cpu_clk_impl(clocks, config); - } - pub fn request_cpu_clk(clocks: &mut ClockTree) { - trace!("Requesting CPU_CLK"); - trace!("Enabling CPU_CLK"); - request_root_clk(clocks); - enable_cpu_clk_impl(clocks, true); + pub fn request_rc_slow_clk(clocks: &mut ClockTree) { + trace!("Requesting RC_SLOW_CLK"); + trace!("Enabling RC_SLOW_CLK"); + enable_rc_slow_clk_impl(clocks, true); } - pub fn release_cpu_clk(clocks: &mut ClockTree) { - trace!("Releasing CPU_CLK"); - trace!("Disabling CPU_CLK"); - enable_cpu_clk_impl(clocks, false); - release_root_clk(clocks); + pub fn release_rc_slow_clk(clocks: &mut ClockTree) { + trace!("Releasing RC_SLOW_CLK"); + trace!("Disabling RC_SLOW_CLK"); + enable_rc_slow_clk_impl(clocks, false); } - pub fn cpu_clk_frequency(clocks: &mut ClockTree) -> u32 { - (root_clk_frequency(clocks) / unwrap!(clocks.cpu_clk).value()) - } - pub fn configure_mem_clk(clocks: &mut ClockTree, config: MemClkConfig) { - clocks.mem_clk = Some(config); - configure_mem_clk_impl(clocks, config); - } - pub fn request_mem_clk(clocks: &mut ClockTree) { - trace!("Requesting MEM_CLK"); - trace!("Enabling MEM_CLK"); - request_cpu_clk(clocks); - enable_mem_clk_impl(clocks, true); - } - pub fn release_mem_clk(clocks: &mut ClockTree) { - trace!("Releasing MEM_CLK"); - trace!("Disabling MEM_CLK"); - enable_mem_clk_impl(clocks, false); - release_cpu_clk(clocks); - } - pub fn mem_clk_frequency(clocks: &mut ClockTree) -> u32 { - (cpu_clk_frequency(clocks) / unwrap!(clocks.mem_clk).value()) - } - pub fn configure_sys_clk(clocks: &mut ClockTree, config: SysClkConfig) { - clocks.sys_clk = Some(config); - configure_sys_clk_impl(clocks, config); - } - pub fn request_sys_clk(clocks: &mut ClockTree) { - trace!("Requesting SYS_CLK"); - trace!("Enabling SYS_CLK"); - request_mem_clk(clocks); - enable_sys_clk_impl(clocks, true); - } - pub fn release_sys_clk(clocks: &mut ClockTree) { - trace!("Releasing SYS_CLK"); - trace!("Disabling SYS_CLK"); - enable_sys_clk_impl(clocks, false); - release_mem_clk(clocks); - } - pub fn sys_clk_frequency(clocks: &mut ClockTree) -> u32 { - (mem_clk_frequency(clocks) / unwrap!(clocks.sys_clk).value()) + pub fn rc_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { + 136000 } - pub fn configure_apb_clk(clocks: &mut ClockTree, config: ApbClkConfig) { - clocks.apb_clk = Some(config); - configure_apb_clk_impl(clocks, config); + pub fn request_rc32k_clk(clocks: &mut ClockTree) { + trace!("Requesting RC32K_CLK"); + trace!("Enabling RC32K_CLK"); + enable_rc32k_clk_impl(clocks, true); } - pub fn request_apb_clk(clocks: &mut ClockTree) { - trace!("Requesting APB_CLK"); - if increment_reference_count(&mut clocks.apb_clk_refcount) { - trace!("Enabling APB_CLK"); - request_sys_clk(clocks); - enable_apb_clk_impl(clocks, true); - } + pub fn release_rc32k_clk(clocks: &mut ClockTree) { + trace!("Releasing RC32K_CLK"); + trace!("Disabling RC32K_CLK"); + enable_rc32k_clk_impl(clocks, false); } - pub fn release_apb_clk(clocks: &mut ClockTree) { - trace!("Releasing APB_CLK"); - if decrement_reference_count(&mut clocks.apb_clk_refcount) { - trace!("Disabling APB_CLK"); - enable_apb_clk_impl(clocks, false); - release_sys_clk(clocks); - } - } - pub fn apb_clk_frequency(clocks: &mut ClockTree) -> u32 { - (sys_clk_frequency(clocks) / unwrap!(clocks.apb_clk).value()) + pub fn rc32k_clk_frequency(clocks: &mut ClockTree) -> u32 { + 32768 } - pub fn request_pll_f50m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F50M_CLK"); - if increment_reference_count(&mut clocks.pll_f50m_clk_refcount) { - trace!("Enabling PLL_F50M_CLK"); - request_mpll_clk(clocks); - enable_pll_f50m_clk_impl(clocks, true); + pub fn request_pll_f20m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F20M"); + if increment_reference_count(&mut clocks.pll_f20m_refcount) { + trace!("Enabling PLL_F20M"); + request_spll_clk(clocks); + enable_pll_f20m_impl(clocks, true); } } - pub fn release_pll_f50m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F50M_CLK"); - if decrement_reference_count(&mut clocks.pll_f50m_clk_refcount) { - trace!("Disabling PLL_F50M_CLK"); - enable_pll_f50m_clk_impl(clocks, false); - release_mpll_clk(clocks); + pub fn release_pll_f20m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F20M"); + if decrement_reference_count(&mut clocks.pll_f20m_refcount) { + trace!("Disabling PLL_F20M"); + enable_pll_f20m_impl(clocks, false); + release_spll_clk(clocks); } } - pub fn pll_f50m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 50000000 + pub fn pll_f20m_frequency(clocks: &mut ClockTree) -> u32 { + (spll_clk_frequency(clocks) / 24) } - pub fn request_pll_f25m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F25M_CLK"); - if increment_reference_count(&mut clocks.pll_f25m_clk_refcount) { - trace!("Enabling PLL_F25M_CLK"); - request_mpll_clk(clocks); - enable_pll_f25m_clk_impl(clocks, true); + pub fn request_pll_f80m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F80M"); + if increment_reference_count(&mut clocks.pll_f80m_refcount) { + trace!("Enabling PLL_F80M"); + request_spll_clk(clocks); + enable_pll_f80m_impl(clocks, true); } } - pub fn release_pll_f25m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F25M_CLK"); - if decrement_reference_count(&mut clocks.pll_f25m_clk_refcount) { - trace!("Disabling PLL_F25M_CLK"); - enable_pll_f25m_clk_impl(clocks, false); - release_mpll_clk(clocks); + pub fn release_pll_f80m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F80M"); + if decrement_reference_count(&mut clocks.pll_f80m_refcount) { + trace!("Disabling PLL_F80M"); + enable_pll_f80m_impl(clocks, false); + release_spll_clk(clocks); } } - pub fn pll_f25m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 25000000 + pub fn pll_f80m_frequency(clocks: &mut ClockTree) -> u32 { + (spll_clk_frequency(clocks) / 6) } - pub fn request_pll_f240m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F240M_CLK"); - if increment_reference_count(&mut clocks.pll_f240m_clk_refcount) { - trace!("Enabling PLL_F240M_CLK"); + pub fn request_pll_f120m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F120M"); + if increment_reference_count(&mut clocks.pll_f120m_refcount) { + trace!("Enabling PLL_F120M"); request_spll_clk(clocks); - enable_pll_f240m_clk_impl(clocks, true); + enable_pll_f120m_impl(clocks, true); } } - pub fn release_pll_f240m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F240M_CLK"); - if decrement_reference_count(&mut clocks.pll_f240m_clk_refcount) { - trace!("Disabling PLL_F240M_CLK"); - enable_pll_f240m_clk_impl(clocks, false); + pub fn release_pll_f120m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F120M"); + if decrement_reference_count(&mut clocks.pll_f120m_refcount) { + trace!("Disabling PLL_F120M"); + enable_pll_f120m_impl(clocks, false); release_spll_clk(clocks); } } - pub fn pll_f240m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 240000000 + pub fn pll_f120m_frequency(clocks: &mut ClockTree) -> u32 { + (spll_clk_frequency(clocks) / 4) } - pub fn request_pll_f160m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F160M_CLK"); - if increment_reference_count(&mut clocks.pll_f160m_clk_refcount) { - trace!("Enabling PLL_F160M_CLK"); + pub fn request_pll_f160m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F160M"); + if increment_reference_count(&mut clocks.pll_f160m_refcount) { + trace!("Enabling PLL_F160M"); request_spll_clk(clocks); - enable_pll_f160m_clk_impl(clocks, true); + enable_pll_f160m_impl(clocks, true); } } - pub fn release_pll_f160m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F160M_CLK"); - if decrement_reference_count(&mut clocks.pll_f160m_clk_refcount) { - trace!("Disabling PLL_F160M_CLK"); - enable_pll_f160m_clk_impl(clocks, false); + pub fn release_pll_f160m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F160M"); + if decrement_reference_count(&mut clocks.pll_f160m_refcount) { + trace!("Disabling PLL_F160M"); + enable_pll_f160m_impl(clocks, false); release_spll_clk(clocks); } } - pub fn pll_f160m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 160000000 + pub fn pll_f160m_frequency(clocks: &mut ClockTree) -> u32 { + (spll_clk_frequency(clocks) / 3) } - pub fn request_pll_f120m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F120M_CLK"); - if increment_reference_count(&mut clocks.pll_f120m_clk_refcount) { - trace!("Enabling PLL_F120M_CLK"); + pub fn request_pll_f240m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F240M"); + if increment_reference_count(&mut clocks.pll_f240m_refcount) { + trace!("Enabling PLL_F240M"); request_spll_clk(clocks); - enable_pll_f120m_clk_impl(clocks, true); + enable_pll_f240m_impl(clocks, true); } } - pub fn release_pll_f120m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F120M_CLK"); - if decrement_reference_count(&mut clocks.pll_f120m_clk_refcount) { - trace!("Disabling PLL_F120M_CLK"); - enable_pll_f120m_clk_impl(clocks, false); + pub fn release_pll_f240m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F240M"); + if decrement_reference_count(&mut clocks.pll_f240m_refcount) { + trace!("Disabling PLL_F240M"); + enable_pll_f240m_impl(clocks, false); release_spll_clk(clocks); } } - pub fn pll_f120m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 120000000 + pub fn pll_f240m_frequency(clocks: &mut ClockTree) -> u32 { + (spll_clk_frequency(clocks) / 2) } - pub fn request_pll_f80m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F80M_CLK"); - if increment_reference_count(&mut clocks.pll_f80m_clk_refcount) { - trace!("Enabling PLL_F80M_CLK"); - request_spll_clk(clocks); - enable_pll_f80m_clk_impl(clocks, true); + pub fn request_pll_f25m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F25M"); + if increment_reference_count(&mut clocks.pll_f25m_refcount) { + trace!("Enabling PLL_F25M"); + request_mpll_clk(clocks); + enable_pll_f25m_impl(clocks, true); } } - pub fn release_pll_f80m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F80M_CLK"); - if decrement_reference_count(&mut clocks.pll_f80m_clk_refcount) { - trace!("Disabling PLL_F80M_CLK"); - enable_pll_f80m_clk_impl(clocks, false); - release_spll_clk(clocks); + pub fn release_pll_f25m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F25M"); + if decrement_reference_count(&mut clocks.pll_f25m_refcount) { + trace!("Disabling PLL_F25M"); + enable_pll_f25m_impl(clocks, false); + release_mpll_clk(clocks); } } - pub fn pll_f80m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 80000000 + pub fn pll_f25m_frequency(clocks: &mut ClockTree) -> u32 { + (mpll_clk_frequency(clocks) / 16) } - pub fn request_pll_f20m_clk(clocks: &mut ClockTree) { - trace!("Requesting PLL_F20M_CLK"); - if increment_reference_count(&mut clocks.pll_f20m_clk_refcount) { - trace!("Enabling PLL_F20M_CLK"); - request_spll_clk(clocks); - enable_pll_f20m_clk_impl(clocks, true); + pub fn request_pll_f50m(clocks: &mut ClockTree) { + trace!("Requesting PLL_F50M"); + if increment_reference_count(&mut clocks.pll_f50m_refcount) { + trace!("Enabling PLL_F50M"); + request_mpll_clk(clocks); + enable_pll_f50m_impl(clocks, true); } } - pub fn release_pll_f20m_clk(clocks: &mut ClockTree) { - trace!("Releasing PLL_F20M_CLK"); - if decrement_reference_count(&mut clocks.pll_f20m_clk_refcount) { - trace!("Disabling PLL_F20M_CLK"); - enable_pll_f20m_clk_impl(clocks, false); - release_spll_clk(clocks); + pub fn release_pll_f50m(clocks: &mut ClockTree) { + trace!("Releasing PLL_F50M"); + if decrement_reference_count(&mut clocks.pll_f50m_refcount) { + trace!("Disabling PLL_F50M"); + enable_pll_f50m_impl(clocks, false); + release_mpll_clk(clocks); } } - pub fn pll_f20m_clk_frequency(clocks: &mut ClockTree) -> u32 { - 20000000 + pub fn pll_f50m_frequency(clocks: &mut ClockTree) -> u32 { + (mpll_clk_frequency(clocks) / 8) } - pub fn configure_lp_slow_clk(clocks: &mut ClockTree, new_selector: LpSlowClkConfig) { - let old_selector = clocks.lp_slow_clk.replace(new_selector); - match new_selector { - LpSlowClkConfig::Xtal32k => request_xtal32k_clk(clocks), - LpSlowClkConfig::RcSlow => request_rc_slow_clk(clocks), - LpSlowClkConfig::OscSlow => request_osc_slow_clk(clocks), - } - configure_lp_slow_clk_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - LpSlowClkConfig::Xtal32k => release_xtal32k_clk(clocks), - LpSlowClkConfig::RcSlow => release_rc_slow_clk(clocks), - LpSlowClkConfig::OscSlow => release_osc_slow_clk(clocks), - } - } + pub fn request_xtal_d2_clk(clocks: &mut ClockTree) { + trace!("Requesting XTAL_D2_CLK"); + trace!("Enabling XTAL_D2_CLK"); + request_xtal_clk(clocks); + enable_xtal_d2_clk_impl(clocks, true); } - fn request_lp_slow_clk(_clocks: &mut ClockTree) {} - fn release_lp_slow_clk(_clocks: &mut ClockTree) {} - pub fn lp_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.lp_slow_clk) { - LpSlowClkConfig::Xtal32k => xtal32k_clk_frequency(clocks), - LpSlowClkConfig::RcSlow => rc_slow_clk_frequency(clocks), - LpSlowClkConfig::OscSlow => osc_slow_clk_frequency(clocks), - } + pub fn release_xtal_d2_clk(clocks: &mut ClockTree) { + trace!("Releasing XTAL_D2_CLK"); + trace!("Disabling XTAL_D2_CLK"); + enable_xtal_d2_clk_impl(clocks, false); + release_xtal_clk(clocks); } - pub fn configure_lp_fast_clk(clocks: &mut ClockTree, new_selector: LpFastClkConfig) { - let old_selector = clocks.lp_fast_clk.replace(new_selector); + pub fn xtal_d2_clk_frequency(clocks: &mut ClockTree) -> u32 { + (xtal_clk_frequency(clocks) / 2) + } + pub fn configure_cpu_root_clk(clocks: &mut ClockTree, new_selector: CpuRootClkConfig) { + let old_selector = clocks.cpu_root_clk.replace(new_selector); match new_selector { - LpFastClkConfig::Xtal => request_xtal_clk(clocks), - LpFastClkConfig::RcFast => request_rc_fast_clk(clocks), - LpFastClkConfig::Pll => request_pll_lp_clk(clocks), + CpuRootClkConfig::Xtal => request_xtal_clk(clocks), + CpuRootClkConfig::Cpll => request_cpll_clk(clocks), + CpuRootClkConfig::RcFast => request_rc_fast_clk(clocks), } - configure_lp_fast_clk_impl(clocks, old_selector, new_selector); + configure_cpu_root_clk_impl(clocks, old_selector, new_selector); if let Some(old_selector) = old_selector { match old_selector { - LpFastClkConfig::Xtal => release_xtal_clk(clocks), - LpFastClkConfig::RcFast => release_rc_fast_clk(clocks), - LpFastClkConfig::Pll => release_pll_lp_clk(clocks), + CpuRootClkConfig::Xtal => release_xtal_clk(clocks), + CpuRootClkConfig::Cpll => release_cpll_clk(clocks), + CpuRootClkConfig::RcFast => release_rc_fast_clk(clocks), } } } - fn request_lp_fast_clk(_clocks: &mut ClockTree) {} - fn release_lp_fast_clk(_clocks: &mut ClockTree) {} - pub fn lp_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.lp_fast_clk) { - LpFastClkConfig::Xtal => xtal_clk_frequency(clocks), - LpFastClkConfig::RcFast => rc_fast_clk_frequency(clocks), - LpFastClkConfig::Pll => pll_lp_clk_frequency(clocks), - } + pub fn cpu_root_clk_config(clocks: &mut ClockTree) -> Option { + clocks.cpu_root_clk } - pub fn configure_lp_dyn_slow_clk(clocks: &mut ClockTree, new_selector: LpDynSlowClkConfig) { - let old_selector = clocks.lp_dyn_slow_clk.replace(new_selector); - match new_selector { - LpDynSlowClkConfig::LpSlow => request_lp_slow_clk(clocks), - LpDynSlowClkConfig::LpFast => request_lp_fast_clk(clocks), - } - configure_lp_dyn_slow_clk_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - LpDynSlowClkConfig::LpSlow => release_lp_slow_clk(clocks), - LpDynSlowClkConfig::LpFast => release_lp_fast_clk(clocks), - } + pub fn request_cpu_root_clk(clocks: &mut ClockTree) { + trace!("Requesting CPU_ROOT_CLK"); + trace!("Enabling CPU_ROOT_CLK"); + match unwrap!(clocks.cpu_root_clk) { + CpuRootClkConfig::Xtal => request_xtal_clk(clocks), + CpuRootClkConfig::Cpll => request_cpll_clk(clocks), + CpuRootClkConfig::RcFast => request_rc_fast_clk(clocks), } + enable_cpu_root_clk_impl(clocks, true); } - fn request_lp_dyn_slow_clk(_clocks: &mut ClockTree) {} - fn release_lp_dyn_slow_clk(_clocks: &mut ClockTree) {} - pub fn lp_dyn_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.lp_dyn_slow_clk) { - LpDynSlowClkConfig::LpSlow => lp_slow_clk_frequency(clocks), - LpDynSlowClkConfig::LpFast => lp_fast_clk_frequency(clocks), + pub fn release_cpu_root_clk(clocks: &mut ClockTree) { + trace!("Releasing CPU_ROOT_CLK"); + trace!("Disabling CPU_ROOT_CLK"); + enable_cpu_root_clk_impl(clocks, false); + match unwrap!(clocks.cpu_root_clk) { + CpuRootClkConfig::Xtal => release_xtal_clk(clocks), + CpuRootClkConfig::Cpll => release_cpll_clk(clocks), + CpuRootClkConfig::RcFast => release_rc_fast_clk(clocks), } } - pub fn configure_lp_dyn_fast_clk(clocks: &mut ClockTree, new_selector: LpDynFastClkConfig) { - let old_selector = clocks.lp_dyn_fast_clk.replace(new_selector); - match new_selector { - LpDynFastClkConfig::LpSlow => request_lp_slow_clk(clocks), - LpDynFastClkConfig::LpFast => request_lp_fast_clk(clocks), - } - configure_lp_dyn_fast_clk_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - LpDynFastClkConfig::LpSlow => release_lp_slow_clk(clocks), - LpDynFastClkConfig::LpFast => release_lp_fast_clk(clocks), - } + #[allow(unused_variables)] + pub fn cpu_root_clk_config_frequency( + clocks: &mut ClockTree, + config: CpuRootClkConfig, + ) -> u32 { + match config { + CpuRootClkConfig::Xtal => xtal_clk_frequency(clocks), + CpuRootClkConfig::Cpll => cpll_clk_frequency(clocks), + CpuRootClkConfig::RcFast => rc_fast_clk_frequency(clocks), } } - fn request_lp_dyn_fast_clk(_clocks: &mut ClockTree) {} - fn release_lp_dyn_fast_clk(_clocks: &mut ClockTree) {} - pub fn lp_dyn_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.lp_dyn_fast_clk) { - LpDynFastClkConfig::LpSlow => lp_slow_clk_frequency(clocks), - LpDynFastClkConfig::LpFast => lp_fast_clk_frequency(clocks), + pub fn cpu_root_clk_frequency(clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.cpu_root_clk { + cpu_root_clk_config_frequency(clocks, config) + } else { + 0 } } - pub fn configure_lp_peri_clk(clocks: &mut ClockTree, config: LpPeriClkConfig) { - clocks.lp_peri_clk = Some(config); - configure_lp_peri_clk_impl(clocks, config); + pub fn configure_cpu_clk(clocks: &mut ClockTree, config: CpuClkConfig) { + let old_config = clocks.cpu_clk.replace(config); + configure_cpu_clk_impl(clocks, old_config, config); } - pub fn request_lp_peri_clk(clocks: &mut ClockTree) { - trace!("Requesting LP_PERI_CLK"); - if increment_reference_count(&mut clocks.lp_peri_clk_refcount) { - trace!("Enabling LP_PERI_CLK"); - request_lp_dyn_fast_clk(clocks); - enable_lp_peri_clk_impl(clocks, true); - } + pub fn cpu_clk_config(clocks: &mut ClockTree) -> Option { + clocks.cpu_clk } - pub fn release_lp_peri_clk(clocks: &mut ClockTree) { - trace!("Releasing LP_PERI_CLK"); - if decrement_reference_count(&mut clocks.lp_peri_clk_refcount) { - trace!("Disabling LP_PERI_CLK"); - enable_lp_peri_clk_impl(clocks, false); - release_lp_dyn_fast_clk(clocks); - } + pub fn request_cpu_clk(clocks: &mut ClockTree) { + trace!("Requesting CPU_CLK"); + trace!("Enabling CPU_CLK"); + request_cpu_root_clk(clocks); + enable_cpu_clk_impl(clocks, true); } - pub fn lp_peri_clk_frequency(clocks: &mut ClockTree) -> u32 { - (lp_dyn_fast_clk_frequency(clocks) / unwrap!(clocks.lp_peri_clk).value()) + pub fn release_cpu_clk(clocks: &mut ClockTree) { + trace!("Releasing CPU_CLK"); + trace!("Disabling CPU_CLK"); + enable_cpu_clk_impl(clocks, false); + release_cpu_root_clk(clocks); } - pub fn request_xtal_d2_clk(clocks: &mut ClockTree) { - trace!("Requesting XTAL_D2_CLK"); - if increment_reference_count(&mut clocks.xtal_d2_clk_refcount) { - trace!("Enabling XTAL_D2_CLK"); - request_xtal_clk(clocks); - enable_xtal_d2_clk_impl(clocks, true); - } + #[allow(unused_variables)] + pub fn cpu_clk_config_frequency(clocks: &mut ClockTree, config: CpuClkConfig) -> u32 { + (cpu_root_clk_frequency(clocks) / (config.divisor() + 1)) } - pub fn release_xtal_d2_clk(clocks: &mut ClockTree) { - trace!("Releasing XTAL_D2_CLK"); - if decrement_reference_count(&mut clocks.xtal_d2_clk_refcount) { - trace!("Disabling XTAL_D2_CLK"); - enable_xtal_d2_clk_impl(clocks, false); - release_xtal_clk(clocks); + pub fn cpu_clk_frequency(clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.cpu_clk { + cpu_clk_config_frequency(clocks, config) + } else { + 0 } } - pub fn xtal_d2_clk_frequency(clocks: &mut ClockTree) -> u32 { - (xtal_clk_frequency(clocks) / 2) + pub fn configure_apb_clk(clocks: &mut ClockTree, config: ApbClkConfig) { + let old_config = clocks.apb_clk.replace(config); + configure_apb_clk_impl(clocks, old_config, config); } - pub fn configure_timg0_function_clock( - clocks: &mut ClockTree, - new_selector: Timg0FunctionClockConfig, - ) { - let old_selector = clocks.timg0_function_clock.replace(new_selector); - if clocks.timg0_function_clock_refcount > 0 { - match new_selector { - Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), - } - configure_timg0_function_clock_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), - } - } - } else { - configure_timg0_function_clock_impl(clocks, old_selector, new_selector); + pub fn apb_clk_config(clocks: &mut ClockTree) -> Option { + clocks.apb_clk + } + pub fn request_apb_clk(clocks: &mut ClockTree) { + trace!("Requesting APB_CLK"); + if increment_reference_count(&mut clocks.apb_clk_refcount) { + trace!("Enabling APB_CLK"); + request_cpu_clk(clocks); + enable_apb_clk_impl(clocks, true); } } - pub fn request_timg0_function_clock(clocks: &mut ClockTree) { - trace!("Requesting TIMG0_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.timg0_function_clock_refcount) { - trace!("Enabling TIMG0_FUNCTION_CLOCK"); - match unwrap!(clocks.timg0_function_clock) { - Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), - } - enable_timg0_function_clock_impl(clocks, true); - } - } - pub fn release_timg0_function_clock(clocks: &mut ClockTree) { - trace!("Releasing TIMG0_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.timg0_function_clock_refcount) { - trace!("Disabling TIMG0_FUNCTION_CLOCK"); - enable_timg0_function_clock_impl(clocks, false); - match unwrap!(clocks.timg0_function_clock) { - Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), - } + pub fn release_apb_clk(clocks: &mut ClockTree) { + trace!("Releasing APB_CLK"); + if decrement_reference_count(&mut clocks.apb_clk_refcount) { + trace!("Disabling APB_CLK"); + enable_apb_clk_impl(clocks, false); + release_cpu_clk(clocks); } } - pub fn timg0_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.timg0_function_clock) { - Timg0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Timg0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Timg0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + #[allow(unused_variables)] + pub fn apb_clk_config_frequency(clocks: &mut ClockTree, config: ApbClkConfig) -> u32 { + (cpu_clk_frequency(clocks) / (config.divisor() + 1)) + } + pub fn apb_clk_frequency(clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.apb_clk { + apb_clk_config_frequency(clocks, config) + } else { + 0 } } - pub fn configure_timg1_function_clock( - clocks: &mut ClockTree, - new_selector: Timg0FunctionClockConfig, - ) { - let old_selector = clocks.timg1_function_clock.replace(new_selector); - if clocks.timg1_function_clock_refcount > 0 { + pub fn configure_lp_fast_clk(clocks: &mut ClockTree, new_selector: LpFastClkConfig) { + let old_selector = clocks.lp_fast_clk.replace(new_selector); + if clocks.lp_fast_clk_refcount > 0 { match new_selector { - Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + LpFastClkConfig::RcFast => request_rc_fast_clk(clocks), + LpFastClkConfig::XtalD2 => request_xtal_d2_clk(clocks), } - configure_timg1_function_clock_impl(clocks, old_selector, new_selector); + configure_lp_fast_clk_impl(clocks, old_selector, new_selector); if let Some(old_selector) = old_selector { match old_selector { - Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + LpFastClkConfig::RcFast => release_rc_fast_clk(clocks), + LpFastClkConfig::XtalD2 => release_xtal_d2_clk(clocks), } } } else { - configure_timg1_function_clock_impl(clocks, old_selector, new_selector); + configure_lp_fast_clk_impl(clocks, old_selector, new_selector); } } - pub fn request_timg1_function_clock(clocks: &mut ClockTree) { - trace!("Requesting TIMG1_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.timg1_function_clock_refcount) { - trace!("Enabling TIMG1_FUNCTION_CLOCK"); - match unwrap!(clocks.timg1_function_clock) { - Timg0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => request_xtal_clk(clocks), - } - enable_timg1_function_clock_impl(clocks, true); - } - } - pub fn release_timg1_function_clock(clocks: &mut ClockTree) { - trace!("Releasing TIMG1_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.timg1_function_clock_refcount) { - trace!("Disabling TIMG1_FUNCTION_CLOCK"); - enable_timg1_function_clock_impl(clocks, false); - match unwrap!(clocks.timg1_function_clock) { - Timg0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Timg0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Timg0FunctionClockConfig::Xtal => release_xtal_clk(clocks), - } - } + pub fn lp_fast_clk_config(clocks: &mut ClockTree) -> Option { + clocks.lp_fast_clk } - pub fn timg1_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.timg1_function_clock) { - Timg0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Timg0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Timg0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + pub fn request_lp_fast_clk(clocks: &mut ClockTree) { + trace!("Requesting LP_FAST_CLK"); + if increment_reference_count(&mut clocks.lp_fast_clk_refcount) { + trace!("Enabling LP_FAST_CLK"); + match unwrap!(clocks.lp_fast_clk) { + LpFastClkConfig::RcFast => request_rc_fast_clk(clocks), + LpFastClkConfig::XtalD2 => request_xtal_d2_clk(clocks), + } + enable_lp_fast_clk_impl(clocks, true); } } - pub fn configure_uart0_function_clock( - clocks: &mut ClockTree, - new_selector: Uart0FunctionClockConfig, - ) { - let old_selector = clocks.uart0_function_clock.replace(new_selector); - if clocks.uart0_function_clock_refcount > 0 { - match new_selector { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), - } - configure_uart0_function_clock_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), - } + pub fn release_lp_fast_clk(clocks: &mut ClockTree) { + trace!("Releasing LP_FAST_CLK"); + if decrement_reference_count(&mut clocks.lp_fast_clk_refcount) { + trace!("Disabling LP_FAST_CLK"); + enable_lp_fast_clk_impl(clocks, false); + match unwrap!(clocks.lp_fast_clk) { + LpFastClkConfig::RcFast => release_rc_fast_clk(clocks), + LpFastClkConfig::XtalD2 => release_xtal_d2_clk(clocks), } - } else { - configure_uart0_function_clock_impl(clocks, old_selector, new_selector); } } - pub fn request_uart0_function_clock(clocks: &mut ClockTree) { - trace!("Requesting UART0_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.uart0_function_clock_refcount) { - trace!("Enabling UART0_FUNCTION_CLOCK"); - match unwrap!(clocks.uart0_function_clock) { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), - } - enable_uart0_function_clock_impl(clocks, true); - } - } - pub fn release_uart0_function_clock(clocks: &mut ClockTree) { - trace!("Releasing UART0_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.uart0_function_clock_refcount) { - trace!("Disabling UART0_FUNCTION_CLOCK"); - enable_uart0_function_clock_impl(clocks, false); - match unwrap!(clocks.uart0_function_clock) { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), - } + #[allow(unused_variables)] + pub fn lp_fast_clk_config_frequency( + clocks: &mut ClockTree, + config: LpFastClkConfig, + ) -> u32 { + match config { + LpFastClkConfig::RcFast => rc_fast_clk_frequency(clocks), + LpFastClkConfig::XtalD2 => xtal_d2_clk_frequency(clocks), } } - pub fn uart0_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.uart0_function_clock) { - Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + pub fn lp_fast_clk_frequency(clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.lp_fast_clk { + lp_fast_clk_config_frequency(clocks, config) + } else { + 0 } } - pub fn configure_uart1_function_clock( - clocks: &mut ClockTree, - new_selector: Uart0FunctionClockConfig, - ) { - let old_selector = clocks.uart1_function_clock.replace(new_selector); - if clocks.uart1_function_clock_refcount > 0 { + pub fn configure_lp_slow_clk(clocks: &mut ClockTree, new_selector: LpSlowClkConfig) { + let old_selector = clocks.lp_slow_clk.replace(new_selector); + if clocks.lp_slow_clk_refcount > 0 { match new_selector { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + LpSlowClkConfig::RcSlow => request_rc_slow_clk(clocks), + LpSlowClkConfig::Xtal32k => request_xtal32k_clk(clocks), + LpSlowClkConfig::Rc32k => request_rc32k_clk(clocks), + LpSlowClkConfig::OscSlow => request_osc_slow_clk(clocks), } - configure_uart1_function_clock_impl(clocks, old_selector, new_selector); + configure_lp_slow_clk_impl(clocks, old_selector, new_selector); if let Some(old_selector) = old_selector { match old_selector { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + LpSlowClkConfig::RcSlow => release_rc_slow_clk(clocks), + LpSlowClkConfig::Xtal32k => release_xtal32k_clk(clocks), + LpSlowClkConfig::Rc32k => release_rc32k_clk(clocks), + LpSlowClkConfig::OscSlow => release_osc_slow_clk(clocks), } } } else { - configure_uart1_function_clock_impl(clocks, old_selector, new_selector); + configure_lp_slow_clk_impl(clocks, old_selector, new_selector); } } - pub fn request_uart1_function_clock(clocks: &mut ClockTree) { - trace!("Requesting UART1_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.uart1_function_clock_refcount) { - trace!("Enabling UART1_FUNCTION_CLOCK"); - match unwrap!(clocks.uart1_function_clock) { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), - } - enable_uart1_function_clock_impl(clocks, true); - } - } - pub fn release_uart1_function_clock(clocks: &mut ClockTree) { - trace!("Releasing UART1_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.uart1_function_clock_refcount) { - trace!("Disabling UART1_FUNCTION_CLOCK"); - enable_uart1_function_clock_impl(clocks, false); - match unwrap!(clocks.uart1_function_clock) { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + pub fn lp_slow_clk_config(clocks: &mut ClockTree) -> Option { + clocks.lp_slow_clk + } + pub fn request_lp_slow_clk(clocks: &mut ClockTree) { + trace!("Requesting LP_SLOW_CLK"); + if increment_reference_count(&mut clocks.lp_slow_clk_refcount) { + trace!("Enabling LP_SLOW_CLK"); + match unwrap!(clocks.lp_slow_clk) { + LpSlowClkConfig::RcSlow => request_rc_slow_clk(clocks), + LpSlowClkConfig::Xtal32k => request_xtal32k_clk(clocks), + LpSlowClkConfig::Rc32k => request_rc32k_clk(clocks), + LpSlowClkConfig::OscSlow => request_osc_slow_clk(clocks), } + enable_lp_slow_clk_impl(clocks, true); } } - pub fn uart1_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.uart1_function_clock) { - Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + pub fn release_lp_slow_clk(clocks: &mut ClockTree) { + trace!("Releasing LP_SLOW_CLK"); + if decrement_reference_count(&mut clocks.lp_slow_clk_refcount) { + trace!("Disabling LP_SLOW_CLK"); + enable_lp_slow_clk_impl(clocks, false); + match unwrap!(clocks.lp_slow_clk) { + LpSlowClkConfig::RcSlow => release_rc_slow_clk(clocks), + LpSlowClkConfig::Xtal32k => release_xtal32k_clk(clocks), + LpSlowClkConfig::Rc32k => release_rc32k_clk(clocks), + LpSlowClkConfig::OscSlow => release_osc_slow_clk(clocks), + } } } - pub fn configure_uart2_function_clock( + #[allow(unused_variables)] + pub fn lp_slow_clk_config_frequency( clocks: &mut ClockTree, - new_selector: Uart0FunctionClockConfig, - ) { - let old_selector = clocks.uart2_function_clock.replace(new_selector); - if clocks.uart2_function_clock_refcount > 0 { - match new_selector { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + config: LpSlowClkConfig, + ) -> u32 { + match config { + LpSlowClkConfig::RcSlow => rc_slow_clk_frequency(clocks), + LpSlowClkConfig::Xtal32k => xtal32k_clk_frequency(clocks), + LpSlowClkConfig::Rc32k => rc32k_clk_frequency(clocks), + LpSlowClkConfig::OscSlow => osc_slow_clk_frequency(clocks), + } + } + pub fn lp_slow_clk_frequency(clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.lp_slow_clk { + lp_slow_clk_config_frequency(clocks, config) + } else { + 0 + } + } + impl TimgInstance { + pub fn configure_function_clock( + self, + clocks: &mut ClockTree, + new_selector: TimgFunctionClockConfig, + ) { + let old_selector = clocks.timg_function_clock[self as usize].replace(new_selector); + if clocks.timg_function_clock_refcount[self as usize] > 0 { + match new_selector { + TimgFunctionClockConfig::XtalClk => request_xtal_clk(clocks), + TimgFunctionClockConfig::RcFastClk => request_rc_fast_clk(clocks), + TimgFunctionClockConfig::PllF80m => request_pll_f80m(clocks), + } + self.configure_function_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + TimgFunctionClockConfig::XtalClk => release_xtal_clk(clocks), + TimgFunctionClockConfig::RcFastClk => release_rc_fast_clk(clocks), + TimgFunctionClockConfig::PllF80m => release_pll_f80m(clocks), + } + } + } else { + self.configure_function_clock_impl(clocks, old_selector, new_selector); } - configure_uart2_function_clock_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + pub fn function_clock_config( + self, + clocks: &mut ClockTree, + ) -> Option { + clocks.timg_function_clock[self as usize] + } + pub fn request_function_clock(self, clocks: &mut ClockTree) { + trace!("Requesting {:?}::FUNCTION_CLOCK", self); + if increment_reference_count( + &mut clocks.timg_function_clock_refcount[self as usize], + ) { + trace!("Enabling {:?}::FUNCTION_CLOCK", self); + match unwrap!(clocks.timg_function_clock[self as usize]) { + TimgFunctionClockConfig::XtalClk => request_xtal_clk(clocks), + TimgFunctionClockConfig::RcFastClk => request_rc_fast_clk(clocks), + TimgFunctionClockConfig::PllF80m => request_pll_f80m(clocks), } + self.enable_function_clock_impl(clocks, true); } - } else { - configure_uart2_function_clock_impl(clocks, old_selector, new_selector); } - } - pub fn request_uart2_function_clock(clocks: &mut ClockTree) { - trace!("Requesting UART2_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.uart2_function_clock_refcount) { - trace!("Enabling UART2_FUNCTION_CLOCK"); - match unwrap!(clocks.uart2_function_clock) { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + pub fn release_function_clock(self, clocks: &mut ClockTree) { + trace!("Releasing {:?}::FUNCTION_CLOCK", self); + if decrement_reference_count( + &mut clocks.timg_function_clock_refcount[self as usize], + ) { + trace!("Disabling {:?}::FUNCTION_CLOCK", self); + self.enable_function_clock_impl(clocks, false); + match unwrap!(clocks.timg_function_clock[self as usize]) { + TimgFunctionClockConfig::XtalClk => release_xtal_clk(clocks), + TimgFunctionClockConfig::RcFastClk => release_rc_fast_clk(clocks), + TimgFunctionClockConfig::PllF80m => release_pll_f80m(clocks), + } } - enable_uart2_function_clock_impl(clocks, true); - } - } - pub fn release_uart2_function_clock(clocks: &mut ClockTree) { - trace!("Releasing UART2_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.uart2_function_clock_refcount) { - trace!("Disabling UART2_FUNCTION_CLOCK"); - enable_uart2_function_clock_impl(clocks, false); - match unwrap!(clocks.uart2_function_clock) { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + #[allow(unused_variables)] + pub fn function_clock_config_frequency( + self, + clocks: &mut ClockTree, + config: TimgFunctionClockConfig, + ) -> u32 { + match config { + TimgFunctionClockConfig::XtalClk => xtal_clk_frequency(clocks), + TimgFunctionClockConfig::RcFastClk => rc_fast_clk_frequency(clocks), + TimgFunctionClockConfig::PllF80m => pll_f80m_frequency(clocks), } } - } - pub fn uart2_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.uart2_function_clock) { - Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + pub fn function_clock_frequency(self, clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.timg_function_clock[self as usize] { + self.function_clock_config_frequency(clocks, config) + } else { + 0 + } } - } - pub fn configure_uart3_function_clock( - clocks: &mut ClockTree, - new_selector: Uart0FunctionClockConfig, - ) { - let old_selector = clocks.uart3_function_clock.replace(new_selector); - if clocks.uart3_function_clock_refcount > 0 { - match new_selector { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + pub fn configure_wdt_clock( + self, + clocks: &mut ClockTree, + new_selector: TimgWdtClockConfig, + ) { + let old_selector = clocks.timg_wdt_clock[self as usize].replace(new_selector); + if clocks.timg_wdt_clock_refcount[self as usize] > 0 { + match new_selector { + TimgWdtClockConfig::XtalClk => request_xtal_clk(clocks), + TimgWdtClockConfig::PllF80m => request_pll_f80m(clocks), + TimgWdtClockConfig::RcFastClk => request_rc_fast_clk(clocks), + } + self.configure_wdt_clock_impl(clocks, old_selector, new_selector); + if let Some(old_selector) = old_selector { + match old_selector { + TimgWdtClockConfig::XtalClk => release_xtal_clk(clocks), + TimgWdtClockConfig::PllF80m => release_pll_f80m(clocks), + TimgWdtClockConfig::RcFastClk => release_rc_fast_clk(clocks), + } + } + } else { + self.configure_wdt_clock_impl(clocks, old_selector, new_selector); } - configure_uart3_function_clock_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + pub fn wdt_clock_config(self, clocks: &mut ClockTree) -> Option { + clocks.timg_wdt_clock[self as usize] + } + pub fn request_wdt_clock(self, clocks: &mut ClockTree) { + trace!("Requesting {:?}::WDT_CLOCK", self); + if increment_reference_count(&mut clocks.timg_wdt_clock_refcount[self as usize]) { + trace!("Enabling {:?}::WDT_CLOCK", self); + match unwrap!(clocks.timg_wdt_clock[self as usize]) { + TimgWdtClockConfig::XtalClk => request_xtal_clk(clocks), + TimgWdtClockConfig::PllF80m => request_pll_f80m(clocks), + TimgWdtClockConfig::RcFastClk => request_rc_fast_clk(clocks), } + self.enable_wdt_clock_impl(clocks, true); } - } else { - configure_uart3_function_clock_impl(clocks, old_selector, new_selector); } - } - pub fn request_uart3_function_clock(clocks: &mut ClockTree) { - trace!("Requesting UART3_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.uart3_function_clock_refcount) { - trace!("Enabling UART3_FUNCTION_CLOCK"); - match unwrap!(clocks.uart3_function_clock) { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + pub fn release_wdt_clock(self, clocks: &mut ClockTree) { + trace!("Releasing {:?}::WDT_CLOCK", self); + if decrement_reference_count(&mut clocks.timg_wdt_clock_refcount[self as usize]) { + trace!("Disabling {:?}::WDT_CLOCK", self); + self.enable_wdt_clock_impl(clocks, false); + match unwrap!(clocks.timg_wdt_clock[self as usize]) { + TimgWdtClockConfig::XtalClk => release_xtal_clk(clocks), + TimgWdtClockConfig::PllF80m => release_pll_f80m(clocks), + TimgWdtClockConfig::RcFastClk => release_rc_fast_clk(clocks), + } } - enable_uart3_function_clock_impl(clocks, true); - } - } - pub fn release_uart3_function_clock(clocks: &mut ClockTree) { - trace!("Releasing UART3_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.uart3_function_clock_refcount) { - trace!("Disabling UART3_FUNCTION_CLOCK"); - enable_uart3_function_clock_impl(clocks, false); - match unwrap!(clocks.uart3_function_clock) { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + #[allow(unused_variables)] + pub fn wdt_clock_config_frequency( + self, + clocks: &mut ClockTree, + config: TimgWdtClockConfig, + ) -> u32 { + match config { + TimgWdtClockConfig::XtalClk => xtal_clk_frequency(clocks), + TimgWdtClockConfig::PllF80m => pll_f80m_frequency(clocks), + TimgWdtClockConfig::RcFastClk => rc_fast_clk_frequency(clocks), } } - } - pub fn uart3_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.uart3_function_clock) { - Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + pub fn wdt_clock_frequency(self, clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.timg_wdt_clock[self as usize] { + self.wdt_clock_config_frequency(clocks, config) + } else { + 0 + } } } - pub fn configure_uart4_function_clock( - clocks: &mut ClockTree, - new_selector: Uart0FunctionClockConfig, - ) { - let old_selector = clocks.uart4_function_clock.replace(new_selector); - if clocks.uart4_function_clock_refcount > 0 { - match new_selector { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + impl UartInstance { + pub fn configure_function_clock( + self, + clocks: &mut ClockTree, + config: UartFunctionClockConfig, + ) { + let old_config = clocks.uart_function_clock[self as usize].replace(config); + if clocks.uart_function_clock_refcount[self as usize] > 0 { + match config.sclk { + UartFunctionClockSclk::Xtal => request_xtal_clk(clocks), + UartFunctionClockSclk::PllF80m => request_pll_f80m(clocks), + UartFunctionClockSclk::RcFast => request_rc_fast_clk(clocks), + } + self.configure_function_clock_impl(clocks, old_config, config); + if let Some(old_config) = old_config { + match old_config.sclk { + UartFunctionClockSclk::Xtal => release_xtal_clk(clocks), + UartFunctionClockSclk::PllF80m => release_pll_f80m(clocks), + UartFunctionClockSclk::RcFast => release_rc_fast_clk(clocks), + } + } + } else { + self.configure_function_clock_impl(clocks, old_config, config); } - configure_uart4_function_clock_impl(clocks, old_selector, new_selector); - if let Some(old_selector) = old_selector { - match old_selector { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + pub fn function_clock_config( + self, + clocks: &mut ClockTree, + ) -> Option { + clocks.uart_function_clock[self as usize] + } + pub fn request_function_clock(self, clocks: &mut ClockTree) { + trace!("Requesting {:?}::FUNCTION_CLOCK", self); + if increment_reference_count( + &mut clocks.uart_function_clock_refcount[self as usize], + ) { + trace!("Enabling {:?}::FUNCTION_CLOCK", self); + match unwrap!(clocks.uart_function_clock[self as usize]).sclk { + UartFunctionClockSclk::Xtal => request_xtal_clk(clocks), + UartFunctionClockSclk::PllF80m => request_pll_f80m(clocks), + UartFunctionClockSclk::RcFast => request_rc_fast_clk(clocks), } + self.enable_function_clock_impl(clocks, true); } - } else { - configure_uart4_function_clock_impl(clocks, old_selector, new_selector); } - } - pub fn request_uart4_function_clock(clocks: &mut ClockTree) { - trace!("Requesting UART4_FUNCTION_CLOCK"); - if increment_reference_count(&mut clocks.uart4_function_clock_refcount) { - trace!("Enabling UART4_FUNCTION_CLOCK"); - match unwrap!(clocks.uart4_function_clock) { - Uart0FunctionClockConfig::Pll80 => request_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => request_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => request_xtal_clk(clocks), + pub fn release_function_clock(self, clocks: &mut ClockTree) { + trace!("Releasing {:?}::FUNCTION_CLOCK", self); + if decrement_reference_count( + &mut clocks.uart_function_clock_refcount[self as usize], + ) { + trace!("Disabling {:?}::FUNCTION_CLOCK", self); + self.enable_function_clock_impl(clocks, false); + match unwrap!(clocks.uart_function_clock[self as usize]).sclk { + UartFunctionClockSclk::Xtal => release_xtal_clk(clocks), + UartFunctionClockSclk::PllF80m => release_pll_f80m(clocks), + UartFunctionClockSclk::RcFast => release_rc_fast_clk(clocks), + } } - enable_uart4_function_clock_impl(clocks, true); - } - } - pub fn release_uart4_function_clock(clocks: &mut ClockTree) { - trace!("Releasing UART4_FUNCTION_CLOCK"); - if decrement_reference_count(&mut clocks.uart4_function_clock_refcount) { - trace!("Disabling UART4_FUNCTION_CLOCK"); - enable_uart4_function_clock_impl(clocks, false); - match unwrap!(clocks.uart4_function_clock) { - Uart0FunctionClockConfig::Pll80 => release_pll_f80m_clk(clocks), - Uart0FunctionClockConfig::RcFast => release_rc_fast_clk(clocks), - Uart0FunctionClockConfig::Xtal => release_xtal_clk(clocks), + } + #[allow(unused_variables)] + pub fn function_clock_config_frequency( + self, + clocks: &mut ClockTree, + config: UartFunctionClockConfig, + ) -> u32 { + (match config.sclk { + UartFunctionClockSclk::Xtal => xtal_clk_frequency(clocks), + UartFunctionClockSclk::PllF80m => pll_f80m_frequency(clocks), + UartFunctionClockSclk::RcFast => rc_fast_clk_frequency(clocks), + } / (config.div_num() + 1)) + } + pub fn function_clock_frequency(self, clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.uart_function_clock[self as usize] { + self.function_clock_config_frequency(clocks, config) + } else { + 0 } } - } - pub fn uart4_function_clock_frequency(clocks: &mut ClockTree) -> u32 { - match unwrap!(clocks.uart4_function_clock) { - Uart0FunctionClockConfig::Pll80 => pll_f80m_clk_frequency(clocks), - Uart0FunctionClockConfig::RcFast => rc_fast_clk_frequency(clocks), - Uart0FunctionClockConfig::Xtal => xtal_clk_frequency(clocks), + pub fn configure_baud_rate_generator( + self, + clocks: &mut ClockTree, + config: UartBaudRateGeneratorConfig, + ) { + let old_config = clocks.uart_baud_rate_generator[self as usize].replace(config); + self.configure_baud_rate_generator_impl(clocks, old_config, config); + } + pub fn baud_rate_generator_config( + self, + clocks: &mut ClockTree, + ) -> Option { + clocks.uart_baud_rate_generator[self as usize] + } + pub fn request_baud_rate_generator(self, clocks: &mut ClockTree) { + trace!("Requesting {:?}::BAUD_RATE_GENERATOR", self); + if increment_reference_count( + &mut clocks.uart_baud_rate_generator_refcount[self as usize], + ) { + trace!("Enabling {:?}::BAUD_RATE_GENERATOR", self); + self.request_function_clock(clocks); + self.enable_baud_rate_generator_impl(clocks, true); + } + } + pub fn release_baud_rate_generator(self, clocks: &mut ClockTree) { + trace!("Releasing {:?}::BAUD_RATE_GENERATOR", self); + if decrement_reference_count( + &mut clocks.uart_baud_rate_generator_refcount[self as usize], + ) { + trace!("Disabling {:?}::BAUD_RATE_GENERATOR", self); + self.enable_baud_rate_generator_impl(clocks, false); + self.release_function_clock(clocks); + } + } + #[allow(unused_variables)] + pub fn baud_rate_generator_config_frequency( + self, + clocks: &mut ClockTree, + config: UartBaudRateGeneratorConfig, + ) -> u32 { + ((self.function_clock_frequency(clocks) * 16) + / ((config.integral() * 16) + config.fractional())) + } + pub fn baud_rate_generator_frequency(self, clocks: &mut ClockTree) -> u32 { + if let Some(config) = clocks.uart_baud_rate_generator[self as usize] { + self.baud_rate_generator_config_frequency(clocks, config) + } else { + 0 + } } } /// Clock tree configuration. @@ -1823,84 +2105,34 @@ macro_rules! define_clock_tree_types { #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[instability::unstable] pub struct ClockConfig { - /// `XTAL_CLK` configuration. - pub xtal_clk: Option, - /// `CPLL_CLK` configuration. - pub cpll_clk: Option, - /// `MPLL_CLK` configuration. - pub mpll_clk: Option, - /// `SPLL_CLK` configuration. - pub spll_clk: Option, - /// `PLL_LP_CLK` configuration. - pub pll_lp_clk: Option, - /// `ROOT_CLK` configuration. - pub root_clk: Option, + /// `CPU_ROOT_CLK` configuration. + pub cpu_root_clk: Option, /// `CPU_CLK` configuration. pub cpu_clk: Option, - /// `MEM_CLK` configuration. - pub mem_clk: Option, - /// `SYS_CLK` configuration. - pub sys_clk: Option, /// `APB_CLK` configuration. pub apb_clk: Option, - /// `LP_SLOW_CLK` configuration. - pub lp_slow_clk: Option, /// `LP_FAST_CLK` configuration. pub lp_fast_clk: Option, - /// `LP_DYN_SLOW_CLK` configuration. - pub lp_dyn_slow_clk: Option, - /// `LP_DYN_FAST_CLK` configuration. - pub lp_dyn_fast_clk: Option, - /// `LP_PERI_CLK` configuration. - pub lp_peri_clk: Option, + /// `LP_SLOW_CLK` configuration. + pub lp_slow_clk: Option, } impl ClockConfig { fn apply(&self) { ClockTree::with(|clocks| { - if let Some(config) = self.xtal_clk { - configure_xtal_clk(clocks, config); - } - if let Some(config) = self.cpll_clk { - configure_cpll_clk(clocks, config); - } - if let Some(config) = self.mpll_clk { - configure_mpll_clk(clocks, config); - } - if let Some(config) = self.spll_clk { - configure_spll_clk(clocks, config); - } - if let Some(config) = self.pll_lp_clk { - configure_pll_lp_clk(clocks, config); - } - if let Some(config) = self.root_clk { - configure_root_clk(clocks, config); + if let Some(config) = self.cpu_root_clk { + configure_cpu_root_clk(clocks, config); } if let Some(config) = self.cpu_clk { configure_cpu_clk(clocks, config); } - if let Some(config) = self.mem_clk { - configure_mem_clk(clocks, config); - } - if let Some(config) = self.sys_clk { - configure_sys_clk(clocks, config); - } if let Some(config) = self.apb_clk { configure_apb_clk(clocks, config); } - if let Some(config) = self.lp_slow_clk { - configure_lp_slow_clk(clocks, config); - } if let Some(config) = self.lp_fast_clk { configure_lp_fast_clk(clocks, config); } - if let Some(config) = self.lp_dyn_slow_clk { - configure_lp_dyn_slow_clk(clocks, config); - } - if let Some(config) = self.lp_dyn_fast_clk { - configure_lp_dyn_fast_clk(clocks, config); - } - if let Some(config) = self.lp_peri_clk { - configure_lp_peri_clk(clocks, config); + if let Some(config) = self.lp_slow_clk { + configure_lp_slow_clk(clocks, config); } }); } @@ -1928,125 +2160,17 @@ macro_rules! implement_peripheral_clocks { #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum Peripheral { - /// SYSTIMER peripheral clock signal - Systimer, - /// TIMG0 peripheral clock signal - Timg0, - /// TIMG1 peripheral clock signal - Timg1, - /// UART0 peripheral clock signal - Uart0, - /// UART1 peripheral clock signal - Uart1, - /// UART2 peripheral clock signal - Uart2, - /// UART3 peripheral clock signal - Uart3, - /// UART4 peripheral clock signal - Uart4, - } + pub enum Peripheral {} impl Peripheral { - const KEEP_ENABLED: &[Peripheral] = &[Self::Systimer, Self::Timg0, Self::Uart0]; + const KEEP_ENABLED: &[Peripheral] = &[]; const COUNT: usize = Self::ALL.len(); - const ALL: &[Self] = &[ - Self::Systimer, - Self::Timg0, - Self::Timg1, - Self::Uart0, - Self::Uart1, - Self::Uart2, - Self::Uart3, - Self::Uart4, - ]; + const ALL: &[Self] = &[]; } unsafe fn enable_internal_racey(peripheral: Peripheral, enable: bool) { - match peripheral { - Peripheral::Systimer => { - crate::peripherals::HP_SYS_CLKRST::regs() - .soc_clk_ctrl2() - .modify(|_, w| w.systimer_apb_clk_en().bit(enable)); - } - Peripheral::Timg0 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl21() - .modify(|_, w| w.timergrp0_t0_clk_en().bit(enable)); - } - Peripheral::Timg1 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl20() - .modify(|_, w| w.timergrp1_t0_clk_en().bit(enable)); - } - Peripheral::Uart0 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl110() - .modify(|_, w| w.uart0_clk_en().bit(enable)); - } - Peripheral::Uart1 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl111() - .modify(|_, w| w.uart1_clk_en().bit(enable)); - } - Peripheral::Uart2 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl112() - .modify(|_, w| w.uart2_clk_en().bit(enable)); - } - Peripheral::Uart3 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl113() - .modify(|_, w| w.uart3_clk_en().bit(enable)); - } - Peripheral::Uart4 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .peri_clk_ctrl114() - .modify(|_, w| w.uart4_clk_en().bit(enable)); - } - } + match peripheral {} } unsafe fn assert_peri_reset_racey(peripheral: Peripheral, reset: bool) { - match peripheral { - Peripheral::Systimer => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_stimer().bit(reset)); - } - Peripheral::Timg0 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_timergrp1().bit(reset)); - } - Peripheral::Timg1 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_timergrp0().bit(reset)); - } - Peripheral::Uart0 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_uart0_core().bit(reset)); - } - Peripheral::Uart1 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_uart1_core().bit(reset)); - } - Peripheral::Uart2 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_uart2_core().bit(reset)); - } - Peripheral::Uart3 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_uart3_core().bit(reset)); - } - Peripheral::Uart4 => { - crate::peripherals::HP_SYS_CLKRST::regs() - .hp_rst_en1() - .modify(|_, w| w.rst_en_uart4_core().bit(reset)); - } - } + match peripheral {} } }; } @@ -2061,44 +2185,16 @@ macro_rules! implement_peripheral_clocks { #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! memory_range { ("DRAM") => { - 0x4FF00000..0x4FFC0000 + 0x4FF40000..0x4FFC0000 }; (size as str, "DRAM") => { - "786432" + "524288" }; -} -#[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] -macro_rules! for_each_sw_interrupt { - ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((0, FROM_CPU_INTR0, software_interrupt0)); _for_each_inner!((1, - FROM_CPU_INTR1, software_interrupt1)); _for_each_inner!((2, FROM_CPU_INTR2, - software_interrupt2)); _for_each_inner!((3, FROM_CPU_INTR3, - software_interrupt3)); _for_each_inner!((all(0, FROM_CPU_INTR0, - software_interrupt0), (1, FROM_CPU_INTR1, software_interrupt1), (2, - FROM_CPU_INTR2, software_interrupt2), (3, FROM_CPU_INTR3, software_interrupt3))); + ("DRAM2_UNINIT") => { + 0x4FF00000..0x4FF40000 }; -} -#[macro_export] -macro_rules! sw_interrupt_delay { - () => { - unsafe { - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - ::core::arch::asm!("nop"); - } + (size as str, "DRAM2_UNINIT") => { + "262144" }; } /// This macro can be used to generate code for each peripheral instance of the I2C master driver. @@ -2108,21 +2204,24 @@ macro_rules! sw_interrupt_delay { /// /// This macro has one option for its "Individual matcher" case: /// -/// Syntax: `($instance:ident, $sys:ident, $scl:ident, $sda:ident)` +/// Syntax: `($id:literal, $instance:ident, $sys:ident, $scl:ident, $sda:ident)` /// /// Macro fragments: -/// +/// - `$id`: the index of the I2C instance /// - `$instance`: the name of the I2C instance /// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum. /// - `$scl`, `$sda`: peripheral signal names. /// -/// Example data: `(I2C0, I2cExt0, I2CEXT0_SCL, I2CEXT0_SDA)` +/// Example data: `(0, I2C0, I2cExt0, I2CEXT0_SCL, I2CEXT0_SDA)` #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_i2c_master { ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((all)); + macro_rules! _for_each_inner_i2c_master { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_i2c_master!((0, I2C0, I2c0, I2C0_SCL, I2C0_SDA)); + _for_each_inner_i2c_master!((1, I2C1, I2c1, I2C1_SCL, I2C1_SDA)); + _for_each_inner_i2c_master!((all(0, I2C0, I2c0, I2C0_SCL, I2C0_SDA), (1, I2C1, + I2c1, I2C1_SCL, I2C1_SDA))); }; } /// This macro can be used to generate code for each peripheral instance of the UART driver. @@ -2132,330 +2231,409 @@ macro_rules! for_each_i2c_master { /// /// This macro has one option for its "Individual matcher" case: /// -/// Syntax: `($instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident, $rts:ident)` +/// Syntax: `($id:literal, $instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident, +/// $rts:ident)` /// /// Macro fragments: /// +/// - `$id`: the index of the UART instance /// - `$instance`: the name of the UART instance /// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum. /// - `$rx`, `$tx`, `$cts`, `$rts`: signal names. /// -/// Example data: `(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)` +/// Example data: `(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)` #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_uart { ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((all)); + macro_rules! _for_each_inner_uart { $(($pattern) => $code;)* ($other : tt) => {} + } _for_each_inner_uart!((0, UART0, Uart0, UART0_RXD, UART0_TXD, UART0_CTS, + UART0_RTS)); _for_each_inner_uart!((1, UART1, Uart1, UART1_RXD, UART1_TXD, + UART1_CTS, UART1_RTS)); _for_each_inner_uart!((2, UART2, Uart2, UART2_RXD, + UART2_TXD, UART2_CTS, UART2_RTS)); _for_each_inner_uart!((3, UART3, Uart3, + UART3_RXD, UART3_TXD, UART3_CTS, UART3_RTS)); _for_each_inner_uart!((4, UART4, + Uart4, UART4_RXD, UART4_TXD, UART4_CTS, UART4_RTS)); + _for_each_inner_uart!((all(0, UART0, Uart0, UART0_RXD, UART0_TXD, UART0_CTS, + UART0_RTS), (1, UART1, Uart1, UART1_RXD, UART1_TXD, UART1_CTS, UART1_RTS), (2, + UART2, Uart2, UART2_RXD, UART2_TXD, UART2_CTS, UART2_RTS), (3, UART3, Uart3, + UART3_RXD, UART3_TXD, UART3_CTS, UART3_RTS), (4, UART4, Uart4, UART4_RXD, + UART4_TXD, UART4_CTS, UART4_RTS))); + }; +} +/// This macro can be used to generate code for each peripheral instance of the SPI master driver. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has one option for its "Individual matcher" case: +/// +/// Syntax: `($instance:ident, $sys:ident, $sclk:ident [$($cs:ident),*] [$($sio:ident),*] +/// $($is_qspi:literal)?)` +/// +/// Macro fragments: +/// +/// - `$instance`: the name of the SPI instance +/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum. +/// - `$cs`, `$sio`: chip select and SIO signal names. +/// - `$is_qspi`: a `true` literal present if the SPI instance supports QSPI. +/// +/// Example data: +/// - `(SPI2, Spi2, FSPICLK [FSPICS0, FSPICS1, FSPICS2, FSPICS3, FSPICS4, FSPICS5] [FSPID, FSPIQ, +/// FSPIWP, FSPIHD, FSPIIO4, FSPIIO5, FSPIIO6, FSPIIO7], true)` +/// - `(SPI3, Spi3, SPI3_CLK [SPI3_CS0, SPI3_CS1, SPI3_CS2] [SPI3_D, SPI3_Q])` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_spi_master { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_spi_master { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_spi_master!((SPI2, Spi2, SPI2_CK[SPI2_CS] [SPI2_D, + SPI2_Q, SPI2_WP, SPI2_HOLD], true)); _for_each_inner_spi_master!((SPI3, Spi3, + SPI3_CK[SPI3_CS, SPI3_CS1, SPI3_CS2] [SPI3_D, SPI3_Q, SPI3_WP, SPI3_HOLD], + true)); _for_each_inner_spi_master!((all(SPI2, Spi2, SPI2_CK[SPI2_CS] [SPI2_D, + SPI2_Q, SPI2_WP, SPI2_HOLD], true), (SPI3, Spi3, SPI3_CK[SPI3_CS, SPI3_CS1, + SPI3_CS2] [SPI3_D, SPI3_Q, SPI3_WP, SPI3_HOLD], true))); }; } #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_peripheral { ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((@ peri_type #[doc = "GPIO0 peripheral singleton"] GPIO0 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO1 peripheral singleton"] - GPIO1 <= virtual())); _for_each_inner!((@ peri_type #[doc = + macro_rules! _for_each_inner_peripheral { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO0 peripheral singleton"] GPIO0 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO1 peripheral singleton"] + GPIO1 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO2 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = "
"] #[doc = "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] #[doc = "
    "] #[doc = "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] - #[doc = "
"] #[doc = "
"] GPIO2 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO3 peripheral singleton (Limitations exist)"] #[doc = ""] - #[doc = "
"] #[doc = + #[doc = ""] #[doc = "
"] GPIO2 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO3 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] #[doc = "
    "] #[doc = "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] - #[doc = "
"] #[doc = "
"] GPIO3 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO4 peripheral singleton (Limitations exist)"] #[doc = ""] - #[doc = "
"] #[doc = + #[doc = ""] #[doc = "
"] GPIO3 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO4 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] #[doc = "
    "] #[doc = "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] - #[doc = "
"] #[doc = "
"] GPIO4 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO5 peripheral singleton (Limitations exist)"] #[doc = ""] - #[doc = "
"] #[doc = + #[doc = ""] #[doc = "
"] GPIO4 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO5 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] #[doc = "
    "] #[doc = "
  • These pins may be used to debug the chip using an external JTAG debugger.
  • "] - #[doc = "
"] #[doc = "
"] GPIO5 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO6 peripheral singleton"] GPIO6 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO7 peripheral singleton"] GPIO7 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO8 peripheral singleton"] - GPIO8 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO9 peripheral singleton"] GPIO9 <= virtual())); _for_each_inner!((@ peri_type - #[doc = "GPIO10 peripheral singleton"] GPIO10 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO11 peripheral singleton"] GPIO11 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO12 peripheral singleton"] GPIO12 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO13 peripheral singleton"] - GPIO13 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO14 peripheral singleton"] GPIO14 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO15 peripheral singleton"] GPIO15 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO16 peripheral singleton"] GPIO16 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO17 peripheral singleton"] - GPIO17 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO18 peripheral singleton"] GPIO18 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO19 peripheral singleton"] GPIO19 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO20 peripheral singleton"] GPIO20 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO21 peripheral singleton"] - GPIO21 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO22 peripheral singleton"] GPIO22 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO23 peripheral singleton"] GPIO23 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO24 peripheral singleton"] GPIO24 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO25 peripheral singleton"] - GPIO25 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO26 peripheral singleton"] GPIO26 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO27 peripheral singleton"] GPIO27 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO28 peripheral singleton"] GPIO28 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO29 peripheral singleton"] - GPIO29 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO30 peripheral singleton"] GPIO30 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO31 peripheral singleton"] GPIO31 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO32 peripheral singleton"] GPIO32 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO33 peripheral singleton"] - GPIO33 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO34 peripheral singleton"] GPIO34 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO35 peripheral singleton"] GPIO35 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO36 peripheral singleton"] GPIO36 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO37 peripheral singleton"] - GPIO37 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO38 peripheral singleton"] GPIO38 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO39 peripheral singleton"] GPIO39 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO40 peripheral singleton"] GPIO40 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO41 peripheral singleton"] - GPIO41 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO42 peripheral singleton"] GPIO42 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO43 peripheral singleton"] GPIO43 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO44 peripheral singleton"] GPIO44 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO45 peripheral singleton"] - GPIO45 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO46 peripheral singleton"] GPIO46 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO47 peripheral singleton"] GPIO47 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO48 peripheral singleton"] GPIO48 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO49 peripheral singleton"] - GPIO49 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO50 peripheral singleton"] GPIO50 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "GPIO51 peripheral singleton"] GPIO51 <= virtual())); - _for_each_inner!((@ peri_type #[doc = "GPIO52 peripheral singleton"] GPIO52 <= - virtual())); _for_each_inner!((@ peri_type #[doc = "GPIO53 peripheral singleton"] - GPIO53 <= virtual())); _for_each_inner!((@ peri_type #[doc = - "GPIO54 peripheral singleton"] GPIO54 <= virtual())); _for_each_inner!((@ - peri_type #[doc = "ADC peripheral singleton"] ADC <= ADC() (unstable))); - _for_each_inner!((@ peri_type #[doc = "AES peripheral singleton"] AES <= AES() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "AHB_DMA peripheral singleton"] AHB_DMA <= AHB_DMA() (unstable))); - _for_each_inner!((@ peri_type #[doc = "ASSIST_DEBUG peripheral singleton"] - ASSIST_DEBUG <= ASSIST_DEBUG() (unstable))); _for_each_inner!((@ peri_type #[doc - = "AXI_DMA peripheral singleton"] AXI_DMA <= AXI_DMA() (unstable))); - _for_each_inner!((@ peri_type #[doc = "AXI_ICM peripheral singleton"] AXI_ICM <= - AXI_ICM() (unstable))); _for_each_inner!((@ peri_type #[doc = - "BITSCRAMBLER peripheral singleton"] BITSCRAMBLER <= BITSCRAMBLER() (unstable))); - _for_each_inner!((@ peri_type #[doc = "CACHE peripheral singleton"] CACHE <= - CACHE() (unstable))); _for_each_inner!((@ peri_type #[doc = - "DMA peripheral singleton"] DMA <= DMA() (unstable))); _for_each_inner!((@ - peri_type #[doc = "DS peripheral singleton"] DS <= DS() (unstable))); - _for_each_inner!((@ peri_type #[doc = "ECC peripheral singleton"] ECC <= ECC() - (unstable))); _for_each_inner!((@ peri_type #[doc = "ECDSA peripheral singleton"] - ECDSA <= ECDSA() (unstable))); _for_each_inner!((@ peri_type #[doc = - "EFUSE peripheral singleton"] EFUSE <= EFUSE() (unstable))); _for_each_inner!((@ - peri_type #[doc = "GPIO peripheral singleton"] GPIO <= GPIO() (unstable))); - _for_each_inner!((@ peri_type #[doc = "GPIO_SD peripheral singleton"] GPIO_SD <= - GPIO_SD() (unstable))); _for_each_inner!((@ peri_type #[doc = - "H264 peripheral singleton"] H264 <= H264() (unstable))); _for_each_inner!((@ - peri_type #[doc = "H264_DMA peripheral singleton"] H264_DMA <= H264_DMA() - (unstable))); _for_each_inner!((@ peri_type #[doc = "HMAC peripheral singleton"] - HMAC <= HMAC() (unstable))); _for_each_inner!((@ peri_type #[doc = - "HP_SYS peripheral singleton"] HP_SYS <= HP_SYS() (unstable))); - _for_each_inner!((@ peri_type #[doc = "HP_SYS_CLKRST peripheral singleton"] - HP_SYS_CLKRST <= HP_SYS_CLKRST() (unstable))); _for_each_inner!((@ peri_type - #[doc = "I2C0 peripheral singleton"] I2C0 <= I2C0() (unstable))); - _for_each_inner!((@ peri_type #[doc = "I2C1 peripheral singleton"] I2C1 <= I2C1() - (unstable))); _for_each_inner!((@ peri_type #[doc = "I2S0 peripheral singleton"] - I2S0 <= I2S0() (unstable))); _for_each_inner!((@ peri_type #[doc = - "I2S1 peripheral singleton"] I2S1 <= I2S1() (unstable))); _for_each_inner!((@ - peri_type #[doc = "I2S2 peripheral singleton"] I2S2 <= I2S2() (unstable))); - _for_each_inner!((@ peri_type #[doc = "I3C_MST peripheral singleton"] I3C_MST <= - I3C_MST() (unstable))); _for_each_inner!((@ peri_type #[doc = - "I3C_MST_MEM peripheral singleton"] I3C_MST_MEM <= I3C_MST_MEM() (unstable))); - _for_each_inner!((@ peri_type #[doc = "I3C_SLV peripheral singleton"] I3C_SLV <= - I3C_SLV() (unstable))); _for_each_inner!((@ peri_type #[doc = + #[doc = ""] #[doc = ""] GPIO5 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO6 peripheral singleton"] + GPIO6 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO7 peripheral singleton"] GPIO7 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO8 peripheral singleton"] + GPIO8 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO9 peripheral singleton"] GPIO9 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO10 peripheral singleton"] + GPIO10 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO11 peripheral singleton"] GPIO11 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO12 peripheral singleton"] + GPIO12 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO13 peripheral singleton"] GPIO13 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO14 peripheral singleton"] + GPIO14 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO15 peripheral singleton"] GPIO15 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO16 peripheral singleton"] + GPIO16 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO17 peripheral singleton"] GPIO17 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO18 peripheral singleton"] + GPIO18 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO19 peripheral singleton"] GPIO19 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO20 peripheral singleton"] + GPIO20 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO21 peripheral singleton"] GPIO21 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO22 peripheral singleton"] + GPIO22 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO23 peripheral singleton"] GPIO23 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO24 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO24 <= virtual())); _for_each_inner_peripheral!((@ + peri_type #[doc = "GPIO25 peripheral singleton (Limitations exist)"] #[doc = ""] + #[doc = "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO25 <= virtual())); _for_each_inner_peripheral!((@ + peri_type #[doc = "GPIO26 peripheral singleton (Limitations exist)"] #[doc = ""] + #[doc = "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO26 <= virtual())); _for_each_inner_peripheral!((@ + peri_type #[doc = "GPIO27 peripheral singleton (Limitations exist)"] #[doc = ""] + #[doc = "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO27 <= virtual())); _for_each_inner_peripheral!((@ + peri_type #[doc = "GPIO28 peripheral singleton"] GPIO28 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO29 peripheral singleton"] + GPIO29 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO30 peripheral singleton"] GPIO30 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO31 peripheral singleton"] + GPIO31 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO32 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO32 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO33 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO33 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO34 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO34 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO35 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO35 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO36 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO36 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO37 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO37 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO38 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO38 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO39 peripheral singleton"] + GPIO39 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO40 peripheral singleton"] GPIO40 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO41 peripheral singleton"] + GPIO41 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO42 peripheral singleton"] GPIO42 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO43 peripheral singleton"] + GPIO43 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO44 peripheral singleton"] GPIO44 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO45 peripheral singleton"] + GPIO45 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO46 peripheral singleton"] GPIO46 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO47 peripheral singleton"] + GPIO47 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO48 peripheral singleton"] GPIO48 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO49 peripheral singleton"] + GPIO49 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO50 peripheral singleton"] GPIO50 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO51 peripheral singleton"] + GPIO51 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO52 peripheral singleton"] GPIO52 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "GPIO53 peripheral singleton"] + GPIO53 <= virtual())); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO54 peripheral singleton"] GPIO54 <= virtual())); + _for_each_inner_peripheral!((@ peri_type #[doc = "EFUSE peripheral singleton"] + EFUSE <= EFUSE() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "GPIO peripheral singleton"] GPIO <= GPIO() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "HP_SYS peripheral singleton"] + HP_SYS <= HP_SYS() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "HP_SYS_CLKRST peripheral singleton"] HP_SYS_CLKRST <= HP_SYS_CLKRST() + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = "INTERRUPT_CORE0 peripheral singleton"] INTERRUPT_CORE0 <= INTERRUPT_CORE0() - (unstable))); _for_each_inner!((@ peri_type #[doc = + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = "INTERRUPT_CORE1 peripheral singleton"] INTERRUPT_CORE1 <= INTERRUPT_CORE1() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "IO_MUX peripheral singleton"] IO_MUX <= IO_MUX() (unstable))); - _for_each_inner!((@ peri_type #[doc = "ISP peripheral singleton"] ISP <= ISP() - (unstable))); _for_each_inner!((@ peri_type #[doc = "JPEG peripheral singleton"] - JPEG <= JPEG() (unstable))); _for_each_inner!((@ peri_type #[doc = - "LCD_CAM peripheral singleton"] LCD_CAM <= LCD_CAM() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LEDC peripheral singleton"] LEDC <= LEDC() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "LP_ADC peripheral singleton"] LP_ADC <= LP_ADC() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_ANA peripheral singleton"] LP_ANA <= - LP_ANA() (unstable))); _for_each_inner!((@ peri_type #[doc = + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "CLIC peripheral singleton"] CLIC <= CLIC() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "IO_MUX peripheral singleton"] + IO_MUX <= IO_MUX() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "LP_AON peripheral singleton"] LP_AON <= LP_SYS() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "LP_AON_CLKRST peripheral singleton"] LP_AON_CLKRST <= LP_AON_CLKRST() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "LP_GPIO peripheral singleton"] LP_GPIO <= LP_GPIO() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_HUK peripheral singleton"] LP_HUK <= - LP_HUK() (unstable))); _for_each_inner!((@ peri_type #[doc = - "LP_I2C0 peripheral singleton"] LP_I2C0 <= LP_I2C0() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_I2C_ANA_MST peripheral singleton"] - LP_I2C_ANA_MST <= LP_I2C_ANA_MST() (unstable))); _for_each_inner!((@ peri_type - #[doc = "LP_I2S0 peripheral singleton"] LP_I2S0 <= LP_I2S0() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_INTR peripheral singleton"] LP_INTR <= - LP_INTR() (unstable))); _for_each_inner!((@ peri_type #[doc = - "LP_IO_MUX peripheral singleton"] LP_IO_MUX <= LP_IO_MUX() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_PERI peripheral singleton"] LP_PERI <= - LP_PERI() (unstable))); _for_each_inner!((@ peri_type #[doc = + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = "LP_SYS peripheral singleton"] LP_SYS <= LP_SYS() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_TIMER peripheral singleton"] LP_TIMER - <= LP_TIMER() (unstable))); _for_each_inner!((@ peri_type #[doc = - "LP_TOUCH peripheral singleton"] LP_TOUCH <= LP_TOUCH() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_TSENS peripheral singleton"] LP_TSENS - <= LP_TSENS() (unstable))); _for_each_inner!((@ peri_type #[doc = - "LP_UART peripheral singleton"] LP_UART <= LP_UART() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LP_WDT peripheral singleton"] LP_WDT <= - LP_WDT() (unstable))); _for_each_inner!((@ peri_type #[doc = - "MCPWM0 peripheral singleton"] MCPWM0 <= MCPWM0() (unstable))); - _for_each_inner!((@ peri_type #[doc = "MCPWM1 peripheral singleton"] MCPWM1 <= - MCPWM1() (unstable))); _for_each_inner!((@ peri_type #[doc = - "MIPI_CSI_BRIDGE peripheral singleton"] MIPI_CSI_BRIDGE <= MIPI_CSI_BRIDGE() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "MIPI_CSI_HOST peripheral singleton"] MIPI_CSI_HOST <= MIPI_CSI_HOST() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "MIPI_DSI_BRIDGE peripheral singleton"] MIPI_DSI_BRIDGE <= MIPI_DSI_BRIDGE() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "MIPI_DSI_HOST peripheral singleton"] MIPI_DSI_HOST <= MIPI_DSI_HOST() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "PARL_IO peripheral singleton"] PARL_IO <= PARL_IO() (unstable))); - _for_each_inner!((@ peri_type #[doc = "PAU peripheral singleton"] PAU <= PAU() - (unstable))); _for_each_inner!((@ peri_type #[doc = "PCNT peripheral singleton"] - PCNT <= PCNT() (unstable))); _for_each_inner!((@ peri_type #[doc = - "PMU peripheral singleton"] PMU <= PMU() (unstable))); _for_each_inner!((@ - peri_type #[doc = "PPA peripheral singleton"] PPA <= PPA() (unstable))); - _for_each_inner!((@ peri_type #[doc = "PVT peripheral singleton"] PVT <= PVT() - (unstable))); _for_each_inner!((@ peri_type #[doc = "RMT peripheral singleton"] - RMT <= RMT() (unstable))); _for_each_inner!((@ peri_type #[doc = - "RSA peripheral singleton"] RSA <= RSA() (unstable))); _for_each_inner!((@ - peri_type #[doc = "SDHOST peripheral singleton"] SDHOST <= SDHOST() (unstable))); - _for_each_inner!((@ peri_type #[doc = "SHA peripheral singleton"] SHA <= SHA() - (unstable))); _for_each_inner!((@ peri_type #[doc = - "SOC_ETM peripheral singleton"] SOC_ETM <= SOC_ETM() (unstable))); - _for_each_inner!((@ peri_type #[doc = "SPI0 peripheral singleton"] SPI0 <= SPI0() - (unstable))); _for_each_inner!((@ peri_type #[doc = "SPI1 peripheral singleton"] - SPI1 <= SPI1() (unstable))); _for_each_inner!((@ peri_type #[doc = - "SPI2 peripheral singleton"] SPI2 <= SPI2() (unstable))); _for_each_inner!((@ - peri_type #[doc = "SPI3 peripheral singleton"] SPI3 <= SPI3() (unstable))); - _for_each_inner!((@ peri_type #[doc = "SYSTIMER peripheral singleton"] SYSTIMER - <= SYSTIMER() (unstable))); _for_each_inner!((@ peri_type #[doc = - "TIMG0 peripheral singleton"] TIMG0 <= TIMG0() (unstable))); _for_each_inner!((@ - peri_type #[doc = "TIMG1 peripheral singleton"] TIMG1 <= TIMG1() (unstable))); - _for_each_inner!((@ peri_type #[doc = "TRACE0 peripheral singleton"] TRACE0 <= - TRACE0() (unstable))); _for_each_inner!((@ peri_type #[doc = - "TRACE1 peripheral singleton"] TRACE1 <= TRACE1() (unstable))); - _for_each_inner!((@ peri_type #[doc = "TWAI0 peripheral singleton"] TWAI0 <= - TWAI0() (unstable))); _for_each_inner!((@ peri_type #[doc = - "TWAI1 peripheral singleton"] TWAI1 <= TWAI1() (unstable))); _for_each_inner!((@ - peri_type #[doc = "TWAI2 peripheral singleton"] TWAI2 <= TWAI2() (unstable))); - _for_each_inner!((@ peri_type #[doc = "UART0 peripheral singleton"] UART0 <= - UART0() (unstable))); _for_each_inner!((@ peri_type #[doc = - "UART1 peripheral singleton"] UART1 <= UART1() (unstable))); _for_each_inner!((@ - peri_type #[doc = "UART2 peripheral singleton"] UART2 <= UART2() (unstable))); - _for_each_inner!((@ peri_type #[doc = "UART3 peripheral singleton"] UART3 <= - UART3() (unstable))); _for_each_inner!((@ peri_type #[doc = - "UART4 peripheral singleton"] UART4 <= UART4() (unstable))); _for_each_inner!((@ - peri_type #[doc = "UHCI0 peripheral singleton"] UHCI0 <= UHCI0() (unstable))); - _for_each_inner!((@ peri_type #[doc = "USB_DEVICE peripheral singleton"] - USB_DEVICE <= USB_DEVICE() (unstable))); _for_each_inner!((@ peri_type #[doc = - "USB_WRAP peripheral singleton"] USB_WRAP <= USB_WRAP() (unstable))); - _for_each_inner!((@ peri_type #[doc = "LPWR peripheral singleton"] LPWR <= - LP_AON_CLKRST() (unstable))); _for_each_inner!((@ peri_type #[doc = - "SYSTEM peripheral singleton"] SYSTEM <= HP_SYS() (unstable))); - _for_each_inner!((@ peri_type #[doc = "SW_INTERRUPT peripheral singleton"] - SW_INTERRUPT <= virtual() (unstable))); _for_each_inner!((GPIO0)); - _for_each_inner!((GPIO1)); _for_each_inner!((GPIO2)); _for_each_inner!((GPIO3)); - _for_each_inner!((GPIO4)); _for_each_inner!((GPIO5)); _for_each_inner!((GPIO6)); - _for_each_inner!((GPIO7)); _for_each_inner!((GPIO8)); _for_each_inner!((GPIO9)); - _for_each_inner!((GPIO10)); _for_each_inner!((GPIO11)); - _for_each_inner!((GPIO12)); _for_each_inner!((GPIO13)); - _for_each_inner!((GPIO14)); _for_each_inner!((GPIO15)); - _for_each_inner!((GPIO16)); _for_each_inner!((GPIO17)); - _for_each_inner!((GPIO18)); _for_each_inner!((GPIO19)); - _for_each_inner!((GPIO20)); _for_each_inner!((GPIO21)); - _for_each_inner!((GPIO22)); _for_each_inner!((GPIO23)); - _for_each_inner!((GPIO24)); _for_each_inner!((GPIO25)); - _for_each_inner!((GPIO26)); _for_each_inner!((GPIO27)); - _for_each_inner!((GPIO28)); _for_each_inner!((GPIO29)); - _for_each_inner!((GPIO30)); _for_each_inner!((GPIO31)); - _for_each_inner!((GPIO32)); _for_each_inner!((GPIO33)); - _for_each_inner!((GPIO34)); _for_each_inner!((GPIO35)); - _for_each_inner!((GPIO36)); _for_each_inner!((GPIO37)); - _for_each_inner!((GPIO38)); _for_each_inner!((GPIO39)); - _for_each_inner!((GPIO40)); _for_each_inner!((GPIO41)); - _for_each_inner!((GPIO42)); _for_each_inner!((GPIO43)); - _for_each_inner!((GPIO44)); _for_each_inner!((GPIO45)); - _for_each_inner!((GPIO46)); _for_each_inner!((GPIO47)); - _for_each_inner!((GPIO48)); _for_each_inner!((GPIO49)); - _for_each_inner!((GPIO50)); _for_each_inner!((GPIO51)); - _for_each_inner!((GPIO52)); _for_each_inner!((GPIO53)); - _for_each_inner!((GPIO54)); _for_each_inner!((ADC(unstable))); - _for_each_inner!((AES(unstable))); _for_each_inner!((AHB_DMA(unstable))); - _for_each_inner!((ASSIST_DEBUG(unstable))); - _for_each_inner!((AXI_DMA(unstable))); _for_each_inner!((AXI_ICM(unstable))); - _for_each_inner!((BITSCRAMBLER(unstable))); _for_each_inner!((CACHE(unstable))); - _for_each_inner!((DMA(unstable))); _for_each_inner!((DS(unstable))); - _for_each_inner!((ECC(unstable))); _for_each_inner!((ECDSA(unstable))); - _for_each_inner!((EFUSE(unstable))); _for_each_inner!((GPIO(unstable))); - _for_each_inner!((GPIO_SD(unstable))); _for_each_inner!((H264(unstable))); - _for_each_inner!((H264_DMA(unstable))); _for_each_inner!((HMAC(unstable))); - _for_each_inner!((HP_SYS(unstable))); - _for_each_inner!((HP_SYS_CLKRST(unstable))); _for_each_inner!((I2C0(unstable))); - _for_each_inner!((I2C1(unstable))); _for_each_inner!((I2S0(unstable))); - _for_each_inner!((I2S1(unstable))); _for_each_inner!((I2S2(unstable))); - _for_each_inner!((I3C_MST(unstable))); _for_each_inner!((I3C_MST_MEM(unstable))); - _for_each_inner!((I3C_SLV(unstable))); - _for_each_inner!((INTERRUPT_CORE0(unstable))); - _for_each_inner!((INTERRUPT_CORE1(unstable))); - _for_each_inner!((IO_MUX(unstable))); _for_each_inner!((ISP(unstable))); - _for_each_inner!((JPEG(unstable))); _for_each_inner!((LCD_CAM(unstable))); - _for_each_inner!((LEDC(unstable))); _for_each_inner!((LP_ADC(unstable))); - _for_each_inner!((LP_ANA(unstable))); - _for_each_inner!((LP_AON_CLKRST(unstable))); - _for_each_inner!((LP_GPIO(unstable))); _for_each_inner!((LP_HUK(unstable))); - _for_each_inner!((LP_I2C0(unstable))); - _for_each_inner!((LP_I2C_ANA_MST(unstable))); - _for_each_inner!((LP_I2S0(unstable))); _for_each_inner!((LP_INTR(unstable))); - _for_each_inner!((LP_IO_MUX(unstable))); _for_each_inner!((LP_PERI(unstable))); - _for_each_inner!((LP_SYS(unstable))); _for_each_inner!((LP_TIMER(unstable))); - _for_each_inner!((LP_TOUCH(unstable))); _for_each_inner!((LP_TSENS(unstable))); - _for_each_inner!((LP_UART(unstable))); _for_each_inner!((LP_WDT(unstable))); - _for_each_inner!((MCPWM0(unstable))); _for_each_inner!((MCPWM1(unstable))); - _for_each_inner!((MIPI_CSI_BRIDGE(unstable))); - _for_each_inner!((MIPI_CSI_HOST(unstable))); - _for_each_inner!((MIPI_DSI_BRIDGE(unstable))); - _for_each_inner!((MIPI_DSI_HOST(unstable))); - _for_each_inner!((PARL_IO(unstable))); _for_each_inner!((PAU(unstable))); - _for_each_inner!((PCNT(unstable))); _for_each_inner!((PMU(unstable))); - _for_each_inner!((PPA(unstable))); _for_each_inner!((PVT(unstable))); - _for_each_inner!((RMT(unstable))); _for_each_inner!((RSA(unstable))); - _for_each_inner!((SDHOST(unstable))); _for_each_inner!((SHA(unstable))); - _for_each_inner!((SOC_ETM(unstable))); _for_each_inner!((SPI0(unstable))); - _for_each_inner!((SPI1(unstable))); _for_each_inner!((SPI2(unstable))); - _for_each_inner!((SPI3(unstable))); _for_each_inner!((SYSTIMER(unstable))); - _for_each_inner!((TIMG0(unstable))); _for_each_inner!((TIMG1(unstable))); - _for_each_inner!((TRACE0(unstable))); _for_each_inner!((TRACE1(unstable))); - _for_each_inner!((TWAI0(unstable))); _for_each_inner!((TWAI1(unstable))); - _for_each_inner!((TWAI2(unstable))); _for_each_inner!((UART0(unstable))); - _for_each_inner!((UART1(unstable))); _for_each_inner!((UART2(unstable))); - _for_each_inner!((UART3(unstable))); _for_each_inner!((UART4(unstable))); - _for_each_inner!((UHCI0(unstable))); _for_each_inner!((USB_DEVICE(unstable))); - _for_each_inner!((USB_WRAP(unstable))); _for_each_inner!((LPWR(unstable))); - _for_each_inner!((SYSTEM(unstable))); _for_each_inner!((SW_INTERRUPT(unstable))); - _for_each_inner!((all(@ peri_type #[doc = "GPIO0 peripheral singleton"] GPIO0 <= - virtual()), (@ peri_type #[doc = "GPIO1 peripheral singleton"] GPIO1 <= - virtual()), (@ peri_type #[doc = + _for_each_inner_peripheral!((@ peri_type #[doc = "LP_WDT peripheral singleton"] + LP_WDT <= LP_WDT() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "LPWR peripheral singleton"] LPWR <= LP_SYS() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "PMU peripheral singleton"] PMU + <= PMU() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "SYSTIMER peripheral singleton"] SYSTIMER <= SYSTIMER() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "TIMG0 peripheral singleton"] + TIMG0 <= TIMG0() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "TIMG1 peripheral singleton"] TIMG1 <= TIMG1() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "UART0 peripheral singleton"] + UART0 <= UART0(UART0 : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "UART1 peripheral singleton"] UART1 <= UART1(UART1 : { + bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt }) + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "UART2 peripheral singleton"] UART2 <= UART2(UART2 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "UART3 peripheral singleton"] + UART3 <= UART3(UART3 : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "UART4 peripheral singleton"] UART4 <= UART4(UART4 : { + bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt }) + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "SPI2 peripheral singleton"] SPI2 <= SPI2(SPI2 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "SPI3 peripheral singleton"] + SPI3 <= SPI2(SPI3 : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "I2C0 peripheral singleton"] I2C0 <= I2C0(I2C0 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "I2C1 peripheral singleton"] + I2C1 <= I2C1(I2C1 : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "TWAI0 peripheral singleton"] TWAI0 <= TWAI0(TWAI0 : { + bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt }) + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "TWAI1 peripheral singleton"] TWAI1 <= TWAI1(TWAI1 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "TWAI2 peripheral singleton"] + TWAI2 <= TWAI2(TWAI2 : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "PSRAM peripheral singleton"] PSRAM <= virtual() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "DMA peripheral singleton"] DMA + <= AHB_DMA() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "DMA_CH0 peripheral singleton"] DMA_CH0 <= virtual() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "DMA_CH1 peripheral singleton"] + DMA_CH1 <= virtual() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc + = "DMA_CH2 peripheral singleton"] DMA_CH2 <= virtual() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = + "USB_DEVICE peripheral singleton"] USB_DEVICE <= USB_DEVICE(USB_DEVICE : { + bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt }) + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "SDHOST peripheral singleton"] SDHOST <= SDHOST() (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "LEDC peripheral singleton"] + LEDC <= LEDC(LEDC : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "MCPWM0 peripheral singleton"] MCPWM0 <= MCPWM0(PWM0 : { + bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt }) + (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "MCPWM1 peripheral singleton"] MCPWM1 <= MCPWM1(PWM1 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "PCNT peripheral singleton"] + PCNT <= PCNT(PCNT : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable))); _for_each_inner_peripheral!((@ peri_type + #[doc = "RMT peripheral singleton"] RMT <= RMT(RMT : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "ADC peripheral singleton"] ADC + <= ADC() (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "AES peripheral singleton"] AES <= AES(AES : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "SHA peripheral singleton"] SHA + <= SHA(SHA : { bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt + }) (unstable))); _for_each_inner_peripheral!((@ peri_type #[doc = + "RSA peripheral singleton"] RSA <= RSA(RSA : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable))); + _for_each_inner_peripheral!((@ peri_type #[doc = "ECC peripheral singleton"] ECC + <= ECC(ECC : { bind_peri_interrupt, enable_peri_interrupt, disable_peri_interrupt + }) (unstable))); _for_each_inner_peripheral!((GPIO0)); + _for_each_inner_peripheral!((GPIO1)); _for_each_inner_peripheral!((GPIO2)); + _for_each_inner_peripheral!((GPIO3)); _for_each_inner_peripheral!((GPIO4)); + _for_each_inner_peripheral!((GPIO5)); _for_each_inner_peripheral!((GPIO6)); + _for_each_inner_peripheral!((GPIO7)); _for_each_inner_peripheral!((GPIO8)); + _for_each_inner_peripheral!((GPIO9)); _for_each_inner_peripheral!((GPIO10)); + _for_each_inner_peripheral!((GPIO11)); _for_each_inner_peripheral!((GPIO12)); + _for_each_inner_peripheral!((GPIO13)); _for_each_inner_peripheral!((GPIO14)); + _for_each_inner_peripheral!((GPIO15)); _for_each_inner_peripheral!((GPIO16)); + _for_each_inner_peripheral!((GPIO17)); _for_each_inner_peripheral!((GPIO18)); + _for_each_inner_peripheral!((GPIO19)); _for_each_inner_peripheral!((GPIO20)); + _for_each_inner_peripheral!((GPIO21)); _for_each_inner_peripheral!((GPIO22)); + _for_each_inner_peripheral!((GPIO23)); _for_each_inner_peripheral!((GPIO24)); + _for_each_inner_peripheral!((GPIO25)); _for_each_inner_peripheral!((GPIO26)); + _for_each_inner_peripheral!((GPIO27)); _for_each_inner_peripheral!((GPIO28)); + _for_each_inner_peripheral!((GPIO29)); _for_each_inner_peripheral!((GPIO30)); + _for_each_inner_peripheral!((GPIO31)); _for_each_inner_peripheral!((GPIO32)); + _for_each_inner_peripheral!((GPIO33)); _for_each_inner_peripheral!((GPIO34)); + _for_each_inner_peripheral!((GPIO35)); _for_each_inner_peripheral!((GPIO36)); + _for_each_inner_peripheral!((GPIO37)); _for_each_inner_peripheral!((GPIO38)); + _for_each_inner_peripheral!((GPIO39)); _for_each_inner_peripheral!((GPIO40)); + _for_each_inner_peripheral!((GPIO41)); _for_each_inner_peripheral!((GPIO42)); + _for_each_inner_peripheral!((GPIO43)); _for_each_inner_peripheral!((GPIO44)); + _for_each_inner_peripheral!((GPIO45)); _for_each_inner_peripheral!((GPIO46)); + _for_each_inner_peripheral!((GPIO47)); _for_each_inner_peripheral!((GPIO48)); + _for_each_inner_peripheral!((GPIO49)); _for_each_inner_peripheral!((GPIO50)); + _for_each_inner_peripheral!((GPIO51)); _for_each_inner_peripheral!((GPIO52)); + _for_each_inner_peripheral!((GPIO53)); _for_each_inner_peripheral!((GPIO54)); + _for_each_inner_peripheral!((GPIO(unstable))); + _for_each_inner_peripheral!((HP_SYS(unstable))); + _for_each_inner_peripheral!((HP_SYS_CLKRST(unstable))); + _for_each_inner_peripheral!((INTERRUPT_CORE0(unstable))); + _for_each_inner_peripheral!((INTERRUPT_CORE1(unstable))); + _for_each_inner_peripheral!((CLIC(unstable))); + _for_each_inner_peripheral!((IO_MUX(unstable))); + _for_each_inner_peripheral!((LP_AON(unstable))); + _for_each_inner_peripheral!((LP_AON_CLKRST(unstable))); + _for_each_inner_peripheral!((LP_SYS(unstable))); + _for_each_inner_peripheral!((LP_WDT(unstable))); + _for_each_inner_peripheral!((LPWR(unstable))); + _for_each_inner_peripheral!((PMU(unstable))); + _for_each_inner_peripheral!((SYSTIMER(unstable))); + _for_each_inner_peripheral!((TIMG0(unstable))); + _for_each_inner_peripheral!((TIMG1(unstable))); + _for_each_inner_peripheral!((UART0(unstable))); + _for_each_inner_peripheral!((UART1(unstable))); + _for_each_inner_peripheral!((UART2(unstable))); + _for_each_inner_peripheral!((UART3(unstable))); + _for_each_inner_peripheral!((UART4(unstable))); + _for_each_inner_peripheral!((SPI2(unstable))); + _for_each_inner_peripheral!((SPI3(unstable))); + _for_each_inner_peripheral!((I2C0(unstable))); + _for_each_inner_peripheral!((I2C1(unstable))); + _for_each_inner_peripheral!((TWAI0(unstable))); + _for_each_inner_peripheral!((TWAI1(unstable))); + _for_each_inner_peripheral!((TWAI2(unstable))); + _for_each_inner_peripheral!((PSRAM(unstable))); + _for_each_inner_peripheral!((DMA(unstable))); + _for_each_inner_peripheral!((DMA_CH0(unstable))); + _for_each_inner_peripheral!((DMA_CH1(unstable))); + _for_each_inner_peripheral!((DMA_CH2(unstable))); + _for_each_inner_peripheral!((USB_DEVICE(unstable))); + _for_each_inner_peripheral!((SDHOST(unstable))); + _for_each_inner_peripheral!((LEDC(unstable))); + _for_each_inner_peripheral!((MCPWM0(unstable))); + _for_each_inner_peripheral!((MCPWM1(unstable))); + _for_each_inner_peripheral!((PCNT(unstable))); + _for_each_inner_peripheral!((RMT(unstable))); + _for_each_inner_peripheral!((ADC(unstable))); + _for_each_inner_peripheral!((AES(unstable))); + _for_each_inner_peripheral!((SHA(unstable))); + _for_each_inner_peripheral!((RSA(unstable))); + _for_each_inner_peripheral!((ECC(unstable))); _for_each_inner_peripheral!((SPI2, + Spi2, 1)); _for_each_inner_peripheral!((SPI3, Spi3, 2)); + _for_each_inner_peripheral!((AES, Aes, 4)); _for_each_inner_peripheral!((SHA, + Sha, 5)); _for_each_inner_peripheral!((all(@ peri_type #[doc = + "GPIO0 peripheral singleton"] GPIO0 <= virtual()), (@ peri_type #[doc = + "GPIO1 peripheral singleton"] GPIO1 <= virtual()), (@ peri_type #[doc = "GPIO2 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = "
"] #[doc = "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] @@ -2498,21 +2676,76 @@ macro_rules! for_each_peripheral { "GPIO21 peripheral singleton"] GPIO21 <= virtual()), (@ peri_type #[doc = "GPIO22 peripheral singleton"] GPIO22 <= virtual()), (@ peri_type #[doc = "GPIO23 peripheral singleton"] GPIO23 <= virtual()), (@ peri_type #[doc = - "GPIO24 peripheral singleton"] GPIO24 <= virtual()), (@ peri_type #[doc = - "GPIO25 peripheral singleton"] GPIO25 <= virtual()), (@ peri_type #[doc = - "GPIO26 peripheral singleton"] GPIO26 <= virtual()), (@ peri_type #[doc = - "GPIO27 peripheral singleton"] GPIO27 <= virtual()), (@ peri_type #[doc = + "GPIO24 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO24 <= virtual()), (@ peri_type #[doc = + "GPIO25 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO25 <= virtual()), (@ peri_type #[doc = + "GPIO26 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO26 <= virtual()), (@ peri_type #[doc = + "GPIO27 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • These pins may be used to debug the chip using USB.
  • "] #[doc = "
"] + #[doc = "
"] GPIO27 <= virtual()), (@ peri_type #[doc = "GPIO28 peripheral singleton"] GPIO28 <= virtual()), (@ peri_type #[doc = "GPIO29 peripheral singleton"] GPIO29 <= virtual()), (@ peri_type #[doc = "GPIO30 peripheral singleton"] GPIO30 <= virtual()), (@ peri_type #[doc = "GPIO31 peripheral singleton"] GPIO31 <= virtual()), (@ peri_type #[doc = - "GPIO32 peripheral singleton"] GPIO32 <= virtual()), (@ peri_type #[doc = - "GPIO33 peripheral singleton"] GPIO33 <= virtual()), (@ peri_type #[doc = - "GPIO34 peripheral singleton"] GPIO34 <= virtual()), (@ peri_type #[doc = - "GPIO35 peripheral singleton"] GPIO35 <= virtual()), (@ peri_type #[doc = - "GPIO36 peripheral singleton"] GPIO36 <= virtual()), (@ peri_type #[doc = - "GPIO37 peripheral singleton"] GPIO37 <= virtual()), (@ peri_type #[doc = - "GPIO38 peripheral singleton"] GPIO38 <= virtual()), (@ peri_type #[doc = + "GPIO32 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO32 <= virtual()), (@ peri_type #[doc = + "GPIO33 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO33 <= virtual()), (@ peri_type #[doc = + "GPIO34 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO34 <= virtual()), (@ peri_type #[doc = + "GPIO35 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO35 <= virtual()), (@ peri_type #[doc = + "GPIO36 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO36 <= virtual()), (@ peri_type #[doc = + "GPIO37 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO37 <= virtual()), (@ peri_type #[doc = + "GPIO38 peripheral singleton (Limitations exist)"] #[doc = ""] #[doc = + "
"] #[doc = + "This pin may be available with certain limitations. Check your hardware to make sure whether you can use it."] + #[doc = "
    "] #[doc = + "
  • This pin is a strapping pin, it determines how the chip boots.
  • "] #[doc + = "
"] #[doc = "
"] GPIO38 <= virtual()), (@ peri_type #[doc = "GPIO39 peripheral singleton"] GPIO39 <= virtual()), (@ peri_type #[doc = "GPIO40 peripheral singleton"] GPIO40 <= virtual()), (@ peri_type #[doc = "GPIO41 peripheral singleton"] GPIO41 <= virtual()), (@ peri_type #[doc = @@ -2529,144 +2762,100 @@ macro_rules! for_each_peripheral { "GPIO52 peripheral singleton"] GPIO52 <= virtual()), (@ peri_type #[doc = "GPIO53 peripheral singleton"] GPIO53 <= virtual()), (@ peri_type #[doc = "GPIO54 peripheral singleton"] GPIO54 <= virtual()), (@ peri_type #[doc = - "ADC peripheral singleton"] ADC <= ADC() (unstable)), (@ peri_type #[doc = - "AES peripheral singleton"] AES <= AES() (unstable)), (@ peri_type #[doc = - "AHB_DMA peripheral singleton"] AHB_DMA <= AHB_DMA() (unstable)), (@ peri_type - #[doc = "ASSIST_DEBUG peripheral singleton"] ASSIST_DEBUG <= ASSIST_DEBUG() - (unstable)), (@ peri_type #[doc = "AXI_DMA peripheral singleton"] AXI_DMA <= - AXI_DMA() (unstable)), (@ peri_type #[doc = "AXI_ICM peripheral singleton"] - AXI_ICM <= AXI_ICM() (unstable)), (@ peri_type #[doc = - "BITSCRAMBLER peripheral singleton"] BITSCRAMBLER <= BITSCRAMBLER() (unstable)), - (@ peri_type #[doc = "CACHE peripheral singleton"] CACHE <= CACHE() (unstable)), - (@ peri_type #[doc = "DMA peripheral singleton"] DMA <= DMA() (unstable)), (@ - peri_type #[doc = "DS peripheral singleton"] DS <= DS() (unstable)), (@ peri_type - #[doc = "ECC peripheral singleton"] ECC <= ECC() (unstable)), (@ peri_type #[doc - = "ECDSA peripheral singleton"] ECDSA <= ECDSA() (unstable)), (@ peri_type #[doc - = "EFUSE peripheral singleton"] EFUSE <= EFUSE() (unstable)), (@ peri_type #[doc - = "GPIO peripheral singleton"] GPIO <= GPIO() (unstable)), (@ peri_type #[doc = - "GPIO_SD peripheral singleton"] GPIO_SD <= GPIO_SD() (unstable)), (@ peri_type - #[doc = "H264 peripheral singleton"] H264 <= H264() (unstable)), (@ peri_type - #[doc = "H264_DMA peripheral singleton"] H264_DMA <= H264_DMA() (unstable)), (@ - peri_type #[doc = "HMAC peripheral singleton"] HMAC <= HMAC() (unstable)), (@ - peri_type #[doc = "HP_SYS peripheral singleton"] HP_SYS <= HP_SYS() (unstable)), - (@ peri_type #[doc = "HP_SYS_CLKRST peripheral singleton"] HP_SYS_CLKRST <= - HP_SYS_CLKRST() (unstable)), (@ peri_type #[doc = "I2C0 peripheral singleton"] - I2C0 <= I2C0() (unstable)), (@ peri_type #[doc = "I2C1 peripheral singleton"] - I2C1 <= I2C1() (unstable)), (@ peri_type #[doc = "I2S0 peripheral singleton"] - I2S0 <= I2S0() (unstable)), (@ peri_type #[doc = "I2S1 peripheral singleton"] - I2S1 <= I2S1() (unstable)), (@ peri_type #[doc = "I2S2 peripheral singleton"] - I2S2 <= I2S2() (unstable)), (@ peri_type #[doc = "I3C_MST peripheral singleton"] - I3C_MST <= I3C_MST() (unstable)), (@ peri_type #[doc = - "I3C_MST_MEM peripheral singleton"] I3C_MST_MEM <= I3C_MST_MEM() (unstable)), (@ - peri_type #[doc = "I3C_SLV peripheral singleton"] I3C_SLV <= I3C_SLV() + "EFUSE peripheral singleton"] EFUSE <= EFUSE() (unstable)), (@ peri_type #[doc = + "GPIO peripheral singleton"] GPIO <= GPIO() (unstable)), (@ peri_type #[doc = + "HP_SYS peripheral singleton"] HP_SYS <= HP_SYS() (unstable)), (@ peri_type #[doc + = "HP_SYS_CLKRST peripheral singleton"] HP_SYS_CLKRST <= HP_SYS_CLKRST() (unstable)), (@ peri_type #[doc = "INTERRUPT_CORE0 peripheral singleton"] INTERRUPT_CORE0 <= INTERRUPT_CORE0() (unstable)), (@ peri_type #[doc = "INTERRUPT_CORE1 peripheral singleton"] INTERRUPT_CORE1 <= INTERRUPT_CORE1() + (unstable)), (@ peri_type #[doc = "CLIC peripheral singleton"] CLIC <= CLIC() (unstable)), (@ peri_type #[doc = "IO_MUX peripheral singleton"] IO_MUX <= - IO_MUX() (unstable)), (@ peri_type #[doc = "ISP peripheral singleton"] ISP <= - ISP() (unstable)), (@ peri_type #[doc = "JPEG peripheral singleton"] JPEG <= - JPEG() (unstable)), (@ peri_type #[doc = "LCD_CAM peripheral singleton"] LCD_CAM - <= LCD_CAM() (unstable)), (@ peri_type #[doc = "LEDC peripheral singleton"] LEDC - <= LEDC() (unstable)), (@ peri_type #[doc = "LP_ADC peripheral singleton"] LP_ADC - <= LP_ADC() (unstable)), (@ peri_type #[doc = "LP_ANA peripheral singleton"] - LP_ANA <= LP_ANA() (unstable)), (@ peri_type #[doc = + IO_MUX() (unstable)), (@ peri_type #[doc = "LP_AON peripheral singleton"] LP_AON + <= LP_SYS() (unstable)), (@ peri_type #[doc = "LP_AON_CLKRST peripheral singleton"] LP_AON_CLKRST <= LP_AON_CLKRST() - (unstable)), (@ peri_type #[doc = "LP_GPIO peripheral singleton"] LP_GPIO <= - LP_GPIO() (unstable)), (@ peri_type #[doc = "LP_HUK peripheral singleton"] LP_HUK - <= LP_HUK() (unstable)), (@ peri_type #[doc = "LP_I2C0 peripheral singleton"] - LP_I2C0 <= LP_I2C0() (unstable)), (@ peri_type #[doc = - "LP_I2C_ANA_MST peripheral singleton"] LP_I2C_ANA_MST <= LP_I2C_ANA_MST() - (unstable)), (@ peri_type #[doc = "LP_I2S0 peripheral singleton"] LP_I2S0 <= - LP_I2S0() (unstable)), (@ peri_type #[doc = "LP_INTR peripheral singleton"] - LP_INTR <= LP_INTR() (unstable)), (@ peri_type #[doc = - "LP_IO_MUX peripheral singleton"] LP_IO_MUX <= LP_IO_MUX() (unstable)), (@ - peri_type #[doc = "LP_PERI peripheral singleton"] LP_PERI <= LP_PERI() (unstable)), (@ peri_type #[doc = "LP_SYS peripheral singleton"] LP_SYS <= - LP_SYS() (unstable)), (@ peri_type #[doc = "LP_TIMER peripheral singleton"] - LP_TIMER <= LP_TIMER() (unstable)), (@ peri_type #[doc = - "LP_TOUCH peripheral singleton"] LP_TOUCH <= LP_TOUCH() (unstable)), (@ peri_type - #[doc = "LP_TSENS peripheral singleton"] LP_TSENS <= LP_TSENS() (unstable)), (@ - peri_type #[doc = "LP_UART peripheral singleton"] LP_UART <= LP_UART() - (unstable)), (@ peri_type #[doc = "LP_WDT peripheral singleton"] LP_WDT <= - LP_WDT() (unstable)), (@ peri_type #[doc = "MCPWM0 peripheral singleton"] MCPWM0 - <= MCPWM0() (unstable)), (@ peri_type #[doc = "MCPWM1 peripheral singleton"] - MCPWM1 <= MCPWM1() (unstable)), (@ peri_type #[doc = - "MIPI_CSI_BRIDGE peripheral singleton"] MIPI_CSI_BRIDGE <= MIPI_CSI_BRIDGE() - (unstable)), (@ peri_type #[doc = "MIPI_CSI_HOST peripheral singleton"] - MIPI_CSI_HOST <= MIPI_CSI_HOST() (unstable)), (@ peri_type #[doc = - "MIPI_DSI_BRIDGE peripheral singleton"] MIPI_DSI_BRIDGE <= MIPI_DSI_BRIDGE() - (unstable)), (@ peri_type #[doc = "MIPI_DSI_HOST peripheral singleton"] - MIPI_DSI_HOST <= MIPI_DSI_HOST() (unstable)), (@ peri_type #[doc = - "PARL_IO peripheral singleton"] PARL_IO <= PARL_IO() (unstable)), (@ peri_type - #[doc = "PAU peripheral singleton"] PAU <= PAU() (unstable)), (@ peri_type #[doc - = "PCNT peripheral singleton"] PCNT <= PCNT() (unstable)), (@ peri_type #[doc = - "PMU peripheral singleton"] PMU <= PMU() (unstable)), (@ peri_type #[doc = - "PPA peripheral singleton"] PPA <= PPA() (unstable)), (@ peri_type #[doc = - "PVT peripheral singleton"] PVT <= PVT() (unstable)), (@ peri_type #[doc = - "RMT peripheral singleton"] RMT <= RMT() (unstable)), (@ peri_type #[doc = - "RSA peripheral singleton"] RSA <= RSA() (unstable)), (@ peri_type #[doc = - "SDHOST peripheral singleton"] SDHOST <= SDHOST() (unstable)), (@ peri_type #[doc - = "SHA peripheral singleton"] SHA <= SHA() (unstable)), (@ peri_type #[doc = - "SOC_ETM peripheral singleton"] SOC_ETM <= SOC_ETM() (unstable)), (@ peri_type - #[doc = "SPI0 peripheral singleton"] SPI0 <= SPI0() (unstable)), (@ peri_type - #[doc = "SPI1 peripheral singleton"] SPI1 <= SPI1() (unstable)), (@ peri_type - #[doc = "SPI2 peripheral singleton"] SPI2 <= SPI2() (unstable)), (@ peri_type - #[doc = "SPI3 peripheral singleton"] SPI3 <= SPI3() (unstable)), (@ peri_type - #[doc = "SYSTIMER peripheral singleton"] SYSTIMER <= SYSTIMER() (unstable)), (@ - peri_type #[doc = "TIMG0 peripheral singleton"] TIMG0 <= TIMG0() (unstable)), (@ - peri_type #[doc = "TIMG1 peripheral singleton"] TIMG1 <= TIMG1() (unstable)), (@ - peri_type #[doc = "TRACE0 peripheral singleton"] TRACE0 <= TRACE0() (unstable)), - (@ peri_type #[doc = "TRACE1 peripheral singleton"] TRACE1 <= TRACE1() - (unstable)), (@ peri_type #[doc = "TWAI0 peripheral singleton"] TWAI0 <= TWAI0() - (unstable)), (@ peri_type #[doc = "TWAI1 peripheral singleton"] TWAI1 <= TWAI1() - (unstable)), (@ peri_type #[doc = "TWAI2 peripheral singleton"] TWAI2 <= TWAI2() - (unstable)), (@ peri_type #[doc = "UART0 peripheral singleton"] UART0 <= UART0() - (unstable)), (@ peri_type #[doc = "UART1 peripheral singleton"] UART1 <= UART1() - (unstable)), (@ peri_type #[doc = "UART2 peripheral singleton"] UART2 <= UART2() - (unstable)), (@ peri_type #[doc = "UART3 peripheral singleton"] UART3 <= UART3() - (unstable)), (@ peri_type #[doc = "UART4 peripheral singleton"] UART4 <= UART4() - (unstable)), (@ peri_type #[doc = "UHCI0 peripheral singleton"] UHCI0 <= UHCI0() - (unstable)), (@ peri_type #[doc = "USB_DEVICE peripheral singleton"] USB_DEVICE - <= USB_DEVICE() (unstable)), (@ peri_type #[doc = - "USB_WRAP peripheral singleton"] USB_WRAP <= USB_WRAP() (unstable)), (@ peri_type - #[doc = "LPWR peripheral singleton"] LPWR <= LP_AON_CLKRST() (unstable)), (@ - peri_type #[doc = "SYSTEM peripheral singleton"] SYSTEM <= HP_SYS() (unstable)), - (@ peri_type #[doc = "SW_INTERRUPT peripheral singleton"] SW_INTERRUPT <= - virtual() (unstable)))); _for_each_inner!((singletons(GPIO0), (GPIO1), (GPIO2), - (GPIO3), (GPIO4), (GPIO5), (GPIO6), (GPIO7), (GPIO8), (GPIO9), (GPIO10), - (GPIO11), (GPIO12), (GPIO13), (GPIO14), (GPIO15), (GPIO16), (GPIO17), (GPIO18), - (GPIO19), (GPIO20), (GPIO21), (GPIO22), (GPIO23), (GPIO24), (GPIO25), (GPIO26), - (GPIO27), (GPIO28), (GPIO29), (GPIO30), (GPIO31), (GPIO32), (GPIO33), (GPIO34), - (GPIO35), (GPIO36), (GPIO37), (GPIO38), (GPIO39), (GPIO40), (GPIO41), (GPIO42), - (GPIO43), (GPIO44), (GPIO45), (GPIO46), (GPIO47), (GPIO48), (GPIO49), (GPIO50), - (GPIO51), (GPIO52), (GPIO53), (GPIO54), (ADC(unstable)), (AES(unstable)), - (AHB_DMA(unstable)), (ASSIST_DEBUG(unstable)), (AXI_DMA(unstable)), - (AXI_ICM(unstable)), (BITSCRAMBLER(unstable)), (CACHE(unstable)), - (DMA(unstable)), (DS(unstable)), (ECC(unstable)), (ECDSA(unstable)), - (EFUSE(unstable)), (GPIO(unstable)), (GPIO_SD(unstable)), (H264(unstable)), - (H264_DMA(unstable)), (HMAC(unstable)), (HP_SYS(unstable)), - (HP_SYS_CLKRST(unstable)), (I2C0(unstable)), (I2C1(unstable)), (I2S0(unstable)), - (I2S1(unstable)), (I2S2(unstable)), (I3C_MST(unstable)), (I3C_MST_MEM(unstable)), - (I3C_SLV(unstable)), (INTERRUPT_CORE0(unstable)), (INTERRUPT_CORE1(unstable)), - (IO_MUX(unstable)), (ISP(unstable)), (JPEG(unstable)), (LCD_CAM(unstable)), - (LEDC(unstable)), (LP_ADC(unstable)), (LP_ANA(unstable)), - (LP_AON_CLKRST(unstable)), (LP_GPIO(unstable)), (LP_HUK(unstable)), - (LP_I2C0(unstable)), (LP_I2C_ANA_MST(unstable)), (LP_I2S0(unstable)), - (LP_INTR(unstable)), (LP_IO_MUX(unstable)), (LP_PERI(unstable)), - (LP_SYS(unstable)), (LP_TIMER(unstable)), (LP_TOUCH(unstable)), - (LP_TSENS(unstable)), (LP_UART(unstable)), (LP_WDT(unstable)), - (MCPWM0(unstable)), (MCPWM1(unstable)), (MIPI_CSI_BRIDGE(unstable)), - (MIPI_CSI_HOST(unstable)), (MIPI_DSI_BRIDGE(unstable)), - (MIPI_DSI_HOST(unstable)), (PARL_IO(unstable)), (PAU(unstable)), - (PCNT(unstable)), (PMU(unstable)), (PPA(unstable)), (PVT(unstable)), - (RMT(unstable)), (RSA(unstable)), (SDHOST(unstable)), (SHA(unstable)), - (SOC_ETM(unstable)), (SPI0(unstable)), (SPI1(unstable)), (SPI2(unstable)), - (SPI3(unstable)), (SYSTIMER(unstable)), (TIMG0(unstable)), (TIMG1(unstable)), - (TRACE0(unstable)), (TRACE1(unstable)), (TWAI0(unstable)), (TWAI1(unstable)), - (TWAI2(unstable)), (UART0(unstable)), (UART1(unstable)), (UART2(unstable)), - (UART3(unstable)), (UART4(unstable)), (UHCI0(unstable)), (USB_DEVICE(unstable)), - (USB_WRAP(unstable)), (LPWR(unstable)), (SYSTEM(unstable)), - (SW_INTERRUPT(unstable)))); + LP_SYS() (unstable)), (@ peri_type #[doc = "LP_WDT peripheral singleton"] LP_WDT + <= LP_WDT() (unstable)), (@ peri_type #[doc = "LPWR peripheral singleton"] LPWR + <= LP_SYS() (unstable)), (@ peri_type #[doc = "PMU peripheral singleton"] PMU <= + PMU() (unstable)), (@ peri_type #[doc = "SYSTIMER peripheral singleton"] SYSTIMER + <= SYSTIMER() (unstable)), (@ peri_type #[doc = "TIMG0 peripheral singleton"] + TIMG0 <= TIMG0() (unstable)), (@ peri_type #[doc = "TIMG1 peripheral singleton"] + TIMG1 <= TIMG1() (unstable)), (@ peri_type #[doc = "UART0 peripheral singleton"] + UART0 <= UART0(UART0 : { bind_peri_interrupt, enable_peri_interrupt, + disable_peri_interrupt }) (unstable)), (@ peri_type #[doc = + "UART1 peripheral singleton"] UART1 <= UART1(UART1 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "UART2 peripheral singleton"] UART2 <= UART2(UART2 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "UART3 peripheral singleton"] UART3 <= UART3(UART3 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "UART4 peripheral singleton"] UART4 <= UART4(UART4 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "SPI2 peripheral singleton"] SPI2 <= SPI2(SPI2 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "SPI3 peripheral singleton"] SPI3 <= SPI2(SPI3 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "I2C0 peripheral singleton"] I2C0 <= I2C0(I2C0 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "I2C1 peripheral singleton"] I2C1 <= I2C1(I2C1 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "TWAI0 peripheral singleton"] TWAI0 <= TWAI0(TWAI0 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "TWAI1 peripheral singleton"] TWAI1 <= TWAI1(TWAI1 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "TWAI2 peripheral singleton"] TWAI2 <= TWAI2(TWAI2 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "PSRAM peripheral singleton"] PSRAM <= virtual() (unstable)), (@ peri_type + #[doc = "DMA peripheral singleton"] DMA <= AHB_DMA() (unstable)), (@ peri_type + #[doc = "DMA_CH0 peripheral singleton"] DMA_CH0 <= virtual() (unstable)), (@ + peri_type #[doc = "DMA_CH1 peripheral singleton"] DMA_CH1 <= virtual() + (unstable)), (@ peri_type #[doc = "DMA_CH2 peripheral singleton"] DMA_CH2 <= + virtual() (unstable)), (@ peri_type #[doc = "USB_DEVICE peripheral singleton"] + USB_DEVICE <= USB_DEVICE(USB_DEVICE : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "SDHOST peripheral singleton"] SDHOST <= SDHOST() (unstable)), (@ peri_type + #[doc = "LEDC peripheral singleton"] LEDC <= LEDC(LEDC : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "MCPWM0 peripheral singleton"] MCPWM0 <= MCPWM0(PWM0 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "MCPWM1 peripheral singleton"] MCPWM1 <= MCPWM1(PWM1 : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "PCNT peripheral singleton"] PCNT <= PCNT(PCNT : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "RMT peripheral singleton"] RMT <= RMT(RMT : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "ADC peripheral singleton"] ADC <= ADC() (unstable)), (@ peri_type #[doc = + "AES peripheral singleton"] AES <= AES(AES : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "SHA peripheral singleton"] SHA <= SHA(SHA : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "RSA peripheral singleton"] RSA <= RSA(RSA : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)), (@ peri_type #[doc + = "ECC peripheral singleton"] ECC <= ECC(ECC : { bind_peri_interrupt, + enable_peri_interrupt, disable_peri_interrupt }) (unstable)))); + _for_each_inner_peripheral!((singletons(GPIO0), (GPIO1), (GPIO2), (GPIO3), + (GPIO4), (GPIO5), (GPIO6), (GPIO7), (GPIO8), (GPIO9), (GPIO10), (GPIO11), + (GPIO12), (GPIO13), (GPIO14), (GPIO15), (GPIO16), (GPIO17), (GPIO18), (GPIO19), + (GPIO20), (GPIO21), (GPIO22), (GPIO23), (GPIO24), (GPIO25), (GPIO26), (GPIO27), + (GPIO28), (GPIO29), (GPIO30), (GPIO31), (GPIO32), (GPIO33), (GPIO34), (GPIO35), + (GPIO36), (GPIO37), (GPIO38), (GPIO39), (GPIO40), (GPIO41), (GPIO42), (GPIO43), + (GPIO44), (GPIO45), (GPIO46), (GPIO47), (GPIO48), (GPIO49), (GPIO50), (GPIO51), + (GPIO52), (GPIO53), (GPIO54), (GPIO(unstable)), (HP_SYS(unstable)), + (HP_SYS_CLKRST(unstable)), (INTERRUPT_CORE0(unstable)), + (INTERRUPT_CORE1(unstable)), (CLIC(unstable)), (IO_MUX(unstable)), + (LP_AON(unstable)), (LP_AON_CLKRST(unstable)), (LP_SYS(unstable)), + (LP_WDT(unstable)), (LPWR(unstable)), (PMU(unstable)), (SYSTIMER(unstable)), + (TIMG0(unstable)), (TIMG1(unstable)), (UART0(unstable)), (UART1(unstable)), + (UART2(unstable)), (UART3(unstable)), (UART4(unstable)), (SPI2(unstable)), + (SPI3(unstable)), (I2C0(unstable)), (I2C1(unstable)), (TWAI0(unstable)), + (TWAI1(unstable)), (TWAI2(unstable)), (PSRAM(unstable)), (DMA(unstable)), + (DMA_CH0(unstable)), (DMA_CH1(unstable)), (DMA_CH2(unstable)), + (USB_DEVICE(unstable)), (SDHOST(unstable)), (LEDC(unstable)), (MCPWM0(unstable)), + (MCPWM1(unstable)), (PCNT(unstable)), (RMT(unstable)), (ADC(unstable)), + (AES(unstable)), (SHA(unstable)), (RSA(unstable)), (ECC(unstable)))); + _for_each_inner_peripheral!((dma_eligible(SPI2, Spi2, 1), (SPI3, Spi3, 2), (AES, + Aes, 4), (SHA, Sha, 5))); }; } /// This macro can be used to generate code for each `GPIOn` instance. @@ -2699,116 +2888,154 @@ macro_rules! for_each_peripheral { #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_gpio { ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((0, GPIO0() () ([Input] [Output]))); _for_each_inner!((1, - GPIO1() () ([Input] [Output]))); _for_each_inner!((2, GPIO2(_0 => MTCK) () - ([Input] [Output]))); _for_each_inner!((3, GPIO3(_0 => MTDI) () ([Input] - [Output]))); _for_each_inner!((4, GPIO4(_0 => MTMS) () ([Input] [Output]))); - _for_each_inner!((5, GPIO5(_0 => MTDO) () ([Input] [Output]))); - _for_each_inner!((6, GPIO6(_3 => SPI2_HOLD_PAD) (_3 => SPI2_HOLD_PAD) ([Input] - [Output]))); _for_each_inner!((7, GPIO7(_3 => SPI2_CS_PAD) (_3 => SPI2_CS_PAD) - ([Input] [Output]))); _for_each_inner!((8, GPIO8(_3 => SPI2_D_PAD) (_2 => - UART0_RTS_PAD _3 => SPI2_D_PAD) ([Input] [Output]))); _for_each_inner!((9, - GPIO9(_2 => UART0_CTS_PAD _3 => SPI2_CK_PAD) (_3 => SPI2_CK_PAD) ([Input] - [Output]))); _for_each_inner!((10, GPIO10(_3 => SPI2_Q_PAD) (_2 => UART1_TXD_PAD - _3 => SPI2_Q_PAD) ([Input] [Output]))); _for_each_inner!((11, GPIO11(_2 => - UART1_RXD_PAD _3 => SPI2_WP_PAD) (_3 => SPI2_WP_PAD) ([Input] [Output]))); - _for_each_inner!((12, GPIO12() (_2 => UART1_RTS_PAD) ([Input] [Output]))); - _for_each_inner!((13, GPIO13(_2 => UART1_CTS_PAD) () ([Input] [Output]))); - _for_each_inner!((14, GPIO14() () ([Input] [Output]))); _for_each_inner!((15, - GPIO15() () ([Input] [Output]))); _for_each_inner!((16, GPIO16() () ([Input] - [Output]))); _for_each_inner!((17, GPIO17() () ([Input] [Output]))); - _for_each_inner!((18, GPIO18() () ([Input] [Output]))); _for_each_inner!((19, - GPIO19() () ([Input] [Output]))); _for_each_inner!((20, GPIO20() () ([Input] - [Output]))); _for_each_inner!((21, GPIO21() () ([Input] [Output]))); - _for_each_inner!((22, GPIO22() () ([Input] [Output]))); _for_each_inner!((23, - GPIO23(_3 => REF_50M_CLK_PAD) () ([Input] [Output]))); _for_each_inner!((24, - GPIO24() () ([Input] [Output]))); _for_each_inner!((25, GPIO25() () ([Input] - [Output]))); _for_each_inner!((26, GPIO26() () ([Input] [Output]))); - _for_each_inner!((27, GPIO27() () ([Input] [Output]))); _for_each_inner!((28, - GPIO28(_2 => SPI2_CS_PAD _3 => GMAC_PHY_RXDV_PAD) (_2 => SPI2_CS_PAD) ([Input] - [Output]))); _for_each_inner!((29, GPIO29(_2 => SPI2_D_PAD _3 => - GMAC_PHY_RXD0_PAD) (_2 => SPI2_D_PAD) ([Input] [Output]))); _for_each_inner!((30, - GPIO30(_2 => SPI2_CK_PAD _3 => GMAC_PHY_RXD1_PAD) (_2 => SPI2_CK_PAD) ([Input] - [Output]))); _for_each_inner!((31, GPIO31(_2 => SPI2_Q_PAD _3 => - GMAC_PHY_RXER_PAD) (_2 => SPI2_Q_PAD) ([Input] [Output]))); _for_each_inner!((32, - GPIO32(_2 => SPI2_HOLD_PAD _3 => GMAC_RMII_CLK_PAD) (_2 => SPI2_HOLD_PAD) - ([Input] [Output]))); _for_each_inner!((33, GPIO33(_2 => SPI2_WP_PAD) (_2 => - SPI2_WP_PAD _3 => GMAC_PHY_TXEN_PAD) ([Input] [Output]))); _for_each_inner!((34, - GPIO34(_2 => SPI2_IO4_PAD) (_2 => SPI2_IO4_PAD _3 => GMAC_PHY_TXD0_PAD) ([Input] - [Output]))); _for_each_inner!((35, GPIO35(_2 => SPI2_IO5_PAD) (_2 => SPI2_IO5_PAD - _3 => GMAC_PHY_TXD1_PAD) ([Input] [Output]))); _for_each_inner!((36, GPIO36(_2 => - SPI2_IO6_PAD) (_2 => SPI2_IO6_PAD _3 => GMAC_PHY_TXER_PAD) ([Input] [Output]))); - _for_each_inner!((37, GPIO37(_2 => SPI2_IO7_PAD) (_0 => UART0_TXD_PAD _2 => - SPI2_IO7_PAD) ([Input] [Output]))); _for_each_inner!((38, GPIO38(_0 => - UART0_RXD_PAD) (_2 => SPI2_DQS_PAD) ([Input] [Output]))); _for_each_inner!((39, - GPIO39(_0 => SD1_CDATA0_PAD _3 => REF_50M_CLK_PAD) () ([Input] [Output]))); - _for_each_inner!((40, GPIO40(_0 => SD1_CDATA1_PAD) (_3 => GMAC_PHY_TXEN_PAD) - ([Input] [Output]))); _for_each_inner!((41, GPIO41(_0 => SD1_CDATA2_PAD) (_3 => - GMAC_PHY_TXD0_PAD) ([Input] [Output]))); _for_each_inner!((42, GPIO42(_0 => - SD1_CDATA3_PAD) (_3 => GMAC_PHY_TXD1_PAD) ([Input] [Output]))); - _for_each_inner!((43, GPIO43(_0 => SD1_CCLK_PAD) (_3 => GMAC_PHY_TXER_PAD) - ([Input] [Output]))); _for_each_inner!((44, GPIO44(_0 => SD1_CCMD_PAD _3 => - GMAC_RMII_CLK_PAD) () ([Input] [Output]))); _for_each_inner!((45, GPIO45(_0 => - SD1_CDATA4_PAD _3 => GMAC_PHY_RXDV_PAD) () ([Input] [Output]))); - _for_each_inner!((46, GPIO46(_0 => SD1_CDATA5_PAD _3 => GMAC_PHY_RXD0_PAD) () - ([Input] [Output]))); _for_each_inner!((47, GPIO47(_0 => SD1_CDATA6_PAD _3 => - GMAC_PHY_RXD1_PAD) () ([Input] [Output]))); _for_each_inner!((48, GPIO48(_0 => - SD1_CDATA7_PAD _3 => GMAC_PHY_RXER_PAD) () ([Input] [Output]))); - _for_each_inner!((49, GPIO49() (_3 => GMAC_PHY_TXEN_PAD) ([Input] [Output]))); - _for_each_inner!((50, GPIO50(_3 => GMAC_RMII_CLK_PAD) () ([Input] [Output]))); - _for_each_inner!((51, GPIO51(_3 => GMAC_PHY_RXDV_PAD) () ([Input] [Output]))); - _for_each_inner!((52, GPIO52(_3 => GMAC_PHY_RXD0_PAD) () ([Input] [Output]))); - _for_each_inner!((53, GPIO53(_3 => GMAC_PHY_RXD1_PAD) () ([Input] [Output]))); - _for_each_inner!((54, GPIO54(_3 => GMAC_PHY_RXER_PAD) () ([Input] [Output]))); - _for_each_inner!((all(0, GPIO0() () ([Input] [Output])), (1, GPIO1() () ([Input] - [Output])), (2, GPIO2(_0 => MTCK) () ([Input] [Output])), (3, GPIO3(_0 => MTDI) - () ([Input] [Output])), (4, GPIO4(_0 => MTMS) () ([Input] [Output])), (5, - GPIO5(_0 => MTDO) () ([Input] [Output])), (6, GPIO6(_3 => SPI2_HOLD_PAD) (_3 => - SPI2_HOLD_PAD) ([Input] [Output])), (7, GPIO7(_3 => SPI2_CS_PAD) (_3 => - SPI2_CS_PAD) ([Input] [Output])), (8, GPIO8(_3 => SPI2_D_PAD) (_2 => - UART0_RTS_PAD _3 => SPI2_D_PAD) ([Input] [Output])), (9, GPIO9(_2 => - UART0_CTS_PAD _3 => SPI2_CK_PAD) (_3 => SPI2_CK_PAD) ([Input] [Output])), (10, - GPIO10(_3 => SPI2_Q_PAD) (_2 => UART1_TXD_PAD _3 => SPI2_Q_PAD) ([Input] - [Output])), (11, GPIO11(_2 => UART1_RXD_PAD _3 => SPI2_WP_PAD) (_3 => - SPI2_WP_PAD) ([Input] [Output])), (12, GPIO12() (_2 => UART1_RTS_PAD) ([Input] - [Output])), (13, GPIO13(_2 => UART1_CTS_PAD) () ([Input] [Output])), (14, - GPIO14() () ([Input] [Output])), (15, GPIO15() () ([Input] [Output])), (16, - GPIO16() () ([Input] [Output])), (17, GPIO17() () ([Input] [Output])), (18, - GPIO18() () ([Input] [Output])), (19, GPIO19() () ([Input] [Output])), (20, - GPIO20() () ([Input] [Output])), (21, GPIO21() () ([Input] [Output])), (22, - GPIO22() () ([Input] [Output])), (23, GPIO23(_3 => REF_50M_CLK_PAD) () ([Input] - [Output])), (24, GPIO24() () ([Input] [Output])), (25, GPIO25() () ([Input] - [Output])), (26, GPIO26() () ([Input] [Output])), (27, GPIO27() () ([Input] - [Output])), (28, GPIO28(_2 => SPI2_CS_PAD _3 => GMAC_PHY_RXDV_PAD) (_2 => - SPI2_CS_PAD) ([Input] [Output])), (29, GPIO29(_2 => SPI2_D_PAD _3 => - GMAC_PHY_RXD0_PAD) (_2 => SPI2_D_PAD) ([Input] [Output])), (30, GPIO30(_2 => - SPI2_CK_PAD _3 => GMAC_PHY_RXD1_PAD) (_2 => SPI2_CK_PAD) ([Input] [Output])), - (31, GPIO31(_2 => SPI2_Q_PAD _3 => GMAC_PHY_RXER_PAD) (_2 => SPI2_Q_PAD) ([Input] - [Output])), (32, GPIO32(_2 => SPI2_HOLD_PAD _3 => GMAC_RMII_CLK_PAD) (_2 => - SPI2_HOLD_PAD) ([Input] [Output])), (33, GPIO33(_2 => SPI2_WP_PAD) (_2 => - SPI2_WP_PAD _3 => GMAC_PHY_TXEN_PAD) ([Input] [Output])), (34, GPIO34(_2 => - SPI2_IO4_PAD) (_2 => SPI2_IO4_PAD _3 => GMAC_PHY_TXD0_PAD) ([Input] [Output])), - (35, GPIO35(_2 => SPI2_IO5_PAD) (_2 => SPI2_IO5_PAD _3 => GMAC_PHY_TXD1_PAD) - ([Input] [Output])), (36, GPIO36(_2 => SPI2_IO6_PAD) (_2 => SPI2_IO6_PAD _3 => - GMAC_PHY_TXER_PAD) ([Input] [Output])), (37, GPIO37(_2 => SPI2_IO7_PAD) (_0 => - UART0_TXD_PAD _2 => SPI2_IO7_PAD) ([Input] [Output])), (38, GPIO38(_0 => - UART0_RXD_PAD) (_2 => SPI2_DQS_PAD) ([Input] [Output])), (39, GPIO39(_0 => - SD1_CDATA0_PAD _3 => REF_50M_CLK_PAD) () ([Input] [Output])), (40, GPIO40(_0 => - SD1_CDATA1_PAD) (_3 => GMAC_PHY_TXEN_PAD) ([Input] [Output])), (41, GPIO41(_0 => - SD1_CDATA2_PAD) (_3 => GMAC_PHY_TXD0_PAD) ([Input] [Output])), (42, GPIO42(_0 => - SD1_CDATA3_PAD) (_3 => GMAC_PHY_TXD1_PAD) ([Input] [Output])), (43, GPIO43(_0 => - SD1_CCLK_PAD) (_3 => GMAC_PHY_TXER_PAD) ([Input] [Output])), (44, GPIO44(_0 => - SD1_CCMD_PAD _3 => GMAC_RMII_CLK_PAD) () ([Input] [Output])), (45, GPIO45(_0 => - SD1_CDATA4_PAD _3 => GMAC_PHY_RXDV_PAD) () ([Input] [Output])), (46, GPIO46(_0 => - SD1_CDATA5_PAD _3 => GMAC_PHY_RXD0_PAD) () ([Input] [Output])), (47, GPIO47(_0 => - SD1_CDATA6_PAD _3 => GMAC_PHY_RXD1_PAD) () ([Input] [Output])), (48, GPIO48(_0 => - SD1_CDATA7_PAD _3 => GMAC_PHY_RXER_PAD) () ([Input] [Output])), (49, GPIO49() (_3 - => GMAC_PHY_TXEN_PAD) ([Input] [Output])), (50, GPIO50(_3 => GMAC_RMII_CLK_PAD) - () ([Input] [Output])), (51, GPIO51(_3 => GMAC_PHY_RXDV_PAD) () ([Input] - [Output])), (52, GPIO52(_3 => GMAC_PHY_RXD0_PAD) () ([Input] [Output])), (53, - GPIO53(_3 => GMAC_PHY_RXD1_PAD) () ([Input] [Output])), (54, GPIO54(_3 => - GMAC_PHY_RXER_PAD) () ([Input] [Output])))); + macro_rules! _for_each_inner_gpio { $(($pattern) => $code;)* ($other : tt) => {} + } _for_each_inner_gpio!((0, GPIO0() () ([Input] [Output]))); + _for_each_inner_gpio!((1, GPIO1() () ([Input] [Output]))); + _for_each_inner_gpio!((2, GPIO2(_0 => MTCK) (_0 => MTCK) ([Input] [Output]))); + _for_each_inner_gpio!((3, GPIO3(_0 => MTDI) (_0 => MTDI) ([Input] [Output]))); + _for_each_inner_gpio!((4, GPIO4(_0 => MTMS) (_0 => MTMS) ([Input] [Output]))); + _for_each_inner_gpio!((5, GPIO5(_0 => MTDO) (_0 => MTDO) ([Input] [Output]))); + _for_each_inner_gpio!((6, GPIO6(_3 => SPI2_HOLD) (_3 => SPI2_HOLD) ([Input] + [Output]))); _for_each_inner_gpio!((7, GPIO7(_3 => SPI2_CS) (_3 => SPI2_CS) + ([Input] [Output]))); _for_each_inner_gpio!((8, GPIO8(_3 => SPI2_D) (_2 => + UART0_RTS _3 => SPI2_D) ([Input] [Output]))); _for_each_inner_gpio!((9, GPIO9(_2 + => UART0_CTS _3 => SPI2_CK) (_3 => SPI2_CK) ([Input] [Output]))); + _for_each_inner_gpio!((10, GPIO10(_3 => SPI2_Q) (_2 => UART1_TXD _3 => SPI2_Q) + ([Input] [Output]))); _for_each_inner_gpio!((11, GPIO11(_2 => UART1_RXD _3 => + SPI2_WP) (_3 => SPI2_WP) ([Input] [Output]))); _for_each_inner_gpio!((12, + GPIO12() (_2 => UART1_RTS) ([Input] [Output]))); _for_each_inner_gpio!((13, + GPIO13(_2 => UART1_CTS) () ([Input] [Output]))); _for_each_inner_gpio!((14, + GPIO14() () ([Input] [Output]))); _for_each_inner_gpio!((15, GPIO15() () ([Input] + [Output]))); _for_each_inner_gpio!((16, GPIO16() () ([Input] [Output]))); + _for_each_inner_gpio!((17, GPIO17() () ([Input] [Output]))); + _for_each_inner_gpio!((18, GPIO18() () ([Input] [Output]))); + _for_each_inner_gpio!((19, GPIO19() () ([Input] [Output]))); + _for_each_inner_gpio!((20, GPIO20() () ([Input] [Output]))); + _for_each_inner_gpio!((21, GPIO21() () ([Input] [Output]))); + _for_each_inner_gpio!((22, GPIO22(_4 => DBG_PSRAM_CK) (_4 => DBG_PSRAM_CK) + ([Input] [Output]))); _for_each_inner_gpio!((23, GPIO23(_3 => REF_50M_CLK _4 => + DBG_PSRAM_CS) (_3 => REF_50M_CLK _4 => DBG_PSRAM_CS) ([Input] [Output]))); + _for_each_inner_gpio!((24, GPIO24() () ([Input] [Output]))); + _for_each_inner_gpio!((25, GPIO25() () ([Input] [Output]))); + _for_each_inner_gpio!((26, GPIO26() () ([Input] [Output]))); + _for_each_inner_gpio!((27, GPIO27() () ([Input] [Output]))); + _for_each_inner_gpio!((28, GPIO28(_2 => SPI2_CS _3 => EMAC_PHY_RXDV _4 => + DBG_PSRAM_D) (_2 => SPI2_CS _4 => DBG_PSRAM_D) ([Input] [Output]))); + _for_each_inner_gpio!((29, GPIO29(_2 => SPI2_D _3 => EMAC_PHY_RXD0 _4 => + DBG_PSRAM_Q) (_2 => SPI2_D _4 => DBG_PSRAM_Q) ([Input] [Output]))); + _for_each_inner_gpio!((30, GPIO30(_2 => SPI2_CK _3 => EMAC_PHY_RXD1 _4 => + DBG_PSRAM_WP) (_2 => SPI2_CK _4 => DBG_PSRAM_WP) ([Input] [Output]))); + _for_each_inner_gpio!((31, GPIO31(_2 => SPI2_Q _3 => EMAC_PHY_RXER _4 => + DBG_PSRAM_HOLD) (_2 => SPI2_Q _4 => DBG_PSRAM_HOLD) ([Input] [Output]))); + _for_each_inner_gpio!((32, GPIO32(_2 => SPI2_HOLD _3 => EMAC_RMII_CLK _4 => + DBG_PSRAM_DQ4) (_2 => SPI2_HOLD _3 => EMAC_RMII_CLK _4 => DBG_PSRAM_DQ4) ([Input] + [Output]))); _for_each_inner_gpio!((33, GPIO33(_2 => SPI2_WP _4 => DBG_PSRAM_DQ5) + (_2 => SPI2_WP _3 => EMAC_PHY_TXEN _4 => DBG_PSRAM_DQ5) ([Input] [Output]))); + _for_each_inner_gpio!((34, GPIO34(_2 => SPI2_IO4 _4 => DBG_PSRAM_DQ6) (_2 => + SPI2_IO4 _3 => EMAC_PHY_TXD0 _4 => DBG_PSRAM_DQ6) ([Input] [Output]))); + _for_each_inner_gpio!((35, GPIO35(_2 => SPI2_IO5 _4 => DBG_PSRAM_DQ7) (_2 => + SPI2_IO5 _3 => EMAC_PHY_TXD1 _4 => DBG_PSRAM_DQ7) ([Input] [Output]))); + _for_each_inner_gpio!((36, GPIO36(_2 => SPI2_IO6 _4 => DBG_PSRAM_DQS_0) (_2 => + SPI2_IO6 _3 => EMAC_PHY_TXER _4 => DBG_PSRAM_DQS_0) ([Input] [Output]))); + _for_each_inner_gpio!((37, GPIO37(_2 => SPI2_IO7) (_0 => UART0_TXD _2 => + SPI2_IO7) ([Input] [Output]))); _for_each_inner_gpio!((38, GPIO38(_0 => UART0_RXD + _2 => SPI2_DQS) (_2 => SPI2_DQS) ([Input] [Output]))); _for_each_inner_gpio!((39, + GPIO39(_0 => SD1_CDATA0 _2 => BIST _3 => REF_50M_CLK _4 => DBG_PSRAM_DQ8) (_0 => + SD1_CDATA0 _2 => BIST _3 => REF_50M_CLK _4 => DBG_PSRAM_DQ8) ([Input] + [Output]))); _for_each_inner_gpio!((40, GPIO40(_0 => SD1_CDATA1 _2 => BIST _4 => + DBG_PSRAM_DQ9) (_0 => SD1_CDATA1 _2 => BIST _3 => EMAC_PHY_TXEN _4 => + DBG_PSRAM_DQ9) ([Input] [Output]))); _for_each_inner_gpio!((41, GPIO41(_0 => + SD1_CDATA2 _2 => BIST _4 => DBG_PSRAM_DQ10) (_0 => SD1_CDATA2 _2 => BIST _3 => + EMAC_PHY_TXD0 _4 => DBG_PSRAM_DQ10) ([Input] [Output]))); + _for_each_inner_gpio!((42, GPIO42(_0 => SD1_CDATA3 _2 => BIST _4 => + DBG_PSRAM_DQ11) (_0 => SD1_CDATA3 _2 => BIST _3 => EMAC_PHY_TXD1 _4 => + DBG_PSRAM_DQ11) ([Input] [Output]))); _for_each_inner_gpio!((43, GPIO43(_0 => + SD1_CCLK _2 => BIST _4 => DBG_PSRAM_DQ12) (_0 => SD1_CCLK _2 => BIST _3 => + EMAC_PHY_TXER _4 => DBG_PSRAM_DQ12) ([Input] [Output]))); + _for_each_inner_gpio!((44, GPIO44(_0 => SD1_CCMD _2 => BIST _3 => EMAC_RMII_CLK + _4 => DBG_PSRAM_DQ13) (_0 => SD1_CCMD _2 => BIST _3 => EMAC_RMII_CLK _4 => + DBG_PSRAM_DQ13) ([Input] [Output]))); _for_each_inner_gpio!((45, GPIO45(_0 => + SD1_CDATA4 _2 => BIST _3 => EMAC_PHY_RXDV _4 => DBG_PSRAM_DQ14) (_0 => SD1_CDATA4 + _2 => BIST _4 => DBG_PSRAM_DQ14) ([Input] [Output]))); _for_each_inner_gpio!((46, + GPIO46(_0 => SD1_CDATA5 _2 => BIST _3 => EMAC_PHY_RXD0 _4 => DBG_PSRAM_DQ15) (_0 + => SD1_CDATA5 _2 => BIST _4 => DBG_PSRAM_DQ15) ([Input] [Output]))); + _for_each_inner_gpio!((47, GPIO47(_0 => SD1_CDATA6 _2 => BIST _3 => EMAC_PHY_RXD1 + _4 => DBG_PSRAM_DQS_1) (_0 => SD1_CDATA6 _2 => BIST _4 => DBG_PSRAM_DQS_1) + ([Input] [Output]))); _for_each_inner_gpio!((48, GPIO48(_0 => SD1_CDATA7 _2 => + BIST _3 => EMAC_PHY_RXER) (_0 => SD1_CDATA7 _2 => BIST) ([Input] [Output]))); + _for_each_inner_gpio!((49, GPIO49(_4 => DBG_FLASH_CS) (_3 => EMAC_PHY_TXEN _4 => + DBG_FLASH_CS) ([Input] [Output]))); _for_each_inner_gpio!((50, GPIO50(_3 => + EMAC_RMII_CLK _4 => DBG_FLASH_Q) (_3 => EMAC_RMII_CLK _4 => DBG_FLASH_Q) ([Input] + [Output]))); _for_each_inner_gpio!((51, GPIO51(_3 => EMAC_PHY_RXDV _4 => + DBG_FLASH_WP) (_4 => DBG_FLASH_WP) ([Input] [Output]))); + _for_each_inner_gpio!((52, GPIO52(_3 => EMAC_PHY_RXD0 _4 => DBG_FLASH_HOLD) (_4 + => DBG_FLASH_HOLD) ([Input] [Output]))); _for_each_inner_gpio!((53, GPIO53(_3 => + EMAC_PHY_RXD1 _4 => DBG_FLASH_CK) (_4 => DBG_FLASH_CK) ([Input] [Output]))); + _for_each_inner_gpio!((54, GPIO54(_3 => EMAC_PHY_RXER _4 => DBG_FLASH_D) (_4 => + DBG_FLASH_D) ([Input] [Output]))); _for_each_inner_gpio!((all(0, GPIO0() () + ([Input] [Output])), (1, GPIO1() () ([Input] [Output])), (2, GPIO2(_0 => MTCK) + (_0 => MTCK) ([Input] [Output])), (3, GPIO3(_0 => MTDI) (_0 => MTDI) ([Input] + [Output])), (4, GPIO4(_0 => MTMS) (_0 => MTMS) ([Input] [Output])), (5, GPIO5(_0 + => MTDO) (_0 => MTDO) ([Input] [Output])), (6, GPIO6(_3 => SPI2_HOLD) (_3 => + SPI2_HOLD) ([Input] [Output])), (7, GPIO7(_3 => SPI2_CS) (_3 => SPI2_CS) ([Input] + [Output])), (8, GPIO8(_3 => SPI2_D) (_2 => UART0_RTS _3 => SPI2_D) ([Input] + [Output])), (9, GPIO9(_2 => UART0_CTS _3 => SPI2_CK) (_3 => SPI2_CK) ([Input] + [Output])), (10, GPIO10(_3 => SPI2_Q) (_2 => UART1_TXD _3 => SPI2_Q) ([Input] + [Output])), (11, GPIO11(_2 => UART1_RXD _3 => SPI2_WP) (_3 => SPI2_WP) ([Input] + [Output])), (12, GPIO12() (_2 => UART1_RTS) ([Input] [Output])), (13, GPIO13(_2 + => UART1_CTS) () ([Input] [Output])), (14, GPIO14() () ([Input] [Output])), (15, + GPIO15() () ([Input] [Output])), (16, GPIO16() () ([Input] [Output])), (17, + GPIO17() () ([Input] [Output])), (18, GPIO18() () ([Input] [Output])), (19, + GPIO19() () ([Input] [Output])), (20, GPIO20() () ([Input] [Output])), (21, + GPIO21() () ([Input] [Output])), (22, GPIO22(_4 => DBG_PSRAM_CK) (_4 => + DBG_PSRAM_CK) ([Input] [Output])), (23, GPIO23(_3 => REF_50M_CLK _4 => + DBG_PSRAM_CS) (_3 => REF_50M_CLK _4 => DBG_PSRAM_CS) ([Input] [Output])), (24, + GPIO24() () ([Input] [Output])), (25, GPIO25() () ([Input] [Output])), (26, + GPIO26() () ([Input] [Output])), (27, GPIO27() () ([Input] [Output])), (28, + GPIO28(_2 => SPI2_CS _3 => EMAC_PHY_RXDV _4 => DBG_PSRAM_D) (_2 => SPI2_CS _4 => + DBG_PSRAM_D) ([Input] [Output])), (29, GPIO29(_2 => SPI2_D _3 => EMAC_PHY_RXD0 _4 + => DBG_PSRAM_Q) (_2 => SPI2_D _4 => DBG_PSRAM_Q) ([Input] [Output])), (30, + GPIO30(_2 => SPI2_CK _3 => EMAC_PHY_RXD1 _4 => DBG_PSRAM_WP) (_2 => SPI2_CK _4 => + DBG_PSRAM_WP) ([Input] [Output])), (31, GPIO31(_2 => SPI2_Q _3 => EMAC_PHY_RXER + _4 => DBG_PSRAM_HOLD) (_2 => SPI2_Q _4 => DBG_PSRAM_HOLD) ([Input] [Output])), + (32, GPIO32(_2 => SPI2_HOLD _3 => EMAC_RMII_CLK _4 => DBG_PSRAM_DQ4) (_2 => + SPI2_HOLD _3 => EMAC_RMII_CLK _4 => DBG_PSRAM_DQ4) ([Input] [Output])), (33, + GPIO33(_2 => SPI2_WP _4 => DBG_PSRAM_DQ5) (_2 => SPI2_WP _3 => EMAC_PHY_TXEN _4 + => DBG_PSRAM_DQ5) ([Input] [Output])), (34, GPIO34(_2 => SPI2_IO4 _4 => + DBG_PSRAM_DQ6) (_2 => SPI2_IO4 _3 => EMAC_PHY_TXD0 _4 => DBG_PSRAM_DQ6) ([Input] + [Output])), (35, GPIO35(_2 => SPI2_IO5 _4 => DBG_PSRAM_DQ7) (_2 => SPI2_IO5 _3 => + EMAC_PHY_TXD1 _4 => DBG_PSRAM_DQ7) ([Input] [Output])), (36, GPIO36(_2 => + SPI2_IO6 _4 => DBG_PSRAM_DQS_0) (_2 => SPI2_IO6 _3 => EMAC_PHY_TXER _4 => + DBG_PSRAM_DQS_0) ([Input] [Output])), (37, GPIO37(_2 => SPI2_IO7) (_0 => + UART0_TXD _2 => SPI2_IO7) ([Input] [Output])), (38, GPIO38(_0 => UART0_RXD _2 => + SPI2_DQS) (_2 => SPI2_DQS) ([Input] [Output])), (39, GPIO39(_0 => SD1_CDATA0 _2 + => BIST _3 => REF_50M_CLK _4 => DBG_PSRAM_DQ8) (_0 => SD1_CDATA0 _2 => BIST _3 => + REF_50M_CLK _4 => DBG_PSRAM_DQ8) ([Input] [Output])), (40, GPIO40(_0 => + SD1_CDATA1 _2 => BIST _4 => DBG_PSRAM_DQ9) (_0 => SD1_CDATA1 _2 => BIST _3 => + EMAC_PHY_TXEN _4 => DBG_PSRAM_DQ9) ([Input] [Output])), (41, GPIO41(_0 => + SD1_CDATA2 _2 => BIST _4 => DBG_PSRAM_DQ10) (_0 => SD1_CDATA2 _2 => BIST _3 => + EMAC_PHY_TXD0 _4 => DBG_PSRAM_DQ10) ([Input] [Output])), (42, GPIO42(_0 => + SD1_CDATA3 _2 => BIST _4 => DBG_PSRAM_DQ11) (_0 => SD1_CDATA3 _2 => BIST _3 => + EMAC_PHY_TXD1 _4 => DBG_PSRAM_DQ11) ([Input] [Output])), (43, GPIO43(_0 => + SD1_CCLK _2 => BIST _4 => DBG_PSRAM_DQ12) (_0 => SD1_CCLK _2 => BIST _3 => + EMAC_PHY_TXER _4 => DBG_PSRAM_DQ12) ([Input] [Output])), (44, GPIO44(_0 => + SD1_CCMD _2 => BIST _3 => EMAC_RMII_CLK _4 => DBG_PSRAM_DQ13) (_0 => SD1_CCMD _2 + => BIST _3 => EMAC_RMII_CLK _4 => DBG_PSRAM_DQ13) ([Input] [Output])), (45, + GPIO45(_0 => SD1_CDATA4 _2 => BIST _3 => EMAC_PHY_RXDV _4 => DBG_PSRAM_DQ14) (_0 + => SD1_CDATA4 _2 => BIST _4 => DBG_PSRAM_DQ14) ([Input] [Output])), (46, + GPIO46(_0 => SD1_CDATA5 _2 => BIST _3 => EMAC_PHY_RXD0 _4 => DBG_PSRAM_DQ15) (_0 + => SD1_CDATA5 _2 => BIST _4 => DBG_PSRAM_DQ15) ([Input] [Output])), (47, + GPIO47(_0 => SD1_CDATA6 _2 => BIST _3 => EMAC_PHY_RXD1 _4 => DBG_PSRAM_DQS_1) (_0 + => SD1_CDATA6 _2 => BIST _4 => DBG_PSRAM_DQS_1) ([Input] [Output])), (48, + GPIO48(_0 => SD1_CDATA7 _2 => BIST _3 => EMAC_PHY_RXER) (_0 => SD1_CDATA7 _2 => + BIST) ([Input] [Output])), (49, GPIO49(_4 => DBG_FLASH_CS) (_3 => EMAC_PHY_TXEN + _4 => DBG_FLASH_CS) ([Input] [Output])), (50, GPIO50(_3 => EMAC_RMII_CLK _4 => + DBG_FLASH_Q) (_3 => EMAC_RMII_CLK _4 => DBG_FLASH_Q) ([Input] [Output])), (51, + GPIO51(_3 => EMAC_PHY_RXDV _4 => DBG_FLASH_WP) (_4 => DBG_FLASH_WP) ([Input] + [Output])), (52, GPIO52(_3 => EMAC_PHY_RXD0 _4 => DBG_FLASH_HOLD) (_4 => + DBG_FLASH_HOLD) ([Input] [Output])), (53, GPIO53(_3 => EMAC_PHY_RXD1 _4 => + DBG_FLASH_CK) (_4 => DBG_FLASH_CK) ([Input] [Output])), (54, GPIO54(_3 => + EMAC_PHY_RXER _4 => DBG_FLASH_D) (_4 => DBG_FLASH_D) ([Input] [Output])))); }; } /// This macro can be used to generate code for each analog function of each GPIO. @@ -2841,101 +3068,58 @@ macro_rules! for_each_gpio { #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_analog_function { ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((XTAL_32K_N, GPIO0)); _for_each_inner!((XTAL_32K_P, GPIO1)); - _for_each_inner!((TOUCH_CHANNEL0, GPIO2)); _for_each_inner!((TOUCH_CHANNEL1, - GPIO3)); _for_each_inner!((TOUCH_CHANNEL2, GPIO4)); - _for_each_inner!((TOUCH_CHANNEL3, GPIO5)); _for_each_inner!((TOUCH_CHANNEL4, - GPIO6)); _for_each_inner!((TOUCH_CHANNEL5, GPIO7)); - _for_each_inner!((TOUCH_CHANNEL6, GPIO8)); _for_each_inner!((TOUCH_CHANNEL7, - GPIO9)); _for_each_inner!((TOUCH_CHANNEL8, GPIO10)); - _for_each_inner!((TOUCH_CHANNEL9, GPIO11)); _for_each_inner!((TOUCH_CHANNEL10, - GPIO12)); _for_each_inner!((TOUCH_CHANNEL11, GPIO13)); - _for_each_inner!((TOUCH_CHANNEL12, GPIO14)); _for_each_inner!((TOUCH_CHANNEL13, - GPIO15)); _for_each_inner!((ADC1_CHANNEL0, GPIO16)); - _for_each_inner!((ADC1_CHANNEL1, GPIO17)); _for_each_inner!((ADC1_CHANNEL2, - GPIO18)); _for_each_inner!((ADC1_CHANNEL3, GPIO19)); - _for_each_inner!((ADC1_CHANNEL4, GPIO20)); _for_each_inner!((ADC1_CHANNEL5, - GPIO21)); _for_each_inner!((ADC1_CHANNEL6, GPIO22)); - _for_each_inner!((ADC1_CHANNEL7, GPIO23)); _for_each_inner!((USB1P1_N0, GPIO24)); - _for_each_inner!((USB1P1_P0, GPIO25)); _for_each_inner!((USB1P1_N1, GPIO26)); - _for_each_inner!((USB1P1_P1, GPIO27)); _for_each_inner!((ADC2_CHANNEL2, GPIO28)); - _for_each_inner!((ADC2_CHANNEL3, GPIO29)); _for_each_inner!((ADC2_CHANNEL4, - GPIO30)); _for_each_inner!((ANA_COMP0, GPIO30)); _for_each_inner!((ADC2_CHANNEL5, - GPIO31)); _for_each_inner!((ANA_COMP0, GPIO31)); _for_each_inner!((ADC2_CHANNEL6, - GPIO32)); _for_each_inner!((ANA_COMP1, GPIO32)); _for_each_inner!((ADC2_CHANNEL7, - GPIO33)); _for_each_inner!((ANA_COMP1, GPIO33)); - _for_each_inner!(((TOUCH_CHANNEL0, TOUCH_CHANNELn, 0), GPIO2)); - _for_each_inner!(((TOUCH_CHANNEL1, TOUCH_CHANNELn, 1), GPIO3)); - _for_each_inner!(((TOUCH_CHANNEL2, TOUCH_CHANNELn, 2), GPIO4)); - _for_each_inner!(((TOUCH_CHANNEL3, TOUCH_CHANNELn, 3), GPIO5)); - _for_each_inner!(((TOUCH_CHANNEL4, TOUCH_CHANNELn, 4), GPIO6)); - _for_each_inner!(((TOUCH_CHANNEL5, TOUCH_CHANNELn, 5), GPIO7)); - _for_each_inner!(((TOUCH_CHANNEL6, TOUCH_CHANNELn, 6), GPIO8)); - _for_each_inner!(((TOUCH_CHANNEL7, TOUCH_CHANNELn, 7), GPIO9)); - _for_each_inner!(((TOUCH_CHANNEL8, TOUCH_CHANNELn, 8), GPIO10)); - _for_each_inner!(((TOUCH_CHANNEL9, TOUCH_CHANNELn, 9), GPIO11)); - _for_each_inner!(((TOUCH_CHANNEL10, TOUCH_CHANNELn, 10), GPIO12)); - _for_each_inner!(((TOUCH_CHANNEL11, TOUCH_CHANNELn, 11), GPIO13)); - _for_each_inner!(((TOUCH_CHANNEL12, TOUCH_CHANNELn, 12), GPIO14)); - _for_each_inner!(((TOUCH_CHANNEL13, TOUCH_CHANNELn, 13), GPIO15)); - _for_each_inner!(((ADC1_CHANNEL0, ADCn_CHANNELm, 1, 0), GPIO16)); - _for_each_inner!(((ADC1_CHANNEL1, ADCn_CHANNELm, 1, 1), GPIO17)); - _for_each_inner!(((ADC1_CHANNEL2, ADCn_CHANNELm, 1, 2), GPIO18)); - _for_each_inner!(((ADC1_CHANNEL3, ADCn_CHANNELm, 1, 3), GPIO19)); - _for_each_inner!(((ADC1_CHANNEL4, ADCn_CHANNELm, 1, 4), GPIO20)); - _for_each_inner!(((ADC1_CHANNEL5, ADCn_CHANNELm, 1, 5), GPIO21)); - _for_each_inner!(((ADC1_CHANNEL6, ADCn_CHANNELm, 1, 6), GPIO22)); - _for_each_inner!(((ADC1_CHANNEL7, ADCn_CHANNELm, 1, 7), GPIO23)); - _for_each_inner!(((USB1P1_N0, USB1P1_Nn, 0), GPIO24)); - _for_each_inner!(((USB1P1_P0, USB1P1_Pn, 0), GPIO25)); - _for_each_inner!(((USB1P1_N1, USB1P1_Nn, 1), GPIO26)); - _for_each_inner!(((USB1P1_P1, USB1P1_Pn, 1), GPIO27)); - _for_each_inner!(((ADC2_CHANNEL2, ADCn_CHANNELm, 2, 2), GPIO28)); - _for_each_inner!(((ADC2_CHANNEL3, ADCn_CHANNELm, 2, 3), GPIO29)); - _for_each_inner!(((ADC2_CHANNEL4, ADCn_CHANNELm, 2, 4), GPIO30)); - _for_each_inner!(((ANA_COMP0, ANA_COMPn, 0), GPIO30)); - _for_each_inner!(((ADC2_CHANNEL5, ADCn_CHANNELm, 2, 5), GPIO31)); - _for_each_inner!(((ANA_COMP0, ANA_COMPn, 0), GPIO31)); - _for_each_inner!(((ADC2_CHANNEL6, ADCn_CHANNELm, 2, 6), GPIO32)); - _for_each_inner!(((ANA_COMP1, ANA_COMPn, 1), GPIO32)); - _for_each_inner!(((ADC2_CHANNEL7, ADCn_CHANNELm, 2, 7), GPIO33)); - _for_each_inner!(((ANA_COMP1, ANA_COMPn, 1), GPIO33)); - _for_each_inner!((all(XTAL_32K_N, GPIO0), (XTAL_32K_P, GPIO1), (TOUCH_CHANNEL0, - GPIO2), (TOUCH_CHANNEL1, GPIO3), (TOUCH_CHANNEL2, GPIO4), (TOUCH_CHANNEL3, - GPIO5), (TOUCH_CHANNEL4, GPIO6), (TOUCH_CHANNEL5, GPIO7), (TOUCH_CHANNEL6, - GPIO8), (TOUCH_CHANNEL7, GPIO9), (TOUCH_CHANNEL8, GPIO10), (TOUCH_CHANNEL9, - GPIO11), (TOUCH_CHANNEL10, GPIO12), (TOUCH_CHANNEL11, GPIO13), (TOUCH_CHANNEL12, - GPIO14), (TOUCH_CHANNEL13, GPIO15), (ADC1_CHANNEL0, GPIO16), (ADC1_CHANNEL1, - GPIO17), (ADC1_CHANNEL2, GPIO18), (ADC1_CHANNEL3, GPIO19), (ADC1_CHANNEL4, - GPIO20), (ADC1_CHANNEL5, GPIO21), (ADC1_CHANNEL6, GPIO22), (ADC1_CHANNEL7, - GPIO23), (USB1P1_N0, GPIO24), (USB1P1_P0, GPIO25), (USB1P1_N1, GPIO26), - (USB1P1_P1, GPIO27), (ADC2_CHANNEL2, GPIO28), (ADC2_CHANNEL3, GPIO29), - (ADC2_CHANNEL4, GPIO30), (ANA_COMP0, GPIO30), (ADC2_CHANNEL5, GPIO31), - (ANA_COMP0, GPIO31), (ADC2_CHANNEL6, GPIO32), (ANA_COMP1, GPIO32), - (ADC2_CHANNEL7, GPIO33), (ANA_COMP1, GPIO33))); - _for_each_inner!((all_expanded((TOUCH_CHANNEL0, TOUCH_CHANNELn, 0), GPIO2), - ((TOUCH_CHANNEL1, TOUCH_CHANNELn, 1), GPIO3), ((TOUCH_CHANNEL2, TOUCH_CHANNELn, - 2), GPIO4), ((TOUCH_CHANNEL3, TOUCH_CHANNELn, 3), GPIO5), ((TOUCH_CHANNEL4, - TOUCH_CHANNELn, 4), GPIO6), ((TOUCH_CHANNEL5, TOUCH_CHANNELn, 5), GPIO7), - ((TOUCH_CHANNEL6, TOUCH_CHANNELn, 6), GPIO8), ((TOUCH_CHANNEL7, TOUCH_CHANNELn, - 7), GPIO9), ((TOUCH_CHANNEL8, TOUCH_CHANNELn, 8), GPIO10), ((TOUCH_CHANNEL9, - TOUCH_CHANNELn, 9), GPIO11), ((TOUCH_CHANNEL10, TOUCH_CHANNELn, 10), GPIO12), - ((TOUCH_CHANNEL11, TOUCH_CHANNELn, 11), GPIO13), ((TOUCH_CHANNEL12, - TOUCH_CHANNELn, 12), GPIO14), ((TOUCH_CHANNEL13, TOUCH_CHANNELn, 13), GPIO15), - ((ADC1_CHANNEL0, ADCn_CHANNELm, 1, 0), GPIO16), ((ADC1_CHANNEL1, ADCn_CHANNELm, - 1, 1), GPIO17), ((ADC1_CHANNEL2, ADCn_CHANNELm, 1, 2), GPIO18), ((ADC1_CHANNEL3, - ADCn_CHANNELm, 1, 3), GPIO19), ((ADC1_CHANNEL4, ADCn_CHANNELm, 1, 4), GPIO20), - ((ADC1_CHANNEL5, ADCn_CHANNELm, 1, 5), GPIO21), ((ADC1_CHANNEL6, ADCn_CHANNELm, - 1, 6), GPIO22), ((ADC1_CHANNEL7, ADCn_CHANNELm, 1, 7), GPIO23), ((USB1P1_N0, - USB1P1_Nn, 0), GPIO24), ((USB1P1_P0, USB1P1_Pn, 0), GPIO25), ((USB1P1_N1, - USB1P1_Nn, 1), GPIO26), ((USB1P1_P1, USB1P1_Pn, 1), GPIO27), ((ADC2_CHANNEL2, - ADCn_CHANNELm, 2, 2), GPIO28), ((ADC2_CHANNEL3, ADCn_CHANNELm, 2, 3), GPIO29), - ((ADC2_CHANNEL4, ADCn_CHANNELm, 2, 4), GPIO30), ((ANA_COMP0, ANA_COMPn, 0), - GPIO30), ((ADC2_CHANNEL5, ADCn_CHANNELm, 2, 5), GPIO31), ((ANA_COMP0, ANA_COMPn, - 0), GPIO31), ((ADC2_CHANNEL6, ADCn_CHANNELm, 2, 6), GPIO32), ((ANA_COMP1, - ANA_COMPn, 1), GPIO32), ((ADC2_CHANNEL7, ADCn_CHANNELm, 2, 7), GPIO33), - ((ANA_COMP1, ANA_COMPn, 1), GPIO33))); + macro_rules! _for_each_inner_analog_function { $(($pattern) => $code;)* ($other : + tt) => {} } _for_each_inner_analog_function!((ADC1_CH0, GPIO16)); + _for_each_inner_analog_function!((ADC1_CH1, GPIO17)); + _for_each_inner_analog_function!((ADC1_CH2, GPIO18)); + _for_each_inner_analog_function!((ADC1_CH3, GPIO19)); + _for_each_inner_analog_function!((ADC1_CH4, GPIO20)); + _for_each_inner_analog_function!((ADC1_CH5, GPIO21)); + _for_each_inner_analog_function!((ADC1_CH6, GPIO22)); + _for_each_inner_analog_function!((ADC1_CH7, GPIO23)); + _for_each_inner_analog_function!((USB_PHY0_DM, GPIO24)); + _for_each_inner_analog_function!((USB_PHY0_DP, GPIO25)); + _for_each_inner_analog_function!((USB_PHY1_DM, GPIO26)); + _for_each_inner_analog_function!((USB_PHY1_DP, GPIO27)); + _for_each_inner_analog_function!((ADC2_CH0, GPIO49)); + _for_each_inner_analog_function!((ADC2_CH1, GPIO50)); + _for_each_inner_analog_function!((ADC2_CH2, GPIO51)); + _for_each_inner_analog_function!((ADC2_CH3, GPIO52)); + _for_each_inner_analog_function!((ADC2_CH4, GPIO53)); + _for_each_inner_analog_function!((ADC2_CH5, GPIO54)); + _for_each_inner_analog_function!(((ADC1_CH0, ADCn_CHm, 1, 0), GPIO16)); + _for_each_inner_analog_function!(((ADC1_CH1, ADCn_CHm, 1, 1), GPIO17)); + _for_each_inner_analog_function!(((ADC1_CH2, ADCn_CHm, 1, 2), GPIO18)); + _for_each_inner_analog_function!(((ADC1_CH3, ADCn_CHm, 1, 3), GPIO19)); + _for_each_inner_analog_function!(((ADC1_CH4, ADCn_CHm, 1, 4), GPIO20)); + _for_each_inner_analog_function!(((ADC1_CH5, ADCn_CHm, 1, 5), GPIO21)); + _for_each_inner_analog_function!(((ADC1_CH6, ADCn_CHm, 1, 6), GPIO22)); + _for_each_inner_analog_function!(((ADC1_CH7, ADCn_CHm, 1, 7), GPIO23)); + _for_each_inner_analog_function!(((USB_PHY0_DM, USB_PHYn_DM, 0), GPIO24)); + _for_each_inner_analog_function!(((USB_PHY0_DP, USB_PHYn_DP, 0), GPIO25)); + _for_each_inner_analog_function!(((USB_PHY1_DM, USB_PHYn_DM, 1), GPIO26)); + _for_each_inner_analog_function!(((USB_PHY1_DP, USB_PHYn_DP, 1), GPIO27)); + _for_each_inner_analog_function!(((ADC2_CH0, ADCn_CHm, 2, 0), GPIO49)); + _for_each_inner_analog_function!(((ADC2_CH1, ADCn_CHm, 2, 1), GPIO50)); + _for_each_inner_analog_function!(((ADC2_CH2, ADCn_CHm, 2, 2), GPIO51)); + _for_each_inner_analog_function!(((ADC2_CH3, ADCn_CHm, 2, 3), GPIO52)); + _for_each_inner_analog_function!(((ADC2_CH4, ADCn_CHm, 2, 4), GPIO53)); + _for_each_inner_analog_function!(((ADC2_CH5, ADCn_CHm, 2, 5), GPIO54)); + _for_each_inner_analog_function!((all(ADC1_CH0, GPIO16), (ADC1_CH1, GPIO17), + (ADC1_CH2, GPIO18), (ADC1_CH3, GPIO19), (ADC1_CH4, GPIO20), (ADC1_CH5, GPIO21), + (ADC1_CH6, GPIO22), (ADC1_CH7, GPIO23), (USB_PHY0_DM, GPIO24), (USB_PHY0_DP, + GPIO25), (USB_PHY1_DM, GPIO26), (USB_PHY1_DP, GPIO27), (ADC2_CH0, GPIO49), + (ADC2_CH1, GPIO50), (ADC2_CH2, GPIO51), (ADC2_CH3, GPIO52), (ADC2_CH4, GPIO53), + (ADC2_CH5, GPIO54))); _for_each_inner_analog_function!((all_expanded((ADC1_CH0, + ADCn_CHm, 1, 0), GPIO16), ((ADC1_CH1, ADCn_CHm, 1, 1), GPIO17), ((ADC1_CH2, + ADCn_CHm, 1, 2), GPIO18), ((ADC1_CH3, ADCn_CHm, 1, 3), GPIO19), ((ADC1_CH4, + ADCn_CHm, 1, 4), GPIO20), ((ADC1_CH5, ADCn_CHm, 1, 5), GPIO21), ((ADC1_CH6, + ADCn_CHm, 1, 6), GPIO22), ((ADC1_CH7, ADCn_CHm, 1, 7), GPIO23), ((USB_PHY0_DM, + USB_PHYn_DM, 0), GPIO24), ((USB_PHY0_DP, USB_PHYn_DP, 0), GPIO25), ((USB_PHY1_DM, + USB_PHYn_DM, 1), GPIO26), ((USB_PHY1_DP, USB_PHYn_DP, 1), GPIO27), ((ADC2_CH0, + ADCn_CHm, 2, 0), GPIO49), ((ADC2_CH1, ADCn_CHm, 2, 1), GPIO50), ((ADC2_CH2, + ADCn_CHm, 2, 2), GPIO51), ((ADC2_CH3, ADCn_CHm, 2, 3), GPIO52), ((ADC2_CH4, + ADCn_CHm, 2, 4), GPIO53), ((ADC2_CH5, ADCn_CHm, 2, 5), GPIO54))); }; } /// This macro can be used to generate code for each LP/RTC function of each GPIO. @@ -2968,70 +3152,20 @@ macro_rules! for_each_analog_function { #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_lp_function { ($($pattern:tt => $code:tt;)*) => { - macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} } - _for_each_inner!((LP_GPIO0, GPIO0)); _for_each_inner!((LP_GPIO0, GPIO0)); - _for_each_inner!((LP_GPIO1, GPIO1)); _for_each_inner!((LP_GPIO1, GPIO1)); - _for_each_inner!((LP_GPIO2, GPIO2)); _for_each_inner!((LP_GPIO2, GPIO2)); - _for_each_inner!((LP_GPIO3, GPIO3)); _for_each_inner!((LP_GPIO3, GPIO3)); - _for_each_inner!((LP_GPIO4, GPIO4)); _for_each_inner!((LP_GPIO4, GPIO4)); - _for_each_inner!((LP_GPIO5, GPIO5)); _for_each_inner!((LP_GPIO5, GPIO5)); - _for_each_inner!((LP_GPIO6, GPIO6)); _for_each_inner!((LP_GPIO6, GPIO6)); - _for_each_inner!((LP_GPIO7, GPIO7)); _for_each_inner!((LP_GPIO7, GPIO7)); - _for_each_inner!((LP_GPIO8, GPIO8)); _for_each_inner!((LP_GPIO8, GPIO8)); - _for_each_inner!((LP_GPIO9, GPIO9)); _for_each_inner!((LP_GPIO9, GPIO9)); - _for_each_inner!((LP_GPIO10, GPIO10)); _for_each_inner!((LP_GPIO10, GPIO10)); - _for_each_inner!((LP_GPIO11, GPIO11)); _for_each_inner!((LP_GPIO11, GPIO11)); - _for_each_inner!((LP_GPIO12, GPIO12)); _for_each_inner!((LP_GPIO12, GPIO12)); - _for_each_inner!((LP_GPIO13, GPIO13)); _for_each_inner!((LP_GPIO13, GPIO13)); - _for_each_inner!((LP_UART_TXD_PAD, GPIO14)); _for_each_inner!((LP_GPIO14, - GPIO14)); _for_each_inner!((LP_UART_RXD_PAD, GPIO15)); - _for_each_inner!((LP_GPIO15, GPIO15)); _for_each_inner!(((LP_GPIO0, LP_GPIOn, 0), - GPIO0)); _for_each_inner!(((LP_GPIO0, LP_GPIOn, 0), GPIO0)); - _for_each_inner!(((LP_GPIO1, LP_GPIOn, 1), GPIO1)); _for_each_inner!(((LP_GPIO1, - LP_GPIOn, 1), GPIO1)); _for_each_inner!(((LP_GPIO2, LP_GPIOn, 2), GPIO2)); - _for_each_inner!(((LP_GPIO2, LP_GPIOn, 2), GPIO2)); _for_each_inner!(((LP_GPIO3, - LP_GPIOn, 3), GPIO3)); _for_each_inner!(((LP_GPIO3, LP_GPIOn, 3), GPIO3)); - _for_each_inner!(((LP_GPIO4, LP_GPIOn, 4), GPIO4)); _for_each_inner!(((LP_GPIO4, - LP_GPIOn, 4), GPIO4)); _for_each_inner!(((LP_GPIO5, LP_GPIOn, 5), GPIO5)); - _for_each_inner!(((LP_GPIO5, LP_GPIOn, 5), GPIO5)); _for_each_inner!(((LP_GPIO6, - LP_GPIOn, 6), GPIO6)); _for_each_inner!(((LP_GPIO6, LP_GPIOn, 6), GPIO6)); - _for_each_inner!(((LP_GPIO7, LP_GPIOn, 7), GPIO7)); _for_each_inner!(((LP_GPIO7, - LP_GPIOn, 7), GPIO7)); _for_each_inner!(((LP_GPIO8, LP_GPIOn, 8), GPIO8)); - _for_each_inner!(((LP_GPIO8, LP_GPIOn, 8), GPIO8)); _for_each_inner!(((LP_GPIO9, - LP_GPIOn, 9), GPIO9)); _for_each_inner!(((LP_GPIO9, LP_GPIOn, 9), GPIO9)); - _for_each_inner!(((LP_GPIO10, LP_GPIOn, 10), GPIO10)); - _for_each_inner!(((LP_GPIO10, LP_GPIOn, 10), GPIO10)); - _for_each_inner!(((LP_GPIO11, LP_GPIOn, 11), GPIO11)); - _for_each_inner!(((LP_GPIO11, LP_GPIOn, 11), GPIO11)); - _for_each_inner!(((LP_GPIO12, LP_GPIOn, 12), GPIO12)); - _for_each_inner!(((LP_GPIO12, LP_GPIOn, 12), GPIO12)); - _for_each_inner!(((LP_GPIO13, LP_GPIOn, 13), GPIO13)); - _for_each_inner!(((LP_GPIO13, LP_GPIOn, 13), GPIO13)); - _for_each_inner!(((LP_GPIO14, LP_GPIOn, 14), GPIO14)); - _for_each_inner!(((LP_GPIO15, LP_GPIOn, 15), GPIO15)); - _for_each_inner!((all(LP_GPIO0, GPIO0), (LP_GPIO0, GPIO0), (LP_GPIO1, GPIO1), - (LP_GPIO1, GPIO1), (LP_GPIO2, GPIO2), (LP_GPIO2, GPIO2), (LP_GPIO3, GPIO3), - (LP_GPIO3, GPIO3), (LP_GPIO4, GPIO4), (LP_GPIO4, GPIO4), (LP_GPIO5, GPIO5), - (LP_GPIO5, GPIO5), (LP_GPIO6, GPIO6), (LP_GPIO6, GPIO6), (LP_GPIO7, GPIO7), - (LP_GPIO7, GPIO7), (LP_GPIO8, GPIO8), (LP_GPIO8, GPIO8), (LP_GPIO9, GPIO9), - (LP_GPIO9, GPIO9), (LP_GPIO10, GPIO10), (LP_GPIO10, GPIO10), (LP_GPIO11, GPIO11), - (LP_GPIO11, GPIO11), (LP_GPIO12, GPIO12), (LP_GPIO12, GPIO12), (LP_GPIO13, - GPIO13), (LP_GPIO13, GPIO13), (LP_UART_TXD_PAD, GPIO14), (LP_GPIO14, GPIO14), - (LP_UART_RXD_PAD, GPIO15), (LP_GPIO15, GPIO15))); - _for_each_inner!((all_expanded((LP_GPIO0, LP_GPIOn, 0), GPIO0), ((LP_GPIO0, - LP_GPIOn, 0), GPIO0), ((LP_GPIO1, LP_GPIOn, 1), GPIO1), ((LP_GPIO1, LP_GPIOn, 1), - GPIO1), ((LP_GPIO2, LP_GPIOn, 2), GPIO2), ((LP_GPIO2, LP_GPIOn, 2), GPIO2), - ((LP_GPIO3, LP_GPIOn, 3), GPIO3), ((LP_GPIO3, LP_GPIOn, 3), GPIO3), ((LP_GPIO4, - LP_GPIOn, 4), GPIO4), ((LP_GPIO4, LP_GPIOn, 4), GPIO4), ((LP_GPIO5, LP_GPIOn, 5), - GPIO5), ((LP_GPIO5, LP_GPIOn, 5), GPIO5), ((LP_GPIO6, LP_GPIOn, 6), GPIO6), - ((LP_GPIO6, LP_GPIOn, 6), GPIO6), ((LP_GPIO7, LP_GPIOn, 7), GPIO7), ((LP_GPIO7, - LP_GPIOn, 7), GPIO7), ((LP_GPIO8, LP_GPIOn, 8), GPIO8), ((LP_GPIO8, LP_GPIOn, 8), - GPIO8), ((LP_GPIO9, LP_GPIOn, 9), GPIO9), ((LP_GPIO9, LP_GPIOn, 9), GPIO9), - ((LP_GPIO10, LP_GPIOn, 10), GPIO10), ((LP_GPIO10, LP_GPIOn, 10), GPIO10), - ((LP_GPIO11, LP_GPIOn, 11), GPIO11), ((LP_GPIO11, LP_GPIOn, 11), GPIO11), - ((LP_GPIO12, LP_GPIOn, 12), GPIO12), ((LP_GPIO12, LP_GPIOn, 12), GPIO12), - ((LP_GPIO13, LP_GPIOn, 13), GPIO13), ((LP_GPIO13, LP_GPIOn, 13), GPIO13), - ((LP_GPIO14, LP_GPIOn, 14), GPIO14), ((LP_GPIO15, LP_GPIOn, 15), GPIO15))); + macro_rules! _for_each_inner_lp_function { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_lp_function!((LP_GPIO0, GPIO0)); + _for_each_inner_lp_function!((LP_GPIO1, GPIO1)); + _for_each_inner_lp_function!((LP_GPIO14, GPIO14)); + _for_each_inner_lp_function!((LP_GPIO15, GPIO15)); + _for_each_inner_lp_function!(((LP_GPIO0, LP_GPIOn, 0), GPIO0)); + _for_each_inner_lp_function!(((LP_GPIO1, LP_GPIOn, 1), GPIO1)); + _for_each_inner_lp_function!(((LP_GPIO14, LP_GPIOn, 14), GPIO14)); + _for_each_inner_lp_function!(((LP_GPIO15, LP_GPIOn, 15), GPIO15)); + _for_each_inner_lp_function!((all(LP_GPIO0, GPIO0), (LP_GPIO1, GPIO1), + (LP_GPIO14, GPIO14), (LP_GPIO15, GPIO15))); + _for_each_inner_lp_function!((all_expanded((LP_GPIO0, LP_GPIOn, 0), GPIO0), + ((LP_GPIO1, LP_GPIOn, 1), GPIO1), ((LP_GPIO14, LP_GPIOn, 14), GPIO14), + ((LP_GPIO15, LP_GPIOn, 15), GPIO15))); }; } /// Defines the `InputSignal` and `OutputSignal` enums. @@ -3046,482 +3180,407 @@ macro_rules! define_io_mux_signals { #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[doc(hidden)] pub enum InputSignal { - SD_CARD_CCMD_2_PAD = 1, - SD_CARD_CDATA0_2_PAD = 2, - SD_CARD_CDATA1_2_PAD = 3, - SD_CARD_CDATA2_2_PAD = 4, - SD_CARD_CDATA3_2_PAD = 5, - SD_CARD_CDATA4_2_PAD = 6, - SD_CARD_CDATA5_2_PAD = 7, - SD_CARD_CDATA6_2_PAD = 8, - SD_CARD_CDATA7_2_PAD = 9, - UART0_RXD_PAD = 10, - UART0_CTS_PAD = 11, - UART0_DSR_PAD = 12, - UART1_RXD_PAD = 13, - UART1_CTS_PAD = 14, - UART1_DSR_PAD = 15, - UART2_RXD_PAD = 16, - UART2_CTS_PAD = 17, - UART2_DSR_PAD = 18, - UART3_RXD_PAD = 19, - UART3_CTS_PAD = 20, - UART3_DSR_PAD = 21, - UART4_RXD_PAD = 22, - UART4_CTS_PAD = 23, - UART4_DSR_PAD = 24, - I2S0_O_BCK_PAD = 25, - I2S0_MCLK_PAD = 26, - I2S0_O_WS_PAD = 27, - I2S0_I_SD_PAD = 28, - I2S0_I_BCK_PAD = 29, - I2S0_I_WS_PAD = 30, - I2S1_O_BCK_PAD = 31, - I2S1_MCLK_PAD = 32, - I2S1_O_WS_PAD = 33, - I2S1_I_SD_PAD = 34, - I2S1_I_BCK_PAD = 35, - I2S1_I_WS_PAD = 36, - I2S2_O_BCK_PAD = 37, - I2S2_MCLK_PAD = 38, - I2S2_O_WS_PAD = 39, - I2S2_I_SD_PAD = 40, - I2S2_I_BCK_PAD = 41, - I2S2_I_WS_PAD = 42, - I2S0_I_SD1_PAD = 43, - I2S0_I_SD2_PAD = 44, - I2S0_I_SD3_PAD = 45, - SPI3_CK_PAD = 47, - SPI3_Q_PAD = 48, - SPI3_D_PAD = 49, - SPI3_HOLD_PAD = 50, - SPI3_WP_PAD = 51, - SPI3_CS_PAD = 52, - SPI2_CK_PAD = 53, - SPI2_Q_PAD = 54, - SPI2_D_PAD = 55, - SPI2_HOLD_PAD = 56, - SPI2_WP_PAD = 57, - SPI2_IO4_PAD = 58, - SPI2_IO5_PAD = 59, - SPI2_IO6_PAD = 60, - SPI2_IO7_PAD = 61, - SPI2_CS_PAD = 62, - PCNT_RST_PAD_IN0 = 63, - PCNT_RST_PAD_IN1 = 64, - PCNT_RST_PAD_IN2 = 65, - PCNT_RST_PAD_IN3 = 66, - I2C0_SCL_PAD = 68, - I2C0_SDA_PAD = 69, - I2C1_SCL_PAD = 70, - I2C1_SDA_PAD = 71, - UART0_SLP_CLK_PAD = 74, - UART1_SLP_CLK_PAD = 75, - UART2_SLP_CLK_PAD = 76, - UART3_SLP_CLK_PAD = 77, - UART4_SLP_CLK_PAD = 78, - TWAI0_RX_PAD = 80, - TWAI1_RX_PAD = 83, - TWAI2_RX_PAD = 86, - PWM0_SYNC0_PAD = 89, - PWM0_SYNC1_PAD = 90, - PWM0_SYNC2_PAD = 91, - PWM0_F0_PAD = 92, - PWM0_F1_PAD = 93, - PWM0_F2_PAD = 94, - PWM0_CAP0_PAD = 95, - PWM0_CAP1_PAD = 96, - PWM0_CAP2_PAD = 97, - PWM1_SYNC0_PAD = 98, - PWM1_SYNC1_PAD = 99, - PWM1_SYNC2_PAD = 100, - PWM1_F0_PAD = 101, - PWM1_F1_PAD = 102, - PWM1_F2_PAD = 103, - PWM1_CAP0_PAD = 104, - PWM1_CAP1_PAD = 105, - PWM1_CAP2_PAD = 106, - GMII_MDI_PAD = 107, - GMAC_PHY_COL_PAD = 108, - GMAC_PHY_CRS_PAD = 109, - USB_OTG11_IDDIG_PAD = 110, - USB_OTG11_AVALID_PAD = 111, - USB_SRP_BVALID_PAD = 112, - USB_OTG11_VBUSVALID_PAD = 113, - USB_SRP_SESSEND_PAD = 114, - ULPI_CLK_PAD = 117, - USB_HSPHY_REFCLK = 118, - SD_CARD_DETECT_N_1_PAD = 126, - SD_CARD_DETECT_N_2_PAD = 127, - SD_CARD_INT_N_1_PAD = 128, - SD_CARD_INT_N_2_PAD = 129, - SD_CARD_WRITE_PRT_1_PAD = 130, - SD_CARD_WRITE_PRT_2_PAD = 131, - SD_DATA_STROBE_1_PAD = 132, - SD_DATA_STROBE_2_PAD = 133, - I3C_MST_SCL_PAD = 134, - I3C_MST_SDA_PAD = 135, - I3C_SLV_SCL_PAD = 136, - I3C_SLV_SDA_PAD = 137, - USB_JTAG_TDO_BRIDGE_PAD = 140, - PCNT_SIG_CH0_PAD_IN0 = 141, - PCNT_SIG_CH0_PAD_IN1 = 142, - PCNT_SIG_CH0_PAD_IN2 = 143, - PCNT_SIG_CH0_PAD_IN3 = 144, - PCNT_SIG_CH1_PAD_IN0 = 145, - PCNT_SIG_CH1_PAD_IN1 = 146, - PCNT_SIG_CH1_PAD_IN2 = 147, - PCNT_SIG_CH1_PAD_IN3 = 148, - PCNT_CTRL_CH0_PAD_IN0 = 149, - PCNT_CTRL_CH0_PAD_IN1 = 150, - PCNT_CTRL_CH0_PAD_IN2 = 151, - PCNT_CTRL_CH0_PAD_IN3 = 152, - PCNT_CTRL_CH1_PAD_IN0 = 153, - PCNT_CTRL_CH1_PAD_IN1 = 154, - PCNT_CTRL_CH1_PAD_IN2 = 155, - PCNT_CTRL_CH1_PAD_IN3 = 156, - CAM_PCLK_PAD = 158, - CAM_H_ENABLE_PAD = 159, - CAM_H_SYNC_PAD = 160, - CAM_V_SYNC_PAD = 161, - CAM_DATA_IN_PAD_IN0 = 162, - CAM_DATA_IN_PAD_IN1 = 163, - CAM_DATA_IN_PAD_IN2 = 164, - CAM_DATA_IN_PAD_IN3 = 165, - CAM_DATA_IN_PAD_IN4 = 166, - CAM_DATA_IN_PAD_IN5 = 167, - CAM_DATA_IN_PAD_IN6 = 168, - CAM_DATA_IN_PAD_IN7 = 169, - CAM_DATA_IN_PAD_IN8 = 170, - CAM_DATA_IN_PAD_IN9 = 171, - CAM_DATA_IN_PAD_IN10 = 172, - CAM_DATA_IN_PAD_IN11 = 173, - CAM_DATA_IN_PAD_IN12 = 174, - CAM_DATA_IN_PAD_IN13 = 175, - CAM_DATA_IN_PAD_IN14 = 176, - CAM_DATA_IN_PAD_IN15 = 177, - GMAC_PHY_RXDV_PAD = 178, - GMAC_PHY_RXD0_PAD = 179, - GMAC_PHY_RXD1_PAD = 180, - GMAC_PHY_RXD2_PAD = 181, - GMAC_PHY_RXD3_PAD = 182, - GMAC_PHY_RXER_PAD = 183, - GMAC_RX_CLK_PAD = 184, - GMAC_TX_CLK_PAD = 185, - PARLIO_RX_CLK_PAD = 186, - PARLIO_TX_CLK_PAD = 187, - PARLIO_RX_DATA0_PAD = 188, - PARLIO_RX_DATA1_PAD = 189, - PARLIO_RX_DATA2_PAD = 190, - PARLIO_RX_DATA3_PAD = 191, - PARLIO_RX_DATA4_PAD = 192, - PARLIO_RX_DATA5_PAD = 193, - PARLIO_RX_DATA6_PAD = 194, - PARLIO_RX_DATA7_PAD = 195, - PARLIO_RX_DATA8_PAD = 196, - PARLIO_RX_DATA9_PAD = 197, - PARLIO_RX_DATA10_PAD = 198, - PARLIO_RX_DATA11_PAD = 199, - PARLIO_RX_DATA12_PAD = 200, - PARLIO_RX_DATA13_PAD = 201, - PARLIO_RX_DATA14_PAD = 202, - PARLIO_RX_DATA15_PAD = 203, - CORE_GPIO_IN_PAD_IN0 = 214, - CORE_GPIO_IN_PAD_IN1 = 215, - CORE_GPIO_IN_PAD_IN2 = 216, - CORE_GPIO_IN_PAD_IN3 = 217, - CORE_GPIO_IN_PAD_IN4 = 218, - CORE_GPIO_IN_PAD_IN5 = 219, - CORE_GPIO_IN_PAD_IN6 = 220, - CORE_GPIO_IN_PAD_IN7 = 221, - CORE_GPIO_IN_PAD_IN8 = 222, - CORE_GPIO_IN_PAD_IN9 = 223, - CORE_GPIO_IN_PAD_IN10 = 224, - CORE_GPIO_IN_PAD_IN11 = 225, - CORE_GPIO_IN_PAD_IN12 = 226, - CORE_GPIO_IN_PAD_IN13 = 227, - CORE_GPIO_IN_PAD_IN14 = 228, - CORE_GPIO_IN_PAD_IN15 = 229, - CORE_GPIO_IN_PAD_IN16 = 230, - CORE_GPIO_IN_PAD_IN17 = 231, - CORE_GPIO_IN_PAD_IN18 = 232, - CORE_GPIO_IN_PAD_IN19 = 233, - CORE_GPIO_IN_PAD_IN20 = 234, - CORE_GPIO_IN_PAD_IN21 = 235, - CORE_GPIO_IN_PAD_IN22 = 236, - CORE_GPIO_IN_PAD_IN23 = 237, - CORE_GPIO_IN_PAD_IN24 = 238, - CORE_GPIO_IN_PAD_IN25 = 239, - CORE_GPIO_IN_PAD_IN26 = 240, - CORE_GPIO_IN_PAD_IN27 = 241, - CORE_GPIO_IN_PAD_IN28 = 242, - CORE_GPIO_IN_PAD_IN29 = 243, - CORE_GPIO_IN_PAD_IN30 = 244, - CORE_GPIO_IN_PAD_IN31 = 245, - RMT_SIG_PAD_IN0 = 246, - RMT_SIG_PAD_IN1 = 247, - RMT_SIG_PAD_IN2 = 248, - RMT_SIG_PAD_IN3 = 249, - SIG_IN_FUNC250 = 250, - SIG_IN_FUNC251 = 251, - SIG_IN_FUNC252 = 252, - SIG_IN_FUNC253 = 253, - SIG_IN_FUNC254 = 254, - SIG_IN_FUNC255 = 255, - REF_50M_CLK_PAD, - GMAC_RMII_CLK_PAD, - SD1_CDATA0_PAD, - SD1_CDATA1_PAD, - SD1_CDATA2_PAD, - SD1_CDATA3_PAD, - SD1_CCLK_PAD, - SD1_CCMD_PAD, - SD1_CDATA4_PAD, - SD1_CDATA5_PAD, - SD1_CDATA6_PAD, - SD1_CDATA7_PAD, - MTDI, - MTDO, + SD_CARD_CCMD_2 = 1, + SD_CARD_CDATA0_2 = 2, + SD_CARD_CDATA1_2 = 3, + SD_CARD_CDATA2_2 = 4, + SD_CARD_CDATA3_2 = 5, + SD_CARD_CDATA4_2 = 6, + SD_CARD_CDATA5_2 = 7, + SD_CARD_CDATA6_2 = 8, + SD_CARD_CDATA7_2 = 9, + UART0_RXD = 10, + UART0_CTS = 11, + UART0_DSR = 12, + UART1_RXD = 13, + UART1_CTS = 14, + UART1_DSR = 15, + UART2_RXD = 16, + UART2_CTS = 17, + UART2_DSR = 18, + UART3_RXD = 19, + UART3_CTS = 20, + UART3_DSR = 21, + UART4_RXD = 22, + UART4_CTS = 23, + UART4_DSR = 24, + I2S0_O_BCK = 25, + I2S0_MCLK = 26, + I2S0_O_WS = 27, + I2S0_I_SD = 28, + I2S0_I_BCK = 29, + I2S0_I_WS = 30, + I2S1_O_BCK = 31, + I2S1_MCLK = 32, + I2S1_O_WS = 33, + I2S1_I_SD = 34, + I2S1_I_BCK = 35, + I2S1_I_WS = 36, + I2S2_O_BCK = 37, + I2S2_MCLK = 38, + I2S2_O_WS = 39, + I2S2_I_SD = 40, + I2S2_I_BCK = 41, + I2S2_I_WS = 42, + I2S0_I_SD1 = 43, + I2S0_I_SD2 = 44, + I2S0_I_SD3 = 45, + SPI3_CK = 47, + SPI3_Q = 48, + SPI3_D = 49, + SPI3_HOLD = 50, + SPI3_WP = 51, + SPI3_CS = 52, + SPI2_CK = 53, + SPI2_Q = 54, + SPI2_D = 55, + SPI2_HOLD = 56, + SPI2_WP = 57, + SPI2_IO4 = 58, + SPI2_IO5 = 59, + SPI2_IO6 = 60, + SPI2_IO7 = 61, + SPI2_CS = 62, + I2C0_SCL = 68, + I2C0_SDA = 69, + I2C1_SCL = 70, + I2C1_SDA = 71, + UART0_SLP_CLK = 74, + UART1_SLP_CLK = 75, + UART2_SLP_CLK = 76, + UART3_SLP_CLK = 77, + UART4_SLP_CLK = 78, + TWAI0_RX = 80, + TWAI1_RX = 83, + TWAI2_RX = 86, + PWM0_SYNC0 = 89, + PWM0_SYNC1 = 90, + PWM0_SYNC2 = 91, + PWM0_F0 = 92, + PWM0_F1 = 93, + PWM0_F2 = 94, + PWM0_CAP0 = 95, + PWM0_CAP1 = 96, + PWM0_CAP2 = 97, + PWM1_SYNC0 = 98, + PWM1_SYNC1 = 99, + PWM1_SYNC2 = 100, + PWM1_F0 = 101, + PWM1_F1 = 102, + PWM1_F2 = 103, + PWM1_CAP0 = 104, + PWM1_CAP1 = 105, + PWM1_CAP2 = 106, + MII_MDI = 107, + EMAC_PHY_COL = 108, + EMAC_PHY_CRS = 109, + USB_OTG11_IDDIG = 110, + USB_OTG11_AVALID = 111, + USB_SRP_BVALID = 112, + USB_OTG11_VBUSVALID = 113, + USB_SRP_SESSEND = 114, + ULPI_CLK = 117, + USB_HSPHY_REFCLK = 118, + SD_CARD_DETECT_N_1 = 126, + SD_CARD_DETECT_N_2 = 127, + SD_CARD_INT_N_1 = 128, + SD_CARD_INT_N_2 = 129, + SD_CARD_WRITE_PRT_1 = 130, + SD_CARD_WRITE_PRT_2 = 131, + SD_DATA_STROBE_1 = 132, + SD_DATA_STROBE_2 = 133, + I3C_MST_SCL = 134, + I3C_MST_SDA = 135, + I3C_SLV_SCL = 136, + I3C_SLV_SDA = 137, + USB_JTAG_TDO_BRIDGE = 140, + CAM_PCLK = 158, + CAM_H_ENABLE = 159, + CAM_H_SYNC = 160, + CAM_V_SYNC = 161, + EMAC_PHY_RXDV = 178, + EMAC_PHY_RXD0 = 179, + EMAC_PHY_RXD1 = 180, + EMAC_PHY_RXD2 = 181, + EMAC_PHY_RXD3 = 182, + EMAC_PHY_RXER = 183, + EMAC_RX_CLK = 184, + EMAC_TX_CLK = 185, + PARLIO_RX_CLK = 186, + PARLIO_TX_CLK = 187, + PARLIO_RX_DATA0 = 188, + PARLIO_RX_DATA1 = 189, + PARLIO_RX_DATA2 = 190, + PARLIO_RX_DATA3 = 191, + PARLIO_RX_DATA4 = 192, + PARLIO_RX_DATA5 = 193, + PARLIO_RX_DATA6 = 194, + PARLIO_RX_DATA7 = 195, + PARLIO_RX_DATA8 = 196, + PARLIO_RX_DATA9 = 197, + PARLIO_RX_DATA10 = 198, + PARLIO_RX_DATA11 = 199, + PARLIO_RX_DATA12 = 200, + PARLIO_RX_DATA13 = 201, + PARLIO_RX_DATA14 = 202, + PARLIO_RX_DATA15 = 203, MTCK, + MTDI, MTMS, + MTDO, + SD1_CDATA0, + SD1_CDATA1, + SD1_CDATA2, + SD1_CDATA3, + SD1_CCLK, + SD1_CCMD, + SD1_CDATA4, + SD1_CDATA5, + SD1_CDATA6, + SD1_CDATA7, + EMAC_RMII_CLK, + REF_50M_CLK, + BIST, + DBG_PSRAM_CK, + DBG_PSRAM_CS, + DBG_PSRAM_D, + DBG_PSRAM_Q, + DBG_PSRAM_WP, + DBG_PSRAM_HOLD, + DBG_PSRAM_DQ4, + DBG_PSRAM_DQ5, + DBG_PSRAM_DQ6, + DBG_PSRAM_DQ7, + DBG_PSRAM_DQS_0, + DBG_PSRAM_DQ8, + DBG_PSRAM_DQ9, + DBG_PSRAM_DQ10, + DBG_PSRAM_DQ11, + DBG_PSRAM_DQ12, + DBG_PSRAM_DQ13, + DBG_PSRAM_DQ14, + DBG_PSRAM_DQ15, + DBG_PSRAM_DQS_1, + DBG_FLASH_CS, + DBG_FLASH_Q, + DBG_FLASH_WP, + DBG_FLASH_HOLD, + DBG_FLASH_CK, + DBG_FLASH_D, + SPI2_DQS, } #[allow(non_camel_case_types, clippy::upper_case_acronyms)] #[derive(Debug, PartialEq, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[doc(hidden)] pub enum OutputSignal { - SD_CARD_CCLK_2_PAD = 0, - SD_CARD_CCMD_2_PAD = 1, - SD_CARD_CDATA0_2_PAD = 2, - SD_CARD_CDATA1_2_PAD = 3, - SD_CARD_CDATA2_2_PAD = 4, - SD_CARD_CDATA3_2_PAD = 5, - SD_CARD_CDATA4_2_PAD = 6, - SD_CARD_CDATA5_2_PAD = 7, - SD_CARD_CDATA6_2_PAD = 8, - SD_CARD_CDATA7_2_PAD = 9, - UART0_TXD_PAD = 10, - UART0_RTS_PAD = 11, - UART0_DTR_PAD = 12, - UART1_TXD_PAD = 13, - UART1_RTS_PAD = 14, - UART1_DTR_PAD = 15, - UART2_TXD_PAD = 16, - UART2_RTS_PAD = 17, - UART2_DTR_PAD = 18, - UART3_TXD_PAD = 19, - UART3_RTS_PAD = 20, - UART3_DTR_PAD = 21, - UART4_TXD_PAD = 22, - UART4_RTS_PAD = 23, - UART4_DTR_PAD = 24, - I2S0_O_BCK_PAD = 25, - I2S0_MCLK_PAD = 26, - I2S0_O_WS_PAD = 27, - I2S0_O_SD_PAD = 28, - I2S0_I_BCK_PAD = 29, - I2S0_I_WS_PAD = 30, - I2S1_O_BCK_PAD = 31, - I2S1_MCLK_PAD = 32, - I2S1_O_WS_PAD = 33, - I2S1_O_SD_PAD = 34, - I2S1_I_BCK_PAD = 35, - I2S1_I_WS_PAD = 36, - I2S2_O_BCK_PAD = 37, - I2S2_MCLK_PAD = 38, - I2S2_O_WS_PAD = 39, - I2S2_O_SD_PAD = 40, - I2S2_I_BCK_PAD = 41, - I2S2_I_WS_PAD = 42, - I2S0_O_SD1_PAD = 43, - SPI2_DQS_PAD = 44, - SPI3_CS2_PAD = 45, - SPI3_CS1_PAD = 46, - SPI3_CK_PAD = 47, - SPI3_QO_PAD = 48, - SPI3_D_PAD = 49, - SPI3_HOLD_PAD = 50, - SPI3_WP_PAD = 51, - SPI3_CS_PAD = 52, - SPI2_CK_PAD = 53, - SPI2_Q_PAD = 54, - SPI2_D_PAD = 55, - SPI2_HOLD_PAD = 56, - SPI2_WP_PAD = 57, - SPI2_IO4_PAD = 58, - SPI2_IO5_PAD = 59, - SPI2_IO6_PAD = 60, - SPI2_IO7_PAD = 61, - SPI2_CS_PAD = 62, - SPI2_CS1_PAD = 63, - SPI2_CS2_PAD = 64, - SPI2_CS3_PAD = 65, - SPI2_CS4_PAD = 66, - SPI2_CS5_PAD = 67, - I2C0_SCL_PAD = 68, - I2C0_SDA_PAD = 69, - I2C1_SCL_PAD = 70, - I2C1_SDA_PAD = 71, - GPIO_SD0 = 72, - GPIO_SD1 = 73, - GPIO_SD2 = 74, - GPIO_SD3 = 75, - GPIO_SD4 = 76, - GPIO_SD5 = 77, - GPIO_SD6 = 78, - GPIO_SD7 = 79, - TWAI0_TX_PAD = 80, - TWAI0_BUS_OFF_ON_PAD = 81, - TWAI0_CLKOUT_PAD = 82, - TWAI1_TX_PAD = 83, - TWAI1_BUS_OFF_ON_PAD = 84, - TWAI1_CLKOUT_PAD = 85, - TWAI2_TX_PAD = 86, - TWAI2_BUS_OFF_ON_PAD = 87, - TWAI2_CLKOUT_PAD = 88, - PWM0_CH0_A_PAD = 89, - PWM0_CH0_B_PAD = 90, - PWM0_CH1_A_PAD = 91, - PWM0_CH1_B_PAD = 92, - PWM0_CH2_A_PAD = 93, - PWM0_CH2_B_PAD = 94, - PWM1_CH0_A_PAD = 95, - PWM1_CH0_B_PAD = 96, - PWM1_CH1_A_PAD = 97, - PWM1_CH1_B_PAD = 98, - PWM1_CH2_A_PAD = 99, - PWM1_CH2_B_PAD = 100, - TWAI0_STANDBY_PAD = 105, - TWAI1_STANDBY_PAD = 106, - TWAI2_STANDBY_PAD = 107, - GMII_MDC_PAD = 108, - GMII_MDO_PAD = 109, - USB_SRP_DISCHRGVBUS_PAD = 110, - USB_OTG11_IDPULLUP_PAD = 111, - USB_OTG11_DPPULLDOWN_PAD = 112, - USB_OTG11_DMPULLDOWN_PAD = 113, - USB_OTG11_DRVVBUS_PAD = 114, - USB_SRP_CHRGVBUS_PAD = 115, - LEDC_LS_SIG_OUT_PAD_OUT0 = 126, - LEDC_LS_SIG_OUT_PAD_OUT1 = 127, - LEDC_LS_SIG_OUT_PAD_OUT2 = 128, - LEDC_LS_SIG_OUT_PAD_OUT3 = 129, - LEDC_LS_SIG_OUT_PAD_OUT4 = 130, - LEDC_LS_SIG_OUT_PAD_OUT5 = 131, - LEDC_LS_SIG_OUT_PAD_OUT6 = 132, - LEDC_LS_SIG_OUT_PAD_OUT7 = 133, - I3C_MST_SCL_PAD = 134, - I3C_MST_SDA_PAD = 135, - I3C_SLV_SCL_PAD = 136, - I3C_SLV_SDA_PAD = 137, - I3C_MST_SCL_PULLUP_EN_PAD = 138, - I3C_MST_SDA_PULLUP_EN_PAD = 139, - USB_JTAG_TDI_BRIDGE_PAD = 140, - USB_JTAG_TMS_BRIDGE_PAD = 141, - USB_JTAG_TCK_BRIDGE_PAD = 142, - USB_JTAG_TRST_BRIDGE_PAD = 143, - LCD_CS_PAD = 144, - LCD_DC_PAD = 145, - SD_RST_N_1_PAD = 146, - SD_RST_N_2_PAD = 147, - SD_CCMD_OD_PULLUP_EN_N_PAD = 148, - LCD_PCLK_PAD = 149, - CAM_CLK_PAD = 150, - LCD_H_ENABLE_PAD = 151, - LCD_H_SYNC_PAD = 152, - LCD_V_SYNC_PAD = 153, - LCD_DATA_OUT_PAD_OUT0 = 154, - LCD_DATA_OUT_PAD_OUT1 = 155, - LCD_DATA_OUT_PAD_OUT2 = 156, - LCD_DATA_OUT_PAD_OUT3 = 157, - LCD_DATA_OUT_PAD_OUT4 = 158, - LCD_DATA_OUT_PAD_OUT5 = 159, - LCD_DATA_OUT_PAD_OUT6 = 160, - LCD_DATA_OUT_PAD_OUT7 = 161, - LCD_DATA_OUT_PAD_OUT8 = 162, - LCD_DATA_OUT_PAD_OUT9 = 163, - LCD_DATA_OUT_PAD_OUT10 = 164, - LCD_DATA_OUT_PAD_OUT11 = 165, - LCD_DATA_OUT_PAD_OUT12 = 166, - LCD_DATA_OUT_PAD_OUT13 = 167, - LCD_DATA_OUT_PAD_OUT14 = 168, - LCD_DATA_OUT_PAD_OUT15 = 169, - LCD_DATA_OUT_PAD_OUT16 = 170, - LCD_DATA_OUT_PAD_OUT17 = 171, - LCD_DATA_OUT_PAD_OUT18 = 172, - LCD_DATA_OUT_PAD_OUT19 = 173, - LCD_DATA_OUT_PAD_OUT20 = 174, - LCD_DATA_OUT_PAD_OUT21 = 175, - LCD_DATA_OUT_PAD_OUT22 = 176, - LCD_DATA_OUT_PAD_OUT23 = 177, - GMAC_PHY_TXEN_PAD = 178, - GMAC_PHY_TXD0_PAD = 179, - GMAC_PHY_TXD1_PAD = 180, - GMAC_PHY_TXD2_PAD = 181, - GMAC_PHY_TXD3_PAD = 182, - GMAC_PHY_TXER_PAD = 183, - PARLIO_RX_CLK_PAD = 186, - PARLIO_TX_CLK_PAD = 187, - PARLIO_TX_DATA0_PAD = 188, - PARLIO_TX_DATA1_PAD = 189, - PARLIO_TX_DATA2_PAD = 190, - PARLIO_TX_DATA3_PAD = 191, - PARLIO_TX_DATA4_PAD = 192, - PARLIO_TX_DATA5_PAD = 193, - PARLIO_TX_DATA6_PAD = 194, - PARLIO_TX_DATA7_PAD = 195, - PARLIO_TX_DATA8_PAD = 196, - PARLIO_TX_DATA9_PAD = 197, - PARLIO_TX_DATA10_PAD = 198, - PARLIO_TX_DATA11_PAD = 199, - PARLIO_TX_DATA12_PAD = 200, - PARLIO_TX_DATA13_PAD = 201, - PARLIO_TX_DATA14_PAD = 202, - PARLIO_TX_DATA15_PAD = 203, - CONSTANT0_PAD = 212, - CONSTANT1_PAD = 213, - CORE_GPIO_OUT_PAD_OUT0 = 214, - CORE_GPIO_OUT_PAD_OUT1 = 215, - CORE_GPIO_OUT_PAD_OUT2 = 216, - CORE_GPIO_OUT_PAD_OUT3 = 217, - CORE_GPIO_OUT_PAD_OUT4 = 218, - CORE_GPIO_OUT_PAD_OUT5 = 219, - CORE_GPIO_OUT_PAD_OUT6 = 220, - CORE_GPIO_OUT_PAD_OUT7 = 221, - CORE_GPIO_OUT_PAD_OUT8 = 222, - CORE_GPIO_OUT_PAD_OUT9 = 223, - CORE_GPIO_OUT_PAD_OUT10 = 224, - CORE_GPIO_OUT_PAD_OUT11 = 225, - CORE_GPIO_OUT_PAD_OUT12 = 226, - CORE_GPIO_OUT_PAD_OUT13 = 227, - CORE_GPIO_OUT_PAD_OUT14 = 228, - CORE_GPIO_OUT_PAD_OUT15 = 229, - CORE_GPIO_OUT_PAD_OUT16 = 230, - CORE_GPIO_OUT_PAD_OUT17 = 231, - CORE_GPIO_OUT_PAD_OUT18 = 232, - CORE_GPIO_OUT_PAD_OUT19 = 233, - CORE_GPIO_OUT_PAD_OUT20 = 234, - CORE_GPIO_OUT_PAD_OUT21 = 235, - CORE_GPIO_OUT_PAD_OUT22 = 236, - CORE_GPIO_OUT_PAD_OUT23 = 237, - CORE_GPIO_OUT_PAD_OUT24 = 238, - CORE_GPIO_OUT_PAD_OUT25 = 239, - CORE_GPIO_OUT_PAD_OUT26 = 240, - CORE_GPIO_OUT_PAD_OUT27 = 241, - CORE_GPIO_OUT_PAD_OUT28 = 242, - CORE_GPIO_OUT_PAD_OUT29 = 243, - ANA_COMP0 = 244, - ANA_COMP1 = 245, - RMT_SIG_PAD_OUT0 = 246, - RMT_SIG_PAD_OUT1 = 247, - RMT_SIG_PAD_OUT2 = 248, - RMT_SIG_PAD_OUT3 = 249, - SIG_IN_FUNC250 = 250, - SIG_IN_FUNC251 = 251, - SIG_IN_FUNC252 = 252, - SIG_IN_FUNC253 = 253, - SIG_IN_FUNC254 = 254, - SIG_IN_FUNC255 = 255, + SD_CARD_CCLK_2 = 0, + SD_CARD_CCMD_2 = 1, + SD_CARD_CDATA0_2 = 2, + SD_CARD_CDATA1_2 = 3, + SD_CARD_CDATA2_2 = 4, + SD_CARD_CDATA3_2 = 5, + SD_CARD_CDATA4_2 = 6, + SD_CARD_CDATA5_2 = 7, + SD_CARD_CDATA6_2 = 8, + SD_CARD_CDATA7_2 = 9, + UART0_TXD = 10, + UART0_RTS = 11, + UART0_DTR = 12, + UART1_TXD = 13, + UART1_RTS = 14, + UART1_DTR = 15, + UART2_TXD = 16, + UART2_RTS = 17, + UART2_DTR = 18, + UART3_TXD = 19, + UART3_RTS = 20, + UART3_DTR = 21, + UART4_TXD = 22, + UART4_RTS = 23, + UART4_DTR = 24, + I2S0_O_BCK = 25, + I2S0_MCLK = 26, + I2S0_O_WS = 27, + I2S0_O_SD = 28, + I2S0_I_BCK = 29, + I2S0_I_WS = 30, + I2S1_O_BCK = 31, + I2S1_MCLK = 32, + I2S1_O_WS = 33, + I2S1_O_SD = 34, + I2S1_I_BCK = 35, + I2S1_I_WS = 36, + I2S2_O_BCK = 37, + I2S2_MCLK = 38, + I2S2_O_WS = 39, + I2S2_O_SD = 40, + I2S2_I_BCK = 41, + I2S2_I_WS = 42, + I2S0_O_SD1 = 43, + SPI2_DQS = 44, + SPI3_CS2 = 45, + SPI3_CS1 = 46, + SPI3_CK = 47, + SPI3_Q = 48, + SPI3_D = 49, + SPI3_HOLD = 50, + SPI3_WP = 51, + SPI3_CS = 52, + SPI2_CK = 53, + SPI2_Q = 54, + SPI2_D = 55, + SPI2_HOLD = 56, + SPI2_WP = 57, + SPI2_IO4 = 58, + SPI2_IO5 = 59, + SPI2_IO6 = 60, + SPI2_IO7 = 61, + SPI2_CS = 62, + SPI2_CS1 = 63, + SPI2_CS2 = 64, + SPI2_CS3 = 65, + SPI2_CS4 = 66, + SPI2_CS5 = 67, + I2C0_SCL = 68, + I2C0_SDA = 69, + I2C1_SCL = 70, + I2C1_SDA = 71, + GPIO_SD0 = 72, + GPIO_SD1 = 73, + GPIO_SD2 = 74, + GPIO_SD3 = 75, + GPIO_SD4 = 76, + GPIO_SD5 = 77, + GPIO_SD6 = 78, + GPIO_SD7 = 79, + TWAI0_TX = 80, + TWAI0_BUS_OFF_ON = 81, + TWAI0_CLKOUT = 82, + TWAI1_TX = 83, + TWAI1_BUS_OFF_ON = 84, + TWAI1_CLKOUT = 85, + TWAI2_TX = 86, + TWAI2_BUS_OFF_ON = 87, + TWAI2_CLKOUT = 88, + PWM0_CH0_A = 89, + PWM0_CH0_B = 90, + PWM0_CH1_A = 91, + PWM0_CH1_B = 92, + PWM0_CH2_A = 93, + PWM0_CH2_B = 94, + PWM1_CH0_A = 95, + PWM1_CH0_B = 96, + PWM1_CH1_A = 97, + PWM1_CH1_B = 98, + PWM1_CH2_A = 99, + PWM1_CH2_B = 100, + TWAI0_STANDBY = 105, + TWAI1_STANDBY = 106, + TWAI2_STANDBY = 107, + MII_MDC = 108, + MII_MDO = 109, + USB_SRP_DISCHRGVBUS = 110, + USB_OTG11_IDPULLUP = 111, + USB_OTG11_DPPULLDOWN = 112, + USB_OTG11_DMPULLDOWN = 113, + USB_OTG11_DRVVBUS = 114, + USB_SRP_CHRGVBUS = 115, + RNG_CHAIN_CLK = 117, + I3C_MST_SCL = 134, + I3C_MST_SDA = 135, + I3C_SLV_SCL = 136, + I3C_SLV_SDA = 137, + I3C_MST_SCL_PULLUP_EN = 138, + I3C_MST_SDA_PULLUP_EN = 139, + USB_JTAG_TDI_BRIDGE = 140, + USB_JTAG_TMS_BRIDGE = 141, + USB_JTAG_TCK_BRIDGE = 142, + USB_JTAG_TRST_BRIDGE = 143, + LCD_CS = 144, + LCD_DC = 145, + SD_RST_N_1 = 146, + SD_RST_N_2 = 147, + SD_CCMD_OD_PULLUP_EN_N = 148, + LCD_PCLK = 149, + CAM_CLK = 150, + LCD_H_ENABLE = 151, + LCD_H_SYNC = 152, + LCD_V_SYNC = 153, + EMAC_PHY_TXEN = 178, + EMAC_PHY_TXD0 = 179, + EMAC_PHY_TXD1 = 180, + EMAC_PHY_TXD2 = 181, + EMAC_PHY_TXD3 = 182, + EMAC_PHY_TXER = 183, + PARLIO_RX_CLK = 186, + PARLIO_TX_CLK = 187, + PARLIO_TX_DATA0 = 188, + PARLIO_TX_DATA1 = 189, + PARLIO_TX_DATA2 = 190, + PARLIO_TX_DATA3 = 191, + PARLIO_TX_DATA4 = 192, + PARLIO_TX_DATA5 = 193, + PARLIO_TX_DATA6 = 194, + PARLIO_TX_DATA7 = 195, + PARLIO_TX_DATA8 = 196, + PARLIO_TX_DATA9 = 197, + PARLIO_TX_DATA10 = 198, + PARLIO_TX_DATA11 = 199, + PARLIO_TX_DATA12 = 200, + PARLIO_TX_DATA13 = 201, + PARLIO_TX_DATA14 = 202, + PARLIO_TX_DATA15 = 203, + CONSTANT0 = 212, + CONSTANT1 = 213, + PARLIO_TX_CS = 242, + EMAC_PTP_PPS = 243, + ANA_COMP0 = 244, + ANA_COMP1 = 245, + GPIO = 256, + MTCK, + MTDI, + MTMS, + MTDO, + SD1_CDATA0, + SD1_CDATA1, + SD1_CDATA2, + SD1_CDATA3, + SD1_CCLK, + SD1_CCMD, + SD1_CDATA4, + SD1_CDATA5, + SD1_CDATA6, + SD1_CDATA7, + EMAC_RMII_CLK, + REF_50M_CLK, + BIST, + DBG_PSRAM_CK, + DBG_PSRAM_CS, + DBG_PSRAM_D, + DBG_PSRAM_Q, + DBG_PSRAM_WP, + DBG_PSRAM_HOLD, + DBG_PSRAM_DQ4, + DBG_PSRAM_DQ5, + DBG_PSRAM_DQ6, + DBG_PSRAM_DQ7, + DBG_PSRAM_DQS_0, + DBG_PSRAM_DQ8, + DBG_PSRAM_DQ9, + DBG_PSRAM_DQ10, + DBG_PSRAM_DQ11, + DBG_PSRAM_DQ12, + DBG_PSRAM_DQ13, + DBG_PSRAM_DQ14, + DBG_PSRAM_DQ15, + DBG_PSRAM_DQS_1, + DBG_FLASH_CS, + DBG_FLASH_Q, + DBG_FLASH_WP, + DBG_FLASH_HOLD, + DBG_FLASH_CK, + DBG_FLASH_D, } }; } diff --git a/esp-metadata-generated/src/lib.rs b/esp-metadata-generated/src/lib.rs index 7eb6d3a6389..533e8f4d33e 100644 --- a/esp-metadata-generated/src/lib.rs +++ b/esp-metadata-generated/src/lib.rs @@ -113,6 +113,8 @@ include!("_generated_esp32c6.rs"); include!("_generated_esp32c61.rs"); #[cfg(feature = "esp32h2")] include!("_generated_esp32h2.rs"); +#[cfg(feature = "esp32p4")] +include!("_generated_esp32p4.rs"); #[cfg(feature = "esp32s2")] include!("_generated_esp32s2.rs"); #[cfg(feature = "esp32s3")] diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index c8ac63be2c4..0d84b6669f7 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -6,106 +6,787 @@ # update the table in the esp-hal README. [device] -name = "esp32p4" -arch = "riscv" -cores = 2 +name = "esp32p4" +arch = "riscv" +target = "riscv32imafc-unknown-none-elf" +cores = 2 trm = "https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf" -peripherals = [ - # Peripherals available in the PAC: - # "adc", - # "aes", - # "assist_debug", - # "axi_dma", - # "axi_icm", - # "bitscrambler", - # "cache", - # "dma", - # "ds", - # "ecc", - # "ecdsa", - "efuse", - # "gpio_sd", - "gpio", - # "h264_dma", - # "h264", - # "hmac", - # "hp_sys_clkrst", - "hp_sys", - # "i2c0", - # "i2c1", - # "i2s0", - # "i2s1", - # "i2s2", - # "i3c_mst_mem", - # "i3c_mst", - # "i3c_slv", - "interrupt_core0", - "interrupt_core1", - "io_mux", - # "isp", - # "jpeg", - # "lcd_cam", - # "ledc", - # "lp_adc", - # "lp_ana_peri", - # "lp_aon_clkrst", - # "lp_gpio", - # "lp_huk", - # "lp_i2c_ana_mst", - # "lp_i2c0", - # "lp_i2s0", - # "lp_intr", - # "lp_io_mux", - # "lp_peri", - # "lp_sys", - # "lp_timer", - # "lp_touch", - # "lp_tsens", - # "lp_uart", - # "lp_wdt", - # "mcpwm0", - # "mcpwm1", - # "mipi_csi_bridge", - # "mipi_csi_host", - # "mipi_dsi_bridge", - # "mipi_dsi_host", - # "parl_io", - # "pau", - # "pcnt", - # "pmu", - # "ppa", - # "pvt", - # "rmt", - # "rsa", - # "sdhost", - # "sha", - # "soc_etm", - # "spi0", - # "spi1", - # "spi2", - # "spi3", - # "systimer", - # "timg0", - # "timg1", - # "trace0", - # "trace1", - # "twai0", - # "twai1", - # "twai2", - # "uart0", - # "uhci0", - # "usb_device", - # "usb_wrap", -] - symbols = [ - # Additional peripherals defined by us (the developers): - # "adc1", - # "adc2", "very_large_intr_status", - "gpio_bank_1", "spi_octal", ] -memory = [{ name = "dram", start = 0x4FF0_0000, end = 0x4FFC_0000 }] +[device.interrupts] +support_status = "partial" +# ESP32-P4 uses CLIC with 48 interrupt lines (TRM v0.5, Ch 14) +# "very_large_intr_status" uses 3 status registers (same as C5/C61) +status_registers = 3 +software_interrupt_count = 4 +software_interrupt_delay = 24 +controller = { Riscv = { flavour = "clic", interrupts = 48, priority_levels = 8 } } + +[device.soc] +cpu_has_csr_pc = true +# ESP32-P4 v3.x: 20 MHz RC_FAST default (TRM v0.5, Ch 12) +rc_fast_clk_default = 20_000_000 + +# Clock tree for ESP32-P4X (eco5 / chip revision v3.x) +# 3 PLLs: CPLL (CPU, 360/400MHz), SPLL (480MHz, peripherals), MPLL (400MHz, PSRAM/media) +# Ref: esp-idf clk_tree_defs.h, clk_tree_ll.h, TRM v0.5 Ch 12 +clocks = { system_clocks = { clock_tree = [ + # High-speed clock sources + { name = "XTAL_CLK", type = "source", output = "40_000_000", always_on = true }, + { name = "CPLL_CLK", type = "derived", from = "XTAL_CLK", output = "400_000_000" }, # eco5 default 400MHz + { name = "SPLL_CLK", type = "derived", from = "XTAL_CLK", output = "480_000_000" }, # System PLL + { name = "MPLL_CLK", type = "derived", from = "XTAL_CLK", output = "400_000_000" }, # Media PLL + { name = "RC_FAST_CLK", type = "source", output = "20_000_000" }, + + # Low-speed clocks + { name = "XTAL32K_CLK", type = "source", output = "32768" }, + { name = "OSC_SLOW_CLK", type = "source", output = "32768" }, + { name = "RC_SLOW_CLK", type = "source", output = "136_000" }, + { name = "RC32K_CLK", type = "source", output = "32768" }, + + # SPLL divider taps (from 480 MHz SPLL) + { name = "PLL_F20M", type = "generic", output = "SPLL_CLK / 24" }, + { name = "PLL_F80M", type = "generic", output = "SPLL_CLK / 6" }, + { name = "PLL_F120M", type = "generic", output = "SPLL_CLK / 4" }, + { name = "PLL_F160M", type = "generic", output = "SPLL_CLK / 3" }, + { name = "PLL_F240M", type = "generic", output = "SPLL_CLK / 2" }, + + # MPLL divider taps (from 400 MHz MPLL) + { name = "PLL_F25M", type = "generic", output = "MPLL_CLK / 16" }, + { name = "PLL_F50M", type = "generic", output = "MPLL_CLK / 8" }, + + # XTAL half + { name = "XTAL_D2_CLK", type = "generic", output = "XTAL_CLK / 2" }, + + # CPU root clock (LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel) + { name = "CPU_ROOT_CLK", type = "mux", variants = [ + { name = "XTAL", outputs = "XTAL_CLK" }, + { name = "CPLL", outputs = "CPLL_CLK" }, + { name = "RC_FAST", outputs = "RC_FAST_CLK" }, + ] }, + + # CPU_CLK divider (HP_SYS_CLKRST.root_clk_ctrl0.cpu_clk_div_num) + { name = "CPU_CLK", type = "generic", params = { divisor = "0..256" }, output = "CPU_ROOT_CLK / (divisor + 1)" }, + # APB_CLK divider + { name = "APB_CLK", type = "generic", params = { divisor = "0..256" }, output = "CPU_CLK / (divisor + 1)" }, + + # LP clocks + { name = "LP_FAST_CLK", type = "mux", variants = [ + { name = "RC_FAST", outputs = "RC_FAST_CLK" }, + { name = "XTAL_D2", outputs = "XTAL_D2_CLK" }, + ] }, + { name = "LP_SLOW_CLK", type = "mux", variants = [ + { name = "RC_SLOW", outputs = "RC_SLOW_CLK" }, + { name = "XTAL32K", outputs = "XTAL32K_CLK" }, + { name = "RC32K", outputs = "RC32K_CLK" }, + { name = "OSC_SLOW", outputs = "OSC_SLOW_CLK" }, + ] }, +], template_groups = [ + { group = "UART", clocks = [ + { name = "FUNCTION_CLOCK", type = "generic", output = "sclk / (div_num + 1)", params = { sclk = [ + { name = "XTAL", outputs = "XTAL_CLK", default = true }, + { name = "PLL_F80M", outputs = "PLL_F80M" }, + { name = "RC_FAST", outputs = "RC_FAST_CLK" }, + ], div_num = "0 .. 0x100" } }, + { name = "BAUD_RATE_GENERATOR", type = "generic", output = "(FUNCTION_CLOCK * 16) / (integral * 16 + fractional)", params = { fractional = "0..16", integral = "0..0x1000" } }, + ] }, + { group = "TIMG", clocks = [ + { name = "FUNCTION_CLOCK", type = "mux", variants = [ + { name = "XTAL_CLK", outputs = "XTAL_CLK", default = true }, + { name = "RC_FAST_CLK", outputs = "RC_FAST_CLK" }, + { name = "PLL_F80M", outputs = "PLL_F80M" }, + ] }, + { name = "WDT_CLOCK", type = "mux", variants = [ + { name = "XTAL_CLK", outputs = "XTAL_CLK", default = true }, + { name = "PLL_F80M", outputs = "PLL_F80M" }, + { name = "RC_FAST_CLK", outputs = "RC_FAST_CLK" }, + ] }, + ] }, +] } } + +# HP L2MEM: 0x4FF0_0000 - 0x4FFC_0000 (768 KB) +# ROM bootloader reserves 0x4FF0_0000 - 0x4FF4_0000 (256 KB) +# dram: usable application RAM (after ROM reserved region) +# dram2_uninit: ROM reserved area, reclaimable after 2nd-stage bootloader +# Ref: esp-idf soc.h -- SOC_DIRAM_ROM_RESERVE_HIGH = 0x4FF40000 +memory_map = { ranges = [ + { name = "dram", start = 0x4FF4_0000, end = 0x4FFC_0000 }, + { name = "dram2_uninit", start = 0x4FF0_0000, end = 0x4FF4_0000 }, +] } + +peripherals = [ + # Minimal set for esp-hal compilation + { name = "EFUSE", hidden = true }, + { name = "GPIO" }, + { name = "HP_SYS" }, + { name = "HP_SYS_CLKRST" }, + { name = "INTERRUPT_CORE0" }, + { name = "INTERRUPT_CORE1" }, + # CLIC is the per-core interrupt controller (TRM Ch 14), used by user code + # to enable/disable/prioritize interrupts. + { name = "CLIC" }, + { name = "IO_MUX" }, + { name = "LP_AON", pac = "LP_SYS" }, + { name = "LP_AON_CLKRST" }, + { name = "LP_SYS" }, + { name = "LP_WDT" }, + { name = "LPWR", pac = "LP_SYS" }, + { name = "PMU" }, + { name = "SYSTIMER" }, + { name = "TIMG0", clock_group = "TIMG" }, + { name = "TIMG1", clock_group = "TIMG" }, + { name = "UART0", interrupts = { peri = "UART0" }, clock_group = "UART" }, + { name = "UART1", interrupts = { peri = "UART1" }, clock_group = "UART" }, + { name = "UART2", interrupts = { peri = "UART2" }, clock_group = "UART" }, + { name = "UART3", interrupts = { peri = "UART3" }, clock_group = "UART" }, + { name = "UART4", interrupts = { peri = "UART4" }, clock_group = "UART" }, + # Phase 2 peripherals + { name = "SPI2", interrupts = { peri = "SPI2" }, dma_peripheral = 1 }, + # SPI3: same RegisterBlock layout as SPI2 but different PAC type. + # Map to SPI2 RegisterBlock for esp-hal driver compatibility. + { name = "SPI3", pac = "SPI2", interrupts = { peri = "SPI3" }, dma_peripheral = 2 }, + { name = "I2C0", interrupts = { peri = "I2C0" } }, + { name = "I2C1", interrupts = { peri = "I2C1" } }, + { name = "TWAI0", interrupts = { peri = "TWAI0" } }, + { name = "TWAI1", interrupts = { peri = "TWAI1" } }, + { name = "TWAI2", interrupts = { peri = "TWAI2" } }, + { name = "PSRAM", virtual = true }, + # DMA: PAC "DMA" is DW_GDMA (DesignWare), "AHB_DMA" is GDMA v2 compatible + # Using pac="AHB_DMA" maps DMA singleton to AHB_DMA RegisterBlock + { name = "DMA", pac = "AHB_DMA" }, + { name = "DMA_CH0", virtual = true }, + { name = "DMA_CH1", virtual = true }, + { name = "DMA_CH2", virtual = true }, + # Phase 3 peripherals + { name = "USB_DEVICE", interrupts = { peri = "USB_DEVICE" } }, + { name = "SDHOST" }, + # EMAC: PAC에 없음. MMIO 0x5009_8000. esp-hal에도 EMAC driver 없음 (ESP32만). + # 새 driver 필요: components/esp_hal_emac/esp32p4/include/hal/emac_ll.h 참고 + # { name = "EMAC" }, + # Phase 4 peripherals + { name = "LEDC", interrupts = { peri = "LEDC" } }, + { name = "MCPWM0", interrupts = { peri = "PWM0" } }, + { name = "MCPWM1", interrupts = { peri = "PWM1" } }, + { name = "PCNT", interrupts = { peri = "PCNT" } }, + { name = "RMT", interrupts = { peri = "RMT" } }, + { name = "ADC" }, + { name = "AES", interrupts = { peri = "AES" }, dma_peripheral = 4 }, + { name = "SHA", interrupts = { peri = "SHA" }, dma_peripheral = 5 }, + { name = "RSA", interrupts = { peri = "RSA" } }, + { name = "ECC", interrupts = { peri = "ECC" } }, +] + +# UART: 5 instances (UART0-4), 128-byte FIFO +# Ref: esp-idf uart_ll.h, TRM v0.5 Ch 46 +[device.uart] +support_status = "partial" +instances = [ + { name = "uart0", sys_instance = "Uart0", tx = "UART0_TXD", rx = "UART0_RXD", cts = "UART0_CTS", rts = "UART0_RTS" }, + { name = "uart1", sys_instance = "Uart1", tx = "UART1_TXD", rx = "UART1_RXD", cts = "UART1_CTS", rts = "UART1_RTS" }, + { name = "uart2", sys_instance = "Uart2", tx = "UART2_TXD", rx = "UART2_RXD", cts = "UART2_CTS", rts = "UART2_RTS" }, + { name = "uart3", sys_instance = "Uart3", tx = "UART3_TXD", rx = "UART3_RXD", cts = "UART3_CTS", rts = "UART3_RTS" }, + { name = "uart4", sys_instance = "Uart4", tx = "UART4_TXD", rx = "UART4_RXD", cts = "UART4_CTS", rts = "UART4_RTS" }, +] +ram_size = 128 + +# SYSTIMER: 2 counter units, 3 alarm comparators, 16 MHz (XTAL/2.5) +# Ref: esp-idf systimer_ll.h, TRM v0.5 Ch 17 +# PAC register names verified: unit_op(n), unit_value(n), target_conf(n), +# trgt(n), comp_load(n) all match esp-hal systimer module expectations. +[device.systimer] + +# GP Timer (TIMG): 2 groups, each with 2 timers + WDT +# Ref: esp-idf timer_ll.h, TRM v0.5 Ch 18 +[device.gp_timer] +support_status = "partial" +instances = [ + { name = "timg0", sys_instance = "Timg0", interrupt = "TG0_T0_LEVEL" }, + { name = "timg1", sys_instance = "Timg1", interrupt = "TG1_T0_LEVEL" }, +] + +# SPI Master: 2 instances (GPSPI2, GPSPI3) +# Ref: esp-idf spi_ll.h, TRM v0.5 Ch 47 +# SPI Master: SPI2 only (SPI2 and SPI3 have different PAC RegisterBlock types) +# Ref: esp-idf spi_ll.h, TRM v0.5 Ch 47 +[device.spi_master] +support_status = "partial" +supports_dma = true +instances = [ + { name = "spi2", sys_instance = "Spi2", sclk = "SPI2_CK", sio = ["SPI2_D", "SPI2_Q", "SPI2_WP", "SPI2_HOLD"], cs = ["SPI2_CS"] }, + { name = "spi3", sys_instance = "Spi3", sclk = "SPI3_CK", sio = ["SPI3_D", "SPI3_Q", "SPI3_WP", "SPI3_HOLD"], cs = ["SPI3_CS", "SPI3_CS1", "SPI3_CS2"] }, +] + +# I2C Master: 2 instances +# P4 PAC: data register is read-only, TX uses txfifo_start_addr (fixed in i2c/master/mod.rs) +# Ref: esp-idf i2c_ll.h, TRM v0.5 Ch 48 +[device.i2c_master] +support_status = "partial" +instances = [ + { name = "i2c0", sys_instance = "I2c0", scl = "I2C0_SCL", sda = "I2C0_SDA" }, + { name = "i2c1", sys_instance = "I2c1", scl = "I2C1_SCL", sda = "I2C1_SDA" }, +] +has_fsm_timeouts = true +has_hw_bus_clear = true +ll_intr_mask = 0x3ffff +fifo_size = 32 +has_bus_timeout_enable = true +max_bus_timeout = 0x1F + +# DMA: deferred -- P4 PAC "DMA" is DW_GDMA (DesignWare), not AHB_DMA +# P4 has: AHB_DMA (GDMA v2 at 0x50085000) + AXI_DMA (0x5008A000) + DW_GDMA (0x50086000) +# esp-hal expects DMA singleton to be GDMA v2 compatible (in_conf0/out_conf0/in_link/out_link) +# But P4 PAC's "DMA" type is DW_GDMA (sar0/dar0/ctl0 pattern), NOT compatible +# Need: either PAC fix (rename AHB_DMA -> DMA) or esp-hal adapter layer +# Ref: esp-idf ahb_dma_ll.h for AHB_DMA register layout +# Ref: esp-idf dw_gdma_ll.h for DW_GDMA (different, DesignWare IP) +[device.dma] +support_status = "partial" +kind = "gdma" +gdma_version = 2 +separate_in_out_interrupts = true +max_priority = 5 + +# TWAI (CAN): 3 instances +# Ref: esp-idf twai_ll.h, TRM v0.5 Ch 58 +[device.twai] +support_status = "partial" + +# ADC: HP ADC + LP ADC +# Ref: TRM v0.5 Ch 38 (ADC), Ch 41 (LP ADC) +# Note: P4 ADC calibration needs special value (4 not 1) -- not yet implemented +[device.adc] +support_status = "partial" + +# Temperature sensor (LP_TSENS) +# Ref: TRM v0.5 Ch 43 (Temperature Sensor) +# [device.temperature_sensor] +# support_status = "partial" + +# Touch sensor (LP_TOUCH, 14 channels) +# Ref: TRM v0.5 Ch 42 (Touch Sensor) +# [device.touch] +# support_status = "partial" + +# AES: hardware accelerator +# Ref: esp-idf aes_ll.h, TRM v0.5 Ch 28 +[device.aes] +support_status = "partial" +has_split_text_registers = true +endianness_configurable = false +dma = true +key_length = { options = [ + { bits = 128, encrypt_mode = 0, decrypt_mode = 4 }, + { bits = 256, encrypt_mode = 2, decrypt_mode = 6 }, +] } + +# SHA: hardware accelerator +# Ref: esp-idf sha_ll.h, TRM v0.5 Ch 34 +[device.sha] +support_status = "partial" +dma = true +algo = { sha1 = 0, sha224 = 1, sha256 = 2 } + +# RSA: hardware accelerator +# Ref: esp-idf mpi_ll.h, TRM v0.5 Ch 33 +[device.rsa] +support_status = "partial" +size_increment = 32 +memory_size_bytes = 384 + +# ECC: hardware accelerator (eco5+ supported) +# Ref: esp-idf ecc_ll.h, TRM v0.5 Ch 30 +# USB Serial/JTAG controller +[device.usb_serial_jtag] + +[device.ecc] +support_status = "partial" +working_modes = [ + { id = 0, mode = "affine_point_multiplication" }, + { id = 2, mode = "affine_point_verification" }, + { id = 3, mode = "affine_point_verification_and_multiplication" }, + { id = 4, mode = "jacobian_point_multiplication" }, + { id = 5, mode = "affine_point_addition" }, + { id = 6, mode = "jacobian_point_verification" }, + { id = 7, mode = "affine_point_verification_and_jacobian_point_multiplication" }, + { id = 8, mode = "modular_addition" }, +] +curves = [ + { id = 0, curve = 192 }, + { id = 1, curve = 256 }, + { id = 2, curve = 384 }, +] +separate_jacobian_point_memory = true + +[device.gpio] +support_status = "partial" +has_bank_1 = true +separate_in_out_interrupts = true +gpio_function = 1 +constant_0_input = 0x3E +constant_1_input = 0x3F +input_signals = [ + { name = "SD_CARD_CCMD_2", id = 1 }, + { name = "SD_CARD_CDATA0_2", id = 2 }, + { name = "SD_CARD_CDATA1_2", id = 3 }, + { name = "SD_CARD_CDATA2_2", id = 4 }, + { name = "SD_CARD_CDATA3_2", id = 5 }, + { name = "SD_CARD_CDATA4_2", id = 6 }, + { name = "SD_CARD_CDATA5_2", id = 7 }, + { name = "SD_CARD_CDATA6_2", id = 8 }, + { name = "SD_CARD_CDATA7_2", id = 9 }, + { name = "UART0_RXD", id = 10 }, + { name = "UART0_CTS", id = 11 }, + { name = "UART0_DSR", id = 12 }, + { name = "UART1_RXD", id = 13 }, + { name = "UART1_CTS", id = 14 }, + { name = "UART1_DSR", id = 15 }, + { name = "UART2_RXD", id = 16 }, + { name = "UART2_CTS", id = 17 }, + { name = "UART2_DSR", id = 18 }, + { name = "UART3_RXD", id = 19 }, + { name = "UART3_CTS", id = 20 }, + { name = "UART3_DSR", id = 21 }, + { name = "UART4_RXD", id = 22 }, + { name = "UART4_CTS", id = 23 }, + { name = "UART4_DSR", id = 24 }, + { name = "I2S0_O_BCK", id = 25 }, + { name = "I2S0_MCLK", id = 26 }, + { name = "I2S0_O_WS", id = 27 }, + { name = "I2S0_I_SD", id = 28 }, + { name = "I2S0_I_BCK", id = 29 }, + { name = "I2S0_I_WS", id = 30 }, + { name = "I2S1_O_BCK", id = 31 }, + { name = "I2S1_MCLK", id = 32 }, + { name = "I2S1_O_WS", id = 33 }, + { name = "I2S1_I_SD", id = 34 }, + { name = "I2S1_I_BCK", id = 35 }, + { name = "I2S1_I_WS", id = 36 }, + { name = "I2S2_O_BCK", id = 37 }, + { name = "I2S2_MCLK", id = 38 }, + { name = "I2S2_O_WS", id = 39 }, + { name = "I2S2_I_SD", id = 40 }, + { name = "I2S2_I_BCK", id = 41 }, + { name = "I2S2_I_WS", id = 42 }, + { name = "I2S0_I_SD1", id = 43 }, + { name = "I2S0_I_SD2", id = 44 }, + { name = "I2S0_I_SD3", id = 45 }, + { name = "SPI3_CK", id = 47 }, + { name = "SPI3_Q", id = 48 }, + { name = "SPI3_D", id = 49 }, + { name = "SPI3_HOLD", id = 50 }, + { name = "SPI3_WP", id = 51 }, + { name = "SPI3_CS", id = 52 }, + { name = "SPI2_CK", id = 53 }, + { name = "SPI2_Q", id = 54 }, + { name = "SPI2_D", id = 55 }, + { name = "SPI2_HOLD", id = 56 }, + { name = "SPI2_WP", id = 57 }, + { name = "SPI2_IO4", id = 58 }, + { name = "SPI2_IO5", id = 59 }, + { name = "SPI2_IO6", id = 60 }, + { name = "SPI2_IO7", id = 61 }, + { name = "SPI2_CS", id = 62 }, + { name = "I2C0_SCL", id = 68 }, + { name = "I2C0_SDA", id = 69 }, + { name = "I2C1_SCL", id = 70 }, + { name = "I2C1_SDA", id = 71 }, + { name = "UART0_SLP_CLK", id = 74 }, + { name = "UART1_SLP_CLK", id = 75 }, + { name = "UART2_SLP_CLK", id = 76 }, + { name = "UART3_SLP_CLK", id = 77 }, + { name = "UART4_SLP_CLK", id = 78 }, + { name = "TWAI0_RX", id = 80 }, + { name = "TWAI1_RX", id = 83 }, + { name = "TWAI2_RX", id = 86 }, + { name = "PWM0_SYNC0", id = 89 }, + { name = "PWM0_SYNC1", id = 90 }, + { name = "PWM0_SYNC2", id = 91 }, + { name = "PWM0_F0", id = 92 }, + { name = "PWM0_F1", id = 93 }, + { name = "PWM0_F2", id = 94 }, + { name = "PWM0_CAP0", id = 95 }, + { name = "PWM0_CAP1", id = 96 }, + { name = "PWM0_CAP2", id = 97 }, + { name = "PWM1_SYNC0", id = 98 }, + { name = "PWM1_SYNC1", id = 99 }, + { name = "PWM1_SYNC2", id = 100 }, + { name = "PWM1_F0", id = 101 }, + { name = "PWM1_F1", id = 102 }, + { name = "PWM1_F2", id = 103 }, + { name = "PWM1_CAP0", id = 104 }, + { name = "PWM1_CAP1", id = 105 }, + { name = "PWM1_CAP2", id = 106 }, + { name = "MII_MDI", id = 107 }, + { name = "EMAC_PHY_COL", id = 108 }, + { name = "EMAC_PHY_CRS", id = 109 }, + { name = "USB_OTG11_IDDIG", id = 110 }, + { name = "USB_OTG11_AVALID", id = 111 }, + { name = "USB_SRP_BVALID", id = 112 }, + { name = "USB_OTG11_VBUSVALID", id = 113 }, + { name = "USB_SRP_SESSEND", id = 114 }, + { name = "ULPI_CLK", id = 117 }, + { name = "USB_HSPHY_REFCLK", id = 118 }, + { name = "SD_CARD_DETECT_N_1", id = 126 }, + { name = "SD_CARD_DETECT_N_2", id = 127 }, + { name = "SD_CARD_INT_N_1", id = 128 }, + { name = "SD_CARD_INT_N_2", id = 129 }, + { name = "SD_CARD_WRITE_PRT_1", id = 130 }, + { name = "SD_CARD_WRITE_PRT_2", id = 131 }, + { name = "SD_DATA_STROBE_1", id = 132 }, + { name = "SD_DATA_STROBE_2", id = 133 }, + { name = "I3C_MST_SCL", id = 134 }, + { name = "I3C_MST_SDA", id = 135 }, + { name = "I3C_SLV_SCL", id = 136 }, + { name = "I3C_SLV_SDA", id = 137 }, + { name = "USB_JTAG_TDO_BRIDGE", id = 140 }, + { name = "CAM_PCLK", id = 158 }, + { name = "CAM_H_ENABLE", id = 159 }, + { name = "CAM_H_SYNC", id = 160 }, + { name = "CAM_V_SYNC", id = 161 }, + { name = "EMAC_PHY_RXDV", id = 178 }, + { name = "EMAC_PHY_RXD0", id = 179 }, + { name = "EMAC_PHY_RXD1", id = 180 }, + { name = "EMAC_PHY_RXD2", id = 181 }, + { name = "EMAC_PHY_RXD3", id = 182 }, + { name = "EMAC_PHY_RXER", id = 183 }, + { name = "EMAC_RX_CLK", id = 184 }, + { name = "EMAC_TX_CLK", id = 185 }, + { name = "PARLIO_RX_CLK", id = 186 }, + { name = "PARLIO_TX_CLK", id = 187 }, + { name = "PARLIO_RX_DATA0", id = 188 }, + { name = "PARLIO_RX_DATA1", id = 189 }, + { name = "PARLIO_RX_DATA2", id = 190 }, + { name = "PARLIO_RX_DATA3", id = 191 }, + { name = "PARLIO_RX_DATA4", id = 192 }, + { name = "PARLIO_RX_DATA5", id = 193 }, + { name = "PARLIO_RX_DATA6", id = 194 }, + { name = "PARLIO_RX_DATA7", id = 195 }, + { name = "PARLIO_RX_DATA8", id = 196 }, + { name = "PARLIO_RX_DATA9", id = 197 }, + { name = "PARLIO_RX_DATA10", id = 198 }, + { name = "PARLIO_RX_DATA11", id = 199 }, + { name = "PARLIO_RX_DATA12", id = 200 }, + { name = "PARLIO_RX_DATA13", id = 201 }, + { name = "PARLIO_RX_DATA14", id = 202 }, + { name = "PARLIO_RX_DATA15", id = 203 }, + { name = "MTCK" }, + { name = "MTDI" }, + { name = "MTMS" }, + { name = "MTDO" }, + { name = "SD1_CDATA0" }, + { name = "SD1_CDATA1" }, + { name = "SD1_CDATA2" }, + { name = "SD1_CDATA3" }, + { name = "SD1_CCLK" }, + { name = "SD1_CCMD" }, + { name = "SD1_CDATA4" }, + { name = "SD1_CDATA5" }, + { name = "SD1_CDATA6" }, + { name = "SD1_CDATA7" }, + { name = "EMAC_RMII_CLK" }, + { name = "REF_50M_CLK" }, + { name = "BIST" }, + { name = "DBG_PSRAM_CK" }, + { name = "DBG_PSRAM_CS" }, + { name = "DBG_PSRAM_D" }, + { name = "DBG_PSRAM_Q" }, + { name = "DBG_PSRAM_WP" }, + { name = "DBG_PSRAM_HOLD" }, + { name = "DBG_PSRAM_DQ4" }, + { name = "DBG_PSRAM_DQ5" }, + { name = "DBG_PSRAM_DQ6" }, + { name = "DBG_PSRAM_DQ7" }, + { name = "DBG_PSRAM_DQS_0" }, + { name = "DBG_PSRAM_DQ8" }, + { name = "DBG_PSRAM_DQ9" }, + { name = "DBG_PSRAM_DQ10" }, + { name = "DBG_PSRAM_DQ11" }, + { name = "DBG_PSRAM_DQ12" }, + { name = "DBG_PSRAM_DQ13" }, + { name = "DBG_PSRAM_DQ14" }, + { name = "DBG_PSRAM_DQ15" }, + { name = "DBG_PSRAM_DQS_1" }, + { name = "DBG_FLASH_CS" }, + { name = "DBG_FLASH_Q" }, + { name = "DBG_FLASH_WP" }, + { name = "DBG_FLASH_HOLD" }, + { name = "DBG_FLASH_CK" }, + { name = "DBG_FLASH_D" }, + { name = "SPI2_DQS" }, +] + +output_signals = [ + { name = "SD_CARD_CCLK_2", id = 0 }, + { name = "SD_CARD_CCMD_2", id = 1 }, + { name = "SD_CARD_CDATA0_2", id = 2 }, + { name = "SD_CARD_CDATA1_2", id = 3 }, + { name = "SD_CARD_CDATA2_2", id = 4 }, + { name = "SD_CARD_CDATA3_2", id = 5 }, + { name = "SD_CARD_CDATA4_2", id = 6 }, + { name = "SD_CARD_CDATA5_2", id = 7 }, + { name = "SD_CARD_CDATA6_2", id = 8 }, + { name = "SD_CARD_CDATA7_2", id = 9 }, + { name = "UART0_TXD", id = 10 }, + { name = "UART0_RTS", id = 11 }, + { name = "UART0_DTR", id = 12 }, + { name = "UART1_TXD", id = 13 }, + { name = "UART1_RTS", id = 14 }, + { name = "UART1_DTR", id = 15 }, + { name = "UART2_TXD", id = 16 }, + { name = "UART2_RTS", id = 17 }, + { name = "UART2_DTR", id = 18 }, + { name = "UART3_TXD", id = 19 }, + { name = "UART3_RTS", id = 20 }, + { name = "UART3_DTR", id = 21 }, + { name = "UART4_TXD", id = 22 }, + { name = "UART4_RTS", id = 23 }, + { name = "UART4_DTR", id = 24 }, + { name = "I2S0_O_BCK", id = 25 }, + { name = "I2S0_MCLK", id = 26 }, + { name = "I2S0_O_WS", id = 27 }, + { name = "I2S0_O_SD", id = 28 }, + { name = "I2S0_I_BCK", id = 29 }, + { name = "I2S0_I_WS", id = 30 }, + { name = "I2S1_O_BCK", id = 31 }, + { name = "I2S1_MCLK", id = 32 }, + { name = "I2S1_O_WS", id = 33 }, + { name = "I2S1_O_SD", id = 34 }, + { name = "I2S1_I_BCK", id = 35 }, + { name = "I2S1_I_WS", id = 36 }, + { name = "I2S2_O_BCK", id = 37 }, + { name = "I2S2_MCLK", id = 38 }, + { name = "I2S2_O_WS", id = 39 }, + { name = "I2S2_O_SD", id = 40 }, + { name = "I2S2_I_BCK", id = 41 }, + { name = "I2S2_I_WS", id = 42 }, + { name = "I2S0_O_SD1", id = 43 }, + { name = "SPI2_DQS", id = 44 }, + { name = "SPI3_CS2", id = 45 }, + { name = "SPI3_CS1", id = 46 }, + { name = "SPI3_CK", id = 47 }, + { name = "SPI3_Q", id = 48 }, # PAC: SPI3_QO_PAD_OUT_IDX, renamed to match input signal + { name = "SPI3_D", id = 49 }, + { name = "SPI3_HOLD", id = 50 }, + { name = "SPI3_WP", id = 51 }, + { name = "SPI3_CS", id = 52 }, + { name = "SPI2_CK", id = 53 }, + { name = "SPI2_Q", id = 54 }, + { name = "SPI2_D", id = 55 }, + { name = "SPI2_HOLD", id = 56 }, + { name = "SPI2_WP", id = 57 }, + { name = "SPI2_IO4", id = 58 }, + { name = "SPI2_IO5", id = 59 }, + { name = "SPI2_IO6", id = 60 }, + { name = "SPI2_IO7", id = 61 }, + { name = "SPI2_CS", id = 62 }, + { name = "SPI2_CS1", id = 63 }, + { name = "SPI2_CS2", id = 64 }, + { name = "SPI2_CS3", id = 65 }, + { name = "SPI2_CS4", id = 66 }, + { name = "SPI2_CS5", id = 67 }, + { name = "I2C0_SCL", id = 68 }, + { name = "I2C0_SDA", id = 69 }, + { name = "I2C1_SCL", id = 70 }, + { name = "I2C1_SDA", id = 71 }, + { name = "GPIO_SD0", id = 72 }, + { name = "GPIO_SD1", id = 73 }, + { name = "GPIO_SD2", id = 74 }, + { name = "GPIO_SD3", id = 75 }, + { name = "GPIO_SD4", id = 76 }, + { name = "GPIO_SD5", id = 77 }, + { name = "GPIO_SD6", id = 78 }, + { name = "GPIO_SD7", id = 79 }, + { name = "TWAI0_TX", id = 80 }, + { name = "TWAI0_BUS_OFF_ON", id = 81 }, + { name = "TWAI0_CLKOUT", id = 82 }, + { name = "TWAI1_TX", id = 83 }, + { name = "TWAI1_BUS_OFF_ON", id = 84 }, + { name = "TWAI1_CLKOUT", id = 85 }, + { name = "TWAI2_TX", id = 86 }, + { name = "TWAI2_BUS_OFF_ON", id = 87 }, + { name = "TWAI2_CLKOUT", id = 88 }, + { name = "PWM0_CH0_A", id = 89 }, + { name = "PWM0_CH0_B", id = 90 }, + { name = "PWM0_CH1_A", id = 91 }, + { name = "PWM0_CH1_B", id = 92 }, + { name = "PWM0_CH2_A", id = 93 }, + { name = "PWM0_CH2_B", id = 94 }, + { name = "PWM1_CH0_A", id = 95 }, + { name = "PWM1_CH0_B", id = 96 }, + { name = "PWM1_CH1_A", id = 97 }, + { name = "PWM1_CH1_B", id = 98 }, + { name = "PWM1_CH2_A", id = 99 }, + { name = "PWM1_CH2_B", id = 100 }, + { name = "TWAI0_STANDBY", id = 105 }, + { name = "TWAI1_STANDBY", id = 106 }, + { name = "TWAI2_STANDBY", id = 107 }, + { name = "MII_MDC", id = 108 }, + { name = "MII_MDO", id = 109 }, + { name = "USB_SRP_DISCHRGVBUS", id = 110 }, + { name = "USB_OTG11_IDPULLUP", id = 111 }, + { name = "USB_OTG11_DPPULLDOWN", id = 112 }, + { name = "USB_OTG11_DMPULLDOWN", id = 113 }, + { name = "USB_OTG11_DRVVBUS", id = 114 }, + { name = "USB_SRP_CHRGVBUS", id = 115 }, + { name = "RNG_CHAIN_CLK", id = 117 }, + { name = "I3C_MST_SCL", id = 134 }, + { name = "I3C_MST_SDA", id = 135 }, + { name = "I3C_SLV_SCL", id = 136 }, + { name = "I3C_SLV_SDA", id = 137 }, + { name = "I3C_MST_SCL_PULLUP_EN", id = 138 }, + { name = "I3C_MST_SDA_PULLUP_EN", id = 139 }, + { name = "USB_JTAG_TDI_BRIDGE", id = 140 }, + { name = "USB_JTAG_TMS_BRIDGE", id = 141 }, + { name = "USB_JTAG_TCK_BRIDGE", id = 142 }, + { name = "USB_JTAG_TRST_BRIDGE", id = 143 }, + { name = "LCD_CS", id = 144 }, + { name = "LCD_DC", id = 145 }, + { name = "SD_RST_N_1", id = 146 }, + { name = "SD_RST_N_2", id = 147 }, + { name = "SD_CCMD_OD_PULLUP_EN_N", id = 148 }, + { name = "LCD_PCLK", id = 149 }, + { name = "CAM_CLK", id = 150 }, + { name = "LCD_H_ENABLE", id = 151 }, + { name = "LCD_H_SYNC", id = 152 }, + { name = "LCD_V_SYNC", id = 153 }, + { name = "EMAC_PHY_TXEN", id = 178 }, + { name = "EMAC_PHY_TXD0", id = 179 }, + { name = "EMAC_PHY_TXD1", id = 180 }, + { name = "EMAC_PHY_TXD2", id = 181 }, + { name = "EMAC_PHY_TXD3", id = 182 }, + { name = "EMAC_PHY_TXER", id = 183 }, + { name = "PARLIO_RX_CLK", id = 186 }, + { name = "PARLIO_TX_CLK", id = 187 }, + { name = "PARLIO_TX_DATA0", id = 188 }, + { name = "PARLIO_TX_DATA1", id = 189 }, + { name = "PARLIO_TX_DATA2", id = 190 }, + { name = "PARLIO_TX_DATA3", id = 191 }, + { name = "PARLIO_TX_DATA4", id = 192 }, + { name = "PARLIO_TX_DATA5", id = 193 }, + { name = "PARLIO_TX_DATA6", id = 194 }, + { name = "PARLIO_TX_DATA7", id = 195 }, + { name = "PARLIO_TX_DATA8", id = 196 }, + { name = "PARLIO_TX_DATA9", id = 197 }, + { name = "PARLIO_TX_DATA10", id = 198 }, + { name = "PARLIO_TX_DATA11", id = 199 }, + { name = "PARLIO_TX_DATA12", id = 200 }, + { name = "PARLIO_TX_DATA13", id = 201 }, + { name = "PARLIO_TX_DATA14", id = 202 }, + { name = "PARLIO_TX_DATA15", id = 203 }, + { name = "CONSTANT0", id = 212 }, + { name = "CONSTANT1", id = 213 }, + { name = "PARLIO_TX_CS", id = 242 }, + { name = "EMAC_PTP_PPS", id = 243 }, + { name = "ANA_COMP0", id = 244 }, + { name = "ANA_COMP1", id = 245 }, + { name = "GPIO", id = 256 }, + { name = "MTCK" }, + { name = "MTDI" }, + { name = "MTMS" }, + { name = "MTDO" }, + { name = "SD1_CDATA0" }, + { name = "SD1_CDATA1" }, + { name = "SD1_CDATA2" }, + { name = "SD1_CDATA3" }, + { name = "SD1_CCLK" }, + { name = "SD1_CCMD" }, + { name = "SD1_CDATA4" }, + { name = "SD1_CDATA5" }, + { name = "SD1_CDATA6" }, + { name = "SD1_CDATA7" }, + { name = "EMAC_RMII_CLK" }, + { name = "REF_50M_CLK" }, + { name = "BIST" }, + { name = "DBG_PSRAM_CK" }, + { name = "DBG_PSRAM_CS" }, + { name = "DBG_PSRAM_D" }, + { name = "DBG_PSRAM_Q" }, + { name = "DBG_PSRAM_WP" }, + { name = "DBG_PSRAM_HOLD" }, + { name = "DBG_PSRAM_DQ4" }, + { name = "DBG_PSRAM_DQ5" }, + { name = "DBG_PSRAM_DQ6" }, + { name = "DBG_PSRAM_DQ7" }, + { name = "DBG_PSRAM_DQS_0" }, + { name = "DBG_PSRAM_DQ8" }, + { name = "DBG_PSRAM_DQ9" }, + { name = "DBG_PSRAM_DQ10" }, + { name = "DBG_PSRAM_DQ11" }, + { name = "DBG_PSRAM_DQ12" }, + { name = "DBG_PSRAM_DQ13" }, + { name = "DBG_PSRAM_DQ14" }, + { name = "DBG_PSRAM_DQ15" }, + { name = "DBG_PSRAM_DQS_1" }, + { name = "DBG_FLASH_CS" }, + { name = "DBG_FLASH_Q" }, + { name = "DBG_FLASH_WP" }, + { name = "DBG_FLASH_HOLD" }, + { name = "DBG_FLASH_CK" }, + { name = "DBG_FLASH_D" }, +] + +# 55 GPIO pins (0-54), IO MUX functions from esp-idf io_mux_reg.h +# ADC channels from esp-idf adc_channel.h +# LP pins: GPIO0-5, GPIO12-23 (RTCIO capable) +# Ref: TRM v0.5 Ch 11, esp-idf gpio_periph.c, rtc_io_channel.h +pins = [ + { pin = 0, lp = { 0 = "LP_GPIO0" } }, + { pin = 1, lp = { 0 = "LP_GPIO1" } }, + { pin = 2, functions = { 0 = "MTCK", lp = { 0 = "LP_GPIO2" } }, limitations = ["jtag"] }, + { pin = 3, functions = { 0 = "MTDI", lp = { 0 = "LP_GPIO3" } }, limitations = ["jtag"] }, + { pin = 4, functions = { 0 = "MTMS", lp = { 0 = "LP_GPIO4" } }, limitations = ["jtag"] }, + { pin = 5, functions = { 0 = "MTDO", lp = { 0 = "LP_GPIO5" } }, limitations = ["jtag"] }, + { pin = 6, functions = { 3 = "SPI2_HOLD" } }, + { pin = 7, functions = { 3 = "SPI2_CS" } }, + { pin = 8, functions = { 2 = "UART0_RTS", 3 = "SPI2_D" } }, + { pin = 9, functions = { 2 = "UART0_CTS", 3 = "SPI2_CK" } }, + { pin = 10, functions = { 2 = "UART1_TXD", 3 = "SPI2_Q" } }, + { pin = 11, functions = { 2 = "UART1_RXD", 3 = "SPI2_WP" } }, + { pin = 12, functions = { 2 = "UART1_RTS", lp = { 0 = "LP_GPIO12" } } }, + { pin = 13, functions = { 2 = "UART1_CTS", lp = { 0 = "LP_GPIO13" } } }, + { pin = 14, lp = { 0 = "LP_GPIO14" } }, + { pin = 15, lp = { 0 = "LP_GPIO15" } }, + { pin = 16, analog = { 1 = "ADC1_CH0", lp = { 0 = "LP_GPIO16" } } }, + { pin = 17, analog = { 1 = "ADC1_CH1", lp = { 0 = "LP_GPIO17" } } }, + { pin = 18, analog = { 1 = "ADC1_CH2", lp = { 0 = "LP_GPIO18" } } }, + { pin = 19, analog = { 1 = "ADC1_CH3", lp = { 0 = "LP_GPIO19" } } }, + { pin = 20, analog = { 1 = "ADC1_CH4", lp = { 0 = "LP_GPIO20" } } }, + { pin = 21, analog = { 1 = "ADC1_CH5", lp = { 0 = "LP_GPIO21" } } }, + { pin = 22, functions = { 4 = "DBG_PSRAM_CK", lp = { 0 = "LP_GPIO22" } }, analog = { 1 = "ADC1_CH6" } }, + { pin = 23, functions = { 3 = "REF_50M_CLK", 4 = "DBG_PSRAM_CS", lp = { 0 = "LP_GPIO23" } }, analog = { 1 = "ADC1_CH7" } }, + { pin = 24, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY0_DM" } }, + { pin = 25, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY0_DP" } }, + { pin = 26, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY1_DM" } }, + { pin = 27, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY1_DP" } }, + { pin = 28, functions = { 2 = "SPI2_CS", 3 = "EMAC_PHY_RXDV", 4 = "DBG_PSRAM_D" } }, + { pin = 29, functions = { 2 = "SPI2_D", 3 = "EMAC_PHY_RXD0", 4 = "DBG_PSRAM_Q" } }, + { pin = 30, functions = { 2 = "SPI2_CK", 3 = "EMAC_PHY_RXD1", 4 = "DBG_PSRAM_WP" } }, + { pin = 31, functions = { 2 = "SPI2_Q", 3 = "EMAC_PHY_RXER", 4 = "DBG_PSRAM_HOLD" } }, + { pin = 32, functions = { 2 = "SPI2_HOLD", 3 = "EMAC_RMII_CLK", 4 = "DBG_PSRAM_DQ4" }, limitations = ["strapping"] }, + { pin = 33, functions = { 2 = "SPI2_WP", 3 = "EMAC_PHY_TXEN", 4 = "DBG_PSRAM_DQ5" }, limitations = ["strapping"] }, + { pin = 34, functions = { 2 = "SPI2_IO4", 3 = "EMAC_PHY_TXD0", 4 = "DBG_PSRAM_DQ6" }, limitations = ["strapping"] }, + { pin = 35, functions = { 2 = "SPI2_IO5", 3 = "EMAC_PHY_TXD1", 4 = "DBG_PSRAM_DQ7" }, limitations = ["strapping"] }, + { pin = 36, functions = { 2 = "SPI2_IO6", 3 = "EMAC_PHY_TXER", 4 = "DBG_PSRAM_DQS_0" }, limitations = ["strapping"] }, + { pin = 37, functions = { 0 = "UART0_TXD", 2 = "SPI2_IO7" }, limitations = ["strapping"] }, + { pin = 38, functions = { 0 = "UART0_RXD", 2 = "SPI2_DQS" }, limitations = ["strapping"] }, + { pin = 39, functions = { 0 = "SD1_CDATA0", 2 = "BIST", 3 = "REF_50M_CLK", 4 = "DBG_PSRAM_DQ8" } }, + { pin = 40, functions = { 0 = "SD1_CDATA1", 2 = "BIST", 3 = "EMAC_PHY_TXEN", 4 = "DBG_PSRAM_DQ9" } }, + { pin = 41, functions = { 0 = "SD1_CDATA2", 2 = "BIST", 3 = "EMAC_PHY_TXD0", 4 = "DBG_PSRAM_DQ10" } }, + { pin = 42, functions = { 0 = "SD1_CDATA3", 2 = "BIST", 3 = "EMAC_PHY_TXD1", 4 = "DBG_PSRAM_DQ11" } }, + { pin = 43, functions = { 0 = "SD1_CCLK", 2 = "BIST", 3 = "EMAC_PHY_TXER", 4 = "DBG_PSRAM_DQ12" } }, + { pin = 44, functions = { 0 = "SD1_CCMD", 2 = "BIST", 3 = "EMAC_RMII_CLK", 4 = "DBG_PSRAM_DQ13" } }, + { pin = 45, functions = { 0 = "SD1_CDATA4", 2 = "BIST", 3 = "EMAC_PHY_RXDV", 4 = "DBG_PSRAM_DQ14" } }, + { pin = 46, functions = { 0 = "SD1_CDATA5", 2 = "BIST", 3 = "EMAC_PHY_RXD0", 4 = "DBG_PSRAM_DQ15" } }, + { pin = 47, functions = { 0 = "SD1_CDATA6", 2 = "BIST", 3 = "EMAC_PHY_RXD1", 4 = "DBG_PSRAM_DQS_1" } }, + { pin = 48, functions = { 0 = "SD1_CDATA7", 2 = "BIST", 3 = "EMAC_PHY_RXER" } }, + { pin = 49, functions = { 3 = "EMAC_PHY_TXEN", 4 = "DBG_FLASH_CS" }, analog = { 1 = "ADC2_CH0" } }, + { pin = 50, functions = { 3 = "EMAC_RMII_CLK", 4 = "DBG_FLASH_Q" }, analog = { 1 = "ADC2_CH1" } }, + { pin = 51, functions = { 3 = "EMAC_PHY_RXDV", 4 = "DBG_FLASH_WP" }, analog = { 1 = "ADC2_CH2" } }, + { pin = 52, functions = { 3 = "EMAC_PHY_RXD0", 4 = "DBG_FLASH_HOLD" }, analog = { 1 = "ADC2_CH3" } }, + { pin = 53, functions = { 3 = "EMAC_PHY_RXD1", 4 = "DBG_FLASH_CK" }, analog = { 1 = "ADC2_CH4" } }, + { pin = 54, functions = { 3 = "EMAC_PHY_RXER", 4 = "DBG_FLASH_D" }, analog = { 1 = "ADC2_CH5" } }, +] diff --git a/esp-metadata/src/lib.rs b/esp-metadata/src/lib.rs index f9d8d369834..212cbbf629c 100644 --- a/esp-metadata/src/lib.rs +++ b/esp-metadata/src/lib.rs @@ -123,6 +123,8 @@ pub enum Chip { Esp32c61, /// ESP32-H2 Esp32h2, + /// ESP32-P4 (chip revision v3.x / eco5 only) + Esp32p4, /// ESP32-S2 Esp32s2, /// ESP32-S3 @@ -183,6 +185,7 @@ impl Chip { Chip::Esp32c6 => "Esp32c6", Chip::Esp32c61 => "Esp32c61", Chip::Esp32h2 => "Esp32h2", + Chip::Esp32p4 => "Esp32p4", Chip::Esp32s2 => "Esp32s2", Chip::Esp32s3 => "Esp32s3", } @@ -197,6 +200,7 @@ impl Chip { Chip::Esp32c6 => "ESP32-C6", Chip::Esp32c61 => "ESP32-C61", Chip::Esp32h2 => "ESP32-H2", + Chip::Esp32p4 => "ESP32-P4", Chip::Esp32s2 => "ESP32-S2", Chip::Esp32s3 => "ESP32-S3", } @@ -355,6 +359,7 @@ impl Config { Chip::Esp32c6 => include_toml!(Config, "../devices/esp32c6.toml"), Chip::Esp32c61 => include_toml!(Config, "../devices/esp32c61.toml"), Chip::Esp32h2 => include_toml!(Config, "../devices/esp32h2.toml"), + Chip::Esp32p4 => include_toml!(Config, "../devices/esp32p4.toml"), Chip::Esp32s2 => include_toml!(Config, "../devices/esp32s2.toml"), Chip::Esp32s3 => include_toml!(Config, "../devices/esp32s3.toml"), } diff --git a/esp-println/Cargo.toml b/esp-println/Cargo.toml index 7f468dedf0a..00dc1110d54 100644 --- a/esp-println/Cargo.toml +++ b/esp-println/Cargo.toml @@ -62,6 +62,7 @@ esp32c5 = ["esp-metadata-generated/esp32c5", "esp-sync?/esp32c5"] esp32c6 = ["esp-metadata-generated/esp32c6", "esp-sync?/esp32c6"] esp32c61 = ["esp-metadata-generated/esp32c61", "esp-sync?/esp32c61"] esp32h2 = ["esp-metadata-generated/esp32h2", "esp-sync?/esp32h2"] +esp32p4 = ["esp-metadata-generated/esp32p4", "esp-sync?/esp32p4"] esp32s2 = ["esp-metadata-generated/esp32s2", "esp-sync?/esp32s2"] esp32s3 = ["esp-metadata-generated/esp32s3", "esp-sync?/esp32s3"] diff --git a/esp-println/src/lib.rs b/esp-println/src/lib.rs index 33b5ad583a9..31371d5ede0 100644 --- a/esp-println/src/lib.rs +++ b/esp-println/src/lib.rs @@ -229,6 +229,7 @@ mod auto_printer { feature = "esp32c6", feature = "esp32c61", feature = "esp32h2", + feature = "esp32p4", feature = "esp32s3" ) ))] @@ -263,6 +264,13 @@ mod serial_jtag_printer { #[cfg(feature = "esp32s3")] const SERIAL_JTAG_CONF_REG: usize = 0x6003_8004; + // ESP32-P4: USB_DEVICE peripheral at 0x500D_2000 per PAC. + // FIFO/CONF layout matches C6/H2 (same Synopsys USB Serial/JTAG IP). + #[cfg(feature = "esp32p4")] + const SERIAL_JTAG_FIFO_REG: usize = 0x500D_2000; + #[cfg(feature = "esp32p4")] + const SERIAL_JTAG_CONF_REG: usize = 0x500D_2004; + /// A previous wait has timed out. We use this flag to avoid blocking /// forever if there is no host attached. static TIMED_OUT: AtomicBool = AtomicBool::new(false); @@ -410,6 +418,17 @@ mod uart_printer { struct Device; + // ESP32-P4: ROM uart_tx_one_char at 0x4fc00054 + // Ref: esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld + #[cfg(feature = "esp32p4")] + impl Functions for Device { + const TX_ONE_CHAR: usize = 0x4fc0_0054; + + fn flush() { + // tx_one_char waits for TX FIFO space + } + } + #[cfg(feature = "esp32c2")] impl Functions for Device { const TX_ONE_CHAR: usize = 0x4000_005C; diff --git a/esp-rom-sys/Cargo.toml b/esp-rom-sys/Cargo.toml index 6da1cb8e686..aa9baaddca9 100644 --- a/esp-rom-sys/Cargo.toml +++ b/esp-rom-sys/Cargo.toml @@ -36,6 +36,7 @@ esp32c5 = { version = "0.1", features = ["critical-section"], optional = true, esp32c6 = { version = "0.22", features = ["critical-section"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32c61 = { version = "0.1", features = ["critical-section"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32h2 = { version = "0.18", features = ["critical-section"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } +esp32p4 = { version = "0.2", features = ["critical-section"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32s2 = { version = "0.30", features = ["critical-section"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } esp32s3 = { version = "0.34", features = ["critical-section"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "fc3e6d4" } @@ -63,6 +64,8 @@ esp32c61 = [ "dep:esp32c61" ] ## esp32h2 = [ "dep:esp32h2" ] ## +esp32p4 = [ "dep:esp32p4" ] +## esp32s2 = [ "dep:esp32s2" ] ## esp32s3 = [ "dep:esp32s3" ] diff --git a/esp-rom-sys/ld/esp32p4/rom/additional.ld b/esp-rom-sys/ld/esp32p4/rom/additional.ld index 318f1cd9372..e1181631cd9 100644 --- a/esp-rom-sys/ld/esp32p4/rom/additional.ld +++ b/esp-rom-sys/ld/esp32p4/rom/additional.ld @@ -1,3 +1,5 @@ +/* Ref: esp-idf esp32p4.rom.libc.ld (eco5) */ +syscall_table_ptr = 0x4ffbffe4; ets_update_cpu_frequency = 0x4fc00044; ets_printf = 0x4fc00024; PROVIDE(ets_delay_us = 0x4fc0003c); diff --git a/esp-rom-sys/src/rom/mod.rs b/esp-rom-sys/src/rom/mod.rs index 039ed353404..676ea6daab0 100644 --- a/esp-rom-sys/src/rom/mod.rs +++ b/esp-rom-sys/src/rom/mod.rs @@ -77,7 +77,7 @@ pub fn ets_set_appcpu_boot_addr(boot_addr: u32) { #[unsafe(no_mangle)] extern "C" fn rtc_clk_xtal_freq_get() -> i32 { cfg_if::cfg_if! { - if #[cfg(any(esp32c6, esp32h2))] { + if #[cfg(any(esp32c6, esp32h2, esp32p4))] { unsafe extern "C" { fn ets_clk_get_xtal_freq() -> i32; } diff --git a/esp-rom-sys/src/syscall/mod.rs b/esp-rom-sys/src/syscall/mod.rs index e8261b5a51d..db098e81dd6 100644 --- a/esp-rom-sys/src/syscall/mod.rs +++ b/esp-rom-sys/src/syscall/mod.rs @@ -5,7 +5,8 @@ use core::ffi::{c_char, c_int, c_long, c_void}; // future chips or ECOs _might_ be different - at least ESP-IDF defines the struct per chip #[cfg_attr( any( - esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2 + esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, + esp32p4 ), path = "v1.rs" )] diff --git a/esp-sync/Cargo.toml b/esp-sync/Cargo.toml index 10ad0f738b3..150266c62a8 100644 --- a/esp-sync/Cargo.toml +++ b/esp-sync/Cargo.toml @@ -55,6 +55,8 @@ esp32c6 = ["esp-metadata-generated/esp32c6"] esp32c61 = ["esp-metadata-generated/esp32c61"] ## Target the ESP32-H2. esp32h2 = ["esp-metadata-generated/esp32h2"] +## Target the ESP32-P4. +esp32p4 = ["esp-metadata-generated/esp32p4"] ## Target the ESP32-S2. esp32s2 = ["esp-metadata-generated/esp32s2"] ## Target the ESP32-S3. diff --git a/esp-sync/src/raw.rs b/esp-sync/src/raw.rs index 4d6551031c5..44ee2612788 100644 --- a/esp-sync/src/raw.rs +++ b/esp-sync/src/raw.rs @@ -36,9 +36,31 @@ impl RawLock for SingleCoreInterruptLock { unsafe fn enter(&self) -> RestoreState { cfg_if::cfg_if! { if #[cfg(riscv)] { + // ESP32-P4 (v3.2/ECO7 etc.) Zcmp hardware bug workaround (IDF-14279 / DIG-661): + // Clearing mstatus.mie alone does not fully mask CLIC interrupts -- an + // interrupt can still fire mid-instruction on cm.push (and possibly on + // other multi-cycle sequences). Fix: raise mintthresh (CSR 0x347) to 0xFF + // while mie is cleared, then restore the previous mintthresh on exit. + // Ref: esp-idf commit c27c33a83 "fix(riscv): implement a workaround for + // Zcmp hardware bug". + #[cfg(esp32p4)] + let old_mintthresh: u32; + #[cfg(esp32p4)] + unsafe { + core::arch::asm!( + "li t0, 0xff", + "csrrw {0}, 0x347, t0", + out(reg) old_mintthresh, + out("t0") _, + ); + } let mut mstatus = 0u32; unsafe { core::arch::asm!("csrrci {0}, mstatus, 8", inout(reg) mstatus); } - let token = mstatus & 0b1000; + let mie_bit = mstatus & 0b1000; + #[cfg(esp32p4)] + let token = mie_bit | ((old_mintthresh & 0xff) << 8); + #[cfg(not(esp32p4))] + let token = mie_bit; } else if #[cfg(xtensa)] { let token: u32; unsafe { core::arch::asm!("rsil {0}, 5", out(reg) token); } @@ -66,11 +88,22 @@ impl RawLock for SingleCoreInterruptLock { cfg_if::cfg_if! { if #[cfg(riscv)] { - if token != 0 { + if (token & 0b1000) != 0 { unsafe { riscv::interrupt::enable(); } } + // Restore mintthresh AFTER re-enabling mie (P4 Zcmp workaround, see enter()). + #[cfg(esp32p4)] + { + let old_mintthresh = (token >> 8) & 0xff; + unsafe { + core::arch::asm!( + "csrw 0x347, {0}", + in(reg) old_mintthresh, + ); + } + } } else if #[cfg(xtensa)] { #[cfg(debug_assertions)] if token & RESERVED_MASK != 0 { diff --git a/xtask-mcp-macros/src/lib.rs b/xtask-mcp-macros/src/lib.rs index dbafaba29ef..3feeae28980 100644 --- a/xtask-mcp-macros/src/lib.rs +++ b/xtask-mcp-macros/src/lib.rs @@ -19,6 +19,7 @@ use syn::{ // Attribute parsing helpers /// Parsed information from a `#[arg(...)]` attribute. +#[derive(Default)] struct ArgInfo { /// True if `long` (or `long = "name"`) was present. has_long: bool, @@ -28,33 +29,22 @@ struct ArgInfo { value_delimiter: Option, } -impl Default for ArgInfo { - fn default() -> Self { - Self { - has_long: false, - long_name: String::new(), - value_delimiter: None, - } - } -} /// Parse a string literal from an expression. fn expr_lit_str(expr: &Expr) -> Option { - if let Expr::Lit(el) = expr { - if let Lit::Str(s) = &el.lit { + if let Expr::Lit(el) = expr + && let Lit::Str(s) = &el.lit { return Some(s.value()); } - } None } /// Parse a char literal from an expression. fn expr_lit_char(expr: &Expr) -> Option { - if let Expr::Lit(el) = expr { - if let Lit::Char(c) = &el.lit { + if let Expr::Lit(el) = expr + && let Lit::Char(c) = &el.lit { return Some(c.value()); } - } None } @@ -66,13 +56,11 @@ fn extract_doc(attrs: &[Attribute]) -> String { if !attr.path().is_ident("doc") { return None; } - if let Meta::NameValue(nv) = &attr.meta { - if let Expr::Lit(el) = &nv.value { - if let Lit::Str(s) = &el.lit { + if let Meta::NameValue(nv) = &attr.meta + && let Expr::Lit(el) = &nv.value + && let Lit::Str(s) = &el.lit { return Some(s.value().trim().to_string()); } - } - } None }) .filter(|s| !s.is_empty()) @@ -433,7 +421,7 @@ fn expand_mcp_tool(attrs: McpToolAttrs, item: &ItemStruct) -> syn::Result = attrs diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs index a644ff1266f..c5375d5d081 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/cargo.rs @@ -365,6 +365,12 @@ impl BuiltCommand { } } +impl Default for CargoCommandBatcher { + fn default() -> Self { + Self::new() + } +} + impl CargoCommandBatcher { pub fn new() -> Self { Self { @@ -544,7 +550,7 @@ pub struct CargoToml { pub manifest: toml_edit::DocumentMut, } -const DEPENDENCY_KINDS: [&'static str; 3] = +const DEPENDENCY_KINDS: [&str; 3] = ["dependencies", "dev-dependencies", "build-dependencies"]; impl CargoToml { @@ -575,7 +581,7 @@ impl CargoToml { let Some(espressif) = metadata.get("espressif") else { return None; }; - Some(espressif.as_table()?) + espressif.as_table() } /// Create a `CargoToml` instance from a manifest string. @@ -713,11 +719,10 @@ impl CargoToml { name }; - if let Ok(package) = Package::from_str(name, true) { - if !dependencies.contains(&package) { + if let Ok(package) = Package::from_str(name, true) + && !dependencies.contains(&package) { dependencies.push(package); } - } } }); dependencies @@ -732,7 +737,7 @@ impl CargoToml { self.visit_dependencies(|_, _, table| { // Update dependencies which specify a version: - match &mut table[&package_name] { + match &mut table[package_name] { Item::Value(Value::String(table)) => { // package = "version" *table = Formatted::new(format_dependency_version(table.value(), version)); @@ -754,16 +759,14 @@ impl CargoToml { Item::None => { // alias = { package = "foo", version = "version" } let update_renamed_dep = table.get_values().iter().find_map(|(k, p)| { - if let Value::InlineTable(table) = p { - if let Some(Value::String(name)) = &table.get("package") { - if name.value() == &package_name { + if let Value::InlineTable(table) = p + && let Some(Value::String(name)) = &table.get("package") + && name.value() == package_name { // Return the actual key of this dependency, e.g.: // `procmacros = { package = "esp-hal-procmacros" }` // ^^^^^^^^^^ return Some(k.last().unwrap().get().to_string()); } - } - } None }); diff --git a/xtask/src/commands/build.rs b/xtask/src/commands/build.rs index 25ce0f7d611..98144296d3a 100644 --- a/xtask/src/commands/build.rs +++ b/xtask/src/commands/build.rs @@ -164,7 +164,7 @@ pub fn build_examples( // Build command list for example in examples.iter() { let command = crate::generate_build_command( - &package_path, + package_path, chip, &target, example, diff --git a/xtask/src/commands/mod.rs b/xtask/src/commands/mod.rs index 00c5f3d3c2a..247fe0bb097 100644 --- a/xtask/src/commands/mod.rs +++ b/xtask/src/commands/mod.rs @@ -400,7 +400,7 @@ pub fn examples(workspace: &Path, mut args: ExamplesArgs, action: CargoAction) - args, filtered, &package_path, - out_path.as_ref().map(|p| p.as_path()), + out_path.as_deref(), ), CargoAction::Run => run_examples(args, filtered, &package_path), } @@ -450,13 +450,13 @@ pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<( }; let run_test_extra_args = (action == CargoAction::Run) - .then(|| filter.as_ref().map(|f| std::slice::from_ref(f))) + .then(|| filter.as_ref().map(std::slice::from_ref)) .flatten() .unwrap_or(&[]); let matched: Vec<_> = tests .iter() - .filter(|t| t.matches(test_arg.as_deref())) + .filter(|t| t.matches(test_arg)) .collect(); if matched.is_empty() { diff --git a/xtask/src/commands/release/bump_version.rs b/xtask/src/commands/release/bump_version.rs index 23a6e3b9e1a..fc8aa14a3ff 100644 --- a/xtask/src/commands/release/bump_version.rs +++ b/xtask/src/commands/release/bump_version.rs @@ -119,7 +119,7 @@ fn check_crate_before_bumping(manifest: &mut CargoToml) -> Result<()> { let mut error_message = String::new(); for (dep_kind, errors) in errors { if !error_message.is_empty() { - error_message.push_str("\n"); + error_message.push('\n'); } writeln!(&mut error_message, "In [{dep_kind}]:").unwrap(); for (krate, error) in errors { @@ -219,7 +219,7 @@ fn bump_crate_version( let content = fs::read_to_string(&p) .with_context(|| format!("Could not read {}", p.display()))?; CargoToml::from_str(&bumped_package.workspace, Package::Examples, &content) - .with_context(|| format!("Could not parse Cargo.toml")) + .with_context(|| "Could not parse Cargo.toml".to_string()) })); for dependent in tomls { @@ -273,7 +273,7 @@ pub fn do_version_bump(version: &semver::Version, amount: &VersionBump) -> Resul version.pre = Prerelease::EMPTY; } else { // If the version is not a pre-release, we need to bump the version - bump_version_number(&mut version, &amount); + bump_version_number(&mut version, amount); } } VersionBump::PreRelease(pre) => { diff --git a/xtask/src/commands/run.rs b/xtask/src/commands/run.rs index df681118bc7..8f64f4c6ce1 100644 --- a/xtask/src/commands/run.rs +++ b/xtask/src/commands/run.rs @@ -88,7 +88,7 @@ pub fn run_doc_tests_for_package(workspace: &Path, package: Package, chip: Chip) } // Packages that have doc features are documented. We run doc-tests for these, and only these. - let Some(mut features) = package.doc_feature_rules(&esp_metadata::Config::for_chip(&chip)) + let Some(mut features) = package.doc_feature_rules(esp_metadata::Config::for_chip(&chip)) else { log::info!("Skipping undocumented package {package}."); return Ok(true); diff --git a/xtask/src/documentation.rs b/xtask/src/documentation.rs index 82ab0f9bda9..cc465388f22 100644 --- a/xtask/src/documentation.rs +++ b/xtask/src/documentation.rs @@ -106,12 +106,11 @@ fn build_documentation_for_package( let version = crate::package_version(workspace, *package)?; // Ensure that the package/chip combination provided are valid: - if let Some(chip) = chip { - if let Err(err) = package.validate_package_chip(&chip) { + if let Some(chip) = chip + && let Err(err) = package.validate_package_chip(&chip) { log::warn!("{err}"); return Ok(()); } - } // Build the documentation for the specified package, targeting the // specified chip: @@ -333,11 +332,7 @@ fn pre_process_cargo_toml(chip: Option, package_path: &PathBuf) -> Result< let cargo_toml = cargo_toml.lines(); - let chip_cfg = if let Some(chip) = &chip { - Some(Config::for_chip(chip)) - } else { - None - }; + let chip_cfg = chip.as_ref().map(Config::for_chip); let mut processed_cargo_toml = Vec::new(); let mut engine = somni_expr::Context::new(); engine.add_function("has", move |cond: &str| -> bool { diff --git a/xtask/src/firmware.rs b/xtask/src/firmware.rs index 191d4a18818..bdff69ddc1e 100644 --- a/xtask/src/firmware.rs +++ b/xtask/src/firmware.rs @@ -363,7 +363,7 @@ pub fn load_cargo_toml(examples_path: &Path) -> Result> { let chips = toml .features .keys() - .filter_map(|chip| Chip::from_str(&chip, true).ok()); + .filter_map(|chip| Chip::from_str(chip, true).ok()); for chip in chips { examples.push(Metadata { diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index b551c387e5a..5c9c0ead487 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -111,8 +111,8 @@ impl Package { // This is intended to opt-out in case there are features that look like chip names, but // aren't supposed to be handled like them. - if let Some(metadata) = toml.espressif_metadata() { - if let Some(Item::Value(ov)) = metadata.get("has_chip_features") { + if let Some(metadata) = toml.espressif_metadata() + && let Some(Item::Value(ov)) = metadata.get("has_chip_features") { let Value::Boolean(ov) = ov else { log::warn!("Invalid value for 'has_chip_features' in metadata"); return false; @@ -120,7 +120,6 @@ impl Package { return *ov.value(); } - } features .iter() @@ -176,11 +175,10 @@ impl Package { // Look for files matching the pattern "MIGRATING-*.md" for entry in entries.flatten() { - if let Some(file_name) = entry.file_name().to_str() { - if file_name.starts_with("MIGRATING-") && file_name.ends_with(".md") { + if let Some(file_name) = entry.file_name().to_str() + && file_name.starts_with("MIGRATING-") && file_name.ends_with(".md") { return true; } - } } false @@ -198,7 +196,7 @@ impl Package { .filter_map(Result::ok) .filter(|e| e.path().extension().is_some_and(|ext| ext == "rs")) .any(|entry| { - std::fs::read_to_string(entry.path()).map_or(false, |src| src.contains("#[test]")) + std::fs::read_to_string(entry.path()).is_ok_and(|src| src.contains("#[test]")) }) } @@ -794,32 +792,32 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { match package { Package::EspConfig => { - return cargo::run( + cargo::run( &cmd.clone() .subcommand("test") - .features(&vec!["build".into(), "tui".into()]) + .features(&["build".into(), "tui".into()]) .build(), &package_path, - ); + ) } Package::EspBootloaderEspIdf => { - return cargo::run( + cargo::run( &cmd.clone() .subcommand("test") .arg("--lib") .arg("--tests") - .features(&vec!["std".into()]) + .features(&["std".into()]) .build(), &package_path, - ); + ) } Package::EspStorage => { cargo::run( &cmd.clone() .subcommand("test") - .features(&vec!["emulation".into()]) + .features(&["emulation".into()]) .arg("--") .arg("--test-threads=1") .build(), @@ -829,7 +827,7 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { cargo::run( &cmd.clone() .subcommand("test") - .features(&vec!["emulation".into(), "bytewise-read".into()]) + .features(&["emulation".into(), "bytewise-read".into()]) .arg("--") .arg("--test-threads=1") .build(), @@ -843,38 +841,36 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { .toolchain("nightly") .subcommand("miri") .subcommand("test") - .features(&vec!["emulation".into()]) + .features(&["emulation".into()]) .arg("--") .arg("--test-threads=1") .build(), &package_path, )?; - return cargo::run( + cargo::run( &cmd.clone() .toolchain("nightly") .subcommand("miri") .subcommand("test") - .features(&vec!["emulation".into(), "bytewise-read".into()]) + .features(&["emulation".into(), "bytewise-read".into()]) .arg("--") .arg("--test-threads=1") .build(), &package_path, - ); + ) } Package::EspHalProcmacros => { - return cargo::run( + cargo::run( &cmd.clone() .subcommand("test") - .features(&vec![ - "has-lp-core".into(), + .features(&["has-lp-core".into(), "is-lp-core".into(), "rtc-slow".into(), - "rtc-fast".into(), - ]) + "rtc-fast".into()]) .build(), &package_path, - ); + ) } _ => Err(anyhow!( "Instructions for host testing were not provided for: '{}'", @@ -928,7 +924,7 @@ pub fn format_package_path( log::debug!("{cargo_args:#?}"); - cargo::run(&cargo_args, &package_path) + cargo::run(&cargo_args, package_path) } /// Recursively format all `.yml` files in the `.github/` directory. diff --git a/xtask/src/main.rs b/xtask/src/main.rs index ba240325248..74eb8ad8350 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -100,7 +100,7 @@ fn main() -> Result<()> { builder.init(); let workspace = - std::env::current_dir().with_context(|| format!("Failed to get the current dir!"))?; + std::env::current_dir().with_context(|| "Failed to get the current dir!".to_string())?; let target_path = workspace.join("target"); if std::env::var("CARGO_TARGET_DIR").is_err() { @@ -212,7 +212,7 @@ fn clean(workspace: &Path, args: CleanArgs) -> Result<()> { .arg(path.join("target").display().to_string()) .build(); - xtask::cargo::run(&cargo_args, &path).with_context(|| { + xtask::cargo::run(&cargo_args, path).with_context(|| { format!( "Failed to run `cargo run` with {cargo_args:?} in {}", path.display() @@ -309,7 +309,7 @@ fn build_check_package_command( builder = builder.toolchain(toolchain); } - builder = builder.args(&args); + builder = builder.args(args); if !features.is_empty() { builder = builder.arg(format!("--features={}", features.join(","))); @@ -525,7 +525,7 @@ fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> { log::info!("Running CI checks for chip: {}", args.chip); println!("::add-matcher::.github/rust-matchers.json"); - let run_locally = !std::env::var("CI").is_ok(); + let run_locally = std::env::var("CI").is_err(); let mut runner = Runner::new(&args); @@ -709,9 +709,9 @@ fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> { // The `ota_example` expects a file named `examples/target/ota_image` - it // doesn't care about the contents however std::fs::create_dir_all("./examples/target") - .with_context(|| format!("Failed to create `./examples/target`"))?; + .with_context(|| "Failed to create `./examples/target`".to_string())?; std::fs::write("./examples/target/ota_image", "DUMMY") - .with_context(|| format!("Failed to create a dummy file required by ota example!"))?; + .with_context(|| "Failed to create a dummy file required by ota example!".to_string())?; examples( workspace, @@ -780,7 +780,7 @@ fn host_tests(workspace: &Path, args: HostTestsArgs) -> Result<()> { fn build_rlib(package: &str, chip: &str, target: &str) -> Result { let workspace = std::env::current_dir().with_context(|| "Failed to get the current dir!")?; Command::new("cargo") - .args(&[ + .args([ "+esp", "build", "--no-default-features", @@ -790,7 +790,7 @@ fn build_rlib(package: &str, chip: &str, target: &str) -> Result { target, "-Zbuild-std=core", ]) - .current_dir(workspace.join(package.to_string())) + .current_dir(workspace.join(package)) .status() .context("Failed to run cargo build")?; @@ -818,7 +818,7 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { for chip in chips { let target = package.target_triple(chip)?; - let rlib_path = match build_rlib(&package.to_string(), &chip.to_string(), &target) { + let rlib_path = match build_rlib(package.as_ref(), chip.as_ref(), &target) { Ok(path) => path, Err(e) => { println!( @@ -834,7 +834,7 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { let data = std::fs::read(&rlib_path) .with_context(|| format!("Failed to read {}!", rlib_path.display()))?; let archive = ArchiveFile::parse(data.as_slice()) - .with_context(|| format!("Failed to create archive!"))?; + .with_context(|| "Failed to create archive!".to_string())?; let mut problematic_symbols: Vec<(String, SymbolKind, usize)> = Vec::new(); @@ -846,12 +846,11 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { )?; for symbol in obj.symbols().filter(|s| s.is_global() && s.is_definition()) { - if let Ok(name) = symbol.name() { - if try_demangle(name).is_err() { + if let Ok(name) = symbol.name() + && try_demangle(name).is_err() { let section = symbol.section_index().map(|i| i.0).unwrap_or(0); problematic_symbols.push((name.to_string(), symbol.kind(), section)); } - } } } From 35b3f78a247e944da63b99460f6237e973b8a8a7 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Tue, 21 Apr 2026 01:31:22 +0900 Subject: [PATCH 04/27] Reformat with cargo xtask fmt-packages --- esp-hal/src/clock/mod.rs | 24 +- esp-hal/src/efuse/esp32p4/fields.rs | 77 +++- esp-hal/src/psram/esp32p4.rs | 44 +- esp-hal/src/rtc_cntl/mod.rs | 20 +- esp-hal/src/rtc_cntl/rtc/esp32p4.rs | 17 +- esp-hal/src/soc/esp32p4/clocks.rs | 39 +- esp-hal/src/soc/esp32p4/mod.rs | 1 - esp-hal/src/system.rs | 431 +++++++++++++----- .../src/radio_clocks/clocks_ll/esp32p4.rs | 1 - esp-rom-sys/src/syscall/mod.rs | 3 +- xtask-mcp-macros/src/lib.rs | 22 +- xtask/src/cargo.rs | 23 +- xtask/src/commands/mod.rs | 14 +- xtask/src/documentation.rs | 9 +- xtask/src/lib.rs | 85 ++-- xtask/src/main.rs | 14 +- 16 files changed, 523 insertions(+), 301 deletions(-) diff --git a/esp-hal/src/clock/mod.rs b/esp-hal/src/clock/mod.rs index 73b8d35b8ba..4f40197f148 100644 --- a/esp-hal/src/clock/mod.rs +++ b/esp-hal/src/clock/mod.rs @@ -535,9 +535,13 @@ pub fn cpu_clock() -> Rate { // Ref: esp-idf rtc_clk.c -- default is 400 MHz for eco5 (v3.x) // TRM v0.5 Ch 12 #[cfg(esp32p4)] - { Rate::from_mhz(400) } + { + Rate::from_mhz(400) + } #[cfg(not(esp32p4))] - { Clocks::get().cpu_clock } + { + Clocks::get().cpu_clock + } } /// The XTAL clock frequency. @@ -545,9 +549,13 @@ pub fn xtal_clock() -> Rate { // P4: 40 MHz external crystal (SOC_XTAL_FREQ_40M) // Ref: esp-idf clk_tree_defs.h -- SOC_XTAL_FREQ_40M = 40 #[cfg(esp32p4)] - { Rate::from_mhz(40) } + { + Rate::from_mhz(40) + } #[cfg(not(esp32p4))] - { Clocks::get().xtal_clock } + { + Clocks::get().xtal_clock + } } /// Read the calibrated RTC slow clock period from the STORE1 register. @@ -571,9 +579,13 @@ fn rtc_slow_cal_period() -> u64 { // Ref: esp-idf lp_system_reg.h -- LP_SYSTEM_REG_LP_STORE1_REG = RTC_SLOW_CLK_CAL_REG // esp-idf esp_time_impl.c -- uses store2/store3 for boot time #[cfg(esp32p4)] - { LP_AON::regs().lp_store1().read().bits() as u64 } + { + LP_AON::regs().lp_store1().read().bits() as u64 + } #[cfg(not(esp32p4))] - { LP_AON::regs().store1().read().bits() as u64 } + { + LP_AON::regs().store1().read().bits() as u64 + } } /// Convert RTC slow clock ticks to microseconds using the calibrated period. diff --git a/esp-hal/src/efuse/esp32p4/fields.rs b/esp-hal/src/efuse/esp32p4/fields.rs index f9223d68c89..aea83773f07 100644 --- a/esp-hal/src/efuse/esp32p4/fields.rs +++ b/esp-hal/src/efuse/esp32p4/fields.rs @@ -343,19 +343,25 @@ pub const RD_DIS_TEMPERATURE_SENSOR: EfuseField = EfuseField::new(0, 1, 38, 1); pub const RD_DIS_USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(0, 1, 38, 1); /// `[]` rd_dis of USB_OTG11_EXCHG_PINS pub const RD_DIS_USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this +/// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1: EfuseField = EfuseField::new(0, 1, 39, 2); /// `[]` Set this bit to disable function of usb switch to jtag in module of usb device pub const DIS_USB_JTAG: EfuseField = EfuseField::new(0, 1, 41, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this +/// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2: EfuseField = EfuseField::new(0, 1, 42, 1); /// `[]` Set this bit to disable the function that forces chip into download mode pub const DIS_FORCE_DOWNLOAD: EfuseField = EfuseField::new(0, 1, 44, 1); -/// `[]` Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during boot_mode_download +/// `[]` Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during +/// boot_mode_download pub const SPI_DOWNLOAD_MSPI_DIS: EfuseField = EfuseField::new(0, 1, 45, 1); /// `[]` Set this bit to disable TWAI function pub const DIS_TWAI: EfuseField = EfuseField::new(0, 1, 46, 1); -/// `[]` Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio25 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 +/// `[]` Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping +/// gpio25 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 pub const JTAG_SEL_ENABLE: EfuseField = EfuseField::new(0, 1, 47, 1); /// `[]` Set odd bits to disable JTAG in the soft way. JTAG can be enabled in HMAC module pub const SOFT_DIS_JTAG: EfuseField = EfuseField::new(0, 1, 48, 3); @@ -363,33 +369,53 @@ pub const SOFT_DIS_JTAG: EfuseField = EfuseField::new(0, 1, 48, 3); pub const DIS_PAD_JTAG: EfuseField = EfuseField::new(0, 1, 51, 1); /// `[]` Set this bit to disable flash manual encrypt function (except in SPI boot mode) pub const DIS_DOWNLOAD_MANUAL_ENCRYPT: EfuseField = EfuseField::new(0, 1, 52, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this +/// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6: EfuseField = EfuseField::new(0, 1, 53, 4); -/// `[]` 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) <---> usb_device 1: intphy(24/25) <---> usb_otg11 +/// `[]` 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) +/// <---> usb_device 1: intphy(24/25) <---> usb_otg11 pub const USB_PHY_SEL: EfuseField = EfuseField::new(0, 1, 57, 1); -/// `[]` Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid +/// `[]` Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is +/// valid pub const HUK_GEN_STATE: EfuseField = EfuseField::new(0, 1, 58, 5); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this +/// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7: EfuseField = EfuseField::new(0, 1, 63, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this +/// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10: EfuseField = EfuseField::new(0, 2, 64, 3); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled +/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this +/// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11: EfuseField = EfuseField::new(0, 2, 67, 1); -/// `[]` Set the bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles +/// `[]` Set the bits to control key manager random number switch cycle. 0: control by register. 1: +/// 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles pub const KM_RND_SWITCH_CYCLE: EfuseField = EfuseField::new(0, 2, 68, 1); -/// `[]` EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: {EFUSE_KM_DEPLOY_ONLY_ONCE_H; EFUSE_KM_DEPLOY_ONLY_ONCE`[3:0]`}. Set each bit to control whether corresponding key can only be deployed once. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram +/// `[]` EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: +/// {EFUSE_KM_DEPLOY_ONLY_ONCE_H; EFUSE_KM_DEPLOY_ONLY_ONCE`[3:0]`}. Set each bit to control whether +/// corresponding key can only be deployed once. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; +/// bit2: hmac; bit3: ds; bit4:psram pub const KM_DEPLOY_ONLY_ONCE: EfuseField = EfuseField::new(0, 3, 118, 5); -/// `[]` EFUSE_FORCE_USE_KEY_MANAGER_KEY and EFUSE_FORCE_USE_KEY_MANAGER_KEY_H together form one field: {EFUSE_FORCE_USE_KEY_MANAGER_KEY_H; EFUSE_FORCE_USE_KEY_MANAGER_KEY`[3:0]`}. Set each bit to control whether corresponding key must come from key manager. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram +/// `[]` EFUSE_FORCE_USE_KEY_MANAGER_KEY and EFUSE_FORCE_USE_KEY_MANAGER_KEY_H together form one +/// field: {EFUSE_FORCE_USE_KEY_MANAGER_KEY_H; EFUSE_FORCE_USE_KEY_MANAGER_KEY`[3:0]`}. Set each bit +/// to control whether corresponding key must come from key manager. 1 is true; 0 is false. bit 0: +/// ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram pub const FORCE_USE_KEY_MANAGER_KEY: EfuseField = EfuseField::new(0, 3, 119, 5); /// `[]` Set this bit to disable software written init key; and force use efuse_init_key pub const FORCE_DISABLE_SW_INIT_KEY: EfuseField = EfuseField::new(0, 2, 77, 1); -/// `[]` Set this bit to config flash encryption xts-512 key; else use xts-256 key when using the key manager +/// `[]` Set this bit to config flash encryption xts-512 key; else use xts-256 key when using the +/// key manager pub const KM_XTS_KEY_LENGTH_256: EfuseField = EfuseField::new(0, 2, 78, 1); /// `[]` Set this bit to permanently turn on ECC const-time mode pub const ECC_FORCE_CONST_TIME: EfuseField = EfuseField::new(0, 2, 79, 1); -/// `[]` Select lp wdt timeout threshold at startup = initial timeout value * (2 ^ (EFUSE_WDT_DELAY_SEL + 1)) +/// `[]` Select lp wdt timeout threshold at startup = initial timeout value * (2 ^ +/// (EFUSE_WDT_DELAY_SEL + 1)) pub const WDT_DELAY_SEL: EfuseField = EfuseField::new(0, 2, 81, 1); -/// `[]` Set this bit to enable SPI boot encrypt/decrypt. Odd number of 1: enable. even number of 1: disable {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"} +/// `[]` Set this bit to enable SPI boot encrypt/decrypt. Odd number of 1: enable. even number of 1: +/// disable {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"} pub const SPI_BOOT_CRYPT_CNT: EfuseField = EfuseField::new(0, 2, 82, 3); /// `[]` Revoke 1st secure boot key pub const SECURE_BOOT_KEY_REVOKE0: EfuseField = EfuseField::new(0, 2, 85, 1); @@ -421,7 +447,8 @@ pub const SECURE_BOOT_AGGRESSIVE_REVOKE: EfuseField = EfuseField::new(0, 3, 117, pub const FLASH_ECC_EN: EfuseField = EfuseField::new(0, 3, 122, 1); /// `[]` Set this bit to disable download via USB-OTG pub const DIS_USB_OTG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 3, 123, 1); -/// `[]` Configures flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the configurable value. Otherwise; the waiting time is 30 +/// `[]` Configures flash waiting time after power-up; in unit of ms. When the value less than 15; +/// the waiting time is the configurable value. Otherwise; the waiting time is 30 pub const FLASH_TPUW: EfuseField = EfuseField::new(0, 3, 124, 4); /// `[]` Set this bit to disable download mode (boot_mode`[3:0]` = 0; 1; 2; 4; 5; 6; 7) pub const DIS_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 4, 128, 1); @@ -435,13 +462,16 @@ pub const LOCK_KM_KEY: EfuseField = EfuseField::new(0, 4, 131, 1); pub const DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 4, 132, 1); /// `[]` Set this bit to enable security download mode pub const ENABLE_SECURITY_DOWNLOAD: EfuseField = EfuseField::new(0, 4, 133, 1); -/// `[]` Set the type of UART printing; 00: force enable printing; 01: enable printing when GPIO8 is reset at low level; 10: enable printing when GPIO8 is reset at high level; 11: force disable printing +/// `[]` Set the type of UART printing; 00: force enable printing; 01: enable printing when GPIO8 is +/// reset at low level; 10: enable printing when GPIO8 is reset at high level; 11: force disable +/// printing pub const UART_PRINT_CONTROL: EfuseField = EfuseField::new(0, 4, 134, 2); /// `[]` Set this bit to force ROM code to send a resume command during SPI boot pub const FORCE_SEND_RESUME: EfuseField = EfuseField::new(0, 4, 136, 1); /// `[]` Secure version used by ESP-IDF anti-rollback feature pub const SECURE_VERSION: EfuseField = EfuseField::new(0, 4, 137, 16); -/// `[]` Represents whether secure boot do fast verification on wake is disabled. 0: enabled 1: disabled +/// `[]` Represents whether secure boot do fast verification on wake is disabled. 0: enabled 1: +/// disabled pub const SECURE_BOOT_DISABLE_FAST_WAKE: EfuseField = EfuseField::new(0, 4, 153, 1); /// `[]` Set bits to enable hysteresis function of PAD0~27 pub const HYS_EN_PAD: EfuseField = EfuseField::new(0, 4, 154, 1); @@ -449,9 +479,14 @@ pub const HYS_EN_PAD: EfuseField = EfuseField::new(0, 4, 154, 1); pub const PXA0_TIEH_SEL_0: EfuseField = EfuseField::new(0, 5, 160, 2); /// `[]` Represents whether to enable PVT power glitch monitor function.1:Enable. 0:Disable pub const PVT_GLITCH_EN: EfuseField = EfuseField::new(0, 5, 162, 1); -/// `[]` EFUSE_KM_DISABLE_DEPLOY_MODE and EFUSE_KM_DISABLE_DEPLOY_MODE_H together form one field: {EFUSE_KM_DISABLE_DEPLOY_MODE_H; EFUSE_KM_DISABLE_DEPLOY_MODE`[3:0]`}. Set each bit to control whether corresponding key's deploy mode of new value deployment is disabled. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram +/// `[]` EFUSE_KM_DISABLE_DEPLOY_MODE and EFUSE_KM_DISABLE_DEPLOY_MODE_H together form one field: +/// {EFUSE_KM_DISABLE_DEPLOY_MODE_H; EFUSE_KM_DISABLE_DEPLOY_MODE`[3:0]`}. Set each bit to control +/// whether corresponding key's deploy mode of new value deployment is disabled. 1 is true; 0 is +/// false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram pub const KM_DISABLE_DEPLOY_MODE: EfuseField = EfuseField::new(0, 5, 167, 5); -/// `[]` Sets this bit to control the xts pseudo-round anti-dpa attack function. 0: controlled by register. 1-3: the higher the value is; the more pseudo-rounds are inserted to the xts-aes calculation +/// `[]` Sets this bit to control the xts pseudo-round anti-dpa attack function. 0: controlled by +/// register. 1-3: the higher the value is; the more pseudo-rounds are inserted to the xts-aes +/// calculation pub const XTS_DPA_PSEUDO_LEVEL: EfuseField = EfuseField::new(0, 5, 176, 2); /// `[]` HP system power source select. 0:LDO 1: DCDC pub const HP_PWR_SRC_SEL: EfuseField = EfuseField::new(0, 5, 178, 1); diff --git a/esp-hal/src/psram/esp32p4.rs b/esp-hal/src/psram/esp32p4.rs index 5e256a990de..5e8bcf4cf51 100644 --- a/esp-hal/src/psram/esp32p4.rs +++ b/esp-hal/src/psram/esp32p4.rs @@ -207,10 +207,10 @@ fn psram_detect_size(mspi_base: u32) -> usize { // Decode density field [2:0] match mr2 & 0x7 { - 0x1 => 4 * 1024 * 1024, // 32 Mbit = 4 MB - 0x3 => 8 * 1024 * 1024, // 64 Mbit = 8 MB - 0x5 => 16 * 1024 * 1024, // 128 Mbit = 16 MB - 0x7 => 32 * 1024 * 1024, // 256 Mbit = 32 MB + 0x1 => 4 * 1024 * 1024, // 32 Mbit = 4 MB + 0x3 => 8 * 1024 * 1024, // 64 Mbit = 8 MB + 0x5 => 16 * 1024 * 1024, // 128 Mbit = 16 MB + 0x7 => 32 * 1024 * 1024, // 256 Mbit = 32 MB _ => { // Unknown/invalid response -> fall back to EV Board default 32 * 1024 * 1024 @@ -321,12 +321,8 @@ fn cache_resume() { pub(crate) fn cache_invalidate(addr: u32, size: u32) { let cache = unsafe { &*crate::pac::CACHE::PTR }; - cache - .sync_addr() - .write(|w| unsafe { w.bits(addr) }); - cache - .sync_size() - .write(|w| unsafe { w.bits(size) }); + cache.sync_addr().write(|w| unsafe { w.bits(addr) }); + cache.sync_size().write(|w| unsafe { w.bits(size) }); // Trigger invalidate: sync_ctrl.invalidate_ena cache @@ -334,12 +330,7 @@ pub(crate) fn cache_invalidate(addr: u32, size: u32) { .modify(|_, w| w.invalidate_ena().set_bit()); // Wait for completion - while !cache - .sync_ctrl() - .read() - .sync_done() - .bit_is_set() - { + while !cache.sync_ctrl().read().sync_done().bit_is_set() { core::hint::spin_loop(); } } @@ -353,24 +344,13 @@ pub(crate) fn cache_invalidate(addr: u32, size: u32) { pub(crate) fn cache_writeback(addr: u32, size: u32) { let cache = unsafe { &*crate::pac::CACHE::PTR }; - cache - .sync_addr() - .write(|w| unsafe { w.bits(addr) }); - cache - .sync_size() - .write(|w| unsafe { w.bits(size) }); + cache.sync_addr().write(|w| unsafe { w.bits(addr) }); + cache.sync_size().write(|w| unsafe { w.bits(size) }); // Trigger writeback: sync_ctrl.writeback_ena - cache - .sync_ctrl() - .modify(|_, w| w.writeback_ena().set_bit()); + cache.sync_ctrl().modify(|_, w| w.writeback_ena().set_bit()); - while !cache - .sync_ctrl() - .read() - .sync_done() - .bit_is_set() - { + while !cache.sync_ctrl().read().sync_done().bit_is_set() { core::hint::spin_loop(); } } @@ -453,7 +433,7 @@ fn configure_psram_mspi(base: u32) { let sctrl = (base + CACHE_SCTRL) as *mut u32; let val = sctrl.read_volatile(); let val = val | (1 << 20); // cache_sram_usr_rcmd = 1 - let val = val | (1 << 5); // cache_sram_usr_wcmd = 1 + let val = val | (1 << 5); // cache_sram_usr_wcmd = 1 // sram_addr_bitlen = 31 (32-bit address) let val = (val & !(0x3F << 14)) | (31 << 14); // usr_rd_sram_dummy = 1, sram_rdummy_cyclelen = 13 (14-1 for 200MHz) diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index 75d96eca9b5..0d16ea40c7e 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -716,9 +716,7 @@ impl Rwdt { fn set_write_protection(&mut self, enable: bool) { // Ref: esp-idf lpwdt_ll.h -- LP_WDT_WKEY_VALUE = 0x50D83AA1 let wkey = if enable { 0u32 } else { 0x50D8_3AA1 }; - LP_WDT::regs() - .wprotect() - .write(|w| unsafe { w.bits(wkey) }); + LP_WDT::regs().wprotect().write(|w| unsafe { w.bits(wkey) }); } fn set_enabled(&mut self, enable: bool) { @@ -759,10 +757,18 @@ impl Rwdt { // Ref: esp-idf lp_wdt_struct.h let timeout_raw = timeout_raw >> (1 + crate::efuse::rwdt_multiplier()); match stage { - RwdtStage::Stage0 => rtc_cntl.config1().modify(|_, w| unsafe { w.wdt_stg0_hold().bits(timeout_raw) }), - RwdtStage::Stage1 => rtc_cntl.config2().modify(|_, w| unsafe { w.bits(timeout_raw) }), - RwdtStage::Stage2 => rtc_cntl.config3().modify(|_, w| unsafe { w.bits(timeout_raw) }), - RwdtStage::Stage3 => rtc_cntl.config4().modify(|_, w| unsafe { w.bits(timeout_raw) }), + RwdtStage::Stage0 => rtc_cntl + .config1() + .modify(|_, w| unsafe { w.wdt_stg0_hold().bits(timeout_raw) }), + RwdtStage::Stage1 => rtc_cntl + .config2() + .modify(|_, w| unsafe { w.bits(timeout_raw) }), + RwdtStage::Stage2 => rtc_cntl + .config3() + .modify(|_, w| unsafe { w.bits(timeout_raw) }), + RwdtStage::Stage3 => rtc_cntl + .config4() + .modify(|_, w| unsafe { w.bits(timeout_raw) }), }; self.set_write_protection(true); } diff --git a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs index 0719016a9de..8fc73b3aa6a 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs @@ -194,7 +194,7 @@ pub(crate) fn init() { // Set CPU divider: cpu_clk_div_num = divider - 1 = 0 // Ref: HP_SYS_CLKRST.root_clk_ctrl0.reg_cpu_clk_div_num clkrst.root_clk_ctrl0().modify(|_, w| unsafe { - w.cpu_clk_div_num().bits(0); // CPU: /1 = 400 MHz + w.cpu_clk_div_num().bits(0); // CPU: /1 = 400 MHz w.cpu_clk_div_numerator().bits(0); w.cpu_clk_div_denominator().bits(0) }); @@ -284,12 +284,7 @@ fn cpll_configure(freq_mhz: u32) { .modify(|_, w| w.cpu_pll_cal_stop().clear_bit()); // Wait for calibration to complete - while !clkrst - .ana_pll_ctrl0() - .read() - .cpu_pll_cal_end() - .bit_is_set() - { + while !clkrst.ana_pll_ctrl0().read().cpu_pll_cal_end().bit_is_set() { core::hint::spin_loop(); } @@ -347,12 +342,7 @@ fn spll_configure(freq_mhz: u32) { .ana_pll_ctrl0() .modify(|_, w| w.sys_pll_cal_stop().clear_bit()); - while !clkrst - .ana_pll_ctrl0() - .read() - .sys_pll_cal_end() - .bit_is_set() - { + while !clkrst.ana_pll_ctrl0().read().sys_pll_cal_end().bit_is_set() { core::hint::spin_loop(); } @@ -362,4 +352,3 @@ fn spll_configure(freq_mhz: u32) { crate::rom::ets_delay_us(10); } - diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index a9825cf40fd..d72aa0e0bc5 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -43,32 +43,32 @@ impl CpuClock { // Ref: esp-idf rtc_clk.c:262 -- case 400: cpu=1, mem=2, apb=2 const PRESET_400: ClockConfig = ClockConfig { cpu_root_clk: Some(CpuRootClkConfig::Cpll), - cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 400 MHz - apb_clk: Some(ApbClkConfig::new(3)), // /4 = 100 MHz + cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 400 MHz + apb_clk: Some(ApbClkConfig::new(3)), // /4 = 100 MHz lp_fast_clk: Some(LpFastClkConfig::RcFast), lp_slow_clk: Some(LpSlowClkConfig::RcSlow), }; const PRESET_360: ClockConfig = ClockConfig { cpu_root_clk: Some(CpuRootClkConfig::Cpll), - cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 360 MHz (CPLL at 360) - apb_clk: Some(ApbClkConfig::new(3)), // /4 = 90 MHz + cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 360 MHz (CPLL at 360) + apb_clk: Some(ApbClkConfig::new(3)), // /4 = 90 MHz lp_fast_clk: Some(LpFastClkConfig::RcFast), lp_slow_clk: Some(LpSlowClkConfig::RcSlow), }; const PRESET_200: ClockConfig = ClockConfig { cpu_root_clk: Some(CpuRootClkConfig::Cpll), - cpu_clk: Some(CpuClkConfig::new(1)), // /2 = 200 MHz - apb_clk: Some(ApbClkConfig::new(1)), // /2 = 100 MHz + cpu_clk: Some(CpuClkConfig::new(1)), // /2 = 200 MHz + apb_clk: Some(ApbClkConfig::new(1)), // /2 = 100 MHz lp_fast_clk: Some(LpFastClkConfig::RcFast), lp_slow_clk: Some(LpSlowClkConfig::RcSlow), }; const PRESET_100: ClockConfig = ClockConfig { cpu_root_clk: Some(CpuRootClkConfig::Cpll), - cpu_clk: Some(CpuClkConfig::new(3)), // /4 = 100 MHz - apb_clk: Some(ApbClkConfig::new(0)), // /1 = 100 MHz + cpu_clk: Some(CpuClkConfig::new(3)), // /4 = 100 MHz + apb_clk: Some(ApbClkConfig::new(0)), // /1 = 100 MHz lp_fast_clk: Some(LpFastClkConfig::RcFast), lp_slow_clk: Some(LpSlowClkConfig::RcSlow), }; @@ -132,7 +132,11 @@ fn configure_cpu_root_clk_impl( // CPU_CLK divider fn enable_cpu_clk_impl(_clocks: &mut ClockTree, _en: bool) {} -fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _old_config: Option, new_config: CpuClkConfig) { +fn configure_cpu_clk_impl( + _clocks: &mut ClockTree, + _old_config: Option, + new_config: CpuClkConfig, +) { // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_divider() // HP_SYS_CLKRST.root_clk_ctrl0.cpu_clk_div_num = divider - 1 let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); @@ -142,15 +146,26 @@ fn configure_cpu_clk_impl(_clocks: &mut ClockTree, _old_config: Option, _new_config: ApbClkConfig) { +fn configure_apb_clk_impl( + _clocks: &mut ClockTree, + _old_config: Option, + _new_config: ApbClkConfig, +) { // TODO(P4X): APB divider register in HP_SYS_CLKRST // For now, APB freq is derived from CPU freq via divider } diff --git a/esp-hal/src/soc/esp32p4/mod.rs b/esp-hal/src/soc/esp32p4/mod.rs index 3f1bdaece03..ace7c5b2044 100644 --- a/esp-hal/src/soc/esp32p4/mod.rs +++ b/esp-hal/src/soc/esp32p4/mod.rs @@ -30,7 +30,6 @@ pub(crate) mod constants { pub const SOC_DRAM_HIGH: u32 = 0x4FFC_0000; } - pub(crate) fn pre_init() { // TODO: Check if anything needs to be done here } diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index f17d2810fd3..a7bf27c95b7 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -94,9 +94,9 @@ mod _p4_peripheral_clocks { // AHB_DMA (AHB PDMA): GDMA v2 compatible, used by esp-hal as "Dma" // DW_GDMA (DesignWare GDMA): different register layout, not used by esp-hal // AXI_DMA (AXI PDMA): AXI bus DMA - Dma = 37, // maps to AHB_DMA (GDMA v2 compatible) - Gdma = 38, // DW_GDMA (DesignWare GDMA) -- NOT esp-hal compatible - AhbPdma = 39, // alias for Dma (legacy) + Dma = 37, // maps to AHB_DMA (GDMA v2 compatible) + Gdma = 38, // DW_GDMA (DesignWare GDMA) -- NOT esp-hal compatible + AhbPdma = 39, // alias for Dma (legacy) AxiPdma = 40, // -- ADC -- SOC_CLK_CTRL2 apb + HP_RST_EN2 Adc = 41, @@ -113,23 +113,57 @@ mod _p4_peripheral_clocks { // init silences all subsequent println output and looks like a hang. // TODO: gate this on a console feature; for now we keep it always on // because the EV board and probe firmware both use USB-JTAG-Serial. - pub const KEEP_ENABLED: &[Peripheral] = - &[Peripheral::Systimer, Peripheral::Iomux, Peripheral::UsbDevice]; + pub const KEEP_ENABLED: &[Peripheral] = &[ + Peripheral::Systimer, + Peripheral::Iomux, + Peripheral::UsbDevice, + ]; pub const COUNT: usize = Self::ALL.len(); pub const ALL: &[Self] = &[ - Self::Uart0, Self::Uart1, Self::Uart2, Self::Uart3, Self::Uart4, - Self::Spi2, Self::Spi3, - Self::I2c0, Self::I2c1, - Self::I2s0, Self::I2s1, Self::I2s2, - Self::Systimer, Self::Timg0, Self::Timg1, + Self::Uart0, + Self::Uart1, + Self::Uart2, + Self::Uart3, + Self::Uart4, + Self::Spi2, + Self::Spi3, + Self::I2c0, + Self::I2c1, + Self::I2s0, + Self::I2s1, + Self::I2s2, + Self::Systimer, + Self::Timg0, + Self::Timg1, Self::Iomux, - Self::Ledc, Self::Pcnt, Self::Mcpwm0, Self::Mcpwm1, Self::Rmt, - Self::Twai0, Self::Twai1, Self::Twai2, - Self::UsbOtg11, Self::UsbOtg20, Self::UsbDevice, - Self::Emac, Self::Sdmmc, Self::Uhci, - Self::Aes, Self::Sha, Self::Rsa, Self::Ecc, Self::Ecdsa, Self::Hmac, Self::Ds, - Self::Dma, Self::Gdma, Self::AhbPdma, Self::AxiPdma, - Self::Adc, Self::Parlio, Self::LcdCam, + Self::Ledc, + Self::Pcnt, + Self::Mcpwm0, + Self::Mcpwm1, + Self::Rmt, + Self::Twai0, + Self::Twai1, + Self::Twai2, + Self::UsbOtg11, + Self::UsbOtg20, + Self::UsbDevice, + Self::Emac, + Self::Sdmmc, + Self::Uhci, + Self::Aes, + Self::Sha, + Self::Rsa, + Self::Ecc, + Self::Ecdsa, + Self::Hmac, + Self::Ds, + Self::Dma, + Self::Gdma, + Self::AhbPdma, + Self::AxiPdma, + Self::Adc, + Self::Parlio, + Self::LcdCam, ]; } @@ -142,65 +176,89 @@ mod _p4_peripheral_clocks { match peripheral { // -- UARTs: sys_clk + apb_clk -- Peripheral::Uart0 => { - c.soc_clk_ctrl1().modify(|_, w| w.uart0_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.uart0_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.uart0_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.uart0_apb_clk_en().bit(enable)); } Peripheral::Uart1 => { - c.soc_clk_ctrl1().modify(|_, w| w.uart1_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.uart1_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.uart1_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.uart1_apb_clk_en().bit(enable)); } Peripheral::Uart2 => { - c.soc_clk_ctrl1().modify(|_, w| w.uart2_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.uart2_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.uart2_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.uart2_apb_clk_en().bit(enable)); } Peripheral::Uart3 => { - c.soc_clk_ctrl1().modify(|_, w| w.uart3_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.uart3_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.uart3_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.uart3_apb_clk_en().bit(enable)); } Peripheral::Uart4 => { - c.soc_clk_ctrl1().modify(|_, w| w.uart4_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.uart4_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.uart4_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.uart4_apb_clk_en().bit(enable)); } // -- SPI: sys_clk + apb_clk -- Peripheral::Spi2 => { - c.soc_clk_ctrl1().modify(|_, w| w.gpspi2_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.gpspi2_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.gpspi2_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.gpspi2_apb_clk_en().bit(enable)); } Peripheral::Spi3 => { - c.soc_clk_ctrl1().modify(|_, w| w.gpspi3_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.gpspi3_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.gpspi3_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.gpspi3_apb_clk_en().bit(enable)); } // -- I2C: apb_clk only -- Peripheral::I2c0 => { - c.soc_clk_ctrl2().modify(|_, w| w.i2c0_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.i2c0_apb_clk_en().bit(enable)); } Peripheral::I2c1 => { - c.soc_clk_ctrl2().modify(|_, w| w.i2c1_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.i2c1_apb_clk_en().bit(enable)); } // -- I2S: apb_clk -- Peripheral::I2s0 => { - c.soc_clk_ctrl2().modify(|_, w| w.i2s0_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.i2s0_apb_clk_en().bit(enable)); } Peripheral::I2s1 => { - c.soc_clk_ctrl2().modify(|_, w| w.i2s1_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.i2s1_apb_clk_en().bit(enable)); } Peripheral::I2s2 => { - c.soc_clk_ctrl2().modify(|_, w| w.i2s2_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.i2s2_apb_clk_en().bit(enable)); } // -- Timers -- Peripheral::Systimer => { - c.soc_clk_ctrl2().modify(|_, w| w.systimer_apb_clk_en().bit(enable)); - c.peri_clk_ctrl21().modify(|_, w| w.systimer_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.systimer_apb_clk_en().bit(enable)); + c.peri_clk_ctrl21() + .modify(|_, w| w.systimer_clk_en().bit(enable)); } Peripheral::Timg0 => { - c.soc_clk_ctrl2().modify(|_, w| w.timergrp0_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.timergrp0_apb_clk_en().bit(enable)); } Peripheral::Timg1 => { - c.soc_clk_ctrl2().modify(|_, w| w.timergrp1_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.timergrp1_apb_clk_en().bit(enable)); } // -- GPIO/IOMUX -- Peripheral::Iomux => { - c.peri_clk_ctrl26().modify(|_, w| w.iomux_clk_en().bit(enable)); + c.peri_clk_ctrl26() + .modify(|_, w| w.iomux_clk_en().bit(enable)); } // -- PWM/Counter -- Peripheral::Ledc => { @@ -209,76 +267,103 @@ mod _p4_peripheral_clocks { // For now just reset control } Peripheral::Pcnt => { - c.soc_clk_ctrl2().modify(|_, w| w.pcnt_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.pcnt_apb_clk_en().bit(enable)); } Peripheral::Mcpwm0 => { - c.soc_clk_ctrl2().modify(|_, w| w.mcpwm0_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.mcpwm0_apb_clk_en().bit(enable)); } Peripheral::Mcpwm1 => { - c.soc_clk_ctrl2().modify(|_, w| w.mcpwm1_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.mcpwm1_apb_clk_en().bit(enable)); } Peripheral::Rmt => { - c.soc_clk_ctrl2().modify(|_, w| w.rmt_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.rmt_sys_clk_en().bit(enable)); } // -- TWAI (CAN) -- Peripheral::Twai0 => { - c.soc_clk_ctrl2().modify(|_, w| w.twai0_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.twai0_apb_clk_en().bit(enable)); } Peripheral::Twai1 => { - c.soc_clk_ctrl2().modify(|_, w| w.twai1_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.twai1_apb_clk_en().bit(enable)); } Peripheral::Twai2 => { - c.soc_clk_ctrl2().modify(|_, w| w.twai2_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.twai2_apb_clk_en().bit(enable)); } // -- USB -- Peripheral::UsbOtg11 => { - c.soc_clk_ctrl1().modify(|_, w| w.usb_otg11_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.usb_otg11_sys_clk_en().bit(enable)); } Peripheral::UsbOtg20 => { - c.soc_clk_ctrl1().modify(|_, w| w.usb_otg20_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.usb_otg20_sys_clk_en().bit(enable)); } Peripheral::UsbDevice => { - c.soc_clk_ctrl2().modify(|_, w| w.usb_device_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.usb_device_apb_clk_en().bit(enable)); } // -- Connectivity -- Peripheral::Emac => { - c.soc_clk_ctrl1().modify(|_, w| w.emac_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.emac_sys_clk_en().bit(enable)); } Peripheral::Sdmmc => { - c.soc_clk_ctrl1().modify(|_, w| w.sdmmc_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.sdmmc_sys_clk_en().bit(enable)); } Peripheral::Uhci => { - c.soc_clk_ctrl1().modify(|_, w| w.uhci_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.uhci_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.uhci_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.uhci_apb_clk_en().bit(enable)); } // -- Crypto (shared sys clock) -- - Peripheral::Aes | Peripheral::Sha | Peripheral::Rsa | - Peripheral::Ecc | Peripheral::Ecdsa | Peripheral::Hmac | Peripheral::Ds => { - c.soc_clk_ctrl1().modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + Peripheral::Aes + | Peripheral::Sha + | Peripheral::Rsa + | Peripheral::Ecc + | Peripheral::Ecdsa + | Peripheral::Hmac + | Peripheral::Ds => { + c.soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); } // -- DMA -- // Dma = AHB_DMA (GDMA v2 compatible, used by esp-hal) Peripheral::Dma => { - c.soc_clk_ctrl1().modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); } // Gdma = DW_GDMA (DesignWare, NOT used by esp-hal DMA driver) Peripheral::Gdma => { - c.soc_clk_ctrl1().modify(|_, w| w.gdma_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.gdma_sys_clk_en().bit(enable)); } Peripheral::AhbPdma => { - c.soc_clk_ctrl1().modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); } Peripheral::AxiPdma => { - c.soc_clk_ctrl1().modify(|_, w| w.axi_pdma_sys_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.axi_pdma_sys_clk_en().bit(enable)); } // -- ADC -- Peripheral::Adc => { - c.soc_clk_ctrl2().modify(|_, w| w.adc_apb_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.adc_apb_clk_en().bit(enable)); } // -- Parallel IO -- Peripheral::Parlio => { - c.soc_clk_ctrl1().modify(|_, w| w.parlio_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2().modify(|_, w| w.parlio_apb_clk_en().bit(enable)); + c.soc_clk_ctrl1() + .modify(|_, w| w.parlio_sys_clk_en().bit(enable)); + c.soc_clk_ctrl2() + .modify(|_, w| w.parlio_apb_clk_en().bit(enable)); } // -- LCD/Camera -- Peripheral::LcdCam => { @@ -296,76 +381,180 @@ mod _p4_peripheral_clocks { let c = HP_SYS_CLKRST::regs(); match peripheral { // -- UARTs: HP_RST_EN1 (core + apb reset) -- - Peripheral::Uart0 => { c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart0_core().bit(reset).rst_en_uart0_apb().bit(reset) - }); } - Peripheral::Uart1 => { c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart1_core().bit(reset).rst_en_uart1_apb().bit(reset) - }); } - Peripheral::Uart2 => { c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart2_core().bit(reset).rst_en_uart2_apb().bit(reset) - }); } - Peripheral::Uart3 => { c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart3_core().bit(reset).rst_en_uart3_apb().bit(reset) - }); } - Peripheral::Uart4 => { c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart4_core().bit(reset).rst_en_uart4_apb().bit(reset) - }); } + Peripheral::Uart0 => { + c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart0_core() + .bit(reset) + .rst_en_uart0_apb() + .bit(reset) + }); + } + Peripheral::Uart1 => { + c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart1_core() + .bit(reset) + .rst_en_uart1_apb() + .bit(reset) + }); + } + Peripheral::Uart2 => { + c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart2_core() + .bit(reset) + .rst_en_uart2_apb() + .bit(reset) + }); + } + Peripheral::Uart3 => { + c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart3_core() + .bit(reset) + .rst_en_uart3_apb() + .bit(reset) + }); + } + Peripheral::Uart4 => { + c.hp_rst_en1().modify(|_, w| { + w.rst_en_uart4_core() + .bit(reset) + .rst_en_uart4_apb() + .bit(reset) + }); + } // -- SPI: HP_RST_EN2 -- - Peripheral::Spi2 => { c.hp_rst_en2().modify(|_, w| w.rst_en_spi2().bit(reset)); } - Peripheral::Spi3 => { c.hp_rst_en2().modify(|_, w| w.rst_en_spi3().bit(reset)); } + Peripheral::Spi2 => { + c.hp_rst_en2().modify(|_, w| w.rst_en_spi2().bit(reset)); + } + Peripheral::Spi3 => { + c.hp_rst_en2().modify(|_, w| w.rst_en_spi3().bit(reset)); + } // -- I2C: HP_RST_EN1 -- - Peripheral::I2c0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_i2c0().bit(reset)); } - Peripheral::I2c1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_i2c1().bit(reset)); } + Peripheral::I2c0 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_i2c0().bit(reset)); + } + Peripheral::I2c1 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_i2c1().bit(reset)); + } // -- I2S: HP_RST_EN2 -- - Peripheral::I2s0 => { c.hp_rst_en2().modify(|_, w| w.rst_en_i2s0_apb().bit(reset)); } - Peripheral::I2s1 => { c.hp_rst_en2().modify(|_, w| w.rst_en_i2s1_apb().bit(reset)); } - Peripheral::I2s2 => { c.hp_rst_en2().modify(|_, w| w.rst_en_i2s2_apb().bit(reset)); } + Peripheral::I2s0 => { + c.hp_rst_en2().modify(|_, w| w.rst_en_i2s0_apb().bit(reset)); + } + Peripheral::I2s1 => { + c.hp_rst_en2().modify(|_, w| w.rst_en_i2s1_apb().bit(reset)); + } + Peripheral::I2s2 => { + c.hp_rst_en2().modify(|_, w| w.rst_en_i2s2_apb().bit(reset)); + } // -- Timers: HP_RST_EN1 -- - Peripheral::Systimer => { c.hp_rst_en1().modify(|_, w| w.rst_en_stimer().bit(reset)); } - Peripheral::Timg0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_timergrp0().bit(reset)); } - Peripheral::Timg1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_timergrp1().bit(reset)); } + Peripheral::Systimer => { + c.hp_rst_en1().modify(|_, w| w.rst_en_stimer().bit(reset)); + } + Peripheral::Timg0 => { + c.hp_rst_en1() + .modify(|_, w| w.rst_en_timergrp0().bit(reset)); + } + Peripheral::Timg1 => { + c.hp_rst_en1() + .modify(|_, w| w.rst_en_timergrp1().bit(reset)); + } // -- IOMUX: HP_RST_EN1 -- - Peripheral::Iomux => { c.hp_rst_en1().modify(|_, w| w.rst_en_iomux().bit(reset)); } + Peripheral::Iomux => { + c.hp_rst_en1().modify(|_, w| w.rst_en_iomux().bit(reset)); + } // -- PWM/Counter: HP_RST_EN1 -- - Peripheral::Ledc => { c.hp_rst_en1().modify(|_, w| w.rst_en_ledc().bit(reset)); } - Peripheral::Pcnt => { c.hp_rst_en1().modify(|_, w| w.rst_en_pcnt().bit(reset)); } - Peripheral::Mcpwm0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_pwm0().bit(reset)); } - Peripheral::Mcpwm1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_pwm1().bit(reset)); } - Peripheral::Rmt => { c.hp_rst_en1().modify(|_, w| w.rst_en_rmt().bit(reset)); } + Peripheral::Ledc => { + c.hp_rst_en1().modify(|_, w| w.rst_en_ledc().bit(reset)); + } + Peripheral::Pcnt => { + c.hp_rst_en1().modify(|_, w| w.rst_en_pcnt().bit(reset)); + } + Peripheral::Mcpwm0 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_pwm0().bit(reset)); + } + Peripheral::Mcpwm1 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_pwm1().bit(reset)); + } + Peripheral::Rmt => { + c.hp_rst_en1().modify(|_, w| w.rst_en_rmt().bit(reset)); + } // -- TWAI: HP_RST_EN1 (named can0/1/2) -- - Peripheral::Twai0 => { c.hp_rst_en1().modify(|_, w| w.rst_en_can0().bit(reset)); } - Peripheral::Twai1 => { c.hp_rst_en1().modify(|_, w| w.rst_en_can1().bit(reset)); } - Peripheral::Twai2 => { c.hp_rst_en1().modify(|_, w| w.rst_en_can2().bit(reset)); } + Peripheral::Twai0 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_can0().bit(reset)); + } + Peripheral::Twai1 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_can1().bit(reset)); + } + Peripheral::Twai2 => { + c.hp_rst_en1().modify(|_, w| w.rst_en_can2().bit(reset)); + } // -- USB: reset via LP domain registers, not HP_RST_EN -- - Peripheral::UsbOtg11 | Peripheral::UsbOtg20 | Peripheral::UsbDevice => { return; } + Peripheral::UsbOtg11 | Peripheral::UsbOtg20 | Peripheral::UsbDevice => { + return; + } // -- Connectivity -- - Peripheral::Emac => { return; } // EMAC reset via dedicated register, not HP_RST_EN - Peripheral::Sdmmc => { return; } // SDMMC reset not in HP_RST_EN - Peripheral::Uhci => { c.hp_rst_en1().modify(|_, w| w.rst_en_uhci().bit(reset)); } + Peripheral::Emac => { + return; + } // EMAC reset via dedicated register, not HP_RST_EN + Peripheral::Sdmmc => { + return; + } // SDMMC reset not in HP_RST_EN + Peripheral::Uhci => { + c.hp_rst_en1().modify(|_, w| w.rst_en_uhci().bit(reset)); + } // -- Crypto: HP_RST_EN2 -- - Peripheral::Aes => { c.hp_rst_en2().modify(|_, w| w.rst_en_aes().bit(reset)); } - Peripheral::Sha => { c.hp_rst_en2().modify(|_, w| w.rst_en_sha().bit(reset)); } - Peripheral::Rsa => { c.hp_rst_en2().modify(|_, w| w.rst_en_rsa().bit(reset)); } - Peripheral::Ecc => { c.hp_rst_en2().modify(|_, w| w.rst_en_ecc().bit(reset)); } - Peripheral::Ecdsa => { c.hp_rst_en2().modify(|_, w| w.rst_en_ecdsa().bit(reset)); } - Peripheral::Hmac => { c.hp_rst_en2().modify(|_, w| w.rst_en_hmac().bit(reset)); } - Peripheral::Ds => { c.hp_rst_en2().modify(|_, w| w.rst_en_ds().bit(reset)); } + Peripheral::Aes => { + c.hp_rst_en2().modify(|_, w| w.rst_en_aes().bit(reset)); + } + Peripheral::Sha => { + c.hp_rst_en2().modify(|_, w| w.rst_en_sha().bit(reset)); + } + Peripheral::Rsa => { + c.hp_rst_en2().modify(|_, w| w.rst_en_rsa().bit(reset)); + } + Peripheral::Ecc => { + c.hp_rst_en2().modify(|_, w| w.rst_en_ecc().bit(reset)); + } + Peripheral::Ecdsa => { + c.hp_rst_en2().modify(|_, w| w.rst_en_ecdsa().bit(reset)); + } + Peripheral::Hmac => { + c.hp_rst_en2().modify(|_, w| w.rst_en_hmac().bit(reset)); + } + Peripheral::Ds => { + c.hp_rst_en2().modify(|_, w| w.rst_en_ds().bit(reset)); + } // -- DMA: HP_RST_EN0/1 -- - Peripheral::Dma => { c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); } - Peripheral::Gdma => { c.hp_rst_en0().modify(|_, w| w.rst_en_gdma().bit(reset)); } - Peripheral::AhbPdma => { c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); } - Peripheral::AxiPdma => { c.hp_rst_en1().modify(|_, w| w.rst_en_axi_pdma().bit(reset)); } + Peripheral::Dma => { + c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); + } + Peripheral::Gdma => { + c.hp_rst_en0().modify(|_, w| w.rst_en_gdma().bit(reset)); + } + Peripheral::AhbPdma => { + c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); + } + Peripheral::AxiPdma => { + c.hp_rst_en1().modify(|_, w| w.rst_en_axi_pdma().bit(reset)); + } // -- ADC: HP_RST_EN2 -- - Peripheral::Adc => { c.hp_rst_en2().modify(|_, w| w.rst_en_adc().bit(reset)); } + Peripheral::Adc => { + c.hp_rst_en2().modify(|_, w| w.rst_en_adc().bit(reset)); + } // -- Parallel IO: HP_RST_EN2 -- - Peripheral::Parlio => { c.hp_rst_en2().modify(|_, w| { - w.rst_en_parlio().bit(reset) - .rst_en_parlio_rx().bit(reset) - .rst_en_parlio_tx().bit(reset) - }); } + Peripheral::Parlio => { + c.hp_rst_en2().modify(|_, w| { + w.rst_en_parlio() + .bit(reset) + .rst_en_parlio_rx() + .bit(reset) + .rst_en_parlio_tx() + .bit(reset) + }); + } // -- LCD/Camera: HP_RST_EN2 -- - Peripheral::LcdCam => { c.hp_rst_en2().modify(|_, w| w.rst_en_lcdcam().bit(reset)); } + Peripheral::LcdCam => { + c.hp_rst_en2().modify(|_, w| w.rst_en_lcdcam().bit(reset)); + } } } } diff --git a/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs b/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs index 4e36fd95f84..5266d23346d 100644 --- a/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs +++ b/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs @@ -40,7 +40,6 @@ pub(super) fn init_clocks() { PMU::regs() .imm_sleep_sysclk() .write(|w| w.update_dig_icg_switch().set_bit()); - } } diff --git a/esp-rom-sys/src/syscall/mod.rs b/esp-rom-sys/src/syscall/mod.rs index db098e81dd6..93de758f8f7 100644 --- a/esp-rom-sys/src/syscall/mod.rs +++ b/esp-rom-sys/src/syscall/mod.rs @@ -5,8 +5,7 @@ use core::ffi::{c_char, c_int, c_long, c_void}; // future chips or ECOs _might_ be different - at least ESP-IDF defines the struct per chip #[cfg_attr( any( - esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, - esp32p4 + esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32p4 ), path = "v1.rs" )] diff --git a/xtask-mcp-macros/src/lib.rs b/xtask-mcp-macros/src/lib.rs index 3feeae28980..7ccd119d3b0 100644 --- a/xtask-mcp-macros/src/lib.rs +++ b/xtask-mcp-macros/src/lib.rs @@ -29,22 +29,23 @@ struct ArgInfo { value_delimiter: Option, } - /// Parse a string literal from an expression. fn expr_lit_str(expr: &Expr) -> Option { if let Expr::Lit(el) = expr - && let Lit::Str(s) = &el.lit { - return Some(s.value()); - } + && let Lit::Str(s) = &el.lit + { + return Some(s.value()); + } None } /// Parse a char literal from an expression. fn expr_lit_char(expr: &Expr) -> Option { if let Expr::Lit(el) = expr - && let Lit::Char(c) = &el.lit { - return Some(c.value()); - } + && let Lit::Char(c) = &el.lit + { + return Some(c.value()); + } None } @@ -58,9 +59,10 @@ fn extract_doc(attrs: &[Attribute]) -> String { } if let Meta::NameValue(nv) = &attr.meta && let Expr::Lit(el) = &nv.value - && let Lit::Str(s) = &el.lit { - return Some(s.value().trim().to_string()); - } + && let Lit::Str(s) = &el.lit + { + return Some(s.value().trim().to_string()); + } None }) .filter(|s| !s.is_empty()) diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs index 6154ed03a94..ff5eab16318 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/cargo.rs @@ -550,8 +550,7 @@ pub struct CargoToml { pub manifest: toml_edit::DocumentMut, } -const DEPENDENCY_KINDS: [&str; 3] = - ["dependencies", "dev-dependencies", "build-dependencies"]; +const DEPENDENCY_KINDS: [&str; 3] = ["dependencies", "dev-dependencies", "build-dependencies"]; impl CargoToml { /// Load and parse the Cargo.toml for the specified package in the given workspace. @@ -720,9 +719,10 @@ impl CargoToml { }; if let Ok(package) = Package::from_str(name, true) - && !dependencies.contains(&package) { - dependencies.push(package); - } + && !dependencies.contains(&package) + { + dependencies.push(package); + } } }); dependencies @@ -761,12 +761,13 @@ impl CargoToml { let update_renamed_dep = table.get_values().iter().find_map(|(k, p)| { if let Value::InlineTable(table) = p && let Some(Value::String(name)) = &table.get("package") - && name.value() == package_name { - // Return the actual key of this dependency, e.g.: - // `procmacros = { package = "esp-hal-procmacros" }` - // ^^^^^^^^^^ - return Some(k.last().unwrap().get().to_string()); - } + && name.value() == package_name + { + // Return the actual key of this dependency, e.g.: + // `procmacros = { package = "esp-hal-procmacros" }` + // ^^^^^^^^^^ + return Some(k.last().unwrap().get().to_string()); + } None }); diff --git a/xtask/src/commands/mod.rs b/xtask/src/commands/mod.rs index 4b7bf921755..ace436e0016 100644 --- a/xtask/src/commands/mod.rs +++ b/xtask/src/commands/mod.rs @@ -396,12 +396,9 @@ pub fn examples(workspace: &Path, mut args: ExamplesArgs, action: CargoAction) - // Execute the specified action: match action { - CargoAction::Build(out_path) => build_examples( - args, - filtered, - &package_path, - out_path.as_deref(), - ), + CargoAction::Build(out_path) => { + build_examples(args, filtered, &package_path, out_path.as_deref()) + } CargoAction::Run => run_examples(args, filtered, &package_path), } } @@ -456,10 +453,7 @@ pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<( .flatten() .unwrap_or(&[]); - let matched: Vec<_> = all_tests - .iter() - .filter(|t| t.matches(test_arg)) - .collect(); + let matched: Vec<_> = all_tests.iter().filter(|t| t.matches(test_arg)).collect(); if matched.is_empty() { unknown_selected.push(selected.to_string()); diff --git a/xtask/src/documentation.rs b/xtask/src/documentation.rs index 0e3e1c3696e..742d626a4c5 100644 --- a/xtask/src/documentation.rs +++ b/xtask/src/documentation.rs @@ -107,10 +107,11 @@ fn build_documentation_for_package( // Ensure that the package/chip combination provided are valid: if let Some(chip) = chip - && let Err(err) = package.validate_package_chip(&chip) { - log::warn!("{err}"); - return Ok(()); - } + && let Err(err) = package.validate_package_chip(&chip) + { + log::warn!("{err}"); + return Ok(()); + } // Build the documentation for the specified package, targeting the // specified chip: diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index a8fb71e0b4f..f0747eb8b85 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -112,14 +112,15 @@ impl Package { // This is intended to opt-out in case there are features that look like chip names, but // aren't supposed to be handled like them. if let Some(metadata) = toml.espressif_metadata() - && let Some(Item::Value(ov)) = metadata.get("has_chip_features") { - let Value::Boolean(ov) = ov else { - log::warn!("Invalid value for 'has_chip_features' in metadata"); - return false; - }; + && let Some(Item::Value(ov)) = metadata.get("has_chip_features") + { + let Value::Boolean(ov) = ov else { + log::warn!("Invalid value for 'has_chip_features' in metadata"); + return false; + }; - return *ov.value(); - } + return *ov.value(); + } features .iter() @@ -176,9 +177,11 @@ impl Package { // Look for files matching the pattern "MIGRATING-*.md" for entry in entries.flatten() { if let Some(file_name) = entry.file_name().to_str() - && file_name.starts_with("MIGRATING-") && file_name.ends_with(".md") { - return true; - } + && file_name.starts_with("MIGRATING-") + && file_name.ends_with(".md") + { + return true; + } } false @@ -796,27 +799,23 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { let cmd = CargoArgsBuilder::default(); match package { - Package::EspConfig => { - cargo::run( - &cmd.clone() - .subcommand("test") - .features(&["build".into(), "tui".into()]) - .build(), - &package_path, - ) - } - - Package::EspBootloaderEspIdf => { - cargo::run( - &cmd.clone() - .subcommand("test") - .arg("--lib") - .arg("--tests") - .features(&["std".into()]) - .build(), - &package_path, - ) - } + Package::EspConfig => cargo::run( + &cmd.clone() + .subcommand("test") + .features(&["build".into(), "tui".into()]) + .build(), + &package_path, + ), + + Package::EspBootloaderEspIdf => cargo::run( + &cmd.clone() + .subcommand("test") + .arg("--lib") + .arg("--tests") + .features(&["std".into()]) + .build(), + &package_path, + ), Package::EspStorage => { cargo::run( @@ -865,18 +864,18 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { &package_path, ) } - Package::EspHalProcmacros => { - cargo::run( - &cmd.clone() - .subcommand("test") - .features(&["has-lp-core".into(), - "is-lp-core".into(), - "rtc-slow".into(), - "rtc-fast".into()]) - .build(), - &package_path, - ) - } + Package::EspHalProcmacros => cargo::run( + &cmd.clone() + .subcommand("test") + .features(&[ + "has-lp-core".into(), + "is-lp-core".into(), + "rtc-slow".into(), + "rtc-fast".into(), + ]) + .build(), + &package_path, + ), _ => Err(anyhow!( "Instructions for host testing were not provided for: '{}'", package, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 74eb8ad8350..7ef555b4e48 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -710,8 +710,9 @@ fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> { // doesn't care about the contents however std::fs::create_dir_all("./examples/target") .with_context(|| "Failed to create `./examples/target`".to_string())?; - std::fs::write("./examples/target/ota_image", "DUMMY") - .with_context(|| "Failed to create a dummy file required by ota example!".to_string())?; + std::fs::write("./examples/target/ota_image", "DUMMY").with_context(|| { + "Failed to create a dummy file required by ota example!".to_string() + })?; examples( workspace, @@ -847,10 +848,11 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { for symbol in obj.symbols().filter(|s| s.is_global() && s.is_definition()) { if let Ok(name) = symbol.name() - && try_demangle(name).is_err() { - let section = symbol.section_index().map(|i| i.0).unwrap_or(0); - problematic_symbols.push((name.to_string(), symbol.kind(), section)); - } + && try_demangle(name).is_err() + { + let section = symbol.section_index().map(|i| i.0).unwrap_or(0); + problematic_symbols.push((name.to_string(), symbol.kind(), section)); + } } } From b9d606d3dd9197a674895e29239bd9ce841323d6 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Wed, 22 Apr 2026 02:05:18 +0900 Subject: [PATCH 05/27] Revert modification tooling of esp-hal by clippy --- xtask-mcp-macros/src/lib.rs | 40 +++++--- xtask/src/cargo.rs | 38 ++++---- xtask/src/commands/build.rs | 2 +- xtask/src/commands/mod.rs | 16 +++- xtask/src/commands/release/bump_version.rs | 4 +- xtask/src/commands/run.rs | 2 +- xtask/src/documentation.rs | 16 ++-- xtask/src/firmware.rs | 2 +- xtask/src/lib.rs | 105 +++++++++++---------- xtask/src/main.rs | 33 ++++--- 10 files changed, 139 insertions(+), 119 deletions(-) diff --git a/xtask-mcp-macros/src/lib.rs b/xtask-mcp-macros/src/lib.rs index 7ccd119d3b0..dbafaba29ef 100644 --- a/xtask-mcp-macros/src/lib.rs +++ b/xtask-mcp-macros/src/lib.rs @@ -19,7 +19,6 @@ use syn::{ // Attribute parsing helpers /// Parsed information from a `#[arg(...)]` attribute. -#[derive(Default)] struct ArgInfo { /// True if `long` (or `long = "name"`) was present. has_long: bool, @@ -29,22 +28,32 @@ struct ArgInfo { value_delimiter: Option, } +impl Default for ArgInfo { + fn default() -> Self { + Self { + has_long: false, + long_name: String::new(), + value_delimiter: None, + } + } +} + /// Parse a string literal from an expression. fn expr_lit_str(expr: &Expr) -> Option { - if let Expr::Lit(el) = expr - && let Lit::Str(s) = &el.lit - { - return Some(s.value()); + if let Expr::Lit(el) = expr { + if let Lit::Str(s) = &el.lit { + return Some(s.value()); + } } None } /// Parse a char literal from an expression. fn expr_lit_char(expr: &Expr) -> Option { - if let Expr::Lit(el) = expr - && let Lit::Char(c) = &el.lit - { - return Some(c.value()); + if let Expr::Lit(el) = expr { + if let Lit::Char(c) = &el.lit { + return Some(c.value()); + } } None } @@ -57,11 +66,12 @@ fn extract_doc(attrs: &[Attribute]) -> String { if !attr.path().is_ident("doc") { return None; } - if let Meta::NameValue(nv) = &attr.meta - && let Expr::Lit(el) = &nv.value - && let Lit::Str(s) = &el.lit - { - return Some(s.value().trim().to_string()); + if let Meta::NameValue(nv) = &attr.meta { + if let Expr::Lit(el) = &nv.value { + if let Lit::Str(s) = &el.lit { + return Some(s.value().trim().to_string()); + } + } } None }) @@ -423,7 +433,7 @@ fn expand_mcp_tool(attrs: McpToolAttrs, item: &ItemStruct) -> syn::Result = attrs diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs index ff5eab16318..094a9e245ae 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/cargo.rs @@ -365,12 +365,6 @@ impl BuiltCommand { } } -impl Default for CargoCommandBatcher { - fn default() -> Self { - Self::new() - } -} - impl CargoCommandBatcher { pub fn new() -> Self { Self { @@ -550,7 +544,8 @@ pub struct CargoToml { pub manifest: toml_edit::DocumentMut, } -const DEPENDENCY_KINDS: [&str; 3] = ["dependencies", "dev-dependencies", "build-dependencies"]; +const DEPENDENCY_KINDS: [&'static str; 3] = + ["dependencies", "dev-dependencies", "build-dependencies"]; impl CargoToml { /// Load and parse the Cargo.toml for the specified package in the given workspace. @@ -580,7 +575,7 @@ impl CargoToml { let Some(espressif) = metadata.get("espressif") else { return None; }; - espressif.as_table() + Some(espressif.as_table()?) } /// Create a `CargoToml` instance from a manifest string. @@ -718,10 +713,10 @@ impl CargoToml { name }; - if let Ok(package) = Package::from_str(name, true) - && !dependencies.contains(&package) - { - dependencies.push(package); + if let Ok(package) = Package::from_str(name, true) { + if !dependencies.contains(&package) { + dependencies.push(package); + } } } }); @@ -737,7 +732,7 @@ impl CargoToml { self.visit_dependencies(|_, _, table| { // Update dependencies which specify a version: - match &mut table[package_name] { + match &mut table[&package_name] { Item::Value(Value::String(table)) => { // package = "version" *table = Formatted::new(format_dependency_version(table.value(), version)); @@ -759,14 +754,15 @@ impl CargoToml { Item::None => { // alias = { package = "foo", version = "version" } let update_renamed_dep = table.get_values().iter().find_map(|(k, p)| { - if let Value::InlineTable(table) = p - && let Some(Value::String(name)) = &table.get("package") - && name.value() == package_name - { - // Return the actual key of this dependency, e.g.: - // `procmacros = { package = "esp-hal-procmacros" }` - // ^^^^^^^^^^ - return Some(k.last().unwrap().get().to_string()); + if let Value::InlineTable(table) = p { + if let Some(Value::String(name)) = &table.get("package") { + if name.value() == &package_name { + // Return the actual key of this dependency, e.g.: + // `procmacros = { package = "esp-hal-procmacros" }` + // ^^^^^^^^^^ + return Some(k.last().unwrap().get().to_string()); + } + } } None diff --git a/xtask/src/commands/build.rs b/xtask/src/commands/build.rs index 98144296d3a..25ce0f7d611 100644 --- a/xtask/src/commands/build.rs +++ b/xtask/src/commands/build.rs @@ -164,7 +164,7 @@ pub fn build_examples( // Build command list for example in examples.iter() { let command = crate::generate_build_command( - package_path, + &package_path, chip, &target, example, diff --git a/xtask/src/commands/mod.rs b/xtask/src/commands/mod.rs index ace436e0016..b593be6794d 100644 --- a/xtask/src/commands/mod.rs +++ b/xtask/src/commands/mod.rs @@ -396,9 +396,12 @@ pub fn examples(workspace: &Path, mut args: ExamplesArgs, action: CargoAction) - // Execute the specified action: match action { - CargoAction::Build(out_path) => { - build_examples(args, filtered, &package_path, out_path.as_deref()) - } + CargoAction::Build(out_path) => build_examples( + args, + filtered, + &package_path, + out_path.as_ref().map(|p| p.as_path()), + ), CargoAction::Run => run_examples(args, filtered, &package_path), } } @@ -449,11 +452,14 @@ pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<( }; let run_test_extra_args = (action == CargoAction::Run) - .then(|| filter.as_ref().map(std::slice::from_ref)) + .then(|| filter.as_ref().map(|f| std::slice::from_ref(f))) .flatten() .unwrap_or(&[]); - let matched: Vec<_> = all_tests.iter().filter(|t| t.matches(test_arg)).collect(); + let matched: Vec<_> = all_tests + .iter() + .filter(|t| t.matches(test_arg.as_deref())) + .collect(); if matched.is_empty() { unknown_selected.push(selected.to_string()); diff --git a/xtask/src/commands/release/bump_version.rs b/xtask/src/commands/release/bump_version.rs index 3bfcd227c1d..36fe45a4a51 100644 --- a/xtask/src/commands/release/bump_version.rs +++ b/xtask/src/commands/release/bump_version.rs @@ -161,7 +161,7 @@ fn check_crate_before_bumping(manifest: &mut CargoToml) -> Result<()> { let mut error_message = String::new(); for (dep_kind, errors) in errors { if !error_message.is_empty() { - error_message.push('\n'); + error_message.push_str("\n"); } writeln!(&mut error_message, "In [{dep_kind}]:").unwrap(); for (krate, error) in errors { @@ -261,7 +261,7 @@ fn bump_crate_version( let content = fs::read_to_string(&p) .with_context(|| format!("Could not read {}", p.display()))?; CargoToml::from_str(&bumped_package.workspace, Package::Examples, &content) - .with_context(|| "Could not parse Cargo.toml".to_string()) + .with_context(|| format!("Could not parse Cargo.toml")) })); for dependent in tomls { diff --git a/xtask/src/commands/run.rs b/xtask/src/commands/run.rs index 8f64f4c6ce1..df681118bc7 100644 --- a/xtask/src/commands/run.rs +++ b/xtask/src/commands/run.rs @@ -88,7 +88,7 @@ pub fn run_doc_tests_for_package(workspace: &Path, package: Package, chip: Chip) } // Packages that have doc features are documented. We run doc-tests for these, and only these. - let Some(mut features) = package.doc_feature_rules(esp_metadata::Config::for_chip(&chip)) + let Some(mut features) = package.doc_feature_rules(&esp_metadata::Config::for_chip(&chip)) else { log::info!("Skipping undocumented package {package}."); return Ok(true); diff --git a/xtask/src/documentation.rs b/xtask/src/documentation.rs index 742d626a4c5..bdcd3bda0cf 100644 --- a/xtask/src/documentation.rs +++ b/xtask/src/documentation.rs @@ -106,11 +106,11 @@ fn build_documentation_for_package( let version = crate::package_version(workspace, *package)?; // Ensure that the package/chip combination provided are valid: - if let Some(chip) = chip - && let Err(err) = package.validate_package_chip(&chip) - { - log::warn!("{err}"); - return Ok(()); + if let Some(chip) = chip { + if let Err(err) = package.validate_package_chip(&chip) { + log::warn!("{err}"); + return Ok(()); + } } // Build the documentation for the specified package, targeting the @@ -333,7 +333,11 @@ fn pre_process_cargo_toml(chip: Option, package_path: &PathBuf) -> Result< let cargo_toml = cargo_toml.lines(); - let chip_cfg = chip.as_ref().map(Config::for_chip); + let chip_cfg = if let Some(chip) = &chip { + Some(Config::for_chip(chip)) + } else { + None + }; let mut processed_cargo_toml = Vec::new(); let mut engine = somni_expr::Context::new(); engine.add_function("has", move |cond: &str| -> bool { diff --git a/xtask/src/firmware.rs b/xtask/src/firmware.rs index bdff69ddc1e..191d4a18818 100644 --- a/xtask/src/firmware.rs +++ b/xtask/src/firmware.rs @@ -363,7 +363,7 @@ pub fn load_cargo_toml(examples_path: &Path) -> Result> { let chips = toml .features .keys() - .filter_map(|chip| Chip::from_str(chip, true).ok()); + .filter_map(|chip| Chip::from_str(&chip, true).ok()); for chip in chips { examples.push(Metadata { diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index f0747eb8b85..349a9a9c3b3 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -111,15 +111,15 @@ impl Package { // This is intended to opt-out in case there are features that look like chip names, but // aren't supposed to be handled like them. - if let Some(metadata) = toml.espressif_metadata() - && let Some(Item::Value(ov)) = metadata.get("has_chip_features") - { - let Value::Boolean(ov) = ov else { - log::warn!("Invalid value for 'has_chip_features' in metadata"); - return false; - }; + if let Some(metadata) = toml.espressif_metadata() { + if let Some(Item::Value(ov)) = metadata.get("has_chip_features") { + let Value::Boolean(ov) = ov else { + log::warn!("Invalid value for 'has_chip_features' in metadata"); + return false; + }; - return *ov.value(); + return *ov.value(); + } } features @@ -176,11 +176,10 @@ impl Package { // Look for files matching the pattern "MIGRATING-*.md" for entry in entries.flatten() { - if let Some(file_name) = entry.file_name().to_str() - && file_name.starts_with("MIGRATING-") - && file_name.ends_with(".md") - { - return true; + if let Some(file_name) = entry.file_name().to_str() { + if file_name.starts_with("MIGRATING-") && file_name.ends_with(".md") { + return true; + } } } @@ -199,7 +198,7 @@ impl Package { .filter_map(Result::ok) .filter(|e| e.path().extension().is_some_and(|ext| ext == "rs")) .any(|entry| { - std::fs::read_to_string(entry.path()).is_ok_and(|src| src.contains("#[test]")) + std::fs::read_to_string(entry.path()).map_or(false, |src| src.contains("#[test]")) }) } @@ -799,29 +798,33 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { let cmd = CargoArgsBuilder::default(); match package { - Package::EspConfig => cargo::run( - &cmd.clone() - .subcommand("test") - .features(&["build".into(), "tui".into()]) - .build(), - &package_path, - ), - - Package::EspBootloaderEspIdf => cargo::run( - &cmd.clone() - .subcommand("test") - .arg("--lib") - .arg("--tests") - .features(&["std".into()]) - .build(), - &package_path, - ), + Package::EspConfig => { + return cargo::run( + &cmd.clone() + .subcommand("test") + .features(&vec!["build".into(), "tui".into()]) + .build(), + &package_path, + ); + } + + Package::EspBootloaderEspIdf => { + return cargo::run( + &cmd.clone() + .subcommand("test") + .arg("--lib") + .arg("--tests") + .features(&vec!["std".into()]) + .build(), + &package_path, + ); + } Package::EspStorage => { cargo::run( &cmd.clone() .subcommand("test") - .features(&["emulation".into()]) + .features(&vec!["emulation".into()]) .arg("--") .arg("--test-threads=1") .build(), @@ -831,7 +834,7 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { cargo::run( &cmd.clone() .subcommand("test") - .features(&["emulation".into(), "bytewise-read".into()]) + .features(&vec!["emulation".into(), "bytewise-read".into()]) .arg("--") .arg("--test-threads=1") .build(), @@ -845,37 +848,39 @@ pub fn run_host_tests(workspace: &Path, package: Package) -> Result<()> { .toolchain("nightly") .subcommand("miri") .subcommand("test") - .features(&["emulation".into()]) + .features(&vec!["emulation".into()]) .arg("--") .arg("--test-threads=1") .build(), &package_path, )?; - cargo::run( + return cargo::run( &cmd.clone() .toolchain("nightly") .subcommand("miri") .subcommand("test") - .features(&["emulation".into(), "bytewise-read".into()]) + .features(&vec!["emulation".into(), "bytewise-read".into()]) .arg("--") .arg("--test-threads=1") .build(), &package_path, - ) + ); + } + Package::EspHalProcmacros => { + return cargo::run( + &cmd.clone() + .subcommand("test") + .features(&vec![ + "has-lp-core".into(), + "is-lp-core".into(), + "rtc-slow".into(), + "rtc-fast".into(), + ]) + .build(), + &package_path, + ); } - Package::EspHalProcmacros => cargo::run( - &cmd.clone() - .subcommand("test") - .features(&[ - "has-lp-core".into(), - "is-lp-core".into(), - "rtc-slow".into(), - "rtc-fast".into(), - ]) - .build(), - &package_path, - ), _ => Err(anyhow!( "Instructions for host testing were not provided for: '{}'", package, @@ -928,7 +933,7 @@ pub fn format_package_path( log::debug!("{cargo_args:#?}"); - cargo::run(&cargo_args, package_path) + cargo::run(&cargo_args, &package_path) } /// Recursively format all `.yml` files in the `.github/` directory. diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 7ef555b4e48..ba240325248 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -100,7 +100,7 @@ fn main() -> Result<()> { builder.init(); let workspace = - std::env::current_dir().with_context(|| "Failed to get the current dir!".to_string())?; + std::env::current_dir().with_context(|| format!("Failed to get the current dir!"))?; let target_path = workspace.join("target"); if std::env::var("CARGO_TARGET_DIR").is_err() { @@ -212,7 +212,7 @@ fn clean(workspace: &Path, args: CleanArgs) -> Result<()> { .arg(path.join("target").display().to_string()) .build(); - xtask::cargo::run(&cargo_args, path).with_context(|| { + xtask::cargo::run(&cargo_args, &path).with_context(|| { format!( "Failed to run `cargo run` with {cargo_args:?} in {}", path.display() @@ -309,7 +309,7 @@ fn build_check_package_command( builder = builder.toolchain(toolchain); } - builder = builder.args(args); + builder = builder.args(&args); if !features.is_empty() { builder = builder.arg(format!("--features={}", features.join(","))); @@ -525,7 +525,7 @@ fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> { log::info!("Running CI checks for chip: {}", args.chip); println!("::add-matcher::.github/rust-matchers.json"); - let run_locally = std::env::var("CI").is_err(); + let run_locally = !std::env::var("CI").is_ok(); let mut runner = Runner::new(&args); @@ -709,10 +709,9 @@ fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> { // The `ota_example` expects a file named `examples/target/ota_image` - it // doesn't care about the contents however std::fs::create_dir_all("./examples/target") - .with_context(|| "Failed to create `./examples/target`".to_string())?; - std::fs::write("./examples/target/ota_image", "DUMMY").with_context(|| { - "Failed to create a dummy file required by ota example!".to_string() - })?; + .with_context(|| format!("Failed to create `./examples/target`"))?; + std::fs::write("./examples/target/ota_image", "DUMMY") + .with_context(|| format!("Failed to create a dummy file required by ota example!"))?; examples( workspace, @@ -781,7 +780,7 @@ fn host_tests(workspace: &Path, args: HostTestsArgs) -> Result<()> { fn build_rlib(package: &str, chip: &str, target: &str) -> Result { let workspace = std::env::current_dir().with_context(|| "Failed to get the current dir!")?; Command::new("cargo") - .args([ + .args(&[ "+esp", "build", "--no-default-features", @@ -791,7 +790,7 @@ fn build_rlib(package: &str, chip: &str, target: &str) -> Result { target, "-Zbuild-std=core", ]) - .current_dir(workspace.join(package)) + .current_dir(workspace.join(package.to_string())) .status() .context("Failed to run cargo build")?; @@ -819,7 +818,7 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { for chip in chips { let target = package.target_triple(chip)?; - let rlib_path = match build_rlib(package.as_ref(), chip.as_ref(), &target) { + let rlib_path = match build_rlib(&package.to_string(), &chip.to_string(), &target) { Ok(path) => path, Err(e) => { println!( @@ -835,7 +834,7 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { let data = std::fs::read(&rlib_path) .with_context(|| format!("Failed to read {}!", rlib_path.display()))?; let archive = ArchiveFile::parse(data.as_slice()) - .with_context(|| "Failed to create archive!".to_string())?; + .with_context(|| format!("Failed to create archive!"))?; let mut problematic_symbols: Vec<(String, SymbolKind, usize)> = Vec::new(); @@ -847,11 +846,11 @@ fn check_global_symbols(chips: &[Chip]) -> Result<()> { )?; for symbol in obj.symbols().filter(|s| s.is_global() && s.is_definition()) { - if let Ok(name) = symbol.name() - && try_demangle(name).is_err() - { - let section = symbol.section_index().map(|i| i.0).unwrap_or(0); - problematic_symbols.push((name.to_string(), symbol.kind(), section)); + if let Ok(name) = symbol.name() { + if try_demangle(name).is_err() { + let section = symbol.section_index().map(|i| i.0).unwrap_or(0); + problematic_symbols.push((name.to_string(), symbol.kind(), section)); + } } } } From 0250e7ab112da30f3dc846f342afcd09c8146fcd Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Wed, 22 Apr 2026 02:16:35 +0900 Subject: [PATCH 06/27] Addressing comment avoid DW DMA --- esp-hal/src/clock/mod.rs | 24 ++---------------------- esp-hal/src/dma/gdma/ahb_v2.rs | 8 +++++--- esp-hal/src/soc/esp32p4/mod.rs | 6 +++--- esp-hal/src/system.rs | 15 +++++++-------- esp-metadata/devices/esp32p4.toml | 20 +++++++++++--------- 5 files changed, 28 insertions(+), 45 deletions(-) diff --git a/esp-hal/src/clock/mod.rs b/esp-hal/src/clock/mod.rs index 4f40197f148..ed07613203b 100644 --- a/esp-hal/src/clock/mod.rs +++ b/esp-hal/src/clock/mod.rs @@ -530,32 +530,12 @@ impl Clocks { /// The CPU clock frequency. pub fn cpu_clock() -> Rate { - // P4: ClockConfig is empty (no clock node framework yet). - // Return the actual configured frequency from CPLL init. - // Ref: esp-idf rtc_clk.c -- default is 400 MHz for eco5 (v3.x) - // TRM v0.5 Ch 12 - #[cfg(esp32p4)] - { - Rate::from_mhz(400) - } - #[cfg(not(esp32p4))] - { - Clocks::get().cpu_clock - } + Clocks::get().cpu_clock } /// The XTAL clock frequency. pub fn xtal_clock() -> Rate { - // P4: 40 MHz external crystal (SOC_XTAL_FREQ_40M) - // Ref: esp-idf clk_tree_defs.h -- SOC_XTAL_FREQ_40M = 40 - #[cfg(esp32p4)] - { - Rate::from_mhz(40) - } - #[cfg(not(esp32p4))] - { - Clocks::get().xtal_clock - } + Clocks::get().xtal_clock } /// Read the calibrated RTC slow clock period from the STORE1 register. diff --git a/esp-hal/src/dma/gdma/ahb_v2.rs b/esp-hal/src/dma/gdma/ahb_v2.rs index 42ad40fe86f..f8b4c3408f8 100644 --- a/esp-hal/src/dma/gdma/ahb_v2.rs +++ b/esp-hal/src/dma/gdma/ahb_v2.rs @@ -1,9 +1,11 @@ use super::*; use crate::RegisterToggle; -// P4: PAC "dma" module is DW_GDMA (DesignWare), "ahb_dma" is GDMA v2 (what we need). -// Other chips: PAC "dma" module IS the GDMA v2 module. -// Ref: esp-idf ahb_dma_ll.h vs dw_gdma_ll.h +// P4 has two DMA controllers: `ahb_dma` (GDMA-AHB, GDMA v2 layout, used here) and +// `axi_dma` (GDMA-AXI, different register layout). The PAC's `dma` module maps to +// a separate block that is not GDMA-AHB, so alias `ahb_dma` as `gdma_pac` on P4. +// Other chips: PAC `dma` module is the GDMA v2 module directly. +// Ref: esp-idf async_memcpy docs -- only `gdma_ahb` / `gdma_axi` are public names. cfg_if::cfg_if! { if #[cfg(esp32p4)] { use pac::ahb_dma as gdma_pac; diff --git a/esp-hal/src/soc/esp32p4/mod.rs b/esp-hal/src/soc/esp32p4/mod.rs index ace7c5b2044..439e719d6d8 100644 --- a/esp-hal/src/soc/esp32p4/mod.rs +++ b/esp-hal/src/soc/esp32p4/mod.rs @@ -10,9 +10,9 @@ pub(crate) mod regi2c; pub(crate) use esp32p4 as pac; -// P4 DMA module alias: pac::dma is DW_GDMA, but esp-hal GDMA driver expects AHB_DMA layout. -// Provide `pac::dma` alias pointing to `pac::ahb_dma` module for GDMA driver compatibility. -// This is necessary because ahb_v2.rs uses `pac::dma::ch::CH` type directly. +// P4 DMA module alias: the esp-hal GDMA driver expects the GDMA-AHB (`ahb_dma`) +// register layout. The PAC's `dma` module maps to a different block (see +// SOC_DW_GDMA_SUPPORTED), so alias `ahb_dma` to keep ahb_v2.rs type paths working. #[allow(unused)] pub(crate) mod dma_compat { pub use super::pac::ahb_dma::*; diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index a7bf27c95b7..d74d2289834 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -90,12 +90,9 @@ mod _p4_peripheral_clocks { Hmac = 35, Ds = 36, // -- DMA -- SOC_CLK_CTRL1 sys + HP_RST_EN0/1 - // P4 has 3 DMA controllers: - // AHB_DMA (AHB PDMA): GDMA v2 compatible, used by esp-hal as "Dma" - // DW_GDMA (DesignWare GDMA): different register layout, not used by esp-hal - // AXI_DMA (AXI PDMA): AXI bus DMA - Dma = 37, // maps to AHB_DMA (GDMA v2 compatible) - Gdma = 38, // DW_GDMA (DesignWare GDMA) -- NOT esp-hal compatible + // P4 has several DMA controllers (IDF public naming: see async_memcpy docs): + Dma = 37, // GDMA-AHB + Gdma = 38, // DMA block at 0x50081000 (SOC_DW_GDMA_SUPPORTED), unused AhbPdma = 39, // alias for Dma (legacy) AxiPdma = 40, // -- ADC -- SOC_CLK_CTRL2 apb + HP_RST_EN2 @@ -335,12 +332,14 @@ mod _p4_peripheral_clocks { .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); } // -- DMA -- - // Dma = AHB_DMA (GDMA v2 compatible, used by esp-hal) + // GDMA-AHB (GDMA v2 compatible, used by esp-hal) Peripheral::Dma => { c.soc_clk_ctrl1() .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); } - // Gdma = DW_GDMA (DesignWare, NOT used by esp-hal DMA driver) + // the DMA block at 0x50081000 (SOC_DW_GDMA_SUPPORTED in Kconfig), + // may not used by esp-hal's DMA driver. + // TODO: Investigate more on 0x50081000 DMA block. Peripheral::Gdma => { c.soc_clk_ctrl1() .modify(|_, w| w.gdma_sys_clk_en().bit(enable)); diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index 2975eea0669..899f1928d1c 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -155,8 +155,8 @@ peripherals = [ { name = "TWAI1", interrupts = { peri = "TWAI1" } }, { name = "TWAI2", interrupts = { peri = "TWAI2" } }, { name = "PSRAM", virtual = true }, - # DMA: PAC "DMA" is DW_GDMA (DesignWare), "AHB_DMA" is GDMA v2 compatible - # Using pac="AHB_DMA" maps DMA singleton to AHB_DMA RegisterBlock + # DMA: P4 has three DMA blocks; see [device.dma] below for the table. + # esp-hal's `Dma` singleton needs the GDMA v2 layout, so map it to AHB_DMA. { name = "DMA", pac = "AHB_DMA" }, { name = "DMA_CH0", virtual = true }, { name = "DMA_CH1", virtual = true }, @@ -236,13 +236,15 @@ fifo_size = 32 has_bus_timeout_enable = true max_bus_timeout = 0x1F -# DMA: deferred -- P4 PAC "DMA" is DW_GDMA (DesignWare), not AHB_DMA -# P4 has: AHB_DMA (GDMA v2 at 0x50085000) + AXI_DMA (0x5008A000) + DW_GDMA (0x50086000) -# esp-hal expects DMA singleton to be GDMA v2 compatible (in_conf0/out_conf0/in_link/out_link) -# But P4 PAC's "DMA" type is DW_GDMA (sar0/dar0/ctl0 pattern), NOT compatible -# Need: either PAC fix (rename AHB_DMA -> DMA) or esp-hal adapter layer -# Ref: esp-idf ahb_dma_ll.h for AHB_DMA register layout -# Ref: esp-idf dw_gdma_ll.h for DW_GDMA (different, DesignWare IP) +# DMA: P4 exposes three DMA controllers. IDF public docs +# (https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-reference/system/async_memcpy.html) +# refer to them as GDMA-AHB and GDMA-AXI: +# AHB_DMA / GDMA-AHB (0x50085000): GDMA v2 layout -- used by esp-hal as `Dma` +# AXI_DMA / GDMA-AXI (0x5008A000): AXI-bus DMA, different layout +# DMA (separate block at 0x50081000, SOC_DW_GDMA_SUPPORTED): +# another register layout, not used by esp-hal +# esp-hal's `Dma` singleton must be GDMA v2 compatible, hence PAC alias AHB_DMA above. +# Ref: IDF linker esp32p4.peripherals.ld (AHB_DMA, AXI_DMA, DW_GDMA symbols). [device.dma] support_status = "partial" kind = "gdma" From b1545b010d10a009ada26480dd656d52456a7842 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Wed, 22 Apr 2026 03:01:59 +0900 Subject: [PATCH 07/27] Remove redundant interrupt provides from esp32p4.x PAC --- esp-hal/ld/esp32p4/esp32p4.x | 105 +---------------------------------- 1 file changed, 2 insertions(+), 103 deletions(-) diff --git a/esp-hal/ld/esp32p4/esp32p4.x b/esp-hal/ld/esp32p4/esp32p4.x index 7f00a9c8b3e..171eedf75fc 100644 --- a/esp-hal/ld/esp32p4/esp32p4.x +++ b/esp-hal/ld/esp32p4/esp32p4.x @@ -20,109 +20,8 @@ PROVIDE(ExceptionHandler = DefaultExceptionHandler); one additional interrupt ID: */ PROVIDE(interrupt0 = DefaultHandler); -/* ESP32-P4 peripheral interrupt handlers (99 sources from PAC). - Each maps to DefaultHandler unless overridden by the application. - Ref: esp32p4 PAC lib.rs __EXTERNAL_INTERRUPTS vector table - TRM v0.5 Ch 14 (Interrupt Matrix) */ -PROVIDE(LP_WDT = DefaultHandler); -PROVIDE(LP_TIMER0 = DefaultHandler); -PROVIDE(LP_TIMER1 = DefaultHandler); -PROVIDE(PMU0 = DefaultHandler); -PROVIDE(PMU1 = DefaultHandler); -PROVIDE(LP_ANA = DefaultHandler); -PROVIDE(LP_ADC = DefaultHandler); -PROVIDE(LP_GPIO = DefaultHandler); -PROVIDE(LP_I2C0 = DefaultHandler); -PROVIDE(LP_I2S0 = DefaultHandler); -PROVIDE(LP_TOUCH = DefaultHandler); -PROVIDE(LP_TSENS = DefaultHandler); -PROVIDE(LP_UART = DefaultHandler); -PROVIDE(LP_SYS = DefaultHandler); -PROVIDE(LP_HUK = DefaultHandler); -PROVIDE(USB_DEVICE = DefaultHandler); -PROVIDE(DMA = DefaultHandler); -PROVIDE(SPI2 = DefaultHandler); -PROVIDE(SPI3 = DefaultHandler); -PROVIDE(I2S0 = DefaultHandler); -PROVIDE(I2S1 = DefaultHandler); -PROVIDE(I2S2 = DefaultHandler); -PROVIDE(UHCI0 = DefaultHandler); -PROVIDE(UART0 = DefaultHandler); -PROVIDE(UART1 = DefaultHandler); -PROVIDE(UART2 = DefaultHandler); -PROVIDE(UART3 = DefaultHandler); -PROVIDE(UART4 = DefaultHandler); -PROVIDE(PWM0 = DefaultHandler); -PROVIDE(PWM1 = DefaultHandler); -PROVIDE(TWAI0 = DefaultHandler); -PROVIDE(TWAI1 = DefaultHandler); -PROVIDE(TWAI2 = DefaultHandler); -PROVIDE(RMT = DefaultHandler); -PROVIDE(I2C0 = DefaultHandler); -PROVIDE(I2C1 = DefaultHandler); -PROVIDE(TG0_T0_LEVEL = DefaultHandler); -PROVIDE(TG0_T1_LEVEL = DefaultHandler); -PROVIDE(TG0_WDT_LEVEL = DefaultHandler); -PROVIDE(TG1_T0_LEVEL = DefaultHandler); -PROVIDE(TG1_T1_LEVEL = DefaultHandler); -PROVIDE(TG1_WDT_LEVEL = DefaultHandler); -PROVIDE(LEDC = DefaultHandler); -PROVIDE(SYSTIMER_TARGET0 = DefaultHandler); -PROVIDE(SYSTIMER_TARGET1 = DefaultHandler); -PROVIDE(SYSTIMER_TARGET2 = DefaultHandler); -PROVIDE(AHB_PDMA_IN_CH0 = DefaultHandler); -PROVIDE(AHB_PDMA_IN_CH1 = DefaultHandler); -PROVIDE(AHB_PDMA_IN_CH2 = DefaultHandler); -PROVIDE(AHB_PDMA_OUT_CH0 = DefaultHandler); -PROVIDE(AHB_PDMA_OUT_CH1 = DefaultHandler); -PROVIDE(AHB_PDMA_OUT_CH2 = DefaultHandler); -PROVIDE(AXI_PDMA_IN_CH0 = DefaultHandler); -PROVIDE(AXI_PDMA_IN_CH1 = DefaultHandler); -PROVIDE(AXI_PDMA_IN_CH2 = DefaultHandler); -PROVIDE(AXI_PDMA_OUT_CH0 = DefaultHandler); -PROVIDE(AXI_PDMA_OUT_CH1 = DefaultHandler); -PROVIDE(AXI_PDMA_OUT_CH2 = DefaultHandler); -PROVIDE(RSA = DefaultHandler); -PROVIDE(AES = DefaultHandler); -PROVIDE(SHA = DefaultHandler); -PROVIDE(ECC = DefaultHandler); -PROVIDE(GPIO = DefaultHandler); -PROVIDE(GPIO_INT1 = DefaultHandler); -PROVIDE(GPIO_INT2 = DefaultHandler); -PROVIDE(GPIO_INT3 = DefaultHandler); -PROVIDE(GPIO_PAD_COMP = DefaultHandler); -PROVIDE(FROM_CPU_INTR0 = DefaultHandler); -PROVIDE(FROM_CPU_INTR1 = DefaultHandler); -PROVIDE(FROM_CPU_INTR2 = DefaultHandler); -PROVIDE(FROM_CPU_INTR3 = DefaultHandler); -PROVIDE(CACHE = DefaultHandler); -PROVIDE(CSI_BRIDGE = DefaultHandler); -PROVIDE(DSI_BRIDGE = DefaultHandler); -PROVIDE(CSI = DefaultHandler); -PROVIDE(DSI = DefaultHandler); -PROVIDE(JPEG = DefaultHandler); -PROVIDE(PPA = DefaultHandler); -PROVIDE(ISP = DefaultHandler); -PROVIDE(I3C = DefaultHandler); -PROVIDE(I3C_SLV = DefaultHandler); -PROVIDE(HP_SYS = DefaultHandler); -PROVIDE(PCNT = DefaultHandler); -PROVIDE(PAU = DefaultHandler); -PROVIDE(PARLIO_RX = DefaultHandler); -PROVIDE(PARLIO_TX = DefaultHandler); -PROVIDE(H264_DMA2D_OUT_CH0 = DefaultHandler); -PROVIDE(H264_DMA2D_OUT_CH1 = DefaultHandler); -PROVIDE(H264_DMA2D_OUT_CH2 = DefaultHandler); -PROVIDE(H264_DMA2D_OUT_CH3 = DefaultHandler); -PROVIDE(H264_DMA2D_OUT_CH4 = DefaultHandler); -PROVIDE(H264_DMA2D_IN_CH0 = DefaultHandler); -PROVIDE(H264_DMA2D_IN_CH1 = DefaultHandler); -PROVIDE(H264_DMA2D_IN_CH2 = DefaultHandler); -PROVIDE(H264_DMA2D_IN_CH3 = DefaultHandler); -PROVIDE(H264_DMA2D_IN_CH4 = DefaultHandler); -PROVIDE(H264_DMA2D_IN_CH5 = DefaultHandler); -PROVIDE(H264_REG = DefaultHandler); -PROVIDE(ASSIST_DEBUG = DefaultHandler); +/* Peripheral interrupt symbols are provided by the esp32p4 PAC's `device.x`, + which is included by `hal-defaults.x`. No need to list them here. */ PROVIDE(__post_init = default_post_init); From 6a788e9c91cf6e971b760752bcadf5df809ac4c7 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Wed, 22 Apr 2026 23:40:22 +0900 Subject: [PATCH 08/27] Addressing comment USB and wrong metadata P4 --- esp-hal/src/gpio/mod.rs | 5 +++-- esp-metadata/devices/esp32p4.toml | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 29f6621eba4..3e88c5d101b 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -1671,8 +1671,9 @@ impl<'lt> AnyPin<'lt> { { /// Workaround to make D+ and D- work when the pin is assigned to /// the `USB_SERIAL_JTAG` peripheral by default. - // P4 uses dedicated pins (GPIO49/50) for USB, so USB_DM/USB_DP are - // not in the analog function table -> this inner fn is unused on P4. + // TODO: considering USB1P1_N0/1 USB1P1_P0/1 on P4 + // On P4 the analog table uses USB_PHY{0,1}_DM/DP instead of + // USB_DM/DP, so neither arm below matches and this fn is unused. #[allow(dead_code)] fn disable_usb_pads(_gpionum: u8) { crate::peripherals::USB_DEVICE::regs() diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index 899f1928d1c..88210aaf565 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -26,6 +26,14 @@ software_interrupt_count = 4 software_interrupt_delay = 24 controller = { Riscv = { flavour = "clic", interrupts = 48, priority_levels = 8 } } +# TODO: Tyding new TRM after 0.5 document +# Currently following section is not fully written. +# - Bus Architecture +# - Processor Instruction Extensions +# - AXI Performance Monitor +# - MIPI DSI (CAM) +# - I3C + [device.soc] cpu_has_csr_pc = true # ESP32-P4 v3.x: 20 MHz RC_FAST default (TRM v0.5, Ch 12) @@ -33,7 +41,7 @@ rc_fast_clk_default = 20_000_000 # Clock tree for ESP32-P4X (eco5 / chip revision v3.x) # 3 PLLs: CPLL (CPU, 360/400MHz), SPLL (480MHz, peripherals), MPLL (400MHz, PSRAM/media) -# Ref: esp-idf clk_tree_defs.h, clk_tree_ll.h, TRM v0.5 Ch 12 +# Ref: esp-idf clk_tree_defs.h, clk_tree_ll.h, DS, TRM v0.5 Ch 12 clocks = { system_clocks = { clock_tree = [ # High-speed clock sources { name = "XTAL_CLK", type = "source", output = "40_000_000", always_on = true }, @@ -126,8 +134,6 @@ peripherals = [ { name = "HP_SYS_CLKRST" }, { name = "INTERRUPT_CORE0" }, { name = "INTERRUPT_CORE1" }, - # CLIC is the per-core interrupt controller (TRM Ch 14), used by user code - # to enable/disable/prioritize interrupts. { name = "CLIC" }, { name = "IO_MUX" }, { name = "LP_AON", pac = "LP_SYS" }, @@ -144,10 +150,9 @@ peripherals = [ { name = "UART2", interrupts = { peri = "UART2" }, clock_group = "UART" }, { name = "UART3", interrupts = { peri = "UART3" }, clock_group = "UART" }, { name = "UART4", interrupts = { peri = "UART4" }, clock_group = "UART" }, - # Phase 2 peripherals + # Map to SPI2 RegisterBlock for esp-hal driver compatibility. { name = "SPI2", interrupts = { peri = "SPI2" }, dma_peripheral = 1 }, # SPI3: same RegisterBlock layout as SPI2 but different PAC type. - # Map to SPI2 RegisterBlock for esp-hal driver compatibility. { name = "SPI3", pac = "SPI2", interrupts = { peri = "SPI3" }, dma_peripheral = 2 }, { name = "I2C0", interrupts = { peri = "I2C0" } }, { name = "I2C1", interrupts = { peri = "I2C1" } }, @@ -161,13 +166,12 @@ peripherals = [ { name = "DMA_CH0", virtual = true }, { name = "DMA_CH1", virtual = true }, { name = "DMA_CH2", virtual = true }, - # Phase 3 peripherals + { name = "USB_DEVICE", interrupts = { peri = "USB_DEVICE" } }, { name = "SDHOST" }, - # EMAC: PAC에 없음. MMIO 0x5009_8000. esp-hal에도 EMAC driver 없음 (ESP32만). - # 새 driver 필요: components/esp_hal_emac/esp32p4/include/hal/emac_ll.h 참고 + # TODO: clear about EMAC and PAC relationship + # But ESP-IDF have: components/esp_hal_emac/esp32p4/include/hal/emac_ll.h # { name = "EMAC" }, - # Phase 4 peripherals { name = "LEDC", interrupts = { peri = "LEDC" } }, { name = "MCPWM0", interrupts = { peri = "PWM0" } }, { name = "MCPWM1", interrupts = { peri = "PWM1" } }, @@ -739,7 +743,7 @@ output_signals = [ # 55 GPIO pins (0-54), IO MUX functions from esp-idf io_mux_reg.h # ADC channels from esp-idf adc_channel.h # LP pins: GPIO0-5, GPIO12-23 (RTCIO capable) -# Ref: TRM v0.5 Ch 11, esp-idf gpio_periph.c, rtc_io_channel.h +# Ref: DS, TRM v0.5 Ch 11, esp-idf gpio_periph.c, rtc_io_channel.h pins = [ { pin = 0, lp = { 0 = "LP_GPIO0" } }, { pin = 1, lp = { 0 = "LP_GPIO1" } }, From 4381c33edee49219e43c3025e9ec7f9ad40b8758 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Thu, 23 Apr 2026 02:18:01 +0900 Subject: [PATCH 09/27] P4 cpu_wait_mode_on, per-core WAITI_ICG_EN read. --- esp-hal/src/interrupt/riscv.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/esp-hal/src/interrupt/riscv.rs b/esp-hal/src/interrupt/riscv.rs index ee76a45d73c..f26e249f3d7 100644 --- a/esp-hal/src/interrupt/riscv.rs +++ b/esp-hal/src/interrupt/riscv.rs @@ -419,14 +419,18 @@ fn cpu_wait_mode_on() -> bool { cfg_if::cfg_if! { if #[cfg(soc_has_pcr)] { crate::peripherals::PCR::regs().cpu_waiti_conf().read().cpu_wait_mode_force_on().bit_is_set() - } else if #[cfg(esp32p4)] { - // P4: CPU_WAITI_CTRL0_REG in HP_SYS_CLKRST (offset 0xf4) controls - // whether WFI gates the clock. Default: core0_waiti_icg_en=1 (enabled). - // This register is only in hw_ver3 (eco5+), not in current PAC. - // Ref: esp-idf hp_sys_clkrst_reg.h -- HP_SYS_CLKRST_CPU_WAITI_CTRL0_REG - // TRM v0.5 Ch 22 (v3.x addition) - // Return true (WFI clock gating active) -- matches default hardware state. - true + } else if #[cfg(all(multi_core, soc_has_hp_sys_clkrst))] { + // AMP-aware: read this core's CORE{N}_WAITI_ICG_EN bit in + // HP_SYS_CLKRST.CPU_WAITI_CTRL0 (hw_ver3). Each core answers + // locally, so AMP setups where cores run different firmware get + // the right per-core result. + // ICG_EN = 1 -> this core's WFI may gate clock -> NOT safe + // ICG_EN = 0 -> WFI will not gate -> safe + // TODO: add HP_SYS_CLKRST.CPU_WAITI_CTRL0 (offset 0xF4) to the + // esp32p4 PAC and replace this raw MMIO with the PAC accessor. + const HP_SYS_CLKRST_CPU_WAITI_CTRL0: *const u32 = 0x500E_60F4 as *const u32; + let reg = unsafe { core::ptr::read_volatile(HP_SYS_CLKRST_CPU_WAITI_CTRL0) }; + (reg & (1 << Cpu::current() as u32)) == 0 } else { crate::peripherals::SYSTEM::regs() .cpu_per_conf() From e68b4accc4a356d4ce91ef49ef50ac08a609b9b8 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 27 Apr 2026 01:16:12 +0900 Subject: [PATCH 10/27] Remove some reference tracking comment (p4) --- esp-hal/src/analog/adc/riscv.rs | 1 - esp-hal/src/clock/mod.rs | 12 +++--- esp-hal/src/dma/gdma/ahb_v2.rs | 1 - esp-hal/src/gpio/interrupt.rs | 2 - esp-hal/src/gpio/mod.rs | 4 -- esp-hal/src/i2c/master/mod.rs | 5 ++- esp-hal/src/interrupt/mod.rs | 17 ++++++--- esp-hal/src/interrupt/riscv.rs | 3 +- esp-hal/src/interrupt/riscv/clic.rs | 3 +- esp-hal/src/psram/esp32p4.rs | 25 +++---------- esp-hal/src/rtc_cntl/mod.rs | 16 +------- esp-hal/src/rtc_cntl/rtc/esp32p4.rs | 29 --------------- esp-hal/src/rtc_cntl/sleep/esp32p4.rs | 2 +- esp-hal/src/soc/esp32p4/clocks.rs | 16 ++------ esp-hal/src/soc/esp32p4/gpio.rs | 4 +- esp-hal/src/soc/esp32p4/regi2c.rs | 3 -- esp-hal/src/spi/master/mod.rs | 1 - esp-hal/src/system.rs | 13 +++---- .../src/_build_script_utils.rs | 6 ++- .../src/_generated_esp32p4.rs | 37 ++++++++++--------- esp-metadata/devices/esp32p4.toml | 30 +++++++++++---- 21 files changed, 90 insertions(+), 140 deletions(-) diff --git a/esp-hal/src/analog/adc/riscv.rs b/esp-hal/src/analog/adc/riscv.rs index 244139e8c54..9209702f23b 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -184,7 +184,6 @@ impl RegisterAccess for crate::peripherals::ADC1<'_> { } // ESP32-P4 uses DREF value 4 (same as S2/S3) not 1. - // Ref: esp-idf esp32p4/adc_ll.h -- adc_ll_calibration_init() // REGI2C_SAR_I2C (0x69) reg 2, bits [6:4] = DREF #[cfg(esp32p4)] fn calibration_init() { diff --git a/esp-hal/src/clock/mod.rs b/esp-hal/src/clock/mod.rs index ed07613203b..a4268550996 100644 --- a/esp-hal/src/clock/mod.rs +++ b/esp-hal/src/clock/mod.rs @@ -46,11 +46,16 @@ #![cfg_attr(not(feature = "rt"), expect(unused))] use clocks::ClockTree; -#[cfg(soc_has_clock_node_lp_slow_clk)] +// Only used inside the calibrate_rtc_slow_clock() path, which is itself +// gated by soc_has_clock_node_timg_calibration_clock. +#[cfg(all(soc_has_clock_node_lp_slow_clk, soc_has_clock_node_timg_calibration_clock))] use clocks::LpSlowClkConfig; #[cfg(all(not(esp32s2), soc_has_clock_node_rtc_slow_clk))] use clocks::RtcSlowClkConfig; -#[cfg(soc_has_clock_node_timg_function_clock)] +#[cfg(all( + soc_has_clock_node_timg_function_clock, + soc_has_clock_node_timg_calibration_clock +))] use clocks::TimgFunctionClockConfig; /// # Low-level clock control @@ -208,7 +213,6 @@ impl Clocks { ESP_HAL_LOCK.lock(|| { // P4: init() disables all WDTs and resets PMU power domain force flags. // Full PLL/clock tree config is NOT yet implemented -- relies on ROM bootloader. - // Ref: esp-idf pmu_init.c, bootloader_esp32p4.c, TRM v0.5 Ch 16 crate::rtc_cntl::rtc::init(); let config = Self::configure(cpu_clock_config); @@ -556,8 +560,6 @@ fn rtc_slow_cal_period() -> u64 { // P4: store registers are in LP_SYS (mapped as LP_AON in esp-hal). // LP_SYS has lp_store0..lp_store14 registers. - // Ref: esp-idf lp_system_reg.h -- LP_SYSTEM_REG_LP_STORE1_REG = RTC_SLOW_CLK_CAL_REG - // esp-idf esp_time_impl.c -- uses store2/store3 for boot time #[cfg(esp32p4)] { LP_AON::regs().lp_store1().read().bits() as u64 diff --git a/esp-hal/src/dma/gdma/ahb_v2.rs b/esp-hal/src/dma/gdma/ahb_v2.rs index f8b4c3408f8..6a6ff3b1b81 100644 --- a/esp-hal/src/dma/gdma/ahb_v2.rs +++ b/esp-hal/src/dma/gdma/ahb_v2.rs @@ -5,7 +5,6 @@ use crate::RegisterToggle; // `axi_dma` (GDMA-AXI, different register layout). The PAC's `dma` module maps to // a separate block that is not GDMA-AHB, so alias `ahb_dma` as `gdma_pac` on P4. // Other chips: PAC `dma` module is the GDMA v2 module directly. -// Ref: esp-idf async_memcpy docs -- only `gdma_ahb` / `gdma_axi` are public names. cfg_if::cfg_if! { if #[cfg(esp32p4)] { use pac::ahb_dma as gdma_pac; diff --git a/esp-hal/src/gpio/interrupt.rs b/esp-hal/src/gpio/interrupt.rs index 76d2aa45de3..a63071f5698 100644 --- a/esp-hal/src/gpio/interrupt.rs +++ b/esp-hal/src/gpio/interrupt.rs @@ -233,8 +233,6 @@ impl InterruptStatusRegisterAccess { } } else if #[cfg(esp32p4)] { // P4 PAC: intr_0() (Core0 GPIO interrupt status) - // Ref: esp-idf gpio_ll.h -- gpio_ll_get_intr_status() - // TRM v0.5 Ch 11 -- GPIO_STATUS_INT_REG match self { Self::Bank0 => GPIO::regs().intr_0().read().bits(), #[cfg(gpio_has_bank_1)] diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 3e88c5d101b..d89baf910ca 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -1671,10 +1671,6 @@ impl<'lt> AnyPin<'lt> { { /// Workaround to make D+ and D- work when the pin is assigned to /// the `USB_SERIAL_JTAG` peripheral by default. - // TODO: considering USB1P1_N0/1 USB1P1_P0/1 on P4 - // On P4 the analog table uses USB_PHY{0,1}_DM/DP instead of - // USB_DM/DP, so neither arm below matches and this fn is unused. - #[allow(dead_code)] fn disable_usb_pads(_gpionum: u8) { crate::peripherals::USB_DEVICE::regs() .conf0() diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index 100fda22af0..173467aa6ae 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -3369,9 +3369,10 @@ fn write_fifo(register_block: &RegisterBlock, data: u8) { } else if #[cfg(esp32p4)] { // P4: data register is read-only (RX FIFO only). TX uses txfifo_start_addr. // PAC txfifo_start_addr is also read-only in SVD, use direct MMIO. - // Ref: esp-idf i2c_ll.h -- i2c_ll_write_txfifo() uses HAL_FORCE_MODIFY - // TRM v0.5 Ch 48 -- I2C_TXFIFO_START_ADDR (offset 0x100) let base = register_block as *const _ as usize; + // SAFETY: `register_block` is a borrow of a live I2C PAC register block. + // offset 0x100 is the TX FIFO write port inside the same block, so the + // computed pointer is valid MMIO for the peripheral we already hold. unsafe { ((base + 0x100) as *mut u32).write_volatile(data as u32); } diff --git a/esp-hal/src/interrupt/mod.rs b/esp-hal/src/interrupt/mod.rs index 66639a9d885..6ad08181fb5 100644 --- a/esp-hal/src/interrupt/mod.rs +++ b/esp-hal/src/interrupt/mod.rs @@ -52,6 +52,9 @@ cfg_if::cfg_if! { use crate::peripherals::DPORT as INTERRUPT_CORE0; use crate::peripherals::DPORT as INTERRUPT_CORE1; } else { + // P4 reads these registers via raw MMIO, not through the PAC singletons, + // so the INTERRUPT_CORE0/1 imports aren't needed there. + #[cfg(not(esp32p4))] use crate::peripherals::INTERRUPT_CORE0; #[cfg(esp32s3)] use crate::peripherals::INTERRUPT_CORE1; @@ -199,15 +202,16 @@ impl InterruptStatus { Cpu::ProCpu => InterruptStatus { status: core::array::from_fn(|idx| { // P4: Status registers at base + 0x200 (4 x 32-bit = 128 sources) - // Ref: esp-idf interrupt_core0_reg.h // INTERRUPT_CORE0_INTR_STATUS_REG_0_REG = base + 0x200 // INTERRUPT_CORE0_INTR_STATUS_REG_1_REG = base + 0x204 // INTERRUPT_CORE0_INTR_STATUS_REG_2_REG = base + 0x208 // INTERRUPT_CORE0_INTR_STATUS_REG_3_REG = base + 0x20c - // TRM v0.5 Ch 14 #[cfg(esp32p4)] { let base = crate::soc::registers::INTERRUPT_MAP_BASE + 0x200; + // SAFETY: fixed MMIO address of a read-only interrupt-status + // register; `idx` is bounded by STATUS_WORDS (4) which stays + // inside the 0x200..0x210 status-register window. unsafe { ((base as *const u32).add(idx)).read_volatile() } } #[cfg(not(esp32p4))] @@ -223,11 +227,11 @@ impl InterruptStatus { Cpu::AppCpu => InterruptStatus { status: core::array::from_fn(|idx| { // P4 Core1: base + 0x800 + 0x200 - // Ref: esp-idf interrupt_core1_reg.h // INTERRUPT_CORE1 = INTERRUPT_CORE0 + 0x800 #[cfg(esp32p4)] { let base = crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU + 0x200; + // SAFETY: same as Core0 path above, against the Core1 block. unsafe { ((base as *const u32).add(idx)).read_volatile() } } #[cfg(not(esp32p4))] @@ -381,9 +385,7 @@ pub(super) fn map_raw(core: Cpu, interrupt: Interrupt, cpu_interrupt: u32) { // P4: 120 individual INT_MAP registers at sequential 4-byte offsets from base. // Each register has 6-bit field [5:0] for CPU interrupt line (0-63). // Core0: base = 0x500D_6000, Core1: base = 0x500D_6800 - // Ref: esp-idf interrupt_core0_reg.h -- LP_RTC_INT_MAP_REG at offset 0x0, // LP_WDT_INT_MAP_REG at offset 0x4, etc. - // TRM v0.5 Ch 14 #[cfg(esp32p4)] { let base = match core { @@ -391,6 +393,9 @@ pub(super) fn map_raw(core: Cpu, interrupt: Interrupt, cpu_interrupt: u32) { #[cfg(multi_core)] Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU, }; + // SAFETY: `base` points at the per-core INT_MAP register array; `interrupt` + // is a peripheral-interrupt index which is bounded by the PAC's enum and + // always maps to a valid register slot inside the 120-entry array. unsafe { let reg = (base as *mut u32).add(interrupt as usize); reg.write_volatile(cpu_interrupt); @@ -419,7 +424,6 @@ pub(crate) fn mapped_to(cpu: Cpu, interrupt: Interrupt) -> Option pub(crate) fn mapped_to_raw(cpu: Cpu, interrupt: u32) -> Option { // P4: read INT_MAP register directly. 6-bit field [5:0] = CPU interrupt line. - // Ref: esp-idf interrupt_core0_reg.h, TRM v0.5 Ch 14 #[cfg(esp32p4)] let cpu_intr = { let base = match cpu { @@ -427,6 +431,7 @@ pub(crate) fn mapped_to_raw(cpu: Cpu, interrupt: u32) -> Option { #[cfg(multi_core)] Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU, }; + // SAFETY: matches map_raw -- same bounded INT_MAP array, read-only volatile. unsafe { let reg = (base as *const u32).add(interrupt as usize); reg.read_volatile() & 0x3F // 6-bit field diff --git a/esp-hal/src/interrupt/riscv.rs b/esp-hal/src/interrupt/riscv.rs index f26e249f3d7..49d24fb99a2 100644 --- a/esp-hal/src/interrupt/riscv.rs +++ b/esp-hal/src/interrupt/riscv.rs @@ -317,7 +317,6 @@ pub fn enable_direct( // P4: CLIC uses consolidated int_ctrl register (not separate int_attr). // int_ctrl contains: int_ip[0], int_ie[8], int_attr_shv[16], // int_attr_trig[17:18], int_attr_mode[22:23], int_ctl[24:31] - // Ref: esp-idf clic_reg.h, TRM v0.5 Ch 2/14 w.int_attr_shv().set_bit(); w.int_attr_trig().bits(0) // positive level }); @@ -429,6 +428,8 @@ fn cpu_wait_mode_on() -> bool { // TODO: add HP_SYS_CLKRST.CPU_WAITI_CTRL0 (offset 0xF4) to the // esp32p4 PAC and replace this raw MMIO with the PAC accessor. const HP_SYS_CLKRST_CPU_WAITI_CTRL0: *const u32 = 0x500E_60F4 as *const u32; + // SAFETY: fixed MMIO address of a read-only status register. The + // volatile read has no side effects. let reg = unsafe { core::ptr::read_volatile(HP_SYS_CLKRST_CPU_WAITI_CTRL0) }; (reg & (1 << Cpu::current() as u32)) == 0 } else { diff --git a/esp-hal/src/interrupt/riscv/clic.rs b/esp-hal/src/interrupt/riscv/clic.rs index 839aee5f4a2..de1ae701bac 100644 --- a/esp-hal/src/interrupt/riscv/clic.rs +++ b/esp-hal/src/interrupt/riscv/clic.rs @@ -7,7 +7,6 @@ pub(super) fn init() { // Set 3 level bits = 8 priority levels // P4 PAC: int_config_nlbits() (not mnlbits()) - // Ref: esp-idf clic_reg.h -- CLIC_INT_CONFIG_REG, nlbits field cfg_if::cfg_if! { if #[cfg(esp32p4)] { clic.int_config() @@ -205,7 +204,7 @@ core::arch::global_asm!( * If an interrupt occurs and is configured as (hardware) vectored, the CPU will jump to * MTVT[31:0] + 4 * interrupt_id * - * In the case of the ESP32P4/ESP32C5, the interrupt matrix, between the CPU interrupt lines + * In the case of the ESP32-P4/ESP32-C5, the interrupt matrix, between the CPU interrupt lines * and the peripherals, offers 32 lines, and the lower 16 interrupts are used for CLINT. */ .balign 0x40 diff --git a/esp-hal/src/psram/esp32p4.rs b/esp-hal/src/psram/esp32p4.rs index 5e8bcf4cf51..7961ea39841 100644 --- a/esp-hal/src/psram/esp32p4.rs +++ b/esp-hal/src/psram/esp32p4.rs @@ -56,18 +56,15 @@ pub(crate) fn map_psram(config: PsramConfig) -> core::ops::Range { PSRAM_VADDR_START..PSRAM_VADDR_START + size } +// TODO: Test and debug with several PSRAM size fn init_psram_inner(config: PsramConfig) { // 1. Enable MPLL (400 MHz) for PSRAM clock - // Ref: esp-idf clk_tree_ll.h -- clk_ll_mpll_enable(), clk_ll_mpll_set_config() - // regi2c_mpll.h -- I2C_MPLL = 0x63 configure_mpll(400); // 2. Enable PSRAM controller clock and select MPLL source - // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_enable_module_clock() // HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_en = 1 // HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_src_sel = 1 (MPLL) let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); - // Ref: esp-idf clk_gate_ll.h -- psram_ctrlr_ll_enable_module_clock() clkrst.peri_clk_ctrl00().modify(|_, w| unsafe { w.psram_pll_clk_en().set_bit(); w.psram_core_clk_en().set_bit(); @@ -75,22 +72,19 @@ fn init_psram_inner(config: PsramConfig) { }); // 3. Set bus clock divider: MPLL(400MHz) / 2 = 200MHz PSRAM bus - // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_set_bus_clock() // SPI_MEM_S_SRAM_CLK_REG: SCLKCNT_N=1, SCLKCNT_H=0, SCLKCNT_L=1 - // TODO(P4X): These registers are in SPIMEM2 which may not be in PAC. + // TODO(esp32p4): These registers are in SPIMEM2 which may not be in PAC. // Using direct MMIO for now. // PSRAM MSPI controller base - // Ref: esp-idf reg_base.h -- DR_REG_PSRAM_MSPI0_BASE = 0x5008_E000 const PSRAM_MSPI_BASE: u32 = 0x5008_E000; // 3a. Set PSRAM bus clock divider: MPLL(400MHz) / 2 = 200MHz // Ref: SPI_MEM_S_SRAM_CLK_REG offset from PSRAM_MSPI_BASE // sclkcnt_n=1, sclkcnt_h=0, sclkcnt_l=1 - // TODO(P4X): verify exact register offset for SRAM_CLK_REG + // TODO(esp32p4): verify exact register offset for SRAM_CLK_REG // const SRAM_CLK_OFFSET: u32 = ...; // need to find from spi_mem_s_reg.h // 3b. Configure PSRAM read/write commands for HEX sync mode - // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_set_rd_cmd/wr_cmd() // SPI_MEM_S_CACHE_SCTRL_REG: cache_sram_usr_rcmd, cache_sram_usr_wcmd // SPI_MEM_S_SRAM_DRD_CMD_REG: cmd_bitlen=15, cmd_value=0x0000 (sync read) // SPI_MEM_S_SRAM_DWR_CMD_REG: cmd_bitlen=15, cmd_value=0x8080 (sync write) @@ -109,12 +103,10 @@ fn init_psram_inner(config: PsramConfig) { // SPI_MEM_S_CACHE_FCTRL_REG: axi_req_en=1 // 4. Configure PSRAM MSPI controller - // Ref: esp-idf psram_ctrlr_ll.h, spi_mem_s_reg.h // PSRAM_MSPI_BASE = 0x5008_E000 configure_psram_mspi(PSRAM_MSPI_BASE); // 5. Map PSRAM via MMU (0x48000000 virtual -> physical) - // Ref: esp-idf mmu_ll.h -- mmu_ll_write_entry() mmu_map_psram(PSRAM_MSPI_BASE, config); // Determine PSRAM size @@ -130,7 +122,7 @@ fn init_psram_inner(config: PsramConfig) { unsafe { super::set_psram_range(start..end) }; } - // TODO(P4X): Full PSRAM init needs: + // TODO(esp32p4): Full PSRAM init needs: // - SPIMEM2 read/write command configuration (HEX sync mode) // - Address bitlen (32-bit), dummy cycles (14 read, 7 write at 200MHz) // - CS timing, DDR mode enable @@ -250,14 +242,12 @@ fn mmu_map_psram(mspi_base: u32, config: PsramConfig) { // PSRAM virtual starts at 0x4800_0000. The MMU entry index depends on // the overall virtual address map layout. For P4, PSRAM region starts // at a fixed offset in the MMU table. - // Ref: esp-idf mmu_ll.h -- mmu_ll_get_entry_id() // The formula: entry_id = (vaddr - SOC_MMU_VADDR_BASE) / MMU_PAGE_SIZE // SOC_MMU_VADDR_BASE = 0x4000_0000 (flash mapping start) // PSRAM at 0x4800_0000: entry_id = (0x4800_0000 - 0x4000_0000) / 0x10000 = 0x800 const PSRAM_MMU_START_ENTRY: u32 = 0x800; // Disable data cache before modifying MMU - // Ref: esp-idf cache_ll.h -- cache_ll_l1_disable_cache() cache_suspend(); unsafe { @@ -363,20 +353,17 @@ fn configure_mpll(freq_mhz: u32) { use crate::soc::regi2c; const I2C_MPLL: u8 = 0x63; - // Ref: esp-idf soc/esp32p4/include/soc/regi2c_mpll.h const I2C_MPLL_DIV_REG_ADDR: u8 = 2; const I2C_MPLL_DHREF: u8 = 3; const I2C_MPLL_IR_CAL_RSTB: u8 = 5; // Enable MPLL power - // Ref: esp-idf clk_tree_ll.h -- clk_ll_mpll_enable() // PMU.rf_pwc: mspi_phy_xpd // LP_AON_CLKRST: hp_mpll_500m_clk_en - // TODO(P4X): PMU rf_pwc register access for MPLL power + // TODO(esp32p4): PMU rf_pwc register access for MPLL power // Calculate divider: MPLL_freq = XTAL(40MHz) * (div+1) / (ref_div+1) // For 400MHz: ref_div=1, div=19 -> 40*20/2 = 400MHz - // Ref: esp-idf clk_tree_ll.h:508 let div_val: u8 = match freq_mhz { 400 => (9 << 3) | 1, // div=9, ref_div=1 -> 40*10/2 = 200... needs recalc 500 => (12 << 3) | 1, // div=12, ref_div=1 @@ -384,7 +371,6 @@ fn configure_mpll(freq_mhz: u32) { }; // MPLL calibration sequence - // Ref: esp-idf clk_tree_ll.h:484-498 // 1. Set DHREF bits [5:4] = 3 let dhref = regi2c::regi2c_read(I2C_MPLL, 0, I2C_MPLL_DHREF); regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_DHREF, dhref | (3 << 4)); @@ -460,7 +446,6 @@ fn configure_psram_mspi(base: u32) { let sram_cmd = (base + SRAM_CMD) as *mut u32; let val = sram_cmd.read_volatile(); // sdin_hex (bit 4) and sdout_hex (bit 5) -- exact bit positions need verification - // Ref: esp-idf psram_ctrlr_ll.h -- psram_ctrlr_ll_set_line_mode() let val = val | (1 << 4) | (1 << 5); // HEX mode data lines sram_cmd.write_volatile(val); diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index 0d16ea40c7e..1b10d4596bf 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -416,7 +416,6 @@ impl<'d> Rtc<'d> { // ESP32-H2: TRM v0.5 chapter 8.2.3 // P4: store registers are in LP_SYS (mapped as LP_AON). - // Ref: esp-idf rom/rtc.h -- RTC_XTAL_FREQ_REG = LP_SYSTEM_REG_LP_STORE4_REG // RTC_DISABLE_ROM_LOG = (1<<0)|(1<<16) // esp-idf rtc_suppress_rom_log() uses LP_STORE4 #[cfg(esp32p4)] @@ -671,7 +670,6 @@ impl Rwdt { pub fn listen(&mut self) { let rtc_cntl = LP_WDT::regs(); self.set_write_protection(false); - // Ref: esp-idf lpwdt_ll.h -- lpwdt_ll_set_wdt_config0() rtc_cntl .config0() .modify(|_, w| unsafe { w.wdt_stg0().bits(RwdtStageAction::Interrupt as u8) }); @@ -714,7 +712,6 @@ impl Rwdt { } fn set_write_protection(&mut self, enable: bool) { - // Ref: esp-idf lpwdt_ll.h -- LP_WDT_WKEY_VALUE = 0x50D83AA1 let wkey = if enable { 0u32 } else { 0x50D8_3AA1 }; LP_WDT::regs().wprotect().write(|w| unsafe { w.bits(wkey) }); } @@ -754,7 +751,6 @@ impl Rwdt { self.set_write_protection(false); // P4 PAC: config1().wdt_stg0_hold(), config2().wdt_stg1_hold(), etc. - // Ref: esp-idf lp_wdt_struct.h let timeout_raw = timeout_raw >> (1 + crate::efuse::rwdt_multiplier()); match stage { RwdtStage::Stage0 => rtc_cntl @@ -844,16 +840,8 @@ pub fn wakeup_cause() -> SleepSource { cfg_if::cfg_if! { if #[cfg(esp32)] { let wakeup_cause_bits = LPWR::regs().wakeup_state().read().wakeup_cause().bits() as u32; - } else if #[cfg(soc_has_intpri)] { - let wakeup_cause_bits = crate::peripherals::PMU::regs() - .slp_wakeup_status0() - .read() - .wakeup_cause() - .bits(); - } else if #[cfg(esp32p4)] { - // P4: PMU_SLP_WAKEUP_STATUS0_REG (offset 0x144), field wakeup_cause [30:0] - // Ref: esp-idf pmu_reg.h -- PMU_SLP_WAKEUP_STATUS0_REG - // TRM v0.5 Ch 16 + } else if #[cfg(soc_has_pmu)] { + // C5/C6/C61/H2/P4: PMU.slp_wakeup_status0.wakeup_cause let wakeup_cause_bits = crate::peripherals::PMU::regs() .slp_wakeup_status0() .read() diff --git a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs index 8fc73b3aa6a..1cfd0c31b7c 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs @@ -77,7 +77,6 @@ fn pmu_power_domain_force_default() { let pmu = PMU::regs(); // PMU_HP_PD_TOP - // Ref: esp-idf pmu_init.c, pmu_ll.h -- pmu_ll_hp_set_power_force_* pmu.power_pd_top_cntl().modify(|_, w| { w.force_top_reset().bit(false); w.force_top_iso().bit(false); @@ -88,7 +87,6 @@ fn pmu_power_domain_force_default() { }); // PMU_HP_PD_CNNT (eco5: replaces hpaon + hpcpu + hpwifi from eco4) - // Ref: esp-idf pmu_reg.h -- PMU_POWER_PD_CNNT_CNTL_REG pmu.power_pd_cnnt_cntl().modify(|_, w| { w.force_cnnt_reset().bit(false); w.force_cnnt_iso().bit(false); @@ -99,7 +97,6 @@ fn pmu_power_domain_force_default() { }); // PMU_HP_PD_HPMEM - // Ref: esp-idf pmu_reg.h -- PMU_POWER_PD_HPMEM_CNTL_REG pmu.power_pd_hpmem_cntl().modify(|_, w| { w.force_hp_mem_reset().bit(false); w.force_hp_mem_iso().bit(false); @@ -110,7 +107,6 @@ fn pmu_power_domain_force_default() { }); // PMU_LP_PD_LPPERI (eco5 new) - // Ref: esp-idf pmu_reg.h -- PMU_POWER_PD_LPPERI_CNTL_REG pmu.power_pd_lpperi_cntl().modify(|_, w| { w.force_lp_peri_reset().bit(false); w.force_lp_peri_iso().bit(false); @@ -134,9 +130,7 @@ pub(crate) fn init() { pmu_power_domain_force_default(); // 2. Disable TIMG0 watchdog - // Ref: esp-idf wdt_hal.c -- wdt_hal_init(), wdt_hal_disable() // TIMG WDT write protect key: 0x50D8_3AA1 - // TRM v0.5 Ch 19 -- TIMG0_WDTWPROTECT_REG, TIMG0_WDTCONFIG0_REG let tg0 = TIMG0::regs(); tg0.wdtwprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); tg0.wdtconfig0().modify(|_, w| w.wdt_en().clear_bit()); @@ -149,18 +143,14 @@ pub(crate) fn init() { tg1.wdtwprotect().write(|w| unsafe { w.bits(0) }); // 4. Disable LP_WDT (Low-Power Watchdog) - // Ref: esp-idf lpwdt_ll.h -- LP_WDT write protect key: 0x50D8_3AA1 // P4 PAC: config0() (not wdtconfig0()), wprotect() (not wdtwprotect()) - // TRM v0.5 Ch 19 -- LP_WDT_CONFIG0_REG let lp_wdt = LP_WDT::regs(); lp_wdt.wprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); lp_wdt.config0().modify(|_, w| unsafe { w.bits(0) }); lp_wdt.wprotect().write(|w| unsafe { w.bits(0) }); // 5. Disable SWD (Super Watchdog) by enabling auto-feed - // Ref: esp-idf bootloader_esp32p4.c -- bootloader_super_wdt_auto_feed() // LP_WDT SWD write protect key: 0x50D8_3AA1 (same key) - // TRM v0.5 Ch 19 -- LP_WDT_SWD_CONFIG_REG lp_wdt .swd_wprotect() .write(|w| unsafe { w.bits(0x50D8_3AA1) }); @@ -170,7 +160,6 @@ pub(crate) fn init() { lp_wdt.swd_wprotect().write(|w| unsafe { w.bits(0) }); // 6. Clear DCDC switch force flags - // Ref: esp-idf pmu_init.c -- pmu_ll_set_dcdc_switch_force_power_up/down // PMU_POWER_DCDC_SWITCH_REG (offset 0x10c) let pmu = PMU::regs(); pmu.power_dcdc_switch().modify(|_, w| { @@ -179,16 +168,10 @@ pub(crate) fn init() { }); // 7. Enable CPLL (400 MHz) and SPLL (480 MHz) - // Ref: esp-idf rtc_clk.c:401 -- rtc_clk_cpu_freq_set_config() - // esp-idf clk_tree_ll.h:375 -- clk_ll_cpll_set_config() - // esp-idf clk_tree_ll.h:430 -- clk_ll_spll_set_config() - // TRM v0.5 Ch 12 (Reset and Clock) cpll_configure(400); spll_configure(480); // 8. Set CPU divider to 1 (400 MHz CPU), MEM divider 2, APB divider 2 - // Ref: esp-idf rtc_clk.c:262 -- case 400: mem_divider=2, apb_divider=2 - // esp-idf clk_tree_ll.h -- clk_ll_cpu_set_divider() let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); // Set CPU divider: cpu_clk_div_num = divider - 1 = 0 @@ -212,7 +195,6 @@ pub(crate) fn init() { } // 9. Switch CPU clock source from XTAL to CPLL - // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_CPLL) // LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel: 0=XTAL, 1=CPLL, 2=RC_FAST crate::peripherals::LP_AON_CLKRST::regs() .lp_aonclkrst_hp_clk_ctrl() @@ -229,20 +211,17 @@ fn cpll_configure(freq_mhz: u32) { use crate::soc::regi2c; // I2C CPLL register addresses - // Ref: esp-idf soc/esp32p4/include/soc/regi2c_cpll.h const I2C_CPLL: u8 = 0x67; // CPLL slave address const I2C_CPLL_OC_REF_DIV: u8 = 2; const I2C_CPLL_OC_DIV_7_0: u8 = 3; const I2C_CPLL_OC_DCUR: u8 = 6; // 1. Enable CPLL power - // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpll_enable() // PMU.imm_hp_ck_power: tie_high_xpd_pll, tie_high_xpd_pll_i2c // Note: PAC uses "pll" not "cpll" (eco4 PAC, single PLL) let pmu = PMU::regs(); // PAC: tie_high_xpd_pll is 4-bit field (one bit per PLL: CPLL/SPLL/MPLL/PLLA). // Set all bits to enable all PLLs. Same for pll_i2c. - // Ref: esp-idf pmu_reg.h -- PMU_TIE_HIGH_XPD_CPLL (BIT27) etc. pmu.imm_hp_ck_power().write(|w| unsafe { w.tie_high_xpd_pll().bits(0xF); w.tie_high_xpd_pll_i2c().bits(0xF) @@ -254,7 +233,6 @@ fn cpll_configure(freq_mhz: u32) { // 2. Configure CPLL via I2C analog registers // eco5 values (v3.x): div7_0 = 10 (400MHz), 9 (360MHz) with 40MHz XTAL - // Ref: esp-idf clk_tree_ll.h:400-410 -- !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 path let div7_0: u8 = match freq_mhz { 400 => 10, // eco5: 400 MHz 360 => 9, // eco5: 360 MHz @@ -262,11 +240,9 @@ fn cpll_configure(freq_mhz: u32) { }; // OC_REF_DIV + DCHGP: (oc_enb_fcal << 7) | (dchgp << 4) | div_ref = 0x50 - // Ref: esp-idf clk_tree_ll.h:414 let lref: u8 = 0x50; // dchgp=5, div_ref=0, oc_enb_fcal=0 // OC_DCUR: (dlref_sel << 6) | (dhref_sel << 4) | dcur = 0x73 - // Ref: esp-idf clk_tree_ll.h:421 let dcur: u8 = 0x73; // dlref_sel=1, dhref_sel=3, dcur=3 regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_REF_DIV, lref); @@ -274,7 +250,6 @@ fn cpll_configure(freq_mhz: u32) { regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_DCUR, dcur); // 3. Run CPLL calibration - // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpll_calibration_start/stop/is_done // HP_SYS_CLKRST.ana_pll_ctrl0.cpu_pll_cal_stop let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); @@ -307,7 +282,6 @@ fn spll_configure(freq_mhz: u32) { use crate::soc::regi2c; // I2C SPLL register addresses - // Ref: esp-idf soc/esp32p4/include/soc/regi2c_syspll.h const I2C_SPLL: u8 = regi2c::REGI2C_SYS_PLL; const I2C_SPLL_OC_REF_DIV: u8 = 2; const I2C_SPLL_OC_DIV_7_0: u8 = 3; @@ -317,7 +291,6 @@ fn spll_configure(freq_mhz: u32) { // Configure SPLL via I2C analog registers // eco5 values: div7_0 = (freq_mhz / 40) - 1, same formula as CPLL - // Ref: esp-idf clk_tree_ll.h:460 -- !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 path let div7_0: u8 = match freq_mhz { 480 => 11, // 480 MHz: (480/40) - 1 = 11 240 => 5, // 240 MHz: (240/40) - 1 = 5 @@ -325,7 +298,6 @@ fn spll_configure(freq_mhz: u32) { }; // Same OC_REF_DIV and OC_DCUR values as CPLL - // Ref: esp-idf clk_tree_ll.h:468-475 let lref: u8 = 0x50; // dchgp=5, div_ref=0, oc_enb_fcal=0 let dcur: u8 = 0x73; // dlref_sel=1, dhref_sel=3, dcur=3 @@ -334,7 +306,6 @@ fn spll_configure(freq_mhz: u32) { regi2c::regi2c_write(I2C_SPLL, 0, I2C_SPLL_OC_DCUR, dcur); // Run SPLL calibration - // Ref: esp-idf clk_tree_ll.h -- clk_ll_spll_calibration_start/stop/is_done // HP_SYS_CLKRST.ana_pll_ctrl0.sys_pll_cal_stop let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); diff --git a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs index 0277416bb1b..29dee876c13 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs @@ -9,7 +9,7 @@ //! - crate::clock::Clock, crate::efuse::Efuse (old API pattern) //! - PMU hp_active/hp_modem/hp_sleep register groups //! -//! TODO(P4X): Implement sleep mode once PMU eco5 registers are validated. +//! TODO(esp32p4): Implement sleep mode once PMU eco5 registers are validated. //! Ref: esp-idf pmu_sleep.c, pmu_eco5_struct.h //! TRM v0.5 Ch 16 (Low-Power Management) //! .investigation/ESP32P4_ECO5_PERIPHERAL_AUDIT.md diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index d72aa0e0bc5..cbfe7fac1c5 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -40,7 +40,6 @@ pub enum CpuClock { impl CpuClock { // Preset: 400 MHz CPU, 100 MHz APB - // Ref: esp-idf rtc_clk.c:262 -- case 400: cpu=1, mem=2, apb=2 const PRESET_400: ClockConfig = ClockConfig { cpu_root_clk: Some(CpuRootClkConfig::Cpll), cpu_clk: Some(CpuClkConfig::new(0)), // /1 = 400 MHz @@ -118,7 +117,6 @@ fn configure_cpu_root_clk_impl( _old_selector: Option, new_selector: CpuRootClkConfig, ) { - // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_src() // LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel: 0=XTAL, 1=CPLL, 2=RC_FAST let sel = match new_selector { CpuRootClkConfig::Xtal => 0, @@ -137,7 +135,6 @@ fn configure_cpu_clk_impl( _old_config: Option, new_config: CpuClkConfig, ) { - // Ref: esp-idf clk_tree_ll.h -- clk_ll_cpu_set_divider() // HP_SYS_CLKRST.root_clk_ctrl0.cpu_clk_div_num = divider - 1 let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); clkrst.root_clk_ctrl0().modify(|_, w| unsafe { @@ -166,7 +163,7 @@ fn configure_apb_clk_impl( _old_config: Option, _new_config: ApbClkConfig, ) { - // TODO(P4X): APB divider register in HP_SYS_CLKRST + // TODO(esp32p4): APB divider register in HP_SYS_CLKRST // For now, APB freq is derived from CPU freq via divider } @@ -176,7 +173,6 @@ fn configure_lp_fast_clk_impl( _old_selector: Option, new_selector: LpFastClkConfig, ) { - // Ref: esp-idf clk_tree_ll.h -- clk_ll_rtc_fast_set_src() crate::peripherals::LP_AON_CLKRST::regs() .lp_aonclkrst_lp_clk_conf() .modify(|_, w| unsafe { @@ -193,7 +189,6 @@ fn configure_lp_slow_clk_impl( _old_selector: Option, new_selector: LpSlowClkConfig, ) { - // Ref: esp-idf clk_tree_ll.h -- clk_ll_rtc_slow_set_src() crate::peripherals::LP_AON_CLKRST::regs() .lp_aonclkrst_lp_clk_conf() .modify(|_, w| unsafe { @@ -208,7 +203,6 @@ fn configure_lp_slow_clk_impl( // ============================================================ // Per-instance clock impl for UART (called on UartInstance enum) -// Ref: esp-idf uart_ll.h, hp_sys_clkrst_reg.h // ============================================================ impl UartInstance { @@ -222,9 +216,8 @@ impl UartInstance { _old_config: Option, _new_config: UartFunctionClockConfig, ) { - // TODO(P4X): Configure UART clock source selection + // TODO(esp32p4): Configure UART clock source selection // HP_SYS_CLKRST PERI_CLK_CTRL110-114 for UART0-4 - // Ref: esp-idf clk_tree_ll.h -- clk_ll_uart_set_sclk() } fn enable_baud_rate_generator_impl(self, _clocks: &mut ClockTree, _en: bool) { @@ -243,7 +236,6 @@ impl UartInstance { // ============================================================ // Per-instance clock impl for TIMG -// Ref: esp-idf timer_ll.h // ============================================================ impl TimgInstance { @@ -257,7 +249,7 @@ impl TimgInstance { _old_config: Option, _new_config: TimgFunctionClockConfig, ) { - // TODO(P4X): Configure TIMG clock source + // TODO(esp32p4): Configure TIMG clock source // HP_SYS_CLKRST PERI_CLK_CTRL20/21 } @@ -269,7 +261,7 @@ impl TimgInstance { _old_config: Option, _new_config: TimgWdtClockConfig, ) { - // TODO(P4X): Configure TIMG WDT clock source + // TODO(esp32p4): Configure TIMG WDT clock source } } diff --git a/esp-hal/src/soc/esp32p4/gpio.rs b/esp-hal/src/soc/esp32p4/gpio.rs index 6eb9be309c4..b3773452e87 100644 --- a/esp-hal/src/soc/esp32p4/gpio.rs +++ b/esp-hal/src/soc/esp32p4/gpio.rs @@ -51,8 +51,8 @@ macro_rules! p4_rtc_pin { fn rtcio_pad_hold(&self, enable: bool) { // LP_AON (LP_SYS) doesn't have gpio_hold for P4. // P4 uses LP_IO_MUX pad hold instead. - // Ref: esp-idf rtc_io_ll.h -- rtcio_ll_force_hold_enable() - // For now, no-op. TODO(P4X): implement LP pad hold + // TODO: implement LP pad hold + // For now, no-op. let _ = enable; } diff --git a/esp-hal/src/soc/esp32p4/regi2c.rs b/esp-hal/src/soc/esp32p4/regi2c.rs index 770481bc1e4..d61dabccf90 100644 --- a/esp-hal/src/soc/esp32p4/regi2c.rs +++ b/esp-hal/src/soc/esp32p4/regi2c.rs @@ -8,7 +8,6 @@ //! TRM v0.5 Ch 49 (Analog I2C Controller) // I2C slave addresses for analog blocks -// Ref: esp-idf regi2c_impl.c lines 57-81 #[allow(dead_code)] pub(crate) const REGI2C_DIG_REG: u8 = 0x6d; #[allow(dead_code)] @@ -27,7 +26,6 @@ pub(crate) const REGI2C_PLLA: u8 = 0x6f; pub(crate) const REGI2C_SAR_I2C: u8 = 0x69; // Master select bits in ANA_CONF2 register -// Ref: esp-idf regi2c_impl.c lines 21-28 const REGI2C_DIG_REG_MST_SEL: u16 = 1 << 10; const REGI2C_PLL_CPU_MST_SEL: u16 = 1 << 11; #[allow(dead_code)] @@ -65,7 +63,6 @@ const LP_I2C_ANA_MST_ANA_CONF2_REG: u32 = LP_I2C_ANA_MST_BASE + 0x08; /// Ref: esp-idf regi2c_impl.c:83-117 -- regi2c_enable_block() fn regi2c_enable_block(block: u8) { // Clear both conf registers first - // Ref: esp-idf regi2c_impl.c:86-87 unsafe { (LP_I2C_ANA_MST_ANA_CONF2_REG as *mut u32).write_volatile(0); (LP_I2C_ANA_MST_ANA_CONF1_REG as *mut u32).write_volatile(0); diff --git a/esp-hal/src/spi/master/mod.rs b/esp-hal/src/spi/master/mod.rs index 989a3c90cef..57231cd08b1 100644 --- a/esp-hal/src/spi/master/mod.rs +++ b/esp-hal/src/spi/master/mod.rs @@ -2398,7 +2398,6 @@ impl Driver { if #[cfg(esp32p4)] { // P4 PAC: cmd.update() is write-only (no read method). // Write update bit and wait a short time instead of polling. - // Ref: esp-idf spi_ll.h -- spi_ll_update_conf() let reg_block = self.regs(); reg_block.cmd().modify(|_, w| w.update().set_bit()); // Small delay for SPI register sync diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index d74d2289834..cb613b99716 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -12,9 +12,8 @@ cfg_if::cfg_if! { // Implements the Peripheral enum based on esp-metadata/device.soc/peripheral_clocks // ESP32-P4: manual Peripheral enum with HP_SYS_CLKRST clock gate registers. -// The generated macro produces an empty #[repr(u8)] enum (no clock nodes in metadata). -// This manual definition covers all 43 peripherals with their enable/reset registers. -// Ref: esp-idf clk_gate_ll.h, hp_sys_clkrst_reg.h, TRM v0.5 Ch 12/22. +// The generated macro produces an empty #[repr(u8)] enum (no clock nodes in metadata), +// so this manual definition covers all 43 peripherals with their enable/reset registers. #[cfg(not(esp32p4))] implement_peripheral_clocks!(); @@ -259,9 +258,8 @@ mod _p4_peripheral_clocks { } // -- PWM/Counter -- Peripheral::Ledc => { - // Note: LEDC uses SOC_CLK_CTRL3 in esp-idf, but PAC may differ - // Ref: esp-idf clk_gate_ll.h -- _ledc_ll_enable_bus_clock - // For now just reset control + // TODO(esp32p4): LEDC uses SOC_CLK_CTRL3 in IDF, but PAC may differ. + // Only reset wiring is handled here for now. } Peripheral::Pcnt => { c.soc_clk_ctrl2() @@ -366,8 +364,7 @@ mod _p4_peripheral_clocks { } // -- LCD/Camera -- Peripheral::LcdCam => { - // LCD_CAM uses SOC_CLK_CTRL3 which may not be in PAC - // Ref: esp-idf clk_gate_ll.h -- _lcdcam_ll_enable_bus_clock + // TODO(esp32p4): LCD_CAM uses SOC_CLK_CTRL3 which may not be in PAC. } } } diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index 7e1441afae1..318ca5719d5 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -4137,6 +4137,7 @@ impl Chip { "gpio_driver_supported", "i2c_master_driver_supported", "interrupts_driver_supported", + "psram_driver_supported", "rsa_driver_supported", "sha_driver_supported", "soc_driver_supported", @@ -4183,6 +4184,7 @@ impl Chip { "i2c_master_fifo_size=\"32\"", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", + "psram_extmem_origin=\"1207959552\"", "rsa_size_increment=\"32\"", "rsa_memory_size_bytes=\"384\"", "sha_dma", @@ -4279,6 +4281,7 @@ impl Chip { "cargo:rustc-cfg=gpio_driver_supported", "cargo:rustc-cfg=i2c_master_driver_supported", "cargo:rustc-cfg=interrupts_driver_supported", + "cargo:rustc-cfg=psram_driver_supported", "cargo:rustc-cfg=rsa_driver_supported", "cargo:rustc-cfg=sha_driver_supported", "cargo:rustc-cfg=soc_driver_supported", @@ -4325,6 +4328,7 @@ impl Chip { "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", + "cargo:rustc-cfg=psram_extmem_origin=\"1207959552\"", "cargo:rustc-cfg=rsa_size_increment=\"32\"", "cargo:rustc-cfg=rsa_memory_size_bytes=\"384\"", "cargo:rustc-cfg=sha_dma", @@ -6447,7 +6451,7 @@ pub fn emit_check_cfg_directives() { ); println!( "cargo:rustc-check-cfg=cfg(psram_extmem_origin, \ - values(\"1065353216\",\"1107296256\",\"1062207488\",\"1006632960\"))" + values(\"1065353216\",\"1107296256\",\"1207959552\",\"1062207488\",\"1006632960\"))" ); println!( "cargo:rustc-check-cfg=cfg(rmt_ram_start, \ diff --git a/esp-metadata-generated/src/_generated_esp32p4.rs b/esp-metadata-generated/src/_generated_esp32p4.rs index 0567ac06575..60de5c455bf 100644 --- a/esp-metadata-generated/src/_generated_esp32p4.rs +++ b/esp-metadata-generated/src/_generated_esp32p4.rs @@ -70,6 +70,9 @@ macro_rules! property { ("dma.can_access_psram") => { false }; + ("dma.ext_mem_configurable_block_size") => { + false + }; ("dma.separate_in_out_interrupts") => { true }; @@ -199,6 +202,9 @@ macro_rules! property { ("interrupts.disabled_interrupt") => { 0 }; + ("psram.octal_spi") => { + false + }; ("psram.extmem_origin") => { 1207959552 }; @@ -3083,8 +3089,8 @@ macro_rules! for_each_analog_function { _for_each_inner_analog_function!((ADC1_CH5, GPIO21)); _for_each_inner_analog_function!((ADC1_CH6, GPIO22)); _for_each_inner_analog_function!((ADC1_CH7, GPIO23)); - _for_each_inner_analog_function!((USB_PHY0_DM, GPIO24)); - _for_each_inner_analog_function!((USB_PHY0_DP, GPIO25)); + _for_each_inner_analog_function!((USB_DM, GPIO24)); + _for_each_inner_analog_function!((USB_DP, GPIO25)); _for_each_inner_analog_function!((USB_PHY1_DM, GPIO26)); _for_each_inner_analog_function!((USB_PHY1_DP, GPIO27)); _for_each_inner_analog_function!((ADC2_CH0, GPIO49)); @@ -3101,8 +3107,6 @@ macro_rules! for_each_analog_function { _for_each_inner_analog_function!(((ADC1_CH5, ADCn_CHm, 1, 5), GPIO21)); _for_each_inner_analog_function!(((ADC1_CH6, ADCn_CHm, 1, 6), GPIO22)); _for_each_inner_analog_function!(((ADC1_CH7, ADCn_CHm, 1, 7), GPIO23)); - _for_each_inner_analog_function!(((USB_PHY0_DM, USB_PHYn_DM, 0), GPIO24)); - _for_each_inner_analog_function!(((USB_PHY0_DP, USB_PHYn_DP, 0), GPIO25)); _for_each_inner_analog_function!(((USB_PHY1_DM, USB_PHYn_DM, 1), GPIO26)); _for_each_inner_analog_function!(((USB_PHY1_DP, USB_PHYn_DP, 1), GPIO27)); _for_each_inner_analog_function!(((ADC2_CH0, ADCn_CHm, 2, 0), GPIO49)); @@ -3113,19 +3117,18 @@ macro_rules! for_each_analog_function { _for_each_inner_analog_function!(((ADC2_CH5, ADCn_CHm, 2, 5), GPIO54)); _for_each_inner_analog_function!((all(ADC1_CH0, GPIO16), (ADC1_CH1, GPIO17), (ADC1_CH2, GPIO18), (ADC1_CH3, GPIO19), (ADC1_CH4, GPIO20), (ADC1_CH5, GPIO21), - (ADC1_CH6, GPIO22), (ADC1_CH7, GPIO23), (USB_PHY0_DM, GPIO24), (USB_PHY0_DP, - GPIO25), (USB_PHY1_DM, GPIO26), (USB_PHY1_DP, GPIO27), (ADC2_CH0, GPIO49), - (ADC2_CH1, GPIO50), (ADC2_CH2, GPIO51), (ADC2_CH3, GPIO52), (ADC2_CH4, GPIO53), - (ADC2_CH5, GPIO54))); _for_each_inner_analog_function!((all_expanded((ADC1_CH0, - ADCn_CHm, 1, 0), GPIO16), ((ADC1_CH1, ADCn_CHm, 1, 1), GPIO17), ((ADC1_CH2, - ADCn_CHm, 1, 2), GPIO18), ((ADC1_CH3, ADCn_CHm, 1, 3), GPIO19), ((ADC1_CH4, - ADCn_CHm, 1, 4), GPIO20), ((ADC1_CH5, ADCn_CHm, 1, 5), GPIO21), ((ADC1_CH6, - ADCn_CHm, 1, 6), GPIO22), ((ADC1_CH7, ADCn_CHm, 1, 7), GPIO23), ((USB_PHY0_DM, - USB_PHYn_DM, 0), GPIO24), ((USB_PHY0_DP, USB_PHYn_DP, 0), GPIO25), ((USB_PHY1_DM, - USB_PHYn_DM, 1), GPIO26), ((USB_PHY1_DP, USB_PHYn_DP, 1), GPIO27), ((ADC2_CH0, - ADCn_CHm, 2, 0), GPIO49), ((ADC2_CH1, ADCn_CHm, 2, 1), GPIO50), ((ADC2_CH2, - ADCn_CHm, 2, 2), GPIO51), ((ADC2_CH3, ADCn_CHm, 2, 3), GPIO52), ((ADC2_CH4, - ADCn_CHm, 2, 4), GPIO53), ((ADC2_CH5, ADCn_CHm, 2, 5), GPIO54))); + (ADC1_CH6, GPIO22), (ADC1_CH7, GPIO23), (USB_DM, GPIO24), (USB_DP, GPIO25), + (USB_PHY1_DM, GPIO26), (USB_PHY1_DP, GPIO27), (ADC2_CH0, GPIO49), (ADC2_CH1, + GPIO50), (ADC2_CH2, GPIO51), (ADC2_CH3, GPIO52), (ADC2_CH4, GPIO53), (ADC2_CH5, + GPIO54))); _for_each_inner_analog_function!((all_expanded((ADC1_CH0, ADCn_CHm, 1, + 0), GPIO16), ((ADC1_CH1, ADCn_CHm, 1, 1), GPIO17), ((ADC1_CH2, ADCn_CHm, 1, 2), + GPIO18), ((ADC1_CH3, ADCn_CHm, 1, 3), GPIO19), ((ADC1_CH4, ADCn_CHm, 1, 4), + GPIO20), ((ADC1_CH5, ADCn_CHm, 1, 5), GPIO21), ((ADC1_CH6, ADCn_CHm, 1, 6), + GPIO22), ((ADC1_CH7, ADCn_CHm, 1, 7), GPIO23), ((USB_PHY1_DM, USB_PHYn_DM, 1), + GPIO26), ((USB_PHY1_DP, USB_PHYn_DP, 1), GPIO27), ((ADC2_CH0, ADCn_CHm, 2, 0), + GPIO49), ((ADC2_CH1, ADCn_CHm, 2, 1), GPIO50), ((ADC2_CH2, ADCn_CHm, 2, 2), + GPIO51), ((ADC2_CH3, ADCn_CHm, 2, 3), GPIO52), ((ADC2_CH4, ADCn_CHm, 2, 4), + GPIO53), ((ADC2_CH5, ADCn_CHm, 2, 5), GPIO54))); }; } /// This macro can be used to generate code for each LP/RTC function of each GPIO. diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index 88210aaf565..d263c50f0a2 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -26,8 +26,8 @@ software_interrupt_count = 4 software_interrupt_delay = 24 controller = { Riscv = { flavour = "clic", interrupts = 48, priority_levels = 8 } } -# TODO: Tyding new TRM after 0.5 document -# Currently following section is not fully written. +# TODO: align with newer TRM revisions after v0.5. The v0.5 TRM still has +# the following sections incomplete: # - Bus Architecture # - Processor Instruction Extensions # - AXI Performance Monitor @@ -136,6 +136,10 @@ peripherals = [ { name = "INTERRUPT_CORE1" }, { name = "CLIC" }, { name = "IO_MUX" }, + # LP_AON / LPWR: compatibility aliases -- other chips expose an `LP_AON` + # (and the `LPWR` alias) register block; on P4 the same registers live in + # `LP_SYS` in the PAC, so we point the esp-hal `LP_AON` / `LPWR` singletons + # at the `LP_SYS` PAC type. { name = "LP_AON", pac = "LP_SYS" }, { name = "LP_AON_CLKRST" }, { name = "LP_SYS" }, @@ -150,9 +154,11 @@ peripherals = [ { name = "UART2", interrupts = { peri = "UART2" }, clock_group = "UART" }, { name = "UART3", interrupts = { peri = "UART3" }, clock_group = "UART" }, { name = "UART4", interrupts = { peri = "UART4" }, clock_group = "UART" }, - # Map to SPI2 RegisterBlock for esp-hal driver compatibility. { name = "SPI2", interrupts = { peri = "SPI2" }, dma_peripheral = 1 }, - # SPI3: same RegisterBlock layout as SPI2 but different PAC type. + # SPI3 has the same RegisterBlock layout as SPI2 but the PAC exposes it as + # a distinct type. Map to SPI2 so the SPI master driver can reuse its + # register accessors directly. Verified field-compatible against the + # upstream esp32p4 PAC at the time of this port. { name = "SPI3", pac = "SPI2", interrupts = { peri = "SPI3" }, dma_peripheral = 2 }, { name = "I2C0", interrupts = { peri = "I2C0" } }, { name = "I2C1", interrupts = { peri = "I2C1" } }, @@ -169,8 +175,9 @@ peripherals = [ { name = "USB_DEVICE", interrupts = { peri = "USB_DEVICE" } }, { name = "SDHOST" }, - # TODO: clear about EMAC and PAC relationship - # But ESP-IDF have: components/esp_hal_emac/esp32p4/include/hal/emac_ll.h + # TODO: clarify EMAC <-> PAC mapping before exposing it. + # IDF has the LL header at components/esp_hal_emac/esp32p4/include/hal/emac_ll.h + # but the esp32p4 PAC has not been generated with a matching peripheral yet. # { name = "EMAC" }, { name = "LEDC", interrupts = { peri = "LEDC" } }, { name = "MCPWM0", interrupts = { peri = "PWM0" } }, @@ -769,8 +776,15 @@ pins = [ { pin = 21, analog = { 1 = "ADC1_CH5", lp = { 0 = "LP_GPIO21" } } }, { pin = 22, functions = { 4 = "DBG_PSRAM_CK", lp = { 0 = "LP_GPIO22" } }, analog = { 1 = "ADC1_CH6" } }, { pin = 23, functions = { 3 = "REF_50M_CLK", 4 = "DBG_PSRAM_CS", lp = { 0 = "LP_GPIO23" } }, analog = { 1 = "ADC1_CH7" } }, - { pin = 24, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY0_DM" } }, - { pin = 25, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY0_DP" } }, + # Pins 24/25 are the default USB-Serial/JTAG pair (PHY0). Use the canonical + # `USB_DM`/`USB_DP` names so `disable_usb_pads!` (see esp-hal gpio/mod.rs) + # and the `UsbJtag` pin-limitation auto-derive pick them up like on every + # other chip. `usb_jtag` limitation is set automatically via the names. + { pin = 24, analog = { 0 = "USB_DM" } }, + { pin = 25, analog = { 0 = "USB_DP" } }, + # Pins 26/27 are the USB OTG FS (PHY1) pair. Kept under the PHY1 names + # until the P4 OTG FS driver lands -- at that point consider whether to + # rename to USB_DM/USB_DP so the same helpers fire here too. { pin = 26, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY1_DM" } }, { pin = 27, limitations = ["usb_jtag"], analog = { 0 = "USB_PHY1_DP" } }, { pin = 28, functions = { 2 = "SPI2_CS", 3 = "EMAC_PHY_RXDV", 4 = "DBG_PSRAM_D" } }, From b0b003d5ffa305f1d96121a407cf1d04db1a42c8 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Wed, 29 Apr 2026 14:08:33 +0900 Subject: [PATCH 11/27] Addressing comment about crc and md5 rom --- esp-bootloader-esp-idf/src/lib.rs | 13 ++++--------- .../src/_build_script_utils.rs | 10 ++++++++++ esp-metadata/devices/esp32p4.toml | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/esp-bootloader-esp-idf/src/lib.rs b/esp-bootloader-esp-idf/src/lib.rs index ade87236be3..bf426e5183a 100644 --- a/esp-bootloader-esp-idf/src/lib.rs +++ b/esp-bootloader-esp-idf/src/lib.rs @@ -101,21 +101,16 @@ // MUST be the first module mod fmt; -// P4 ROM does not have md5/crc functions (rom_crc_le/rom_md5_bsd flags not set). -// Use software crypto for P4, ROM crypto for other chips. -// Ref: esp-rom-sys rom/mod.rs -- pub mod crc gated on rom_crc_le -// P4 ROM does not have md5/crc functions (rom_crc_le/rom_md5_bsd flags not set). -// Use software crypto (non_rom module) for P4 and std builds. -#[cfg(all(not(feature = "std"), not(feature = "esp32p4")))] +#[cfg(not(feature = "std"))] mod rom; -#[cfg(all(not(feature = "std"), not(feature = "esp32p4")))] +#[cfg(not(feature = "std"))] pub(crate) use rom as crypto; -#[cfg(any(feature = "std", feature = "esp32p4"))] +#[cfg(feature = "std")] mod non_rom; #[cfg(embedded_test)] pub use crypto::Crc32 as Crc32ForTesting; -#[cfg(any(feature = "std", feature = "esp32p4"))] +#[cfg(feature = "std")] pub(crate) use non_rom as crypto; pub mod partitions; diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index 37d01b70d14..fcfaf26e922 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -4176,6 +4176,11 @@ impl Chip { "soc_has_ecc", "very_large_intr_status", "spi_octal", + "rom_crc_le", + "rom_crc_be", + "rom_md5_bsd", + "pm_support_ext1_wakeup", + "pm_support_touch_sensor_wakeup", "adc_driver_supported", "aes_driver_supported", "dma_driver_supported", @@ -4320,6 +4325,11 @@ impl Chip { "cargo:rustc-cfg=soc_has_ecc", "cargo:rustc-cfg=very_large_intr_status", "cargo:rustc-cfg=spi_octal", + "cargo:rustc-cfg=rom_crc_le", + "cargo:rustc-cfg=rom_crc_be", + "cargo:rustc-cfg=rom_md5_bsd", + "cargo:rustc-cfg=pm_support_ext1_wakeup", + "cargo:rustc-cfg=pm_support_touch_sensor_wakeup", "cargo:rustc-cfg=adc_driver_supported", "cargo:rustc-cfg=aes_driver_supported", "cargo:rustc-cfg=dma_driver_supported", diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index d263c50f0a2..5535c836d16 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -13,8 +13,24 @@ cores = 2 trm = "https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf" symbols = [ + # Additional peripherals defined by us (the developers): "very_large_intr_status", "spi_octal", + + # ROM capabilities + "rom_crc_le", + "rom_crc_be", + "rom_md5_bsd", + + # Wakeup SOC based on ESP-IDF: + "pm_support_ext1_wakeup", + "pm_support_touch_sensor_wakeup", + + # TODO: add the following symbols when investigation and getting ready + # - "lp_core" + # - "swd" + # - "gpio_support_deepsleep_wakeup" + # - "uart_support_wakeup_int" ] [device.interrupts] From 87acd4af0f829b5528831d2c403cdc616779db54 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Thu, 30 Apr 2026 08:06:04 +0900 Subject: [PATCH 12/27] Tyding esp32p4 rom ld for eco5 and idf 6.0.1 --- esp-rom-sys/ld/esp32p4/rom-functions.x | 3 - .../ld/esp32p4/rom/esp32p4.rom.eco5.ld | 592 ------------------ .../ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld | 95 --- .../ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld | 101 --- esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld | 497 +++++++-------- .../ld/esp32p4/rom/esp32p4.rom.libgcc.ld | 156 ++--- .../ld/esp32p4/rom/esp32p4.rom.rvfp.ld | 171 +++-- 7 files changed, 408 insertions(+), 1207 deletions(-) delete mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld delete mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld delete mode 100644 esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld diff --git a/esp-rom-sys/ld/esp32p4/rom-functions.x b/esp-rom-sys/ld/esp32p4/rom-functions.x index 55c3da4d6b4..02a91bc7deb 100644 --- a/esp-rom-sys/ld/esp32p4/rom-functions.x +++ b/esp-rom-sys/ld/esp32p4/rom-functions.x @@ -1,7 +1,4 @@ INCLUDE "rom/esp32p4.rom.api.ld" -INCLUDE "rom/esp32p4.rom.eco5.ld" -INCLUDE "rom/esp32p4.rom.eco5.libgcc.ld" -INCLUDE "rom/esp32p4.rom.eco5.rvfp.ld" INCLUDE "rom/esp32p4.rom.ld" INCLUDE "rom/esp32p4.rom.libgcc.ld" INCLUDE "rom/esp32p4.rom.rvfp.ld" diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld deleted file mode 100644 index 0df2f533eb2..00000000000 --- a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.ld +++ /dev/null @@ -1,592 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -/* ROM function interface esp32p4.rom.ld for esp32p4 - * - * - * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 - * - * Compatible with ROM where ECO version equal or greater to 5. - * - * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. - */ - -/*************************************** - Group common - ***************************************/ - -/* Functions */ -rtc_get_reset_reason = 0x4fc00018; -rtc_get_wakeup_cause = 0x4fc0001c; -pmu_enable_unhold_pads = 0x4fc00020; -ets_printf = 0x4fc00024; -ets_install_putc1 = 0x4fc00028; -ets_install_putc2 = 0x4fc0002c; -ets_install_uart_printf = 0x4fc00030; -ets_install_usb_printf = 0x4fc00034; -ets_get_printf_channel = 0x4fc00038; -ets_delay_us = 0x4fc0003c; -ets_get_cpu_frequency = 0x4fc00040; -ets_update_cpu_frequency = 0x4fc00044; -ets_install_lock = 0x4fc00048; -UartRxString = 0x4fc0004c; -UartGetCmdLn = 0x4fc00050; -uart_tx_one_char = 0x4fc00054; -uart_tx_one_char2 = 0x4fc00058; -uart_tx_one_char3 = 0x4fc0005c; -uart_rx_one_char = 0x4fc00060; -uart_rx_one_char_block = 0x4fc00064; -uart_rx_intr_handler = 0x4fc00068; -uart_rx_readbuff = 0x4fc0006c; -uartAttach = 0x4fc00070; -uart_tx_flush = 0x4fc00074; -uart_tx_wait_idle = 0x4fc00078; -uart_div_modify = 0x4fc0007c; -ets_write_char_uart = 0x4fc00080; -uart_tx_switch = 0x4fc00084; -uart_buff_switch = 0x4fc00088; -roundup2 = 0x4fc0008c; -multofup = 0x4fc00090; -software_reset = 0x4fc00094; -software_reset_cpu = 0x4fc00098; -ets_clk_assist_debug_clock_enable = 0x4fc0009c; -clear_super_wdt_reset_flag = 0x4fc000a0; -disable_default_watchdog = 0x4fc000a4; -ets_set_appcpu_boot_addr = 0x4fc000a8; -send_packet = 0x4fc000ac; -recv_packet = 0x4fc000b0; -GetUartDevice = 0x4fc000b4; -UartDwnLdProc = 0x4fc000b8; -GetSecurityInfoProc = 0x4fc000bc; -Uart_Init = 0x4fc000c0; -ets_set_user_start = 0x4fc000c4; -/* Data (.data, .bss, .rodata) */ -ets_rom_layout_p = 0x4fc1fffc; -ets_ops_table_ptr = 0x4ffbfff4; -g_saved_pc = 0x4ffbfff8; - - -/*************************************** - Group miniz - ***************************************/ - -/* Functions */ -mz_adler32 = 0x4fc000c8; -mz_free = 0x4fc000cc; -tdefl_compress = 0x4fc000d0; -tdefl_compress_buffer = 0x4fc000d4; -tdefl_compress_mem_to_heap = 0x4fc000d8; -tdefl_compress_mem_to_mem = 0x4fc000dc; -tdefl_compress_mem_to_output = 0x4fc000e0; -tdefl_get_adler32 = 0x4fc000e4; -tdefl_get_prev_return_status = 0x4fc000e8; -tdefl_init = 0x4fc000ec; -tdefl_write_image_to_png_file_in_memory = 0x4fc000f0; -tdefl_write_image_to_png_file_in_memory_ex = 0x4fc000f4; -tinfl_decompress = 0x4fc000f8; -tinfl_decompress_mem_to_callback = 0x4fc000fc; -tinfl_decompress_mem_to_heap = 0x4fc00100; -tinfl_decompress_mem_to_mem = 0x4fc00104; - - -/*************************************** - Group spi_extmem_common - ***************************************/ - -/* Functions */ -esp_rom_spi_cmd_config = 0x4fc00108; -esp_rom_spi_cmd_start = 0x4fc0010c; -esp_rom_spi_set_op_mode = 0x4fc00110; -esp_rom_spi_set_dtr_swap_mode = 0x4fc00114; - - -/*************************************** - Group spiflash_legacy - ***************************************/ - -/* Functions */ -esp_rom_spiflash_wait_idle = 0x4fc00118; -esp_rom_spiflash_write_encrypted = 0x4fc0011c; -esp_rom_spiflash_write_encrypted_dest = 0x4fc00120; -esp_rom_spiflash_write_encrypted_enable = 0x4fc00124; -esp_rom_spiflash_write_encrypted_disable = 0x4fc00128; -esp_rom_spiflash_erase_chip = 0x4fc0012c; -_esp_rom_spiflash_erase_sector = 0x4fc00130; -_esp_rom_spiflash_erase_block = 0x4fc00134; -_esp_rom_spiflash_write = 0x4fc00138; -_esp_rom_spiflash_read = 0x4fc0013c; -_esp_rom_spiflash_unlock = 0x4fc00140; -_SPIEraseArea = 0x4fc00144; -_SPI_write_enable = 0x4fc00148; -esp_rom_spiflash_erase_sector = 0x4fc0014c; -esp_rom_spiflash_erase_block = 0x4fc00150; -esp_rom_spiflash_write = 0x4fc00154; -esp_rom_spiflash_read = 0x4fc00158; -esp_rom_spiflash_unlock = 0x4fc0015c; -SPIEraseArea = 0x4fc00160; -SPI_write_enable = 0x4fc00164; -esp_rom_spiflash_config_param = 0x4fc00168; -esp_rom_spiflash_read_user_cmd = 0x4fc0016c; -esp_rom_spiflash_select_qio_pins = 0x4fc00170; -esp_rom_spi_flash_auto_sus_res = 0x4fc00174; -esp_rom_spi_flash_send_resume = 0x4fc00178; -esp_rom_spi_flash_update_id = 0x4fc0017c; -esp_rom_spiflash_config_clk = 0x4fc00180; -esp_rom_spiflash_config_readmode = 0x4fc00184; -esp_rom_spiflash_read_status = 0x4fc00188; -esp_rom_spiflash_read_statushigh = 0x4fc0018c; -esp_rom_spiflash_write_status = 0x4fc00190; -esp_rom_spiflash_write_disable = 0x4fc00194; -spi_cache_mode_switch = 0x4fc00198; -spi_common_set_dummy_output = 0x4fc0019c; -spi_common_set_flash_cs_timing = 0x4fc001a0; -esp_rom_spi_set_address_bit_len = 0x4fc001a4; -SPILock = 0x4fc001a8; -SPIMasterReadModeCnfig = 0x4fc001ac; -SPI_Common_Command = 0x4fc001b0; -SPI_WakeUp = 0x4fc001b4; -SPI_block_erase = 0x4fc001b8; -SPI_chip_erase = 0x4fc001bc; -SPI_init = 0x4fc001c0; -SPI_page_program = 0x4fc001c4; -SPI_read_data = 0x4fc001c8; -SPI_sector_erase = 0x4fc001cc; -SelectSpiFunction = 0x4fc001d0; -SetSpiDrvs = 0x4fc001d4; -Wait_SPI_Idle = 0x4fc001d8; -spi_dummy_len_fix = 0x4fc001dc; -Disable_QMode = 0x4fc001e0; -Enable_QMode = 0x4fc001e4; -spi_flash_attach = 0x4fc001e8; -spi_flash_get_chip_size = 0x4fc001ec; -spi_flash_guard_set = 0x4fc001f0; -spi_flash_guard_get = 0x4fc001f4; -spi_flash_read_encrypted = 0x4fc001f8; -/* Data (.data, .bss, .rodata) */ -rom_spiflash_legacy_funcs = 0x4ffbffec; -rom_spiflash_legacy_data = 0x4ffbffe8; -g_flash_guard_ops = 0x4ffbfff0; - - -/*************************************** - Group cache - ***************************************/ - -/* Functions */ -Cache_Get_L1_ICache_Line_Size = 0x4fc003c4; -Cache_Get_L1_DCache_Line_Size = 0x4fc003c8; -Cache_Get_L2_Cache_Line_Size = 0x4fc003cc; -Cache_Get_Mode = 0x4fc003d0; -Cache_Set_L2_Cache_Mode = 0x4fc003d4; -Cache_Address_Through_Cache = 0x4fc003d8; -ROM_Boot_Cache_Init = 0x4fc003dc; -Cache_Sync_Addr = 0x4fc003e0; -Cache_Invalidate_Addr = 0x4fc003e4; -Cache_Invalidate_Addr_Gid = 0x4fc003e8; -Cache_Clean_Addr = 0x4fc003ec; -Cache_Clean_Addr_Gid = 0x4fc003f0; -Cache_WriteBack_Addr = 0x4fc003f4; -Cache_WriteBack_Addr_Gid = 0x4fc003f8; -Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; -Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; -Cache_Invalidate_All = 0x4fc00404; -Cache_Invalidate_All_Gid = 0x4fc00408; -Cache_Clean_All = 0x4fc0040c; -Cache_Clean_All_Gid = 0x4fc00410; -Cache_WriteBack_All = 0x4fc00414; -Cache_WriteBack_All_Gid = 0x4fc00418; -Cache_WriteBack_Invalidate_All = 0x4fc0041c; -Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; -Cache_Mask_All = 0x4fc00424; -Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; -Cache_Resume_L1_CORE0_ICache_Autoload = 0x4fc0042c; -Cache_Suspend_L1_CORE1_ICache_Autoload = 0x4fc00430; -Cache_Resume_L1_CORE1_ICache_Autoload = 0x4fc00434; -Cache_Suspend_L1_DCache_Autoload = 0x4fc00438; -Cache_Resume_L1_DCache_Autoload = 0x4fc0043c; -Cache_Suspend_L2_Cache_Autoload = 0x4fc00440; -Cache_Resume_L2_Cache_Autoload = 0x4fc00444; -Cache_Start_L1_CORE0_ICache_Preload = 0x4fc00448; -Cache_L1_CORE0_ICache_Preload_Done = 0x4fc0044c; -Cache_End_L1_CORE0_ICache_Preload = 0x4fc00450; -Cache_Start_L1_CORE1_ICache_Preload = 0x4fc00454; -Cache_L1_CORE1_ICache_Preload_Done = 0x4fc00458; -Cache_End_L1_CORE1_ICache_Preload = 0x4fc0045c; -Cache_Start_L1_DCache_Preload = 0x4fc00460; -Cache_L1_DCache_Preload_Done = 0x4fc00464; -Cache_End_L1_DCache_Preload = 0x4fc00468; -Cache_Start_L2_Cache_Preload = 0x4fc0046c; -Cache_L2_Cache_Preload_Done = 0x4fc00470; -Cache_End_L2_Cache_Preload = 0x4fc00474; -Cache_Config_L1_CORE0_ICache_Autoload = 0x4fc00478; -Cache_Enable_L1_CORE0_ICache_Autoload = 0x4fc0047c; -Cache_Disable_L1_CORE0_ICache_Autoload = 0x4fc00480; -Cache_Config_L1_CORE1_ICache_Autoload = 0x4fc00484; -Cache_Enable_L1_CORE1_ICache_Autoload = 0x4fc00488; -Cache_Disable_L1_CORE1_ICache_Autoload = 0x4fc0048c; -Cache_Config_L1_DCache_Autoload = 0x4fc00490; -Cache_Enable_L1_DCache_Autoload = 0x4fc00494; -Cache_Disable_L1_DCache_Autoload = 0x4fc00498; -Cache_Config_L2_Cache_Autoload = 0x4fc0049c; -Cache_Enable_L2_Cache_Autoload = 0x4fc004a0; -Cache_Disable_L2_Cache_Autoload = 0x4fc004a4; -Cache_Enable_L1_CORE0_ICache_PreLock = 0x4fc004a8; -Cache_Disable_L1_CORE0_ICache_PreLock = 0x4fc004ac; -Cache_Enable_L1_CORE1_ICache_PreLock = 0x4fc004b0; -Cache_Disable_L1_CORE1_ICache_PreLock = 0x4fc004b4; -Cache_Enable_L1_DCache_PreLock = 0x4fc004b8; -Cache_Disable_L1_DCache_PreLock = 0x4fc004bc; -Cache_Enable_L2_Cache_PreLock = 0x4fc004c0; -Cache_Disable_L2_Cache_PreLock = 0x4fc004c4; -Cache_Lock_Addr = 0x4fc004c8; -Cache_Unlock_Addr = 0x4fc004cc; -Cache_Disable_L1_CORE0_ICache = 0x4fc004d0; -Cache_Enable_L1_CORE0_ICache = 0x4fc004d4; -Cache_Suspend_L1_CORE0_ICache = 0x4fc004d8; -Cache_Resume_L1_CORE0_ICache = 0x4fc004dc; -Cache_Disable_L1_CORE1_ICache = 0x4fc004e0; -Cache_Enable_L1_CORE1_ICache = 0x4fc004e4; -Cache_Suspend_L1_CORE1_ICache = 0x4fc004e8; -Cache_Resume_L1_CORE1_ICache = 0x4fc004ec; -Cache_Disable_L1_DCache = 0x4fc004f0; -Cache_Enable_L1_DCache = 0x4fc004f4; -Cache_Suspend_L1_DCache = 0x4fc004f8; -Cache_Resume_L1_DCache = 0x4fc004fc; -Cache_Disable_L2_Cache = 0x4fc00500; -Cache_Enable_L2_Cache = 0x4fc00504; -Cache_Suspend_L2_Cache = 0x4fc00508; -Cache_Resume_L2_Cache = 0x4fc0050c; -Cache_FLASH_MMU_Init = 0x4fc00510; -Cache_PSRAM_MMU_Init = 0x4fc00514; -Cache_FLASH_MMU_Set = 0x4fc00518; -Cache_FLASH_MMU_Set_Secure = 0x4fc0051c; -Cache_PSRAM_MMU_Set = 0x4fc00520; -Cache_PSRAM_MMU_Set_Secure = 0x4fc00524; -Cache_Count_Flash_Pages = 0x4fc00528; -Cache_Flash_To_SPIRAM_Copy = 0x4fc0052c; -Cache_Set_IDROM_MMU_Size = 0x4fc00530; -flash2spiram_instruction_offset = 0x4fc00534; -flash2spiram_rodata_offset = 0x4fc00538; -flash_instr_rodata_start_page = 0x4fc0053c; -flash_instr_rodata_end_page = 0x4fc00540; -Cache_Set_IDROM_MMU_Info = 0x4fc00544; -Cache_Get_IROM_MMU_End = 0x4fc00548; -Cache_Get_DROM_MMU_End = 0x4fc0054c; -/* Data (.data, .bss, .rodata) */ -rom_cache_op_cb = 0x4ffbffdc; -rom_cache_internal_table_ptr = 0x4ffbffd8; - - -/*************************************** - Group clock - ***************************************/ - -/* Functions */ -ets_clk_get_xtal_freq = 0x4fc00550; -ets_clk_get_cpu_freq = 0x4fc00554; - - -/*************************************** - Group gpio - ***************************************/ - -/* Functions */ -gpio_set_output_level = 0x4fc00558; -gpio_get_input_level = 0x4fc0055c; -gpio_matrix_in = 0x4fc00560; -gpio_matrix_out = 0x4fc00564; -gpio_bypass_matrix_in = 0x4fc00568; -/* gpio_output_disable = 0x4fc0056c; */ -/* gpio_output_enable = 0x4fc00570; */ -gpio_pad_input_disable = 0x4fc00574; -gpio_pad_input_enable = 0x4fc00578; -gpio_pad_pulldown = 0x4fc0057c; -gpio_pad_pullup = 0x4fc00580; -gpio_pad_select_gpio = 0x4fc00584; -gpio_pad_set_drv = 0x4fc00588; -gpio_pad_unhold = 0x4fc0058c; -gpio_pad_hold = 0x4fc00590; -gpio_lppad_select_mux = 0x4fc00594; -gpio_ded_pad_set_drv = 0x4fc00598; -gpio_ded_pad_pullup = 0x4fc0059c; -gpio_ded_pad_pulldown = 0x4fc005a0; -gpio_ded_pad_hold = 0x4fc005a4; -gpio_ded_pad_unhold = 0x4fc005a8; - - -/*************************************** - Group interrupts - ***************************************/ - -/* Functions */ -esprv_intc_int_set_priority = 0x4fc005ac; -esprv_intc_int_set_threshold = 0x4fc005b0; -esprv_intc_int_enable = 0x4fc005b4; -esprv_intc_int_disable = 0x4fc005b8; -esprv_intc_int_set_type = 0x4fc005bc; -PROVIDE( intr_handler_set = 0x4fc005c0 ); -intr_matrix_set = 0x4fc005c4; -ets_intr_lock = 0x4fc005c8; -ets_intr_unlock = 0x4fc005cc; -ets_isr_attach = 0x4fc005d0; -ets_isr_mask = 0x4fc005d4; -ets_isr_unmask = 0x4fc005d8; - - -/*************************************** - Group crypto - ***************************************/ - -/* Functions */ -md5_vector = 0x4fc005dc; -MD5Init = 0x4fc005e0; -MD5Update = 0x4fc005e4; -MD5Final = 0x4fc005e8; -crc32_le = 0x4fc005ec; -crc16_le = 0x4fc005f0; -crc8_le = 0x4fc005f4; -crc32_be = 0x4fc005f8; -crc16_be = 0x4fc005fc; -crc8_be = 0x4fc00600; -esp_crc8 = 0x4fc00604; -ets_sha_enable = 0x4fc00608; -ets_sha_disable = 0x4fc0060c; -ets_sha_get_state = 0x4fc00610; -ets_sha_init = 0x4fc00614; -ets_sha_process = 0x4fc00618; -ets_sha_starts = 0x4fc0061c; -ets_sha_update = 0x4fc00620; -ets_sha_finish = 0x4fc00624; -ets_sha_clone = 0x4fc00628; -ets_hmac_enable = 0x4fc0062c; -ets_hmac_disable = 0x4fc00630; -ets_hmac_calculate_message = 0x4fc00634; -ets_hmac_calculate_downstream = 0x4fc00638; -ets_hmac_invalidate_downstream = 0x4fc0063c; -ets_jtag_enable_temporarily = 0x4fc00640; -ets_aes_enable = 0x4fc00644; -ets_aes_disable = 0x4fc00648; -ets_aes_setkey = 0x4fc0064c; -ets_aes_block = 0x4fc00650; -ets_aes_setkey_dec = 0x4fc00654; -ets_aes_setkey_enc = 0x4fc00658; -ets_bigint_enable = 0x4fc0065c; -ets_bigint_disable = 0x4fc00660; -ets_bigint_multiply = 0x4fc00664; -ets_bigint_modmult = 0x4fc00668; -ets_bigint_modexp = 0x4fc0066c; -ets_bigint_wait_finish = 0x4fc00670; -ets_bigint_getz = 0x4fc00674; -ets_ds_enable = 0x4fc00678; -ets_ds_disable = 0x4fc0067c; -ets_ds_start_sign = 0x4fc00680; -ets_ds_is_busy = 0x4fc00684; -ets_ds_finish_sign = 0x4fc00688; -ets_ds_encrypt_params = 0x4fc0068c; -ets_mgf1_sha256 = 0x4fc00690; -/* Data (.data, .bss, .rodata) */ -crc32_le_table_ptr = 0x4fc1fff8; -crc16_le_table_ptr = 0x4fc1fff4; -crc8_le_table_ptr = 0x4fc1fff0; -crc32_be_table_ptr = 0x4fc1ffec; -crc16_be_table_ptr = 0x4fc1ffe8; -crc8_be_table_ptr = 0x4fc1ffe4; - - -/*************************************** - Group efuse - ***************************************/ - -/* Functions */ -ets_efuse_read = 0x4fc00694; -ets_efuse_program = 0x4fc00698; -ets_efuse_clear_program_registers = 0x4fc0069c; -ets_efuse_write_key = 0x4fc006a0; -ets_efuse_get_read_register_address = 0x4fc006a4; -ets_efuse_get_key_purpose = 0x4fc006a8; -ets_efuse_key_block_unused = 0x4fc006ac; -ets_efuse_find_unused_key_block = 0x4fc006b0; -ets_efuse_rs_calculate = 0x4fc006b4; -ets_efuse_count_unused_key_blocks = 0x4fc006b8; -ets_efuse_secure_boot_enabled = 0x4fc006bc; -ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4fc006c0; -ets_efuse_cache_encryption_enabled = 0x4fc006c4; -ets_efuse_download_modes_disabled = 0x4fc006c8; -ets_efuse_find_purpose = 0x4fc006cc; -ets_efuse_force_send_resume = 0x4fc006d0; -ets_efuse_get_flash_delay_us = 0x4fc006d4; -ets_efuse_get_uart_print_control = 0x4fc006d8; -ets_efuse_direct_boot_mode_disabled = 0x4fc006dc; -ets_efuse_security_download_modes_enabled = 0x4fc006e0; -ets_efuse_jtag_disabled = 0x4fc006e4; -ets_efuse_usb_print_is_disabled = 0x4fc006e8; -ets_efuse_usb_download_mode_disabled = 0x4fc006ec; -ets_efuse_usb_device_disabled = 0x4fc006f0; -ets_efuse_get_km_huk_gen_state = 0x4fc006f4; -ets_efuse_get_km_deploy_only_once = 0x4fc006f8; -ets_efuse_get_force_use_km_key = 0x4fc006fc; -ets_efuse_xts_key_length_256 = 0x4fc00700; -ets_efuse_get_km_key_lock = 0x4fc00704; - - -/*************************************** - Group key_mgr - ***************************************/ - -/* Functions */ -esp_rom_check_recover_key = 0x4fc00708; -esp_rom_km_huk_conf = 0x4fc0070c; -esp_rom_km_huk_risk = 0x4fc00710; - - -/*************************************** - Group secureboot - ***************************************/ - -/* Functions */ -ets_emsa_pss_verify = 0x4fc00714; -ets_rsa_pss_verify = 0x4fc00718; -ets_ecdsa_verify = 0x4fc0071c; -ets_secure_boot_verify_bootloader_with_keys = 0x4fc00720; -ets_secure_boot_verify_signature = 0x4fc00724; -ets_secure_boot_read_key_digests = 0x4fc00728; -ets_secure_boot_revoke_public_key_digest = 0x4fc0072c; - - -/*************************************** - Group usb_device_uart - ***************************************/ - -/* Functions */ -usb_serial_device_rx_one_char = 0x4fc008a4; -usb_serial_device_rx_one_char_block = 0x4fc008a8; -usb_serial_device_tx_flush = 0x4fc008ac; -usb_serial_device_tx_one_char = 0x4fc008b0; - - -/*************************************** - Group usb_dwcotg_uart - ***************************************/ - -/* Functions */ -Uart_Init_USB = 0x4fc008b4; -usb_serial_otg_rx_one_char = 0x4fc008b8; -usb_serial_otg_rx_one_char_block = 0x4fc008bc; -usb_serial_otg_tx_flush = 0x4fc008c0; -usb_serial_otg_tx_one_char = 0x4fc008c4; -/* Data (.data, .bss, .rodata) */ -uart_acm_dev = 0x4ffbffd4; - - -/*************************************** - Group usb_dwcotg_module - ***************************************/ - -/* Functions */ -cdc_acm_class_handle_req = 0x4fc008c8; -cdc_acm_init = 0x4fc008cc; -cdc_acm_fifo_fill = 0x4fc008d0; -cdc_acm_rx_fifo_cnt = 0x4fc008d4; -cdc_acm_fifo_read = 0x4fc008d8; -cdc_acm_irq_tx_enable = 0x4fc008dc; -cdc_acm_irq_tx_disable = 0x4fc008e0; -cdc_acm_irq_state_enable = 0x4fc008e4; -cdc_acm_irq_state_disable = 0x4fc008e8; -cdc_acm_irq_tx_ready = 0x4fc008ec; -cdc_acm_irq_rx_enable = 0x4fc008f0; -cdc_acm_irq_rx_disable = 0x4fc008f4; -cdc_acm_irq_rx_ready = 0x4fc008f8; -cdc_acm_irq_is_pending = 0x4fc008fc; -cdc_acm_irq_callback_set = 0x4fc00900; -cdc_acm_line_ctrl_set = 0x4fc00904; -cdc_acm_line_ctrl_get = 0x4fc00908; -cdc_acm_poll_out = 0x4fc0090c; -chip_usb_dw_did_persist = 0x4fc00910; -chip_usb_dw_init = 0x4fc00914; -chip_usb_detach = 0x4fc00918; -chip_usb_dw_prepare_persist = 0x4fc0091c; -chip_usb_get_persist_flags = 0x4fc00920; -chip_usb_set_persist_flags = 0x4fc00924; -cpio_start = 0x4fc00928; -cpio_feed = 0x4fc0092c; -cpio_done = 0x4fc00930; -cpio_destroy = 0x4fc00934; -dfu_flash_init = 0x4fc00938; -dfu_flash_erase = 0x4fc0093c; -dfu_flash_program = 0x4fc00940; -dfu_flash_read = 0x4fc00944; -dfu_flash_attach = 0x4fc00948; -dfu_cpio_callback = 0x4fc0094c; -dfu_updater_get_err = 0x4fc00950; -dfu_updater_clear_err = 0x4fc00954; -dfu_updater_enable = 0x4fc00958; -dfu_updater_begin = 0x4fc0095c; -dfu_updater_feed = 0x4fc00960; -dfu_updater_end = 0x4fc00964; -dfu_updater_set_raw_addr = 0x4fc00968; -dfu_updater_flash_read = 0x4fc0096c; -usb_dc_prepare_persist = 0x4fc00970; -usb_dw_isr_handler = 0x4fc00974; -usb_dc_attach = 0x4fc00978; -usb_dc_detach = 0x4fc0097c; -usb_dc_reset = 0x4fc00980; -usb_dc_set_address = 0x4fc00984; -usb_dc_ep_check_cap = 0x4fc00988; -usb_dc_ep_configure = 0x4fc0098c; -usb_dc_ep_set_stall = 0x4fc00990; -usb_dc_ep_clear_stall = 0x4fc00994; -usb_dc_ep_halt = 0x4fc00998; -usb_dc_ep_is_stalled = 0x4fc0099c; -usb_dc_ep_enable = 0x4fc009a0; -usb_dc_ep_disable = 0x4fc009a4; -usb_dc_ep_flush = 0x4fc009a8; -usb_dc_ep_write_would_block = 0x4fc009ac; -usb_dc_ep_write = 0x4fc009b0; -usb_dc_ep_read_wait = 0x4fc009b4; -usb_dc_ep_read_continue = 0x4fc009b8; -usb_dc_ep_read = 0x4fc009bc; -usb_dc_ep_set_callback = 0x4fc009c0; -usb_dc_set_status_callback = 0x4fc009c4; -usb_dc_ep_mps = 0x4fc009c8; -usb_dc_check_poll_for_interrupts = 0x4fc009cc; -mac_addr_to_serial_str_desc = 0x4fc009d0; -usb_set_current_descriptor = 0x4fc009d4; -usb_get_descriptor = 0x4fc009d8; -usb_dev_resume = 0x4fc009dc; -usb_dev_get_configuration = 0x4fc009e0; -usb_set_config = 0x4fc009e4; -usb_deconfig = 0x4fc009e8; -usb_enable = 0x4fc009ec; -usb_disable = 0x4fc009f0; -usb_write_would_block = 0x4fc009f4; -usb_write = 0x4fc009f8; -usb_read = 0x4fc009fc; -usb_ep_set_stall = 0x4fc00a00; -usb_ep_clear_stall = 0x4fc00a04; -usb_ep_read_wait = 0x4fc00a08; -usb_ep_read_continue = 0x4fc00a0c; -usb_transfer_ep_callback = 0x4fc00a10; -usb_transfer = 0x4fc00a14; -usb_cancel_transfer = 0x4fc00a18; -usb_transfer_sync = 0x4fc00a1c; -usb_dfu_set_detach_cb = 0x4fc00a20; -dfu_class_handle_req = 0x4fc00a24; -dfu_status_cb = 0x4fc00a28; -dfu_custom_handle_req = 0x4fc00a2c; -usb_dfu_init = 0x4fc00a30; -usb_dfu_force_detach = 0x4fc00a34; -usb_dev_deinit = 0x4fc00a38; -usb_dw_ctrl_deinit = 0x4fc00a3c; -/* Data (.data, .bss, .rodata) */ -s_usb_osglue = 0x4ffbffc8; - - -/*************************************** - Group recovery_bootloader - ***************************************/ - -/* Functions */ -ets_get_bootloader_offset = 0x4fc00a40; -ets_set_bootloader_offset = 0x4fc00a44; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld deleted file mode 100644 index 7dcac301e9e..00000000000 --- a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.libgcc.ld +++ /dev/null @@ -1,95 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -/* ROM function interface esp32p4.rom.libgcc.ld for esp32p4 - * - * - * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 - * - * Compatible with ROM where ECO version equal or greater to 5. - * - * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. - */ - -/*************************************** - Group libgccdf - ***************************************/ - -/* Functions */ -__absvdi2 = 0x4fc00730; -__absvsi2 = 0x4fc00734; -__adddf3 = 0x4fc00738; -__addvdi3 = 0x4fc0073c; -__addvsi3 = 0x4fc00740; -__ashldi3 = 0x4fc00744; -__ashrdi3 = 0x4fc00748; -__bswapdi2 = 0x4fc0074c; -__bswapsi2 = 0x4fc00750; -__clear_cache = 0x4fc00754; -__clrsbdi2 = 0x4fc00758; -__clrsbsi2 = 0x4fc0075c; -__clzdi2 = 0x4fc00760; -__clzsi2 = 0x4fc00764; -__cmpdi2 = 0x4fc00768; -__ctzdi2 = 0x4fc0076c; -__ctzsi2 = 0x4fc00770; -__divdc3 = 0x4fc00774; -__divdf3 = 0x4fc00778; -__divdi3 = 0x4fc0077c; -__divsc3 = 0x4fc00780; -__divsi3 = 0x4fc00784; -__eqdf2 = 0x4fc00788; -__extendsfdf2 = 0x4fc0078c; -__ffsdi2 = 0x4fc00790; -__ffssi2 = 0x4fc00794; -__fixdfdi = 0x4fc00798; -__fixdfsi = 0x4fc0079c; -__fixsfdi = 0x4fc007a0; -__fixunsdfsi = 0x4fc007a4; -__fixunssfdi = 0x4fc007a8; -__fixunssfsi = 0x4fc007ac; -__floatdidf = 0x4fc007b0; -__floatdisf = 0x4fc007b4; -__floatsidf = 0x4fc007b8; -__floatundidf = 0x4fc007bc; -__floatundisf = 0x4fc007c0; -__floatunsidf = 0x4fc007c4; -__gcc_bcmp = 0x4fc007c8; -__gedf2 = 0x4fc007cc; -__gtdf2 = 0x4fc007d0; -__ledf2 = 0x4fc007d4; -__lshrdi3 = 0x4fc007d8; -__ltdf2 = 0x4fc007dc; -__moddi3 = 0x4fc007e0; -__modsi3 = 0x4fc007e4; -__muldc3 = 0x4fc007e8; -__muldf3 = 0x4fc007ec; -__muldi3 = 0x4fc007f0; -__mulsc3 = 0x4fc007f4; -__mulsi3 = 0x4fc007f8; -__mulvdi3 = 0x4fc007fc; -__mulvsi3 = 0x4fc00800; -__nedf2 = 0x4fc00804; -__negdf2 = 0x4fc00808; -__negdi2 = 0x4fc0080c; -__negvdi2 = 0x4fc00810; -__negvsi2 = 0x4fc00814; -__paritysi2 = 0x4fc00818; -__popcountdi2 = 0x4fc0081c; -__popcountsi2 = 0x4fc00820; -__powidf2 = 0x4fc00824; -__subdf3 = 0x4fc00828; -__subvdi3 = 0x4fc0082c; -__subvsi3 = 0x4fc00830; -__ucmpdi2 = 0x4fc00834; -__udivdi3 = 0x4fc00838; -__udivmoddi4 = 0x4fc0083c; -__udivsi3 = 0x4fc00840; -__udiv_w_sdiv = 0x4fc00844; -__umoddi3 = 0x4fc00848; -__umodsi3 = 0x4fc0084c; -__unorddf2 = 0x4fc00850; -__extenddftf2 = 0x4fc00854; -__trunctfdf2 = 0x4fc00858; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld deleted file mode 100644 index 05749d8a4d5..00000000000 --- a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.eco5.rvfp.ld +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -/* ROM function interface esp32p4.rom.rvfp.ld for esp32p4 - * - * - * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 - * - * Compatible with ROM where ECO version equal or greater to 5. - * - * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. - */ - -/*************************************** - Group rvfplibdf - ***************************************/ - -/* Functions */ -__adddf3 = 0x4fc0085c; -__eqdf2 = 0x4fc00860; -__fixdfdi = 0x4fc00864; -__fixdfsi = 0x4fc00868; -__fixunsdfsi = 0x4fc00870; -__floatdidf = 0x4fc00878; -__floatsidf = 0x4fc0087c; -__floatundidf = 0x4fc00880; -__floatunsidf = 0x4fc00884; -__gedf2 = 0x4fc00888; -__gtdf2 = 0x4fc0088c; -__ledf2 = 0x4fc00890; -__ltdf2 = 0x4fc00894; -__muldf3 = 0x4fc00898; -__nedf2 = 0x4fc0089c; -__subdf3 = 0x4fc008a0; - -/*************************************** - Group libgcc -***************************************/ - -/* Functions */ -__absvdi2 = 0x4fc00730; -__absvsi2 = 0x4fc00734; -__addvdi3 = 0x4fc0073c; -__addvsi3 = 0x4fc00740; -__ashldi3 = 0x4fc00744; -__ashrdi3 = 0x4fc00748; -__bswapdi2 = 0x4fc0074c; -__bswapsi2 = 0x4fc00750; -__clear_cache = 0x4fc00754; -__clrsbdi2 = 0x4fc00758; -__clrsbsi2 = 0x4fc0075c; -__clzdi2 = 0x4fc00760; -__clzsi2 = 0x4fc00764; -__cmpdi2 = 0x4fc00768; -__ctzdi2 = 0x4fc0076c; -__ctzsi2 = 0x4fc00770; -__divdc3 = 0x4fc00774; -__divdf3 = 0x4fc00778; -__divdi3 = 0x4fc0077c; -__divsc3 = 0x4fc00780; -__divsi3 = 0x4fc00784; -__extendsfdf2 = 0x4fc0078c; -__ffsdi2 = 0x4fc00790; -__ffssi2 = 0x4fc00794; -__fixsfdi = 0x4fc007a0; -__fixunssfdi = 0x4fc007a8; -__fixunssfsi = 0x4fc007ac; -__floatdisf = 0x4fc007b4; -__floatundisf = 0x4fc007c0; -__gcc_bcmp = 0x4fc007c8; -__lshrdi3 = 0x4fc007d8; -__moddi3 = 0x4fc007e0; -__modsi3 = 0x4fc007e4; -__muldc3 = 0x4fc007e8; -__muldi3 = 0x4fc007f0; -__mulsc3 = 0x4fc007f4; -__mulsi3 = 0x4fc007f8; -__mulvdi3 = 0x4fc007fc; -__mulvsi3 = 0x4fc00800; -__negdf2 = 0x4fc00808; -__negdi2 = 0x4fc0080c; -__negvdi2 = 0x4fc00810; -__negvsi2 = 0x4fc00814; -__paritysi2 = 0x4fc00818; -__popcountdi2 = 0x4fc0081c; -__popcountsi2 = 0x4fc00820; -__powidf2 = 0x4fc00824; -__subvdi3 = 0x4fc0082c; -__subvsi3 = 0x4fc00830; -__ucmpdi2 = 0x4fc00834; -__udivdi3 = 0x4fc00838; -__udivmoddi4 = 0x4fc0083c; -__udivsi3 = 0x4fc00840; -__udiv_w_sdiv = 0x4fc00844; -__umoddi3 = 0x4fc00848; -__umodsi3 = 0x4fc0084c; -__unorddf2 = 0x4fc00850; -__extenddftf2 = 0x4fc00854; -__trunctfdf2 = 0x4fc00858; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld index b9950412e06..46d1f3c012f 100644 --- a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld @@ -1,14 +1,14 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ /* ROM function interface esp32p4.rom.ld for esp32p4 * * - * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 * - * Compatible with ROM where ECO version equal or greater to 0. + * Compatible with ROM where ECO version equal or greater to 5. * * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. */ @@ -64,8 +64,8 @@ Uart_Init = 0x4fc000c0; ets_set_user_start = 0x4fc000c4; /* Data (.data, .bss, .rodata) */ ets_rom_layout_p = 0x4fc1fffc; -ets_ops_table_ptr = 0x4ff3fff4; -g_saved_pc = 0x4ff3fff8; +ets_ops_table_ptr = 0x4ffbfff4; +g_saved_pc = 0x4ffbfff8; /*************************************** @@ -165,9 +165,9 @@ spi_flash_guard_set = 0x4fc001f0; spi_flash_guard_get = 0x4fc001f4; spi_flash_read_encrypted = 0x4fc001f8; /* Data (.data, .bss, .rodata) */ -rom_spiflash_legacy_funcs = 0x4ff3ffec; -rom_spiflash_legacy_data = 0x4ff3ffe8; -g_flash_guard_ops = 0x4ff3fff0; +rom_spiflash_legacy_funcs = 0x4ffbffec; +rom_spiflash_legacy_data = 0x4ffbffe8; +g_flash_guard_ops = 0x4ffbfff0; /*************************************** @@ -266,20 +266,17 @@ Cache_PSRAM_MMU_Set = 0x4fc00520; Cache_PSRAM_MMU_Set_Secure = 0x4fc00524; Cache_Count_Flash_Pages = 0x4fc00528; Cache_Flash_To_SPIRAM_Copy = 0x4fc0052c; -Cache_Travel_Tag_Memory = 0x4fc00530; -Cache_Travel_Tag_Memory2 = 0x4fc00534; -Cache_Get_Virtual_Addr = 0x4fc00538; -Cache_Set_IDROM_MMU_Size = 0x4fc0053c; -flash2spiram_instruction_offset = 0x4fc00540; -flash2spiram_rodata_offset = 0x4fc00544; -flash_instr_rodata_start_page = 0x4fc00548; -flash_instr_rodata_end_page = 0x4fc0054c; -Cache_Set_IDROM_MMU_Info = 0x4fc00550; -Cache_Get_IROM_MMU_End = 0x4fc00554; -Cache_Get_DROM_MMU_End = 0x4fc00558; +Cache_Set_IDROM_MMU_Size = 0x4fc00530; +flash2spiram_instruction_offset = 0x4fc00534; +flash2spiram_rodata_offset = 0x4fc00538; +flash_instr_rodata_start_page = 0x4fc0053c; +flash_instr_rodata_end_page = 0x4fc00540; +Cache_Set_IDROM_MMU_Info = 0x4fc00544; +Cache_Get_IROM_MMU_End = 0x4fc00548; +Cache_Get_DROM_MMU_End = 0x4fc0054c; /* Data (.data, .bss, .rodata) */ -rom_cache_op_cb = 0x4ff3ffdc; -rom_cache_internal_table_ptr = 0x4ff3ffd8; +rom_cache_op_cb = 0x4ffbffdc; +rom_cache_internal_table_ptr = 0x4ffbffd8; /*************************************** @@ -287,8 +284,8 @@ rom_cache_internal_table_ptr = 0x4ff3ffd8; ***************************************/ /* Functions */ -ets_clk_get_xtal_freq = 0x4fc0055c; -ets_clk_get_cpu_freq = 0x4fc00560; +ets_clk_get_xtal_freq = 0x4fc00550; +ets_clk_get_cpu_freq = 0x4fc00554; /*************************************** @@ -296,27 +293,27 @@ ets_clk_get_cpu_freq = 0x4fc00560; ***************************************/ /* Functions */ -gpio_set_output_level = 0x4fc00564; -gpio_get_input_level = 0x4fc00568; -gpio_matrix_in = 0x4fc0056c; -gpio_matrix_out = 0x4fc00570; -gpio_bypass_matrix_in = 0x4fc00574; -/* gpio_output_disable = 0x4fc00578; */ -/* gpio_output_enable = 0x4fc0057c; */ -gpio_pad_input_disable = 0x4fc00580; -gpio_pad_input_enable = 0x4fc00584; -gpio_pad_pulldown = 0x4fc00588; -gpio_pad_pullup = 0x4fc0058c; -gpio_pad_select_gpio = 0x4fc00590; -gpio_pad_set_drv = 0x4fc00594; -gpio_pad_unhold = 0x4fc00598; -gpio_pad_hold = 0x4fc0059c; -gpio_lppad_select_mux = 0x4fc005a0; -gpio_ded_pad_set_drv = 0x4fc005a4; -gpio_ded_pad_pullup = 0x4fc005a8; -gpio_ded_pad_pulldown = 0x4fc005ac; -gpio_ded_pad_hold = 0x4fc005b0; -gpio_ded_pad_unhold = 0x4fc005b4; +rom_gpio_set_output_level = 0x4fc00558; +rom_gpio_get_input_level = 0x4fc0055c; +rom_gpio_matrix_in = 0x4fc00560; +rom_gpio_matrix_out = 0x4fc00564; +rom_gpio_bypass_matrix_in = 0x4fc00568; +rom_gpio_output_disable = 0x4fc0056c; +rom_gpio_output_enable = 0x4fc00570; +rom_gpio_pad_input_disable = 0x4fc00574; +rom_gpio_pad_input_enable = 0x4fc00578; +rom_gpio_pad_pulldown = 0x4fc0057c; +rom_gpio_pad_pullup = 0x4fc00580; +rom_gpio_pad_select_gpio = 0x4fc00584; +rom_gpio_pad_set_drv = 0x4fc00588; +rom_gpio_pad_unhold = 0x4fc0058c; +rom_gpio_pad_hold = 0x4fc00590; +rom_gpio_lppad_select_mux = 0x4fc00594; +rom_gpio_ded_pad_set_drv = 0x4fc00598; +rom_gpio_ded_pad_pullup = 0x4fc0059c; +rom_gpio_ded_pad_pulldown = 0x4fc005a0; +rom_gpio_ded_pad_hold = 0x4fc005a4; +rom_gpio_ded_pad_unhold = 0x4fc005a8; /*************************************** @@ -324,17 +321,18 @@ gpio_ded_pad_unhold = 0x4fc005b4; ***************************************/ /* Functions */ -esprv_intc_int_set_priority = 0x4fc005b8; -esprv_intc_int_set_threshold = 0x4fc005bc; -esprv_intc_int_enable = 0x4fc005c0; -esprv_intc_int_disable = 0x4fc005c4; -PROVIDE( intr_handler_set = 0x4fc005cc ); -intr_matrix_set = 0x4fc005d0; -ets_intr_lock = 0x4fc005d4; -ets_intr_unlock = 0x4fc005d8; -ets_isr_attach = 0x4fc005dc; -ets_isr_mask = 0x4fc005e0; -ets_isr_unmask = 0x4fc005e4; +esprv_intc_int_set_priority = 0x4fc005ac; +esprv_intc_int_set_threshold = 0x4fc005b0; +esprv_intc_int_enable = 0x4fc005b4; +esprv_intc_int_disable = 0x4fc005b8; +esprv_intc_int_set_type = 0x4fc005bc; +PROVIDE( intr_handler_set = 0x4fc005c0 ); +intr_matrix_set = 0x4fc005c4; +ets_intr_lock = 0x4fc005c8; +ets_intr_unlock = 0x4fc005cc; +ets_isr_attach = 0x4fc005d0; +ets_isr_mask = 0x4fc005d4; +ets_isr_unmask = 0x4fc005d8; /*************************************** @@ -342,52 +340,52 @@ ets_isr_unmask = 0x4fc005e4; ***************************************/ /* Functions */ -md5_vector = 0x4fc005e8; -MD5Init = 0x4fc005ec; -MD5Update = 0x4fc005f0; -MD5Final = 0x4fc005f4; -crc32_le = 0x4fc005f8; -crc16_le = 0x4fc005fc; -crc8_le = 0x4fc00600; -crc32_be = 0x4fc00604; -crc16_be = 0x4fc00608; -crc8_be = 0x4fc0060c; -esp_crc8 = 0x4fc00610; -ets_sha_enable = 0x4fc00614; -ets_sha_disable = 0x4fc00618; -ets_sha_get_state = 0x4fc0061c; -ets_sha_init = 0x4fc00620; -ets_sha_process = 0x4fc00624; -ets_sha_starts = 0x4fc00628; -ets_sha_update = 0x4fc0062c; -ets_sha_finish = 0x4fc00630; -ets_sha_clone = 0x4fc00634; -ets_hmac_enable = 0x4fc00638; -ets_hmac_disable = 0x4fc0063c; -ets_hmac_calculate_message = 0x4fc00640; -ets_hmac_calculate_downstream = 0x4fc00644; -ets_hmac_invalidate_downstream = 0x4fc00648; -ets_jtag_enable_temporarily = 0x4fc0064c; -ets_aes_enable = 0x4fc00650; -ets_aes_disable = 0x4fc00654; -ets_aes_setkey = 0x4fc00658; -ets_aes_block = 0x4fc0065c; -ets_aes_setkey_dec = 0x4fc00660; -ets_aes_setkey_enc = 0x4fc00664; -ets_bigint_enable = 0x4fc00668; -ets_bigint_disable = 0x4fc0066c; -ets_bigint_multiply = 0x4fc00670; -ets_bigint_modmult = 0x4fc00674; -ets_bigint_modexp = 0x4fc00678; -ets_bigint_wait_finish = 0x4fc0067c; -ets_bigint_getz = 0x4fc00680; -ets_ds_enable = 0x4fc00684; -ets_ds_disable = 0x4fc00688; -ets_ds_start_sign = 0x4fc0068c; -ets_ds_is_busy = 0x4fc00690; -ets_ds_finish_sign = 0x4fc00694; -ets_ds_encrypt_params = 0x4fc00698; -ets_mgf1_sha256 = 0x4fc0069c; +md5_vector = 0x4fc005dc; +MD5Init = 0x4fc005e0; +MD5Update = 0x4fc005e4; +MD5Final = 0x4fc005e8; +crc32_le = 0x4fc005ec; +crc16_le = 0x4fc005f0; +crc8_le = 0x4fc005f4; +crc32_be = 0x4fc005f8; +crc16_be = 0x4fc005fc; +crc8_be = 0x4fc00600; +esp_crc8 = 0x4fc00604; +ets_sha_enable = 0x4fc00608; +ets_sha_disable = 0x4fc0060c; +ets_sha_get_state = 0x4fc00610; +ets_sha_init = 0x4fc00614; +ets_sha_process = 0x4fc00618; +ets_sha_starts = 0x4fc0061c; +ets_sha_update = 0x4fc00620; +ets_sha_finish = 0x4fc00624; +ets_sha_clone = 0x4fc00628; +ets_hmac_enable = 0x4fc0062c; +ets_hmac_disable = 0x4fc00630; +ets_hmac_calculate_message = 0x4fc00634; +ets_hmac_calculate_downstream = 0x4fc00638; +ets_hmac_invalidate_downstream = 0x4fc0063c; +ets_jtag_enable_temporarily = 0x4fc00640; +ets_aes_enable = 0x4fc00644; +ets_aes_disable = 0x4fc00648; +ets_aes_setkey = 0x4fc0064c; +ets_aes_block = 0x4fc00650; +ets_aes_setkey_dec = 0x4fc00654; +ets_aes_setkey_enc = 0x4fc00658; +ets_bigint_enable = 0x4fc0065c; +ets_bigint_disable = 0x4fc00660; +ets_bigint_multiply = 0x4fc00664; +ets_bigint_modmult = 0x4fc00668; +ets_bigint_modexp = 0x4fc0066c; +ets_bigint_wait_finish = 0x4fc00670; +ets_bigint_getz = 0x4fc00674; +ets_ds_enable = 0x4fc00678; +ets_ds_disable = 0x4fc0067c; +ets_ds_start_sign = 0x4fc00680; +ets_ds_is_busy = 0x4fc00684; +ets_ds_finish_sign = 0x4fc00688; +ets_ds_encrypt_params = 0x4fc0068c; +ets_mgf1_sha256 = 0x4fc00690; /* Data (.data, .bss, .rodata) */ crc32_le_table_ptr = 0x4fc1fff8; crc16_le_table_ptr = 0x4fc1fff4; @@ -402,35 +400,35 @@ crc8_be_table_ptr = 0x4fc1ffe4; ***************************************/ /* Functions */ -ets_efuse_read = 0x4fc006a0; -ets_efuse_program = 0x4fc006a4; -ets_efuse_clear_program_registers = 0x4fc006a8; -ets_efuse_write_key = 0x4fc006ac; -ets_efuse_get_read_register_address = 0x4fc006b0; -ets_efuse_get_key_purpose = 0x4fc006b4; -ets_efuse_key_block_unused = 0x4fc006b8; -ets_efuse_find_unused_key_block = 0x4fc006bc; -ets_efuse_rs_calculate = 0x4fc006c0; -ets_efuse_count_unused_key_blocks = 0x4fc006c4; -ets_efuse_secure_boot_enabled = 0x4fc006c8; -ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4fc006cc; -ets_efuse_cache_encryption_enabled = 0x4fc006d0; -ets_efuse_download_modes_disabled = 0x4fc006d4; -ets_efuse_find_purpose = 0x4fc006d8; -ets_efuse_force_send_resume = 0x4fc006dc; -ets_efuse_get_flash_delay_us = 0x4fc006e0; -ets_efuse_get_uart_print_control = 0x4fc006e4; -ets_efuse_direct_boot_mode_disabled = 0x4fc006e8; -ets_efuse_security_download_modes_enabled = 0x4fc006ec; -ets_efuse_jtag_disabled = 0x4fc006f0; -ets_efuse_usb_print_is_disabled = 0x4fc006f4; -ets_efuse_usb_download_mode_disabled = 0x4fc006f8; -ets_efuse_usb_device_disabled = 0x4fc006fc; -ets_efuse_get_km_huk_gen_state = 0x4fc00700; -ets_efuse_get_km_deploy_only_once = 0x4fc00704; -ets_efuse_get_force_use_km_key = 0x4fc00708; -ets_efuse_xts_key_length_256 = 0x4fc0070c; -ets_efuse_get_km_key_lock = 0x4fc00710; +ets_efuse_read = 0x4fc00694; +ets_efuse_program = 0x4fc00698; +ets_efuse_clear_program_registers = 0x4fc0069c; +ets_efuse_write_key = 0x4fc006a0; +ets_efuse_get_read_register_address = 0x4fc006a4; +ets_efuse_get_key_purpose = 0x4fc006a8; +ets_efuse_key_block_unused = 0x4fc006ac; +ets_efuse_find_unused_key_block = 0x4fc006b0; +ets_efuse_rs_calculate = 0x4fc006b4; +ets_efuse_count_unused_key_blocks = 0x4fc006b8; +ets_efuse_secure_boot_enabled = 0x4fc006bc; +ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4fc006c0; +ets_efuse_cache_encryption_enabled = 0x4fc006c4; +ets_efuse_download_modes_disabled = 0x4fc006c8; +ets_efuse_find_purpose = 0x4fc006cc; +ets_efuse_force_send_resume = 0x4fc006d0; +ets_efuse_get_flash_delay_us = 0x4fc006d4; +ets_efuse_get_uart_print_control = 0x4fc006d8; +ets_efuse_direct_boot_mode_disabled = 0x4fc006dc; +ets_efuse_security_download_modes_enabled = 0x4fc006e0; +ets_efuse_jtag_disabled = 0x4fc006e4; +ets_efuse_usb_print_is_disabled = 0x4fc006e8; +ets_efuse_usb_download_mode_disabled = 0x4fc006ec; +ets_efuse_usb_device_disabled = 0x4fc006f0; +ets_efuse_get_km_huk_gen_state = 0x4fc006f4; +ets_efuse_get_km_deploy_only_once = 0x4fc006f8; +ets_efuse_get_force_use_km_key = 0x4fc006fc; +ets_efuse_xts_key_length_256 = 0x4fc00700; +ets_efuse_get_km_key_lock = 0x4fc00704; /*************************************** @@ -438,9 +436,9 @@ ets_efuse_get_km_key_lock = 0x4fc00710; ***************************************/ /* Functions */ -esp_rom_check_recover_key = 0x4fc00714; -esp_rom_km_huk_conf = 0x4fc00718; -esp_rom_km_huk_risk = 0x4fc0071c; +esp_rom_check_recover_key = 0x4fc00708; +esp_rom_km_huk_conf = 0x4fc0070c; +esp_rom_km_huk_risk = 0x4fc00710; /*************************************** @@ -448,13 +446,13 @@ esp_rom_km_huk_risk = 0x4fc0071c; ***************************************/ /* Functions */ -ets_emsa_pss_verify = 0x4fc00720; -ets_rsa_pss_verify = 0x4fc00724; -ets_ecdsa_verify = 0x4fc00728; -ets_secure_boot_verify_bootloader_with_keys = 0x4fc0072c; -ets_secure_boot_verify_signature = 0x4fc00730; -ets_secure_boot_read_key_digests = 0x4fc00734; -ets_secure_boot_revoke_public_key_digest = 0x4fc00738; +ets_emsa_pss_verify = 0x4fc00714; +ets_rsa_pss_verify = 0x4fc00718; +ets_ecdsa_verify = 0x4fc0071c; +ets_secure_boot_verify_bootloader_with_keys = 0x4fc00720; +ets_secure_boot_verify_signature = 0x4fc00724; +ets_secure_boot_read_key_digests = 0x4fc00728; +ets_secure_boot_revoke_public_key_digest = 0x4fc0072c; /*************************************** @@ -462,10 +460,10 @@ ets_secure_boot_revoke_public_key_digest = 0x4fc00738; ***************************************/ /* Functions */ -usb_serial_device_rx_one_char = 0x4fc008b0; -usb_serial_device_rx_one_char_block = 0x4fc008b4; -usb_serial_device_tx_flush = 0x4fc008b8; -usb_serial_device_tx_one_char = 0x4fc008bc; +usb_serial_device_rx_one_char = 0x4fc008a4; +usb_serial_device_rx_one_char_block = 0x4fc008a8; +usb_serial_device_tx_flush = 0x4fc008ac; +usb_serial_device_tx_one_char = 0x4fc008b0; /*************************************** @@ -473,13 +471,13 @@ usb_serial_device_tx_one_char = 0x4fc008bc; ***************************************/ /* Functions */ -Uart_Init_USB = 0x4fc008c0; -usb_serial_otg_rx_one_char = 0x4fc008c4; -usb_serial_otg_rx_one_char_block = 0x4fc008c8; -usb_serial_otg_tx_flush = 0x4fc008cc; -usb_serial_otg_tx_one_char = 0x4fc008d0; +Uart_Init_USB = 0x4fc008b4; +usb_serial_otg_rx_one_char = 0x4fc008b8; +usb_serial_otg_rx_one_char_block = 0x4fc008bc; +usb_serial_otg_tx_flush = 0x4fc008c0; +usb_serial_otg_tx_one_char = 0x4fc008c4; /* Data (.data, .bss, .rodata) */ -uart_acm_dev = 0x4ff3ffd4; +uart_acm_dev = 0x4ffbffd4; /*************************************** @@ -487,99 +485,108 @@ uart_acm_dev = 0x4ff3ffd4; ***************************************/ /* Functions */ -cdc_acm_class_handle_req = 0x4fc008d4; -cdc_acm_init = 0x4fc008d8; -cdc_acm_fifo_fill = 0x4fc008dc; -cdc_acm_rx_fifo_cnt = 0x4fc008e0; -cdc_acm_fifo_read = 0x4fc008e4; -cdc_acm_irq_tx_enable = 0x4fc008e8; -cdc_acm_irq_tx_disable = 0x4fc008ec; -cdc_acm_irq_state_enable = 0x4fc008f0; -cdc_acm_irq_state_disable = 0x4fc008f4; -cdc_acm_irq_tx_ready = 0x4fc008f8; -cdc_acm_irq_rx_enable = 0x4fc008fc; -cdc_acm_irq_rx_disable = 0x4fc00900; -cdc_acm_irq_rx_ready = 0x4fc00904; -cdc_acm_irq_is_pending = 0x4fc00908; -cdc_acm_irq_callback_set = 0x4fc0090c; -cdc_acm_line_ctrl_set = 0x4fc00910; -cdc_acm_line_ctrl_get = 0x4fc00914; -cdc_acm_poll_out = 0x4fc00918; -chip_usb_dw_did_persist = 0x4fc0091c; -chip_usb_dw_init = 0x4fc00920; -chip_usb_detach = 0x4fc00924; -chip_usb_dw_prepare_persist = 0x4fc00928; -chip_usb_get_persist_flags = 0x4fc0092c; -chip_usb_set_persist_flags = 0x4fc00930; -cpio_start = 0x4fc00934; -cpio_feed = 0x4fc00938; -cpio_done = 0x4fc0093c; -cpio_destroy = 0x4fc00940; -dfu_flash_init = 0x4fc00944; -dfu_flash_erase = 0x4fc00948; -dfu_flash_program = 0x4fc0094c; -dfu_flash_read = 0x4fc00950; -dfu_flash_attach = 0x4fc00954; -dfu_cpio_callback = 0x4fc00958; -dfu_updater_get_err = 0x4fc0095c; -dfu_updater_clear_err = 0x4fc00960; -dfu_updater_enable = 0x4fc00964; -dfu_updater_begin = 0x4fc00968; -dfu_updater_feed = 0x4fc0096c; -dfu_updater_end = 0x4fc00970; -dfu_updater_set_raw_addr = 0x4fc00974; -dfu_updater_flash_read = 0x4fc00978; -usb_dc_prepare_persist = 0x4fc0097c; -usb_dw_isr_handler = 0x4fc00980; -usb_dc_attach = 0x4fc00984; -usb_dc_detach = 0x4fc00988; -usb_dc_reset = 0x4fc0098c; -usb_dc_set_address = 0x4fc00990; -usb_dc_ep_check_cap = 0x4fc00994; -usb_dc_ep_configure = 0x4fc00998; -usb_dc_ep_set_stall = 0x4fc0099c; -usb_dc_ep_clear_stall = 0x4fc009a0; -usb_dc_ep_halt = 0x4fc009a4; -usb_dc_ep_is_stalled = 0x4fc009a8; -usb_dc_ep_enable = 0x4fc009ac; -usb_dc_ep_disable = 0x4fc009b0; -usb_dc_ep_flush = 0x4fc009b4; -usb_dc_ep_write_would_block = 0x4fc009b8; -usb_dc_ep_write = 0x4fc009bc; -usb_dc_ep_read_wait = 0x4fc009c0; -usb_dc_ep_read_continue = 0x4fc009c4; -usb_dc_ep_read = 0x4fc009c8; -usb_dc_ep_set_callback = 0x4fc009cc; -usb_dc_set_status_callback = 0x4fc009d0; -usb_dc_ep_mps = 0x4fc009d4; -usb_dc_check_poll_for_interrupts = 0x4fc009d8; -mac_addr_to_serial_str_desc = 0x4fc009dc; -usb_set_current_descriptor = 0x4fc009e0; -usb_get_descriptor = 0x4fc009e4; -usb_dev_resume = 0x4fc009e8; -usb_dev_get_configuration = 0x4fc009ec; -usb_set_config = 0x4fc009f0; -usb_deconfig = 0x4fc009f4; -usb_enable = 0x4fc009f8; -usb_disable = 0x4fc009fc; -usb_write_would_block = 0x4fc00a00; -usb_write = 0x4fc00a04; -usb_read = 0x4fc00a08; -usb_ep_set_stall = 0x4fc00a0c; -usb_ep_clear_stall = 0x4fc00a10; -usb_ep_read_wait = 0x4fc00a14; -usb_ep_read_continue = 0x4fc00a18; -usb_transfer_ep_callback = 0x4fc00a1c; -usb_transfer = 0x4fc00a20; -usb_cancel_transfer = 0x4fc00a24; -usb_transfer_sync = 0x4fc00a28; -usb_dfu_set_detach_cb = 0x4fc00a2c; -dfu_class_handle_req = 0x4fc00a30; -dfu_status_cb = 0x4fc00a34; -dfu_custom_handle_req = 0x4fc00a38; -usb_dfu_init = 0x4fc00a3c; -usb_dfu_force_detach = 0x4fc00a40; -usb_dev_deinit = 0x4fc00a44; -usb_dw_ctrl_deinit = 0x4fc00a48; +cdc_acm_class_handle_req = 0x4fc008c8; +cdc_acm_init = 0x4fc008cc; +cdc_acm_fifo_fill = 0x4fc008d0; +cdc_acm_rx_fifo_cnt = 0x4fc008d4; +cdc_acm_fifo_read = 0x4fc008d8; +cdc_acm_irq_tx_enable = 0x4fc008dc; +cdc_acm_irq_tx_disable = 0x4fc008e0; +cdc_acm_irq_state_enable = 0x4fc008e4; +cdc_acm_irq_state_disable = 0x4fc008e8; +cdc_acm_irq_tx_ready = 0x4fc008ec; +cdc_acm_irq_rx_enable = 0x4fc008f0; +cdc_acm_irq_rx_disable = 0x4fc008f4; +cdc_acm_irq_rx_ready = 0x4fc008f8; +cdc_acm_irq_is_pending = 0x4fc008fc; +cdc_acm_irq_callback_set = 0x4fc00900; +cdc_acm_line_ctrl_set = 0x4fc00904; +cdc_acm_line_ctrl_get = 0x4fc00908; +cdc_acm_poll_out = 0x4fc0090c; +chip_usb_dw_did_persist = 0x4fc00910; +chip_usb_dw_init = 0x4fc00914; +chip_usb_detach = 0x4fc00918; +chip_usb_dw_prepare_persist = 0x4fc0091c; +chip_usb_get_persist_flags = 0x4fc00920; +chip_usb_set_persist_flags = 0x4fc00924; +cpio_start = 0x4fc00928; +cpio_feed = 0x4fc0092c; +cpio_done = 0x4fc00930; +cpio_destroy = 0x4fc00934; +dfu_flash_init = 0x4fc00938; +dfu_flash_erase = 0x4fc0093c; +dfu_flash_program = 0x4fc00940; +dfu_flash_read = 0x4fc00944; +dfu_flash_attach = 0x4fc00948; +dfu_cpio_callback = 0x4fc0094c; +dfu_updater_get_err = 0x4fc00950; +dfu_updater_clear_err = 0x4fc00954; +dfu_updater_enable = 0x4fc00958; +dfu_updater_begin = 0x4fc0095c; +dfu_updater_feed = 0x4fc00960; +dfu_updater_end = 0x4fc00964; +dfu_updater_set_raw_addr = 0x4fc00968; +dfu_updater_flash_read = 0x4fc0096c; +usb_dc_prepare_persist = 0x4fc00970; +usb_dw_isr_handler = 0x4fc00974; +usb_dc_attach = 0x4fc00978; +usb_dc_detach = 0x4fc0097c; +usb_dc_reset = 0x4fc00980; +usb_dc_set_address = 0x4fc00984; +usb_dc_ep_check_cap = 0x4fc00988; +usb_dc_ep_configure = 0x4fc0098c; +usb_dc_ep_set_stall = 0x4fc00990; +usb_dc_ep_clear_stall = 0x4fc00994; +usb_dc_ep_halt = 0x4fc00998; +usb_dc_ep_is_stalled = 0x4fc0099c; +usb_dc_ep_enable = 0x4fc009a0; +usb_dc_ep_disable = 0x4fc009a4; +usb_dc_ep_flush = 0x4fc009a8; +usb_dc_ep_write_would_block = 0x4fc009ac; +usb_dc_ep_write = 0x4fc009b0; +usb_dc_ep_read_wait = 0x4fc009b4; +usb_dc_ep_read_continue = 0x4fc009b8; +usb_dc_ep_read = 0x4fc009bc; +usb_dc_ep_set_callback = 0x4fc009c0; +usb_dc_set_status_callback = 0x4fc009c4; +usb_dc_ep_mps = 0x4fc009c8; +usb_dc_check_poll_for_interrupts = 0x4fc009cc; +mac_addr_to_serial_str_desc = 0x4fc009d0; +usb_set_current_descriptor = 0x4fc009d4; +usb_get_descriptor = 0x4fc009d8; +usb_dev_resume = 0x4fc009dc; +usb_dev_get_configuration = 0x4fc009e0; +usb_set_config = 0x4fc009e4; +usb_deconfig = 0x4fc009e8; +usb_enable = 0x4fc009ec; +usb_disable = 0x4fc009f0; +usb_write_would_block = 0x4fc009f4; +usb_write = 0x4fc009f8; +usb_read = 0x4fc009fc; +usb_ep_set_stall = 0x4fc00a00; +usb_ep_clear_stall = 0x4fc00a04; +usb_ep_read_wait = 0x4fc00a08; +usb_ep_read_continue = 0x4fc00a0c; +usb_transfer_ep_callback = 0x4fc00a10; +usb_transfer = 0x4fc00a14; +usb_cancel_transfer = 0x4fc00a18; +usb_transfer_sync = 0x4fc00a1c; +usb_dfu_set_detach_cb = 0x4fc00a20; +dfu_class_handle_req = 0x4fc00a24; +dfu_status_cb = 0x4fc00a28; +dfu_custom_handle_req = 0x4fc00a2c; +usb_dfu_init = 0x4fc00a30; +usb_dfu_force_detach = 0x4fc00a34; +usb_dev_deinit = 0x4fc00a38; +usb_dw_ctrl_deinit = 0x4fc00a3c; /* Data (.data, .bss, .rodata) */ -s_usb_osglue = 0x4ff3ffc8; +s_usb_osglue = 0x4ffbffc8; + + +/*************************************** + Group recovery_bootloader + ***************************************/ + +/* Functions */ +ets_get_bootloader_offset = 0x4fc00a40; +ets_set_bootloader_offset = 0x4fc00a44; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld index 3b969ade5a9..308bb0c1a19 100644 --- a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.libgcc.ld @@ -1,14 +1,14 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ /* ROM function interface esp32p4.rom.libgcc.ld for esp32p4 * * - * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 * - * Compatible with ROM where ECO version equal or greater to 0. + * Compatible with ROM where ECO version equal or greater to 5. * * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. */ @@ -18,78 +18,78 @@ ***************************************/ /* Functions */ -__absvdi2 = 0x4fc0073c; -__absvsi2 = 0x4fc00740; -__adddf3 = 0x4fc00744; -__addvdi3 = 0x4fc00748; -__addvsi3 = 0x4fc0074c; -__ashldi3 = 0x4fc00750; -__ashrdi3 = 0x4fc00754; -__bswapdi2 = 0x4fc00758; -__bswapsi2 = 0x4fc0075c; -__clear_cache = 0x4fc00760; -__clrsbdi2 = 0x4fc00764; -__clrsbsi2 = 0x4fc00768; -__clzdi2 = 0x4fc0076c; -__clzsi2 = 0x4fc00770; -__cmpdi2 = 0x4fc00774; -__ctzdi2 = 0x4fc00778; -__ctzsi2 = 0x4fc0077c; -__divdc3 = 0x4fc00780; -__divdf3 = 0x4fc00784; -__divdi3 = 0x4fc00788; -__divsc3 = 0x4fc0078c; -__divsi3 = 0x4fc00790; -__eqdf2 = 0x4fc00794; -__extendsfdf2 = 0x4fc00798; -__ffsdi2 = 0x4fc0079c; -__ffssi2 = 0x4fc007a0; -__fixdfdi = 0x4fc007a4; -__fixdfsi = 0x4fc007a8; -__fixsfdi = 0x4fc007ac; -__fixunsdfsi = 0x4fc007b0; -__fixunssfdi = 0x4fc007b4; -__fixunssfsi = 0x4fc007b8; -__floatdidf = 0x4fc007bc; -__floatdisf = 0x4fc007c0; -__floatsidf = 0x4fc007c4; -__floatundidf = 0x4fc007c8; -__floatundisf = 0x4fc007cc; -__floatunsidf = 0x4fc007d0; -__gcc_bcmp = 0x4fc007d4; -__gedf2 = 0x4fc007d8; -__gtdf2 = 0x4fc007dc; -__ledf2 = 0x4fc007e0; -__lshrdi3 = 0x4fc007e4; -__ltdf2 = 0x4fc007e8; -__moddi3 = 0x4fc007ec; -__modsi3 = 0x4fc007f0; -__muldc3 = 0x4fc007f4; -__muldf3 = 0x4fc007f8; -__muldi3 = 0x4fc007fc; -__mulsc3 = 0x4fc00800; -__mulsi3 = 0x4fc00804; -__mulvdi3 = 0x4fc00808; -__mulvsi3 = 0x4fc0080c; -__nedf2 = 0x4fc00810; -__negdf2 = 0x4fc00814; -__negdi2 = 0x4fc00818; -__negvdi2 = 0x4fc0081c; -__negvsi2 = 0x4fc00820; -__paritysi2 = 0x4fc00824; -__popcountdi2 = 0x4fc00828; -__popcountsi2 = 0x4fc0082c; -__powidf2 = 0x4fc00830; -__subdf3 = 0x4fc00834; -__subvdi3 = 0x4fc00838; -__subvsi3 = 0x4fc0083c; -__ucmpdi2 = 0x4fc00840; -__udivdi3 = 0x4fc00844; -__udivmoddi4 = 0x4fc00848; -__udivsi3 = 0x4fc0084c; -__udiv_w_sdiv = 0x4fc00850; -__umoddi3 = 0x4fc00854; -__umodsi3 = 0x4fc00858; -__unorddf2 = 0x4fc0085c; -__extenddftf2 = 0x4fc00860; -__trunctfdf2 = 0x4fc00864; +__absvdi2 = 0x4fc00730; +__absvsi2 = 0x4fc00734; +__adddf3 = 0x4fc00738; +__addvdi3 = 0x4fc0073c; +__addvsi3 = 0x4fc00740; +__ashldi3 = 0x4fc00744; +__ashrdi3 = 0x4fc00748; +__bswapdi2 = 0x4fc0074c; +__bswapsi2 = 0x4fc00750; +__clear_cache = 0x4fc00754; +__clrsbdi2 = 0x4fc00758; +__clrsbsi2 = 0x4fc0075c; +__clzdi2 = 0x4fc00760; +__clzsi2 = 0x4fc00764; +__cmpdi2 = 0x4fc00768; +__ctzdi2 = 0x4fc0076c; +__ctzsi2 = 0x4fc00770; +__divdc3 = 0x4fc00774; +__divdf3 = 0x4fc00778; +__divdi3 = 0x4fc0077c; +__divsc3 = 0x4fc00780; +__divsi3 = 0x4fc00784; +__eqdf2 = 0x4fc00788; +__extendsfdf2 = 0x4fc0078c; +__ffsdi2 = 0x4fc00790; +__ffssi2 = 0x4fc00794; +__fixdfdi = 0x4fc00798; +__fixdfsi = 0x4fc0079c; +__fixsfdi = 0x4fc007a0; +__fixunsdfsi = 0x4fc007a4; +__fixunssfdi = 0x4fc007a8; +__fixunssfsi = 0x4fc007ac; +__floatdidf = 0x4fc007b0; +__floatdisf = 0x4fc007b4; +__floatsidf = 0x4fc007b8; +__floatundidf = 0x4fc007bc; +__floatundisf = 0x4fc007c0; +__floatunsidf = 0x4fc007c4; +__gcc_bcmp = 0x4fc007c8; +__gedf2 = 0x4fc007cc; +__gtdf2 = 0x4fc007d0; +__ledf2 = 0x4fc007d4; +__lshrdi3 = 0x4fc007d8; +__ltdf2 = 0x4fc007dc; +__moddi3 = 0x4fc007e0; +__modsi3 = 0x4fc007e4; +__muldc3 = 0x4fc007e8; +__muldf3 = 0x4fc007ec; +__muldi3 = 0x4fc007f0; +__mulsc3 = 0x4fc007f4; +__mulsi3 = 0x4fc007f8; +__mulvdi3 = 0x4fc007fc; +__mulvsi3 = 0x4fc00800; +__nedf2 = 0x4fc00804; +__negdf2 = 0x4fc00808; +__negdi2 = 0x4fc0080c; +__negvdi2 = 0x4fc00810; +__negvsi2 = 0x4fc00814; +__paritysi2 = 0x4fc00818; +__popcountdi2 = 0x4fc0081c; +__popcountsi2 = 0x4fc00820; +__powidf2 = 0x4fc00824; +__subdf3 = 0x4fc00828; +__subvdi3 = 0x4fc0082c; +__subvsi3 = 0x4fc00830; +__ucmpdi2 = 0x4fc00834; +__udivdi3 = 0x4fc00838; +__udivmoddi4 = 0x4fc0083c; +__udivsi3 = 0x4fc00840; +__udiv_w_sdiv = 0x4fc00844; +__umoddi3 = 0x4fc00848; +__umodsi3 = 0x4fc0084c; +__unorddf2 = 0x4fc00850; +__extenddftf2 = 0x4fc00854; +__trunctfdf2 = 0x4fc00858; diff --git a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld index bb28d141915..28efe7209fd 100644 --- a/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld +++ b/esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.rvfp.ld @@ -1,14 +1,14 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ /* ROM function interface esp32p4.rom.rvfp.ld for esp32p4 * * - * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum 56d78222be1daa0502090a078288f4d5 * - * Compatible with ROM where ECO version equal or greater to 0. + * Compatible with ROM where ECO version equal or greater to 5. * * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. */ @@ -16,101 +16,86 @@ /*************************************** Group rvfplibdf ***************************************/ -/* - * These functions cannot work when compiling with floating point ABI - * implementation assumes argument is passed in a0, but floats will be passed - * in the floating point registers instead - * - * __fixsfdi = 0x4fc00878; - * __fixunssfdi = 0x4fc00880; - */ /* Functions */ -__adddf3 = 0x4fc00868; -__eqdf2 = 0x4fc0086c; -__fixdfdi = 0x4fc00870; -__fixdfsi = 0x4fc00874; -__fixunsdfsi = 0x4fc0087c; -__floatdidf = 0x4fc00884; -__floatsidf = 0x4fc00888; -__floatundidf = 0x4fc0088c; -__floatunsidf = 0x4fc00890; -__gedf2 = 0x4fc00894; -__gtdf2 = 0x4fc00898; -__ledf2 = 0x4fc0089c; -__ltdf2 = 0x4fc008a0; -__muldf3 = 0x4fc008a4; -__nedf2 = 0x4fc008a8; -__subdf3 = 0x4fc008ac; +__adddf3 = 0x4fc0085c; +__eqdf2 = 0x4fc00860; +__fixdfdi = 0x4fc00864; +__fixdfsi = 0x4fc00868; +__fixunsdfsi = 0x4fc00870; +__floatdidf = 0x4fc00878; +__floatsidf = 0x4fc0087c; +__floatundidf = 0x4fc00880; +__floatunsidf = 0x4fc00884; +__gedf2 = 0x4fc00888; +__gtdf2 = 0x4fc0088c; +__ledf2 = 0x4fc00890; +__ltdf2 = 0x4fc00894; +__muldf3 = 0x4fc00898; +__nedf2 = 0x4fc0089c; +__subdf3 = 0x4fc008a0; /*************************************** Group libgcc ***************************************/ -/* Not part of the original ROM interface, but RVFP versions cannot work with float-abi */ -__fixsfdi = 0x4fc007ac; -__fixunssfdi = 0x4fc007b4; - -/* Functions */ -__absvdi2 = 0x4fc0073c; -__absvsi2 = 0x4fc00740; -__addvdi3 = 0x4fc00748; -__addvsi3 = 0x4fc0074c; -__ashldi3 = 0x4fc00750; -__ashrdi3 = 0x4fc00754; -__bswapdi2 = 0x4fc00758; -__bswapsi2 = 0x4fc0075c; -__clear_cache = 0x4fc00760; -__clrsbdi2 = 0x4fc00764; -__clrsbsi2 = 0x4fc00768; -__clzdi2 = 0x4fc0076c; -__clzsi2 = 0x4fc00770; -__cmpdi2 = 0x4fc00774; -__ctzdi2 = 0x4fc00778; -__ctzsi2 = 0x4fc0077c; -__divdc3 = 0x4fc00780; -__divdf3 = 0x4fc00784; -__divdi3 = 0x4fc00788; -__divsc3 = 0x4fc0078c; -__divsi3 = 0x4fc00790; -__extendsfdf2 = 0x4fc00798; -__ffsdi2 = 0x4fc0079c; -__ffssi2 = 0x4fc007a0; -__fixunssfsi = 0x4fc007b8; -__floatdisf = 0x4fc007c0; -__floatundisf = 0x4fc007cc; -__gcc_bcmp = 0x4fc007d4; -__lshrdi3 = 0x4fc007e4; -__moddi3 = 0x4fc007ec; -__modsi3 = 0x4fc007f0; -__muldc3 = 0x4fc007f4; -__muldi3 = 0x4fc007fc; -__mulsc3 = 0x4fc00800; -__mulsi3 = 0x4fc00804; -__mulvdi3 = 0x4fc00808; -__mulvsi3 = 0x4fc0080c; -__negdf2 = 0x4fc00814; -__negdi2 = 0x4fc00818; -__negvdi2 = 0x4fc0081c; -__negvsi2 = 0x4fc00820; -__paritysi2 = 0x4fc00824; -__popcountdi2 = 0x4fc00828; -__popcountsi2 = 0x4fc0082c; -__powidf2 = 0x4fc00830; -__subvdi3 = 0x4fc00838; -__subvsi3 = 0x4fc0083c; -__ucmpdi2 = 0x4fc00840; -__udivdi3 = 0x4fc00844; -__udivmoddi4 = 0x4fc00848; -__udivsi3 = 0x4fc0084c; -__udiv_w_sdiv = 0x4fc00850; -__umoddi3 = 0x4fc00854; -__umodsi3 = 0x4fc00858; -__unorddf2 = 0x4fc0085c; -__extenddftf2 = 0x4fc00860; -__trunctfdf2 = 0x4fc00864; -/*************************************** - Group libgcc -***************************************/ - /* Functions */ +__absvdi2 = 0x4fc00730; +__absvsi2 = 0x4fc00734; +__addvdi3 = 0x4fc0073c; +__addvsi3 = 0x4fc00740; +__ashldi3 = 0x4fc00744; +__ashrdi3 = 0x4fc00748; +__bswapdi2 = 0x4fc0074c; +__bswapsi2 = 0x4fc00750; +__clear_cache = 0x4fc00754; +__clrsbdi2 = 0x4fc00758; +__clrsbsi2 = 0x4fc0075c; +__clzdi2 = 0x4fc00760; +__clzsi2 = 0x4fc00764; +__cmpdi2 = 0x4fc00768; +__ctzdi2 = 0x4fc0076c; +__ctzsi2 = 0x4fc00770; +__divdc3 = 0x4fc00774; +__divdf3 = 0x4fc00778; +__divdi3 = 0x4fc0077c; +__divsc3 = 0x4fc00780; +__divsi3 = 0x4fc00784; +__extendsfdf2 = 0x4fc0078c; +__ffsdi2 = 0x4fc00790; +__ffssi2 = 0x4fc00794; +__fixsfdi = 0x4fc007a0; +__fixunssfdi = 0x4fc007a8; +__fixunssfsi = 0x4fc007ac; +__floatdisf = 0x4fc007b4; +__floatundisf = 0x4fc007c0; +__gcc_bcmp = 0x4fc007c8; +__lshrdi3 = 0x4fc007d8; +__moddi3 = 0x4fc007e0; +__modsi3 = 0x4fc007e4; +__muldc3 = 0x4fc007e8; +__muldi3 = 0x4fc007f0; +__mulsc3 = 0x4fc007f4; +__mulsi3 = 0x4fc007f8; +__mulvdi3 = 0x4fc007fc; +__mulvsi3 = 0x4fc00800; +__negdf2 = 0x4fc00808; +__negdi2 = 0x4fc0080c; +__negvdi2 = 0x4fc00810; +__negvsi2 = 0x4fc00814; +__paritysi2 = 0x4fc00818; +__popcountdi2 = 0x4fc0081c; +__popcountsi2 = 0x4fc00820; +__powidf2 = 0x4fc00824; +__subvdi3 = 0x4fc0082c; +__subvsi3 = 0x4fc00830; +__ucmpdi2 = 0x4fc00834; +__udivdi3 = 0x4fc00838; +__udivmoddi4 = 0x4fc0083c; +__udivsi3 = 0x4fc00840; +__udiv_w_sdiv = 0x4fc00844; +__umoddi3 = 0x4fc00848; +__umodsi3 = 0x4fc0084c; +__unorddf2 = 0x4fc00850; +__extenddftf2 = 0x4fc00854; +__trunctfdf2 = 0x4fc00858; From a3fcecec038d02984f528294a81a8e3207ed42f6 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Sun, 3 May 2026 21:36:16 +0900 Subject: [PATCH 13/27] PSRAM porting for P4X --- esp-bootloader-esp-idf/CHANGELOG.md | 4 + esp-bootloader-esp-idf/Cargo.toml | 2 +- esp-bootloader-esp-idf/src/partitions.rs | 9 +- esp-hal/README.md | 12 +- esp-hal/esp_config.yml | 16 + esp-hal/ld/esp32p4/memory.x | 70 +- esp-hal/src/interrupt/mod.rs | 2 + esp-hal/src/lib.rs | 14 +- esp-hal/src/psram/esp32p4.rs | 1112 ++++++++++++----- esp-hal/src/rtc_cntl/sleep/esp32p4.rs | 8 +- esp-hal/src/soc/esp32p4/clocks.rs | 20 +- esp-hal/src/system.rs | 22 +- .../src/_build_script_utils.rs | 12 - esp-metadata/CHANGELOG.md | 5 + esp-metadata/devices/esp32p4.toml | 53 +- esp-rom-sys/CHANGELOG.md | 7 + 16 files changed, 940 insertions(+), 428 deletions(-) diff --git a/esp-bootloader-esp-idf/CHANGELOG.md b/esp-bootloader-esp-idf/CHANGELOG.md index 3600f31d246..292d0eb29ce 100644 --- a/esp-bootloader-esp-idf/CHANGELOG.md +++ b/esp-bootloader-esp-idf/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- ESP32-P4: Use ROM CRC32 / MD5 functions instead of the software fallback, + matching the behavior on every other supported chip. Made possible by the + new `rom_crc_le`, `rom_crc_be`, `rom_md5_bsd` cfg flags emitted from + `esp-metadata`. ### Fixed diff --git a/esp-bootloader-esp-idf/Cargo.toml b/esp-bootloader-esp-idf/Cargo.toml index fd30f97e2d2..f4a98750336 100644 --- a/esp-bootloader-esp-idf/Cargo.toml +++ b/esp-bootloader-esp-idf/Cargo.toml @@ -83,7 +83,7 @@ esp32c61 = ["esp-rom-sys/esp32c61", "esp-metadata-generated/esp32c61", "esp-ha ## esp32h2 = ["esp-rom-sys/esp32h2", "esp-metadata-generated/esp32h2", "esp-hal/esp32h2"] ## -esp32p4 = ["esp-rom-sys/esp32p4", "esp-metadata-generated/esp32p4", "esp-hal/esp32p4", "dep:crc", "dep:md-5"] +esp32p4 = ["esp-rom-sys/esp32p4", "esp-metadata-generated/esp32p4", "esp-hal/esp32p4"] ## esp32 = ["esp-rom-sys/esp32", "esp-metadata-generated/esp32", "esp-hal/esp32"] ## diff --git a/esp-bootloader-esp-idf/src/partitions.rs b/esp-bootloader-esp-idf/src/partitions.rs index 4fd09be92e2..913cc217aef 100644 --- a/esp-bootloader-esp-idf/src/partitions.rs +++ b/esp-bootloader-esp-idf/src/partitions.rs @@ -337,12 +337,11 @@ impl<'a> PartitionTable<'a> { ((0x600c5000 as *const u32).read_volatile() & 0xff) << 16 }; } else if #[cfg(feature = "esp32p4")] { - // P4: SPI_MEM_C (SPI0) at 0x5008C000 - // Ref: esp-idf reg_base.h -- DR_REG_FLASH_SPI0_BASE = 0x5008C000 - // TODO(P4X): verify MSPI register for partition physical address read + // DR_REG_FLASH_SPI0_BASE : 0x5008C000 = DR_REG_HPPERIPH0_BASE + 0x8C000 + // TODO: verify MSPI register for partition physical address read let paddr = unsafe { - ((0x5008C000 + 0x380) as *mut u32).write_volatile(0); - (((0x5008C000 + 0x37c) as *const u32).read_volatile() & 0xff) << 16 + ((0x5008C000 + 0x380) as *mut u32).write_volatile(0); // SPI_MEM_C_MMU_ITEM_INDEX_REG + (((0x5008C000 + 0x37c) as *const u32).read_volatile() & 0xff) << 16 // SPI_MEM_C_MMU_ITEM_CONTENT_REG }; } else if #[cfg(any(feature = "esp32c5", feature = "esp32c6", feature = "esp32c61", feature = "esp32h2"))] { let paddr = unsafe { diff --git a/esp-hal/README.md b/esp-hal/README.md index 437d2fa39d6..2b6a7210295 100644 --- a/esp-hal/README.md +++ b/esp-hal/README.md @@ -58,8 +58,8 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | Driver | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ------------------------- |:-----:|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:|:--------:| -| ADC | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | [❌][5422] [^1] | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| AES | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| ADC | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | [❌][5422] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | +| AES | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | ASSIST_DEBUG | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | ⚒️ | | Analog Voltage Comparator | | | | [❌][5168] [^1] | | [❌][5423] [^1] | | | | | | Bit Scrambler | | | | [❌][5170] [^1] | | | | | | | @@ -70,7 +70,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | DMA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | DS | | | [❌][884] [^1] | [❌][884] [^1] | [❌][884] [^1] | | [❌][884] [^1] | | [❌][884] [^1] | [❌][884] [^1] | | ECDSA | | | | [❌][5444] [^1] | | [❌][5444] [^1] | [❌][5444] [^1] | | | | -| ECC | | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | +| ECC | | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | | | | Ethernet | ❌ | | | | | | | | | | | ETM | | | | [❌][5167] [^1] | ⚒️ | [❌][5419] [^1] | ⚒️ | | | | | GPIO | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ✔️ | @@ -93,11 +93,11 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | RGB display | ⚒️ | | | | | | | | ❌ | ⚒️ | | RMT | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | | RNG | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | -| RSA | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| RSA | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | RTC Timekeeping | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | SDIO host | ⚒️ | | | | | | | | | ⚒️ | | SDIO slave | ⚒️ | | | [❌][5169] [^1] | ⚒️ | [❌][5417] [^1] | | | | | -| SHA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| SHA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | ⚒️ | ⚒️ | | Light/deep sleep | ⚒️ | ⚒️ | ⚒️ | [❌][5165] [^1] | ⚒️ | [❌][5424] [^1] | ⚒️ | | ⚒️ | ⚒️ | | SPI master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | | SPI slave | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | @@ -105,7 +105,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | Temperature sensor | ⚒️ | ⚒️ | ⚒️ | [❌][5153] [^1] | ⚒️ | [❌][5421] [^1] | ⚒️ | | ⚒️ | ⚒️ | | Timers | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | Touch | ⚒️ | | | [❌][5164] [^1] | | | | | [❌][1905] [^1] | [❌][1905] [^1] | -| TWAI / CAN / CANFD | ⚒️ | | ⚒️ | [❌][5163] [^1] | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | +| TWAI / CAN / CANFD | ⚒️ | | ⚒️ | [❌][5163] [^1] | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | UART | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | | UHCI | ❌ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ❌ | ⚒️ | | ULP (FSM) | ⚒️ | | | | | | | | ⚒️ | ⚒️ | diff --git a/esp-hal/esp_config.yml b/esp-hal/esp_config.yml index 720038551fd..72189935d5c 100644 --- a/esp-hal/esp_config.yml +++ b/esp-hal/esp_config.yml @@ -168,6 +168,22 @@ options: - "8" active: 'chip == "esp32s3"' + - name: l2-cache-size + description: "ESP32-P4 L2 cache size. Must match the 2nd-stage bootloader's + `CACHE.L2_CACHE_CACHESIZE_CONF` setting (TRM L2MEM Config 0..3). Default + `256KB` matches the IDF bootloader bundled by espflash." + default: + - value: '"256KB"' + constraints: + - type: + validator: enumeration + value: + - "0KB" + - "128KB" + - "256KB" + - "512KB" + active: 'chip == "esp32p4"' + - name: min-chip-revision description: "The minimum chip revision required for the application to run, in format: major * 100 + minor." default: diff --git a/esp-hal/ld/esp32p4/memory.x b/esp-hal/ld/esp32p4/memory.x index 3b1c0b88fbe..05e46a6cf4a 100644 --- a/esp-hal/ld/esp32p4/memory.x +++ b/esp-hal/ld/esp32p4/memory.x @@ -1,47 +1,39 @@ -/* ESP32-P4X (chip revision v3.x incl. v3.2 / eco7) Memory Layout - * - * Source: esp-idf soc.h, TRM v0.5, Chip Revision v3.x User Guide v1.0, - * esp-idf 6.1 memory.ld (generated), esptool esp32p4.py - * Target: ESP32-P4NRW16X / ESP32-P4NRW32X only (NOT NRND variants) - * - * WARNING: Chip revision v3.x changed L2MEM cached region mapping - * from top-down to bottom-up (vs v1.x). This linker script is - * specifically for v3.x silicon. - * - * Memory map verified against esp-idf: - * SOC_IRAM_LOW = 0x4FF00000 - * SOC_IRAM_HIGH = 0x4FFC0000 (768 KB total L2MEM) - * SOC_DIRAM_ROM_RESERVE_HIGH = 0x4FF40000 (ROM uses first 256 KB, low end) - * SOC_RTC_IRAM_LOW = 0x50108000 - * SOC_RTC_IRAM_HIGH = 0x50110000 (32 KB LP SRAM) - * SOC_EXTRAM_LOW = 0x48000000 (PSRAM, up to 64 MB via cache) - * - * CRITICAL (v3.x): ROM ALSO reserves the TOP of L2MEM for BSS/stack. - * esptool: BSS_UART_DEV_ADDR = 0x4FFBFEB0 for chip revision >= v3.0 - * esp-idf sram_seg ends at 0x4FFAEFC0 (leaves ~68KB at top for ROM) - * Writing into this region during Rust startup corrupts ROM UART - * state and the bootloader immediately prints "user code done" - * because the UART_DEV struct was trashed by _start's stack push. - */ +/* The 768 KB L2MEM is shared between L2 cache (low end) and L2 RAM + (rest). The 2nd-stage bootloader programs CACHE.L2_CACHE_CACHESIZE_CONF + to one of four splits; the L2 RAM ORIGIN below must match. Top is + fixed at 0x4FFAE000 to leave the v3.x ROM BSS/stack region (top + ~72 KB of L2MEM) untouched. + + CONFIG ESP_HAL_CONFIG_L2_CACHE_SIZE L2 cache L2 RAM ORIGIN + ------ ---------------------------- -------- ------------- + 3 "512KB" 512 KB 0x4FF80000 + 2 "256KB" 256 KB 0x4FF40000 + 1 "128KB" (IDF default) 128 KB 0x4FF20000 + 0 "0KB" 0 KB 0x4FF00000 +*/ MEMORY { - /* 768 KB HP L2MEM (on-chip SRAM) - * Full range: 0x4FF00000 - 0x4FFC0000 - * Low reserve (ROM bootloader): 0x4FF00000 - 0x4FF40000 (256 KB) - * High reserve (ROM BSS/stack, v3+): 0x4FFAE000 - 0x4FFC0000 (~72 KB) - * Usable for application: 0x4FF40000 - 0x4FFAE000 (440 KB) - */ - RAM : ORIGIN = 0x4FF40000, LENGTH = 0x6E000 + /* CONFIG 3 */ +#IF ESP_HAL_CONFIG_L2_CACHE_SIZE_512KB + RAM : ORIGIN = 0x4FF80000, LENGTH = 0x4FFAE000 - 0x4FF80000 +#ENDIF + /* CONFIG 2 */ +#IF ESP_HAL_CONFIG_L2_CACHE_SIZE_256KB + RAM : ORIGIN = 0x4FF40000, LENGTH = 0x4FFAE000 - 0x4FF40000 +#ENDIF + /* CONFIG 1 */ +#IF ESP_HAL_CONFIG_L2_CACHE_SIZE_128KB + RAM : ORIGIN = 0x4FF20000, LENGTH = 0x4FFAE000 - 0x4FF20000 +#ENDIF + /* CONFIG 0 */ +#IF ESP_HAL_CONFIG_L2_CACHE_SIZE_0KB + RAM : ORIGIN = 0x4FF00000, LENGTH = 0x4FFAE000 - 0x4FF00000 +#ENDIF - /* External flash (XIP via cache) - * Mapped at 0x40000000, up to 64 MB - * +0x20 offset to skip flash header - */ + /* External flash (XIP via cache); +0x20 skips the IDF app image header. */ ROM : ORIGIN = 0x40000000 + 0x20, LENGTH = 0x400000 - 0x20 - /* LP SRAM (32 KB, persists over deep sleep) - * Used by LP core and RTC fast memory - */ + /* LP SRAM (32 KB, persists over deep sleep). */ RTC_FAST : ORIGIN = 0x50108000, LENGTH = 32K } diff --git a/esp-hal/src/interrupt/mod.rs b/esp-hal/src/interrupt/mod.rs index 6ad08181fb5..0d7ba96fca3 100644 --- a/esp-hal/src/interrupt/mod.rs +++ b/esp-hal/src/interrupt/mod.rs @@ -69,6 +69,8 @@ mod xtensa; use crate::pac; unstable_driver! { + // TODO: Remove this workaround of P4 and resolve true reason. + #[cfg(not(esp32p4))] pub mod software; } diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index da35f7e51dd..174b88f63c5 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -197,7 +197,19 @@ fn main() -> ! { #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![allow(asm_sub_register, async_fn_in_trait, stable_features)] #![cfg_attr(xtensa, feature(asm_experimental_arch))] -#![deny(missing_docs, rust_2018_idioms, rustdoc::all)] +// `define_clock_tree_types!()` reads doc strings from the chip's +// `esp-metadata/devices/.toml` `[device.clock_tree]` section. +// Other chips (C2/C3/C5/C6/C61/H2/S2/S3, ESP32) populate those strings; +// our esp32p4.toml `[device.clock_tree]` is still partial, so the macro +// emits undocumented public items for P4 with `unstable`. Downgrade +// missing_docs to a warning for P4 only. +// +// TODO: fill the doc strings in `esp-metadata/devices/esp32p4.toml` +// `[device.clock_tree]` so we can promote this back to `deny`. See +// other chips' TOMLs for the field convention. +#![cfg_attr(not(esp32p4), deny(missing_docs))] +#![cfg_attr(esp32p4, warn(missing_docs))] +#![deny(rust_2018_idioms, rustdoc::all)] #![allow(rustdoc::private_doc_tests)] // compile tests are done via rustdoc #![cfg_attr(docsrs, feature(doc_cfg, custom_inner_attributes, proc_macro_hygiene))] // Don't trip up on broken/private links when running semver-checks diff --git a/esp-hal/src/psram/esp32p4.rs b/esp-hal/src/psram/esp32p4.rs index 7961ea39841..bbded01c310 100644 --- a/esp-hal/src/psram/esp32p4.rs +++ b/esp-hal/src/psram/esp32p4.rs @@ -1,286 +1,767 @@ -//! PSRAM driver for ESP32-P4X (chip revision v3.x / eco5). +//! PSRAM driver for ESP32-P4X (chip revision v3.x / ECO5+). //! -//! P4 PSRAM uses HEX (16-line) mode via dedicated MSPI2/3 controller. -//! Memory mapped at 0x4800_0000 - 0x4C00_0000 (64 MB via cache/MMU). -//! -//! Init sequence (from esp-idf esp_psram_impl_ap_hex.c): -//! 1. MPLL enable (400 MHz for 200MHz PSRAM bus clock) -//! 2. MSPI2/3 module clock enable + clock source = MPLL -//! 3. Bus clock divider (MPLL/2 = 200MHz) -//! 4. PSRAM read/write command config (HEX sync mode) -//! 5. Address, dummy, DDR mode config -//! 6. AXI access enable -//! 7. Cache/MMU page mapping -//! -//! Ref: esp-idf components/esp_psram/device/esp_psram_impl_ap_hex.c -//! esp-idf components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h -//! esp-idf components/soc/esp32p4/include/soc/regi2c_mpll.h -//! esp-idf components/hal/esp32p4/include/hal/mmu_ll.h -//! TRM v0.5 Ch 9 (System and Memory) +//! P4 has two PSRAM controllers wired to the same DQ pads +//! The structure is looks same with DDR controller but not same. /// PSRAM virtual address range (cached) -/// Ref: esp-idf ext_mem_defs.h -- SOC_IRAM_PSRAM_ADDRESS_LOW/HIGH pub const PSRAM_VADDR_START: usize = 0x4800_0000; /// MMU page size (64 KB) const MMU_PAGE_SIZE: usize = 0x10000; +/// PSRAM_MSPI0 base, AXI cache controller. +/// CAUTION: Missing area of TRM. +const MSPI0_BASE: u32 = 0x5008_E000; + +/// PSRAM_MSPI1 base, direct-command controller. +/// CAUTION: Missing area of TRM. +const MSPI1_BASE: u32 = 0x5008_F000; + +/// Volatile 32-bit read. +#[inline(always)] +unsafe fn mmio_read_32(addr: u32) -> u32 { + unsafe { (addr as *const u32).read_volatile() } +} + +/// Volatile 32-bit write (full overwrite). +#[inline(always)] +unsafe fn mmio_write_32(addr: u32, val: u32) { + unsafe { (addr as *mut u32).write_volatile(val) } +} + +/// Read-modify-write: set every bit of `mask`. Equivalent to +/// `*addr |= mask`. +#[inline(always)] +unsafe fn mmio_setbits_32(addr: u32, mask: u32) { + unsafe { mmio_write_32(addr, mmio_read_32(addr) | mask) } +} + +/// Read-modify-write: clear every bit of `mask`. Equivalent to +/// `*addr &= !mask`. +#[inline(always)] +unsafe fn mmio_clrbits_32(addr: u32, mask: u32) { + unsafe { mmio_write_32(addr, mmio_read_32(addr) & !mask) } +} + +/// Read-modify-write: clear `clear`-bits then set `set`-bits. +/// Equivalent to `*addr = (*addr & !clear) | set`. +#[inline(always)] +unsafe fn mmio_clrsetbits_32(addr: u32, clear: u32, set: u32) { + unsafe { mmio_write_32(addr, (mmio_read_32(addr) & !clear) | set) } +} + +/// PSRAM interface mode (line count of the data bus). Mirrors IDF's +/// `CONFIG_SPIRAM_MODE_*`. +/// +/// Only `Hex` is currently exercised by this driver; selecting `Oct` +/// requires the cache-side controller config (`mem_sdin_hex` / +/// `mem_sdout_hex` bits) and chip MR8.x16 to flip together. Wire that +/// path before exposing. +#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[instability::unstable] +pub enum PsramMode { + /// 16-line DDR, AP HEX PSRAM with MR8.x16 = 1. Default. + #[default] + Hex, + /// 8-line DDR, MR8.x16 = 0. Not yet implemented in this driver. + Oct, +} + +/// PSRAM bus frequency. Choice ties together MPLL freq + bus divider +/// + chip-side read/write latency (each `SpiRamFreq` corresponds to a +/// `(MPLL, div, RL, WL, RD_dummy_bits, WR_dummy_bits)` tuple). +/// +/// Variants referenced from `CONFIG_SPIRAM_SPEED_*`. +/// +/// | Variant | MPLL | div | MR0.RL | MR4.WL | RD dummy bits | Use case | +/// |-----------|------|-----|--------|--------|---------------|----------| +/// | `Mhz20` | 400 | 20 | 2 | 2 | 18 | Low-power / debug | +/// | `Mhz80` | 320 | 4 | 2 | 2 | 18 | Conservative SI margin | +/// | `Mhz200` | 400 | 2 | 4 | 1 | 26 | IDF default | +/// | `Mhz250` | 500 | 2 | 6 | 3 | 34 | Overclock, **silicon rev v3+ only** | +/// +#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[instability::unstable] +pub enum SpiRamFreq { + /// 20 MHz bus (MPLL 400 / div 20). Lowest-power option; + /// rarely used outside debug. + Mhz20 = 20, + /// 80 MHz bus (MPLL 320 / div 4). Conservative; widest timing + /// margin. + Mhz80 = 80, + /// 200 MHz bus (MPLL 400 / div 2). IDF default for AP HEX PSRAM. + /// Validated on the EV board. + #[default] + Mhz200 = 200, + /// 250 MHz bus (MPLL 500 / div 2). Top speed, silicon rev v3+ only. + Mhz250 = 250, +} + +/// MPLL target frequency override. +/// +/// IDF only programs three discrete MPLL frequencies for the PSRAM +/// clock domain (`MSPI_TIMING_MPLL_FREQ_MHZ` in +/// `mspi_timing_tuning_configs.h`): +/// +/// - `Mhz320` -> paired with `SpiRamFreq::Mhz80` +/// - `Mhz400` -> paired with `SpiRamFreq::Mhz20` / `Mhz200` +/// - `Mhz500` -> paired with `SpiRamFreq::Mhz250` (silicon v3+) +/// +/// The MPLL itself can in principle be set to any value that satisfies +/// the formula `XTAL(40) * (div+1) / (ref_div+1)`, but only these three +/// have been silicon-validated. +#[derive(Copy, Clone, Debug, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[instability::unstable] +pub enum MpllFreq { + /// 320 MHz. IDF pairing: `SpiRamFreq::Mhz80`. + Mhz320 = 320, + /// 400 MHz. IDF pairing: `SpiRamFreq::Mhz20` or `Mhz200`. Default + /// when `core_clock = None` and `ram_frequency = Mhz200`. + Mhz400 = 400, + /// 500 MHz. IDF pairing: `SpiRamFreq::Mhz250` (silicon v3.0+). + Mhz500 = 500, +} + /// PSRAM configuration. #[derive(Copy, Clone, Debug, Default, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[instability::unstable] pub struct PsramConfig { - /// Size of PSRAM to map + /// PSRAM interface mode (Hex 16-line vs Oct 8-line). Default: Hex. + pub mode: PsramMode, + /// Size of PSRAM to map. Default: `AutoDetect` via MR2 density. pub size: super::PsramSize, + /// MPLL override. `None` (default) derives the MPLL frequency + /// from `ram_frequency` per the table on `SpiRamFreq`. + pub core_clock: Option, + /// PSRAM bus frequency. Default: 200 MHz. + pub ram_frequency: SpiRamFreq, + + // TODO: ECC enable. + // The MSPI0 controller has a ECC engine. + // pub ecc: bool, // or any other enum. } /// Initialize PSRAM. -/// -/// Ref: esp-idf esp_psram_impl_enable() in esp_psram_impl_ap_hex.c -/// -/// Signature matches the post-merge (esp-hal 1.1.0-rc.0+) convention: -/// returns `true` on successful bring-up. Our P4 implementation is not -/// yet hardware-validated, so we always return `true` optimistically -- -/// this crate's `psram::Psram::new` only uses the return value to decide -/// whether to `map_psram`, and if the caller hasn't wired up PSRAM pins -/// they won't construct the `Psram` handle anyway. pub(crate) fn init_psram(config: &mut PsramConfig) -> bool { - init_psram_inner(*config); + init_psram_inner(config); true } -/// Returns the virtual-address range that the PSRAM was mapped into. -/// Called by `Psram::new` right after `init_psram` returns true. pub(crate) fn map_psram(config: PsramConfig) -> core::ops::Range { let size = config.size.get(); PSRAM_VADDR_START..PSRAM_VADDR_START + size } -// TODO: Test and debug with several PSRAM size -fn init_psram_inner(config: PsramConfig) { - // 1. Enable MPLL (400 MHz) for PSRAM clock - configure_mpll(400); +/// Per-speed timing parameters. Mirrors IDF's `#if CONFIG_SPIRAM_SPEED_*` +/// branches in `esp_psram_impl_ap_hex.c` + `mspi_timing_tuning_configs.h`. +#[derive(Copy, Clone)] +struct SpeedParams { + /// MPLL freq the analog block must run at. + mpll_mhz: u32, + /// Bus clock divider applied to MPLL. + bus_div: u32, + /// MR0.read_latency field value (cycles = 2 * value + 6). + mr0_rl: u8, + /// MR4.wr_latency field value. + mr4_wl: u8, + /// Read dummy length in bits for sync data reads (cache path). + rd_dummy_bits: u32, + /// Write dummy length in bits for sync data writes (cache path). + wr_dummy_bits: u32, + /// Register-read dummy length for direct command path (MSPI3). + reg_dummy_bits: u32, +} + +impl SpeedParams { + const fn for_freq(f: SpiRamFreq) -> Self { + match f { + SpiRamFreq::Mhz20 => Self { + mpll_mhz: 400, + bus_div: 20, + mr0_rl: 2, + mr4_wl: 2, + rd_dummy_bits: 18, // 2*(10-1) + wr_dummy_bits: 8, // 2*(5-1) + reg_dummy_bits: 8, // 2*(5-1) + }, + SpiRamFreq::Mhz80 => Self { + mpll_mhz: 320, + bus_div: 4, + mr0_rl: 2, + mr4_wl: 2, + rd_dummy_bits: 18, + wr_dummy_bits: 8, + reg_dummy_bits: 8, + }, + SpiRamFreq::Mhz200 => Self { + mpll_mhz: 400, + bus_div: 2, + mr0_rl: 4, + mr4_wl: 1, + rd_dummy_bits: 26, // 2*(14-1) + wr_dummy_bits: 12, // 2*(7-1) + reg_dummy_bits: 12, + }, + SpiRamFreq::Mhz250 => Self { + mpll_mhz: 500, + bus_div: 2, + mr0_rl: 6, + mr4_wl: 3, + rd_dummy_bits: 34, // 2*(18-1) + wr_dummy_bits: 16, // 2*(9-1) + reg_dummy_bits: 16, + }, + } + } +} + +/// CS timing constants (matches IDF AP_HEX_PSRAM_CS_*). Independent of +/// `SpiRamFreq` -- IDF uses the same values across all speed branches. +const AP_HEX_CS_SETUP_TIME: u32 = 4; +const AP_HEX_CS_HOLD_TIME: u32 = 4; +const AP_HEX_CS_HOLD_DELAY: u32 = 3; + +/// Module-scope shadow of the speed parameters set by `init_psram_inner`. +/// Read by the helper functions (`init_mr_registers`, `psram_mr_read`, +/// `configure_psram_mspi`) that need the dummy / latency values without +/// having `config` threaded through every signature. +/// +/// Initialised to `Mhz200` (IDF default, matches default of +/// `SpiRamFreq`) so the value is well-defined before +/// `init_psram_inner` runs; overwritten there based on +/// `config.ram_frequency`. Single-init, single-thread at boot, so a +/// plain `static mut` is enough. +static mut PSRAM_SPEED: SpeedParams = SpeedParams::for_freq(SpiRamFreq::Mhz200); + +/// Read the active speed parameters. Safe wrapper since we only mutate +/// this once at init before any concurrent access. +fn psram_speed() -> SpeedParams { + unsafe { PSRAM_SPEED } +} - // 2. Enable PSRAM controller clock and select MPLL source - // HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_en = 1 - // HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_src_sel = 1 (MPLL) +fn init_psram_inner(config: &mut PsramConfig) { + // Resolve the speed parameter set from `ram_frequency`. The MPLL + // override (`config.core_clock`) lets the caller bypass the default + // pairing (e.g. force 400 MHz MPLL with `Mhz20` bus); `None` + // selects the table-default for the chosen `ram_frequency`. + let mut params = SpeedParams::for_freq(config.ram_frequency); + if let Some(mpll) = config.core_clock { + params.mpll_mhz = mpll as u32; + } + unsafe { PSRAM_SPEED = params }; + + psram_phy_ldo_init(); // PMU EXT_LDO regulator setup for the MSPI PHY analog block. + configure_mpll(params.mpll_mhz); + + // Module clock + clock source let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); + clkrst + .soc_clk_ctrl0() + .modify(|_, w| w.psram_sys_clk_en().set_bit()); clkrst.peri_clk_ctrl00().modify(|_, w| unsafe { w.psram_pll_clk_en().set_bit(); w.psram_core_clk_en().set_bit(); w.psram_clk_src_sel().bits(1) // 1 = MPLL }); - // 3. Set bus clock divider: MPLL(400MHz) / 2 = 200MHz PSRAM bus - // SPI_MEM_S_SRAM_CLK_REG: SCLKCNT_N=1, SCLKCNT_H=0, SCLKCNT_L=1 - // TODO(esp32p4): These registers are in SPIMEM2 which may not be in PAC. - // Using direct MMIO for now. - // PSRAM MSPI controller base - const PSRAM_MSPI_BASE: u32 = 0x5008_E000; + // Controller + PHY pad bring-up. + set_bus_clock(params.bus_div); + enable_dll(); + psram_pad_init(); // required for DDR strobe latch + set_cs_timing(); - // 3a. Set PSRAM bus clock divider: MPLL(400MHz) / 2 = 200MHz - // Ref: SPI_MEM_S_SRAM_CLK_REG offset from PSRAM_MSPI_BASE - // sclkcnt_n=1, sclkcnt_h=0, sclkcnt_l=1 - // TODO(esp32p4): verify exact register offset for SRAM_CLK_REG - // const SRAM_CLK_OFFSET: u32 = ...; // need to find from spi_mem_s_reg.h + // SoC MR init (via MSPI3 SPI direct) + init_mr_registers(); + let psram_size = match config.size { + super::PsramSize::AutoDetect => psram_detect_size(), + super::PsramSize::Size(s) => s, + }; - // 3b. Configure PSRAM read/write commands for HEX sync mode - // SPI_MEM_S_CACHE_SCTRL_REG: cache_sram_usr_rcmd, cache_sram_usr_wcmd - // SPI_MEM_S_SRAM_DRD_CMD_REG: cmd_bitlen=15, cmd_value=0x0000 (sync read) - // SPI_MEM_S_SRAM_DWR_CMD_REG: cmd_bitlen=15, cmd_value=0x8080 (sync write) + config.size = super::PsramSize::Size(psram_size); - // 3c. Set address length (32-bit) and dummy cycles - // SPI_MEM_S_CACHE_SCTRL_REG: sram_addr_bitlen=31 (32-bit) - // rdummy_cyclelen=13 (14-1 at 200MHz), wdummy_cyclelen=6 (7-1) + configure_psram_mspi(MSPI0_BASE); // basic AXI configuration here + mmu_map_psram(MSPI0_BASE, *config); // MMU mapping here - // 3d. Enable DDR mode - // SPI_MEM_S_SMEM_DDR_REG: smem_ddr_en=1 + if psram_size > 0 { + let start = PSRAM_VADDR_START; + let end = start + psram_size; + unsafe { super::set_psram_range(start..end) }; + } +} - // 3e. Enable HEX data lines - // SPI_MEM_S_SRAM_CMD_REG: sdin_hex=1, sdout_hex=1 +/// Set bus-clock divider for both PSRAM_MSPI0 (SRAM_CLK at 0x50) and +/// PSRAM_MSPI1 (CLOCK at 0x14). For divider=2 the value is +/// (N=1)<<16 | (H=0)<<8 | (L=1)<<0 = 0x00010001. For divider=1 the +/// fast path bit `CLK_EQU_SYSCLK` (bit 31) is set instead. +fn set_bus_clock(div: u32) { + const MSPI0_SRAM_CLK: u32 = MSPI0_BASE + 0x50; + const MSPI1_CLOCK: u32 = MSPI1_BASE + 0x14; + + let val = if div == 1 { + 1u32 << 31 + } else { + ((div - 1) << 16) | ((div / 2 - 1) << 8) | (div - 1) + }; + unsafe { + mmio_write_32(MSPI0_SRAM_CLK, val); + mmio_write_32(MSPI1_CLOCK, val); + } +} - // 3f. Enable AXI access - // SPI_MEM_S_CACHE_FCTRL_REG: axi_req_en=1 +/// Enable DLL timing calibration for both controllers. Both DLL bits +/// live in MSPI0's register space (per IDF `psram_ctrlr_ll_enable_dll`): +fn enable_dll() { + /// MSPI3 DLL (0x5008_E180), bit 5 + const MEM_TIMING_CALI: u32 = MSPI0_BASE + 0x180; + /// MSPI2 DLL (0x5008_E190), bit 5 + const SMEM_TIMING_CALI: u32 = MSPI0_BASE + 0x190; + const DLL_BIT: u32 = 1 << 5; + unsafe { + mmio_setbits_32(MEM_TIMING_CALI, DLL_BIT); + mmio_setbits_32(SMEM_TIMING_CALI, DLL_BIT); + } +} - // 4. Configure PSRAM MSPI controller - // PSRAM_MSPI_BASE = 0x5008_E000 - configure_psram_mspi(PSRAM_MSPI_BASE); +/// IOMUX_MSPI_PIN base. Each PSRAM pad has a `..._PIN0_REG` at this base +/// plus the pad-specific offset given by `PsramPad`. +const IOMUX_MSPI_BASE: u32 = 0x500E_1200; + +/// PSRAM IOMUX pads. Discriminant = byte offset from `IOMUX_MSPI_BASE` +/// to that pad's `IOMUX_MSPI_PIN_PSRAM__PIN0_REG`. Per-pad DRV +/// field is bits [13:12]; DQS0 and DQS1 additionally have an XPD enable +/// at bit 0. +#[repr(u32)] +#[derive(Copy, Clone)] +enum PsramPad { + /// DQ0. Matches IDF `IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG` (legacy SPI + /// MOSI naming retained on the IOMUX register itself). + Dq0 = 0x1C, + /// DQ1. IDF `IOMUX_MSPI_PIN_PSRAM_Q_PIN0_REG` (legacy SPI MISO). + Dq1 = 0x20, + /// DQ2. IDF `IOMUX_MSPI_PIN_PSRAM_WP_PIN0_REG` (legacy WP). + Dq2 = 0x24, + /// DQ3. IDF `IOMUX_MSPI_PIN_PSRAM_HOLD_PIN0_REG` (legacy HOLD). + /// In OPI/HEX DDR mode the controller does not treat this as a + /// hold/freeze input -- it is a plain data line. + Dq3 = 0x28, + Dq4 = 0x2C, + Dq5 = 0x30, + Dq6 = 0x34, + Dq7 = 0x38, + Dqs0 = 0x3C, + Dq8 = 0x40, + Dq9 = 0x44, + Dq10 = 0x48, + Dq11 = 0x4C, + Dq12 = 0x50, + Dq13 = 0x54, + Dq14 = 0x58, + Dq15 = 0x5C, + Ck = 0x60, + Cs = 0x64, + Dqs1 = 0x68, +} - // 5. Map PSRAM via MMU (0x48000000 virtual -> physical) - mmu_map_psram(PSRAM_MSPI_BASE, config); +impl PsramPad { + /// Iteration order matches IDF `mspi_timing_ll_pin_drv_set` (all + /// 20 DDR-ish pads in numeric offset order). Add a new variant above + /// and append it here; `set_drv_all` will then cover it + /// automatically. + const ALL: [Self; 20] = [ + // DQ0 ~ DQ7 + Self::Dq0, + Self::Dq1, + Self::Dq2, + Self::Dq3, + Self::Dq4, + Self::Dq5, + Self::Dq6, + Self::Dq7, + /// Strobe0 + Self::Dqs0, + // DQ8 ~ DQ15 + Self::Dq8, + Self::Dq9, + Self::Dq10, + Self::Dq11, + Self::Dq12, + Self::Dq13, + Self::Dq14, + Self::Dq15, + // Ck and Cs + Self::Ck, + Self::Cs, + /// Strobe1 + Self::Dqs1, + ]; + + /// Absolute MMIO address of this pad's `~_PIN0_REG`. + fn reg_addr(self) -> u32 { + IOMUX_MSPI_BASE + self as u32 + } - // Determine PSRAM size - let psram_size = match config.size { - super::PsramSize::AutoDetect => psram_detect_size(PSRAM_MSPI_BASE), - super::PsramSize::Size(s) => s, - }; + /// Set this pad's drive-strength field (bits [13:12]) to `drv`, + /// preserving the other bits. + unsafe fn set_drv(self, drv: u32) { + unsafe { mmio_clrsetbits_32(self.reg_addr(), 0x3 << 12, (drv & 0x3) << 12) }; + } - // Set PSRAM range (virtual address space) - if psram_size > 0 { - let start = PSRAM_VADDR_START; - let end = start + psram_size; - unsafe { super::set_psram_range(start..end) }; + /// Set drive strength on every pad in `Self::ALL`. + unsafe fn set_drv_all(drv: u32) { + for pad in Self::ALL { + unsafe { pad.set_drv(drv) }; + } } - // TODO(esp32p4): Full PSRAM init needs: - // - SPIMEM2 read/write command configuration (HEX sync mode) - // - Address bitlen (32-bit), dummy cycles (14 read, 7 write at 200MHz) - // - CS timing, DDR mode enable - // - HEX data line mode (sdin_hex, sdout_hex) - // - AXI access enable (mem_axi_req_en) - // - Cache/MMU page mapping (SPI_MEM_S_MMU_ITEM_INDEX/CONTENT) - // - AP HEX PSRAM mode register initialization (MR0-MR8) - // - Timing calibration - // - // Without these, PSRAM memory at 0x48000000 is NOT accessible. - // The ROM bootloader may have already initialized PSRAM if esp-idf - // 2nd-stage bootloader was used. -} - -/// Detect PSRAM size by reading mode register MR2 via MSPI direct SPI command. -/// -/// AP HEX PSRAM MR2 format (bits [2:0] = density): -/// 0x1 = 32 Mbit (4 MB) -/// 0x3 = 64 Mbit (8 MB) -/// 0x5 = 128 Mbit (16 MB) -/// 0x7 = 256 Mbit (32 MB) + /// Set bit 0 (XPD power-up enable) of this pad's PIN0 register. + /// Used on strobe to power on the strobe input buffer needed. + unsafe fn enable_xpd(self) { + unsafe { mmio_setbits_32(self.reg_addr(), 1) }; + } +} + +/// Configure PSRAM PHY pads. Mirrors IDF `mspi_timing_ll_pin_drv_set(2)` +/// + `mspi_timing_ll_enable_dqs(true)`. Both DQS XPD bits must be on +/// for DDR reads to latch data; drive strength = 2 matches IDF default +/// for AP HEX PSRAM at 200 MHz. +fn psram_pad_init() { + unsafe { + PsramPad::set_drv_all(2); + PsramPad::Dqs0.enable_xpd(); + PsramPad::Dqs1.enable_xpd(); + } +} + +/// Set PSRAM CS timing on the AXI controller's SMEM_AC register +/// (0x5008_E1A0). SMEM_CS_SETUP=1, SMEM_CS_HOLD=1, setup_time=N-1, +/// hold_time=N-1, hold_delay=N-1, split_trans_en=1. +fn set_cs_timing() { + const SMEM_AC: u32 = MSPI0_BASE + 0x1A0; + unsafe { + let mut val = mmio_read_32(SMEM_AC); + // bit 0 SMEM_CS_SETUP + // bit 1 SMEM_CS_HOLD + // bit 31 SPLIT_TRANS_EN + val |= (1u32 << 31) | 0b11; + // bits 6..2 SETUP_TIME (5-bit, N-1) + // bits 11..7 HOLD_TIME (5-bit, N-1) + // bits 30..25 HOLD_DELAY (6-bit, N-1) + val = (val & !(0x1F << 2)) | ((AP_HEX_CS_SETUP_TIME - 1) << 2); + val = (val & !(0x1F << 7)) | ((AP_HEX_CS_HOLD_TIME - 1) << 7); + val = (val & !(0x3F << 25)) | ((AP_HEX_CS_HOLD_DELAY - 1) << 25); + mmio_write_32(SMEM_AC, val); + } +} + +// MR (a.k.a Mode Register with single byte inside the AP HEX PSRAM chip. + +const MR_ADDR_MR0_MR1: u32 = 0x0; +const MR_ADDR_MR2_MR3: u32 = 0x2; +const MR_ADDR_MR4_MR5: u32 = 0x4; + +/// MR6 only used in current state, MR7 is unused or reserved. +#[allow(dead_code)] // half-sleep trigger; kept for future power-down support +const MR_ADDR_MR6_MR7: u32 = 0x6; +/// MR8 only used in current state, MR9 is unused or reserved. +const MR_ADDR_MR8_MR9: u32 = 0x8; + +/// Read an 8-bit mode-register pair from the AP HEX PSRAM chip. /// -/// Read sequence: issue SPI command 0x40 (read MR), address 0x2 (MR2 index), -/// capture 8-bit MISO response. +/// Returns `(low, high)` where: +/// - `low` = the MR at `mr_addr` +/// - `high` = the MR at `mr_addr + 1` /// -/// Safety: if the MSPI controller is not in a known-good state or the command -/// hangs, we fall back to 32 MB (EV Board default). This is conservative but -/// avoids bricking on chips without PSRAM populated. +/// For pair addresses where the high byte is a reserved slot +/// (MR_ADDR_MR4_MR5 / MR_ADDR_MR6 / MR_ADDR_MR8_MR9 — see the table at the +/// `MR_ADDR_*` constants), the `high` value is don't-care and the +/// caller should ignore it. +fn psram_mr_read(mr_addr: u32) -> (u8, u8) { + let pair = mspi1_reg_read16(mr_addr); + ((pair & 0xFF) as u8, ((pair >> 8) & 0xFF) as u8) +} + +/// Write an 8-bit mode-register pair to the AP HEX PSRAM chip. /// -/// Ref: esp-idf esp_psram_impl_ap_hex.c -- psram_detect_size() -/// TRM v0.5 Ch 9 (MSPI) -- USER/CMD/ADDR/MISO registers -fn psram_detect_size(mspi_base: u32) -> usize { - const SPI_CMD: u32 = 0x00; - const SPI_ADDR: u32 = 0x04; - const SPI_USER: u32 = 0x18; - const SPI_USER1: u32 = 0x1C; - const SPI_USER2: u32 = 0x20; - const SPI_MISO_DLEN: u32 = 0x28; - const SPI_W0: u32 = 0x58; - - // USER: usr_command=bit31, usr_addr=bit30, usr_miso=bit28 - const USR_COMMAND: u32 = 1 << 31; - const USR_ADDR: u32 = 1 << 30; - const USR_MISO: u32 = 1 << 28; - // CMD: usr=bit18 - const CMD_USR: u32 = 1 << 18; +/// `low` goes to the MR at `mr_addr`, `high` goes to the MR at +/// `mr_addr + 1`. For pair addresses whose high slot is reserved, pass +/// the value previously read back (read-modify-write) to keep the chip +/// state consistent. +fn psram_mr_write(mr_addr: u32, low: u8, high: u8) { + let pair = (low as u16) | ((high as u16) << 8); + mspi1_reg_write16(mr_addr, pair) +} - unsafe { - // Command: 0x40 (read MR), command bitlen=7 (8-1) - ((mspi_base + SPI_USER2) as *mut u32).write_volatile((7 << 28) | 0x40); - // Address: MR2 index = 0x2, address bitlen=7 (8-1) in USER1 bits [31:26] - ((mspi_base + SPI_USER1) as *mut u32).write_volatile(7 << 26); - ((mspi_base + SPI_ADDR) as *mut u32).write_volatile(0x2); - // MISO length: 8-1 = 7 bits - ((mspi_base + SPI_MISO_DLEN) as *mut u32).write_volatile(7); - // Enable command + address + MISO phases - ((mspi_base + SPI_USER) as *mut u32).write_volatile(USR_COMMAND | USR_ADDR | USR_MISO); - - // Trigger transaction - ((mspi_base + SPI_CMD) as *mut u32).write_volatile(CMD_USR); - - // Wait for completion with timeout - let mut timeout = 100_000u32; - while ((mspi_base + SPI_CMD) as *const u32).read_volatile() & CMD_USR != 0 { - timeout -= 1; - if timeout == 0 { - // Timeout -> fall back to default (EV Board = 32 MB) - return 32 * 1024 * 1024; - } +/// Initialize AP HEX PSRAM mode registers via PSRAM_MSPI1 OPI DTR +/// referenced IDF `hex_psram_mode_reg_t`), missing on TRM +/// MR0: drive_str[1:0], read_latency[4:2], lt[5] +/// MR4: wr_latency[7:5] +/// MR8: bl[1:0], bt[2], rbx[3], x16[6] +fn init_mr_registers() { + // Read+modify+write MR0 (preserve MR1 high byte). + let (mut mr0, mr1) = psram_mr_read(MR_ADDR_MR0_MR1); + mr0 &= !(0x3 | (0x7 << 2) | (1 << 5)); + mr0 |= ((psram_speed().mr0_rl & 0x7) << 2) | (1 << 5); + psram_mr_write(MR_ADDR_MR0_MR1, mr0, mr1); + + // Read+modify+write MR4 (preserve MR5 reserved high byte). + let (mut mr4, mr5) = psram_mr_read(MR_ADDR_MR4_MR5); + mr4 &= !(0x7 << 5); + mr4 |= (psram_speed().mr4_wl & 0x7) << 5; + psram_mr_write(MR_ADDR_MR4_MR5, mr4, mr5); + + // do nothing for MR6 and MR7 + + // Read+modify+write MR8 (high byte is reserved/absent — pass 0). + let (mut mr8, mr9) = psram_mr_read(MR_ADDR_MR8_MR9); // MR9 is unused + mr8 &= !(0x3 | (1 << 2) | (1 << 3) | (1 << 6)); + mr8 |= 3 // bl = 3 (32-byte burst) + | (0 << 2) // bt = 0 + | (1 << 3) // rbx = 1 + | (1 << 6); // x16 = 1 + psram_mr_write(MR_ADDR_MR8_MR9, mr8, mr9); // keep previous MR9 +} + +/// Mirror of IDF's `esp_rom_spi_cmd_t` (rom/opi_flash.h). Layout must match +/// the C struct exactly; the ROM driver reads it via the pointer. +#[repr(C)] +struct EspRomSpiCmd { + cmd: u16, + cmd_bit_len: u16, + addr: *mut u32, + addr_bit_len: u32, + tx_data: *mut u32, + tx_data_bit_len: u32, + rx_data: *mut u32, + rx_data_bit_len: u32, + dummy_bit_len: u32, +} + +/// `esp_rom_spiflash_read_mode_t`. Only OPI_DTR is used here. +const ESP_ROM_SPIFLASH_OPI_DTR_MODE: u32 = 7; +/// MSPI controller index used for direct (non-cache) PSRAM commands. +/// Maps to `PSRAM_CTRLR_LL_MSPI_ID_3` in IDF (`PSRAM_MSPI1` = 0x5008_F000). +const ROM_SPI_PSRAM_CMD_NUM: i32 = 3; +/// CS mask: PSRAM lives on CS1 (bit 1). Flash on CS0. +const ROM_SPI_PSRAM_CS_MASK: u8 = 1 << 1; + +unsafe extern "C" { + /// Set the controller's read mode (e.g. OPI-DTR). Configures cmd/addr/ + /// data line counts (8-line for OPI) and DDR mode bits in one call. + /// Linked from `esp32p4.rom.ld`: `esp_rom_spi_set_op_mode = 0x4fc00110`. + fn esp_rom_spi_set_op_mode(spi_num: i32, mode: u32); + /// Configure command/addr/dummy/data phases for next transaction. + /// Writes USR / USER1 / USER2 / ADDR / MOSI_DLEN / MISO_DLEN / W0.. + /// Linked from `esp32p4.rom.ld`: `esp_rom_spi_cmd_config = 0x4fc00108`. + fn esp_rom_spi_cmd_config(spi_num: i32, pcmd: *mut EspRomSpiCmd); + + /// `Cache_Suspend_L1_DCache = 0x4fc004f8`. Stops new D-cache fills, + /// drains in-flight transactions, returns previous-state token. + fn Cache_Suspend_L1_DCache() -> u32; + /// `Cache_Resume_L1_DCache = 0x4fc004fc`. Restores D-cache from token. + fn Cache_Resume_L1_DCache(autoload_state: u32); + /// `Cache_Suspend_L2_Cache = 0x4fc00508`. + fn Cache_Suspend_L2_Cache() -> u32; + /// `Cache_Resume_L2_Cache = 0x4fc0050c`. + fn Cache_Resume_L2_Cache(autoload_state: u32); + /// `Cache_Invalidate_All = 0x4fc00404`. Invalidates all cache levels. + fn Cache_Invalidate_All(); +} + +unsafe fn rom_cache_suspend_l1_dcache() -> u32 { + unsafe { Cache_Suspend_L1_DCache() } +} +unsafe fn rom_cache_resume_l1_dcache(s: u32) { + unsafe { Cache_Resume_L1_DCache(s) } +} +unsafe fn rom_cache_suspend_l2_cache() -> u32 { + unsafe { Cache_Suspend_L2_Cache() } +} +unsafe fn rom_cache_resume_l2_cache(s: u32) { + unsafe { Cache_Resume_L2_Cache(s) } +} +unsafe fn rom_cache_invalidate_all() { + unsafe { Cache_Invalidate_All() } +} + +/// Kick the controller (set `SPI_USR` bit 18 in CMD_REG) and poll +/// bounded for completion. Replacement for ROM `esp_rom_spi_cmd_start`, +/// which polls forever; a hang there gives no diagnostic, while the +/// bounded variant surfaces a real failure as a returned error. After +/// the bit clears, copies MISO bytes from W0..W{N} into `rx_buf`. +fn mspi1_kick_and_collect(rx: &mut [u8]) -> Result<(), ()> { + const SPI_CMD: u32 = MSPI1_BASE + 0x00; + const SPI_W0: u32 = MSPI1_BASE + 0x58; + const SPI_USR_TRIGGER: u32 = 1 << 18; + const MAX_ITERS: u32 = 1_000_000; + + // Select CS1 (PSRAM); leave CS0 (flash) disabled. + // bit 0 CS0_DIS = 1 (disable flash CS) + // bit 1 CS1_DIS = 0 (enable PSRAM CS) + const MISC: u32 = MSPI1_BASE + 0x34; + unsafe { mmio_clrsetbits_32(MISC, 0b10, 0b01) }; + + // Kick. + unsafe { mmio_write_32(SPI_CMD, SPI_USR_TRIGGER) }; + let mut t = MAX_ITERS; + while unsafe { mmio_read_32(SPI_CMD) } & SPI_USR_TRIGGER != 0 { + t -= 1; + if t == 0 { + return Err(()); } + core::hint::spin_loop(); + } - // Read MR2 response from W0 register (low 8 bits) - let mr2 = ((mspi_base + SPI_W0) as *const u32).read_volatile() & 0xFF; - - // Decode density field [2:0] - match mr2 & 0x7 { - 0x1 => 4 * 1024 * 1024, // 32 Mbit = 4 MB - 0x3 => 8 * 1024 * 1024, // 64 Mbit = 8 MB - 0x5 => 16 * 1024 * 1024, // 128 Mbit = 16 MB - 0x7 => 32 * 1024 * 1024, // 256 Mbit = 32 MB - _ => { - // Unknown/invalid response -> fall back to EV Board default - 32 * 1024 * 1024 + // Copy MISO bytes from W0..W{N}. + if !rx.is_empty() { + let n_bytes = rx.len(); + let n_words = (n_bytes + 3) / 4; + for i in 0..n_words { + let word = unsafe { mmio_read_32(SPI_W0 + (i as u32) * 4) }; + for b in 0..4 { + let off = i * 4 + b; + if off >= n_bytes { + break; + } + rx[off] = ((word >> (b * 8)) & 0xFF) as u8; } } } + Ok(()) +} + +/// Issue an AP HEX PSRAM register-read command (0x4040, 16-bit cmd, +/// 32-bit address, 16-bit MISO) through `PSRAM_MSPI1`. Setup via ROM +/// helpers (`set_op_mode` + `cmd_config`); kick + poll done manually +/// with a timeout (avoids ROM `cmd_start` poll-forever pitfall). +fn mspi1_reg_read16(addr: u32) -> u16 { + const REG_READ_CMD: u16 = 0x4040; + const CMD_BITLEN: u16 = 16; + const ADDR_BITLEN: u32 = 32; + const DATA_BITLEN: u32 = 16; + + let mut addr_local = addr; + let mut rx: [u8; 2] = [0; 2]; + let mut conf = EspRomSpiCmd { + cmd: REG_READ_CMD, + cmd_bit_len: CMD_BITLEN, + addr: &mut addr_local as *mut u32, + addr_bit_len: ADDR_BITLEN, + tx_data: core::ptr::null_mut(), + tx_data_bit_len: 0, + rx_data: rx.as_mut_ptr() as *mut u32, + rx_data_bit_len: DATA_BITLEN, + dummy_bit_len: psram_speed().reg_dummy_bits, + }; + + unsafe { + esp_rom_spi_set_op_mode(ROM_SPI_PSRAM_CMD_NUM, ESP_ROM_SPIFLASH_OPI_DTR_MODE); + esp_rom_spi_cmd_config(ROM_SPI_PSRAM_CMD_NUM, &mut conf as *mut EspRomSpiCmd); + } + let _ = mspi1_kick_and_collect(&mut rx); + u16::from_le_bytes(rx) +} + +/// Issue an AP HEX PSRAM register-write command (0xC0C0) with 16-bit +/// data through `PSRAM_MSPI1`. Same setup-via-ROM + manual-kick pattern +/// as `mspi1_reg_read16`. +fn mspi1_reg_write16(addr: u32, data: u16) { + const REG_WRITE_CMD: u16 = 0xC0C0; + const CMD_BITLEN: u16 = 16; + const ADDR_BITLEN: u32 = 32; + const DATA_BITLEN: u32 = 16; + + let mut addr_local = addr; + let mut tx = data.to_le_bytes(); + let mut conf = EspRomSpiCmd { + cmd: REG_WRITE_CMD, + cmd_bit_len: CMD_BITLEN, + addr: &mut addr_local as *mut u32, + addr_bit_len: ADDR_BITLEN, + tx_data: tx.as_mut_ptr() as *mut u32, + tx_data_bit_len: DATA_BITLEN, + rx_data: core::ptr::null_mut(), + rx_data_bit_len: 0, + dummy_bit_len: 0, + }; + + unsafe { + esp_rom_spi_set_op_mode(ROM_SPI_PSRAM_CMD_NUM, ESP_ROM_SPIFLASH_OPI_DTR_MODE); + esp_rom_spi_cmd_config(ROM_SPI_PSRAM_CMD_NUM, &mut conf as *mut EspRomSpiCmd); + } + let mut empty: [u8; 0] = []; + let _ = mspi1_kick_and_collect(&mut empty); +} + +/// Detect PSRAM size by reading mode register MR2 via MSPI1. +fn psram_detect_size() -> usize { + let (mr2, _mr3) = psram_mr_read(MR_ADDR_MR2_MR3); + match mr2 & 0x7 { + 0x1 => 4 * 1024 * 1024, // 32 Mbit + 0x3 => 8 * 1024 * 1024, // 64 Mbit + 0x5 => 16 * 1024 * 1024, // 128 Mbit + 0x6 => 64 * 1024 * 1024, // 512 Mbit + 0x7 => 32 * 1024 * 1024, // 256 Mbit + _ => 32 * 1024 * 1024, // unknown -> EV Board default + } } /// Map PSRAM physical pages into the virtual address space via MMU. /// -/// Each MMU entry maps a 64 KB virtual page to a physical PSRAM page. -/// Virtual address range: 0x4800_0000 + page_idx * 0x10000 +/// ESP32-P4 has TWO independent MMUs: +/// - Flash MMU (id 0): registers in `SPI_MEM_C` (FLASH_SPI0) +/// - PSRAM MMU (id 1): registers in `SPI_MEM_S` (PSRAM_MSPI0) at the +/// `MMU_ITEM_INDEX_REG` / `MMU_ITEM_CONTENT_REG` offsets we use here. /// -/// MMU entry format (SPI_MEM_S): -/// - Bit 15: MMU_VALID (1 = entry active) -/// - Bit 14: MMU_TYPE (0 = Flash, 1 = PSRAM) -/// - Bits [13:0]: Physical page number +/// Each PSRAM MMU entry is a 32-bit word: +/// - bits [9:0] : physical page number (`SOC_MMU_PSRAM_VALID_VAL_MASK = 0x3FF`) +/// - bit 10 : `SOC_MMU_ACCESS_PSRAM` (selects PSRAM vs flash) +/// - bit 11 : `SOC_MMU_PSRAM_VALID` +/// - bit 12 : `SOC_MMU_PSRAM_SENSITIVE` (set only when cache encryption is on) /// -/// Ref: esp-idf mmu_ll.h -- mmu_ll_write_entry(), mmu_ll_check_valid_ext_vaddr() -/// esp-idf ext_mem_layout.h -- SOC_MMU_ENTRY_NUM, SOC_MMU_PAGE_SIZE -/// TRM v0.5 Ch 9 (System and Memory) -- MMU configuration +/// Virtual base: `SOC_MMU_PSRAM_VADDR_BASE = 0x4800_0000`. The PSRAM MMU +/// is a separate table from the flash MMU, so PSRAM entries start at +/// **entry index 0**, not at some offset relative to the flash range. +/// `entry_id = (vaddr - 0x4800_0000) / 0x10000`. fn mmu_map_psram(mspi_base: u32, config: PsramConfig) { - const MMU_ITEM_INDEX: u32 = 0x380; const MMU_ITEM_CONTENT: u32 = 0x37C; - const MMU_VALID: u32 = 1 << 15; - const MMU_TYPE_PSRAM: u32 = 1 << 14; - const MMU_INVALID_ENTRY: u32 = 0x4000; // bit 14 set, valid cleared = invalid + const MMU_ITEM_INDEX: u32 = 0x380; + const MMU_PSRAM_VALID: u32 = 1 << 11; + const MMU_ACCESS_PSRAM: u32 = 1 << 10; + const MMU_PADDR_MASK: u32 = 0x3FF; // 10 bits of physical page number let psram_size = match config.size { - super::PsramSize::AutoDetect => 32 * 1024 * 1024, // default 32 MB + super::PsramSize::AutoDetect => 32 * 1024 * 1024, super::PsramSize::Size(s) => s, }; - let page_count = psram_size / MMU_PAGE_SIZE; - // Calculate the starting MMU entry index for PSRAM virtual address - // PSRAM virtual starts at 0x4800_0000. The MMU entry index depends on - // the overall virtual address map layout. For P4, PSRAM region starts - // at a fixed offset in the MMU table. - // The formula: entry_id = (vaddr - SOC_MMU_VADDR_BASE) / MMU_PAGE_SIZE - // SOC_MMU_VADDR_BASE = 0x4000_0000 (flash mapping start) - // PSRAM at 0x4800_0000: entry_id = (0x4800_0000 - 0x4000_0000) / 0x10000 = 0x800 - const PSRAM_MMU_START_ENTRY: u32 = 0x800; - - // Disable data cache before modifying MMU - cache_suspend(); - + // Note: we do NOT call Cache_Suspend_*. The ROM helpers expect + // interrupts/scheduler state we can't guarantee in init context, and + // hang. Since at init time nothing else is reading PSRAM via cache + // yet, we can write the MMU entries unsynchronized and then + // invalidate to drop any stale prefetched lines. unsafe { - let index_reg = (mspi_base + MMU_ITEM_INDEX) as *mut u32; - let content_reg = (mspi_base + MMU_ITEM_CONTENT) as *mut u32; - + let index_reg = mspi_base + MMU_ITEM_INDEX; + let content_reg = mspi_base + MMU_ITEM_CONTENT; for page in 0..page_count { - let entry_id = PSRAM_MMU_START_ENTRY + page as u32; - let content = MMU_VALID | MMU_TYPE_PSRAM | (page as u32 & 0x3FFF); - - // Write entry: set index, then write content - index_reg.write_volatile(entry_id); - content_reg.write_volatile(content); + let entry_id = page as u32; // PSRAM table starts at entry 0 + let content = MMU_PSRAM_VALID | MMU_ACCESS_PSRAM | (page as u32 & MMU_PADDR_MASK); + mmio_write_32(index_reg, entry_id); + mmio_write_32(content_reg, content); } + rom_cache_invalidate_all(); } - - // Re-enable data cache - cache_resume(); } -/// Suspend L1 data cache for MMU/cache configuration. -/// -/// Must be paired with cache_resume(). -/// -/// Ref: esp-idf cache_ll.h -- cache_ll_l1_disable_cache() -/// L1_DCACHE_CTRL register: shut_dbus0, shut_dbus1, shut_dma bits fn cache_suspend() { let cache = unsafe { &*crate::pac::CACHE::PTR }; cache .l1_dcache_ctrl() .modify(|_, w| w.l1_dcache_shut_dbus0().set_bit()); - - // Wait for cache to idle while !cache .l1_dcache_autoload_ctrl() .read() @@ -291,9 +772,6 @@ fn cache_suspend() { } } -/// Resume L1 data cache after MMU/cache configuration. -/// -/// Ref: esp-idf cache_ll.h -- cache_ll_l1_enable_cache() fn cache_resume() { let cache = unsafe { &*crate::pac::CACHE::PTR }; cache @@ -301,54 +779,54 @@ fn cache_resume() { .modify(|_, w| w.l1_dcache_shut_dbus0().clear_bit()); } -/// Invalidate L1 data cache for a given address range. -/// -/// Required after DMA transfers to ensure CPU sees fresh data. -/// -/// Ref: esp-idf cache_ll.h -- cache_ll_l1_invalidate_cache() -/// CACHE.sync_ctrl, sync_addr, sync_size #[allow(dead_code)] pub(crate) fn cache_invalidate(addr: u32, size: u32) { let cache = unsafe { &*crate::pac::CACHE::PTR }; - cache.sync_addr().write(|w| unsafe { w.bits(addr) }); cache.sync_size().write(|w| unsafe { w.bits(size) }); - - // Trigger invalidate: sync_ctrl.invalidate_ena cache .sync_ctrl() .modify(|_, w| w.invalidate_ena().set_bit()); - - // Wait for completion while !cache.sync_ctrl().read().sync_done().bit_is_set() { core::hint::spin_loop(); } } -/// Write back L1 data cache for a given address range. -/// -/// Required before DMA transfers to ensure DMA sees latest CPU writes. -/// -/// Ref: esp-idf cache_ll.h -- cache_ll_l1_writeback_cache() #[allow(dead_code)] pub(crate) fn cache_writeback(addr: u32, size: u32) { let cache = unsafe { &*crate::pac::CACHE::PTR }; - cache.sync_addr().write(|w| unsafe { w.bits(addr) }); cache.sync_size().write(|w| unsafe { w.bits(size) }); - - // Trigger writeback: sync_ctrl.writeback_ena cache.sync_ctrl().modify(|_, w| w.writeback_ena().set_bit()); - while !cache.sync_ctrl().read().sync_done().bit_is_set() { core::hint::spin_loop(); } } +/// Program the PMU external LDO regulators for the MSPI PHY +fn psram_phy_ldo_init() { + const PMU_BASE: u32 = 0x5011_5000; + unsafe { + // P0 power-rail LDOs (general analog). + mmio_write_32(PMU_BASE + 0x1B8, 0x4020_0100); // EXT_LDO_P0_0P1A + mmio_write_32(PMU_BASE + 0x1BC, 0xB100_0000); // EXT_LDO_P0_0P1A_ANA + mmio_write_32(PMU_BASE + 0x1C0, 0x4020_0000); // EXT_LDO_P0_0P2A + mmio_write_32(PMU_BASE + 0x1C4, 0xA000_0000); // EXT_LDO_P0_0P2A_ANA + mmio_write_32(PMU_BASE + 0x1C8, 0x4020_0000); // EXT_LDO_P0_0P3A + mmio_write_32(PMU_BASE + 0x1CC, 0xA000_0000); // EXT_LDO_P0_0P3A_ANA + // P1 power-rail LDOs (MSPI PHY domain). + mmio_write_32(PMU_BASE + 0x1D0, 0x4020_0180); // EXT_LDO_P1_0P1A XPD + current limit + mmio_write_32(PMU_BASE + 0x1D4, 0x5700_0000); // EXT_LDO_P1_0P1A_ANA analog tune (THE one for PSRAM) + mmio_write_32(PMU_BASE + 0x1D8, 0x4020_0000); // EXT_LDO_P1_0P2A + mmio_write_32(PMU_BASE + 0x1DC, 0xA000_0000); // EXT_LDO_P1_0P2A_ANA + mmio_write_32(PMU_BASE + 0x1E0, 0x4020_0000); // EXT_LDO_P1_0P3A + mmio_write_32(PMU_BASE + 0x1E4, 0xA000_0000); // EXT_LDO_P1_0P3A_ANA + } + // Allow LDO output to settle before the MSPI PHY is exercised. + crate::rom::ets_delay_us(50); +} + /// Configure MPLL to target frequency for PSRAM clock. -/// -/// Ref: esp-idf clk_tree_ll.h:475-519 -- clk_ll_mpll_set_config() -/// regi2c_mpll.h -- I2C_MPLL = 0x63 fn configure_mpll(freq_mhz: u32) { use crate::soc::regi2c; @@ -357,103 +835,137 @@ fn configure_mpll(freq_mhz: u32) { const I2C_MPLL_DHREF: u8 = 3; const I2C_MPLL_IR_CAL_RSTB: u8 = 5; - // Enable MPLL power - // PMU.rf_pwc: mspi_phy_xpd - // LP_AON_CLKRST: hp_mpll_500m_clk_en - // TODO(esp32p4): PMU rf_pwc register access for MPLL power - - // Calculate divider: MPLL_freq = XTAL(40MHz) * (div+1) / (ref_div+1) - // For 400MHz: ref_div=1, div=19 -> 40*20/2 = 400MHz - let div_val: u8 = match freq_mhz { - 400 => (9 << 3) | 1, // div=9, ref_div=1 -> 40*10/2 = 200... needs recalc - 500 => (12 << 3) | 1, // div=12, ref_div=1 - _ => (9 << 3) | 1, // default 400MHz - }; + // Power up the MPLL analog block. + let pmu = crate::peripherals::PMU::regs(); + pmu.rf_pwc().modify(|_, w| w.mspi_phy_xpd().set_bit()); + let lp_clkrst = crate::peripherals::LP_AON_CLKRST::regs(); + lp_clkrst + .lp_aonclkrst_hp_clk_ctrl() + .modify(|_, w| w.lp_aonclkrst_hp_mpll_500m_clk_en().set_bit()); + + // div = freq_mhz/20 - 1, ref_div = 1 -> MPLL = XTAL(40) * (div+1) / (ref_div+1) + let ref_div: u8 = 1; + let div: u8 = (freq_mhz / 20).saturating_sub(1) as u8; + let div_val: u8 = (div << 3) | ref_div; - // MPLL calibration sequence - // 1. Set DHREF bits [5:4] = 3 let dhref = regi2c::regi2c_read(I2C_MPLL, 0, I2C_MPLL_DHREF); regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_DHREF, dhref | (3 << 4)); - // 2. Toggle IR_CAL_RSTB bit 5 let rstb = regi2c::regi2c_read(I2C_MPLL, 0, I2C_MPLL_IR_CAL_RSTB); regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_IR_CAL_RSTB, rstb & 0xDF); regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_IR_CAL_RSTB, rstb | (1 << 5)); - // 3. Write divider regi2c::regi2c_write(I2C_MPLL, 0, I2C_MPLL_DIV_REG_ADDR, div_val); - // 4. Run calibration - // Ref: HP_SYS_CLKRST.ana_pll_ctrl0.reg_mspi_cal_stop/end let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); clkrst .ana_pll_ctrl0() .modify(|_, w| w.mspi_cal_stop().clear_bit()); + let mut t = 1_000_000_u32; while !clkrst.ana_pll_ctrl0().read().mspi_cal_end().bit_is_set() { + t = t.saturating_sub(1); + if t == 0 { + break; + } core::hint::spin_loop(); } clkrst .ana_pll_ctrl0() .modify(|_, w| w.mspi_cal_stop().set_bit()); - + // cal_end timeout (t == 0): surfaces later via `psram_detect_size` fallback. + let _ = t; // if need print this for debug crate::rom::ets_delay_us(10); } -/// Configure PSRAM MSPI controller registers for HEX mode operation. +/// Configure PSRAM_MSPI0 (AXI cache) for HEX/DDR access at 0x4800_0000. +/// +/// Faithful port of IDF `s_config_mspi_for_psram` from +/// `esp_psram_impl_ap_hex.c`. Each register field is named after its +/// `psram_ctrlr_ll_*` setter so the mapping is straightforward to verify. +/// +/// Field layout (PSRAM_MSPI0 / SPIMEM2 register bit positions): +/// +/// `CACHE_SCTRL` (0x40): +/// - bit 0: `cache_usr_saddr_4byte` +/// - bit 3: `usr_wr_sram_dummy` +/// - bit 4: `usr_rd_sram_dummy` +/// - bit 5: `cache_sram_usr_rcmd` +/// - bits 11:6: `sram_rdummy_cyclelen` +/// - bits 19:14: `sram_addr_bitlen` +/// - bit 20: `cache_sram_usr_wcmd` +/// - bit 21: `sram_oct` +/// - bits 27:22: `sram_wdummy_cyclelen` +/// +/// `SRAM_CMD` (0x44): +/// - bit 18: `sdin_oct` +/// - bit 19: `sdout_oct` +/// - bit 20: `saddr_oct` +/// - bit 21: `scmd_oct` +/// - bit 22: `sdummy_rin` +/// - bit 23: `sdummy_wout` +/// - bit 26: `sdin_hex` +/// - bit 27: `sdout_hex` +/// +/// `MEM_CTRL1` (0x70): `ar_splice_en` bit 25, `aw_splice_en` bit 26. +/// +/// `SMEM_DDR` (0xD8): bit 0 `smem_ddr_en`, bit 1 `smem_var_dummy`, +/// bit 2 `smem_ddr_rdat_swp`, bit 3 `smem_ddr_wdat_swp`. /// -/// Ref: esp-idf psram_ctrlr_ll.h, spi_mem_s_reg.h -/// All offsets relative to PSRAM_MSPI_BASE (0x5008_E000) +/// `CACHE_FCTRL` (0x3C): bit 0 `mem_axi_req_en`, bit 1 `close_axi_inf_en`. fn configure_psram_mspi(base: u32) { - // Register offsets from spi_mem_s_reg.h - const CACHE_FCTRL: u32 = 0x3C; - const CACHE_SCTRL: u32 = 0x40; - const SRAM_CMD: u32 = 0x44; - const SRAM_DRD_CMD: u32 = 0x48; - const SRAM_DWR_CMD: u32 = 0x4C; - const SMEM_DDR: u32 = 0xD8; + // Dummy bit-counts come from the active speed parameter table. + let rd_dummy_n = psram_speed().rd_dummy_bits; + let wr_dummy_n = psram_speed().wr_dummy_bits; unsafe { - // 1. Configure read command: 16-bit sync read (0x0000) - // SPI_MEM_S_CACHE_SCTRL: cache_sram_usr_rcmd=1 - // SPI_MEM_S_SRAM_DRD_CMD: cmd_bitlen=15, cmd_value=0 - let sctrl = (base + CACHE_SCTRL) as *mut u32; - let val = sctrl.read_volatile(); - let val = val | (1 << 20); // cache_sram_usr_rcmd = 1 - let val = val | (1 << 5); // cache_sram_usr_wcmd = 1 - // sram_addr_bitlen = 31 (32-bit address) - let val = (val & !(0x3F << 14)) | (31 << 14); - // usr_rd_sram_dummy = 1, sram_rdummy_cyclelen = 13 (14-1 for 200MHz) - let val = val | (1 << 22); // usr_rd_sram_dummy - let val = (val & !(0x3F << 6)) | (13 << 6); // rdummy_cyclelen - // cache_usr_saddr_4byte = 1 - let val = val | (1 << 24); - sctrl.write_volatile(val); - - // Read command: sync read 0x0000, bitlen=15 - let drd = (base + SRAM_DRD_CMD) as *mut u32; - drd.write_volatile((15 << 28) | 0x0000); // bitlen[31:28]=15, value[15:0]=0 - - // Write command: sync write 0x8080, bitlen=15 - let dwr = (base + SRAM_DWR_CMD) as *mut u32; - dwr.write_volatile((15 << 28) | 0x8080); - - // 2. Enable DDR mode - let ddr = (base + SMEM_DDR) as *mut u32; - let val = ddr.read_volatile(); - ddr.write_volatile(val | 1); // smem_ddr_en = 1 - - // 3. Enable HEX (16-line) data mode - let sram_cmd = (base + SRAM_CMD) as *mut u32; - let val = sram_cmd.read_volatile(); - // sdin_hex (bit 4) and sdout_hex (bit 5) -- exact bit positions need verification - let val = val | (1 << 4) | (1 << 5); // HEX mode data lines - sram_cmd.write_volatile(val); - - // 4. Enable AXI access - let fctrl = (base + CACHE_FCTRL) as *mut u32; - let val = fctrl.read_volatile(); - let val = val | (1 << 0); // mem_axi_req_en = 1 - let val = val & !(1 << 1); // close_axi_inf_en = 0 - fctrl.write_volatile(val); + // CACHE_SCTRL. + // bit 0 cache_usr_saddr_4byte + // bit 3 usr_wr_sram_dummy + // bit 4 usr_rd_sram_dummy + // bit 5 cache_sram_usr_rcmd + let sctrl_addr = base + 0x40; + let mut val = mmio_read_32(sctrl_addr); + val |= 0b011_1001; + // bits 11..6 sram_rdummy_cyclelen + // bits 19..14 sram_addr_bitlen (N-1 form, here 32-bit addr) + // bits 27..22 sram_wdummy_cyclelen + val = (val & !(0x3F << 6)) | ((rd_dummy_n - 1) << 6); + val = (val & !(0x3F << 14)) | ((32 - 1) << 14); + val = (val & !(0x3F << 22)) | ((wr_dummy_n - 1) << 22); + // bit 20 cache_sram_usr_wcmd + // bit 21 sram_oct (octal mode for cache transactions) + val |= 0b11 << 20; + mmio_write_32(sctrl_addr, val); + + // SRAM_CMD: octal-line + hex-data + dummy-level control. + // bit 18 sdin_oct + // bit 19 sdout_oct + // bit 20 saddr_oct + // bit 21 scmd_oct + // bit 23 sdummy_wout (write-dummy level control enable) + // bit 26 sdin_hex (16-line read data) + // bit 27 sdout_hex (16-line write data) + mmio_setbits_32(base + 0x44, 0b1100_1011_1100 << 16); // bits 27, 26, 23, 21..18 + + // SRAM_DRD_CMD / SRAM_DWR_CMD: 16-bit sync read/write commands. + mmio_write_32(base + 0x48, ((16 - 1) << 28) | 0x0000); // sync read 0x0000 + mmio_write_32(base + 0x4C, ((16 - 1) << 28) | 0x8080); // sync write 0x8080 + + // MEM_CTRL1: splice enables (AXI burst optimization). + // bit 25 ar_splice_en + // bit 26 aw_splice_en + mmio_setbits_32(base + 0x70, 0b11 << 25); + + // SMEM_DDR: DDR mode + variable dummy. + // bit 0 smem_ddr_en set + // bit 1 smem_var_dummy set + // bit 2 smem_ddr_rdat_swp clear (default off) + // bit 3 smem_ddr_wdat_swp clear (default off) + mmio_clrsetbits_32(base + 0xD8, 0b1100, 0b0011); + + // CACHE_FCTRL: enable AXI access. + // bit 0 : MEM_AXI_REQ_EN = 1 (set) + // bit 31 : CLOSE_AXI_INF_EN = 0 (clear -> open the AXI iface) + mmio_clrsetbits_32(base + 0x3C, 1u32 << 31, 1); } } diff --git a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs index 29dee876c13..caaea33c1c2 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs @@ -9,9 +9,5 @@ //! - crate::clock::Clock, crate::efuse::Efuse (old API pattern) //! - PMU hp_active/hp_modem/hp_sleep register groups //! -//! TODO(esp32p4): Implement sleep mode once PMU eco5 registers are validated. -//! Ref: esp-idf pmu_sleep.c, pmu_eco5_struct.h -//! TRM v0.5 Ch 16 (Low-Power Management) -//! .investigation/ESP32P4_ECO5_PERIPHERAL_AUDIT.md - -// florianL21 original: see esp32p4_florianl21_original.rs.bak (1064 lines) +//! TODO: Implement sleep mode once PMU eco5 registers are validated. +// TODO: reference florianL21's implementation diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index cbfe7fac1c5..03a45aebc27 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -7,16 +7,11 @@ //! //! Clock hierarchy: XTAL -> CPLL -> CPU_ROOT -> CPU/APB dividers //! SPLL -> PLL_F240M/160M/120M/80M/20M (peripheral clocks) -//! -//! Ref: esp-idf rtc_clk.c, clk_tree_ll.h, clk_tree_defs.h -//! TRM v0.5 Ch 12 (Reset and Clock) #![allow(dead_code, reason = "Clock functions called from generated macro code")] define_clock_tree_types!(); /// CPU clock frequency presets for ESP32-P4X (eco5 / chip revision v3.x). -/// Ref: esp-idf rtc_clk.c:240 -- !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 path -/// TRM v0.5 Ch 2 -- HP CPU max frequency 400 MHz for v3.x #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] @@ -106,10 +101,8 @@ impl ClockConfig { } } -// ============================================================ // Clock node implementation functions (called from generated macro) // These must match the function names that define_clock_tree_types!() expects. -// ============================================================ // CPU_ROOT_CLK (mux: XTAL / CPLL / RC_FAST) fn configure_cpu_root_clk_impl( @@ -163,7 +156,7 @@ fn configure_apb_clk_impl( _old_config: Option, _new_config: ApbClkConfig, ) { - // TODO(esp32p4): APB divider register in HP_SYS_CLKRST + // TODO: APB divider register in HP_SYS_CLKRST // For now, APB freq is derived from CPU freq via divider } @@ -216,7 +209,7 @@ impl UartInstance { _old_config: Option, _new_config: UartFunctionClockConfig, ) { - // TODO(esp32p4): Configure UART clock source selection + // TODO: Configure UART clock source selection // HP_SYS_CLKRST PERI_CLK_CTRL110-114 for UART0-4 } @@ -234,9 +227,7 @@ impl UartInstance { } } -// ============================================================ // Per-instance clock impl for TIMG -// ============================================================ impl TimgInstance { fn enable_function_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { @@ -249,7 +240,7 @@ impl TimgInstance { _old_config: Option, _new_config: TimgFunctionClockConfig, ) { - // TODO(esp32p4): Configure TIMG clock source + // TODO: Configure TIMG clock source // HP_SYS_CLKRST PERI_CLK_CTRL20/21 } @@ -261,13 +252,12 @@ impl TimgInstance { _old_config: Option, _new_config: TimgWdtClockConfig, ) { - // TODO(esp32p4): Configure TIMG WDT clock source + // TODO: Configure TIMG WDT clock source } } -// ============================================================ // System clock impl functions -// ============================================================ + // Mux enable stubs (mux nodes need enable functions too) fn enable_cpu_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {} diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index cb613b99716..3a70f97a970 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -113,6 +113,9 @@ mod _p4_peripheral_clocks { Peripheral::Systimer, Peripheral::Iomux, Peripheral::UsbDevice, + // TODO: This should be removed before merged. + // UART0: bootloader uses GPIO37/38 for boot log while testing + Peripheral::Uart0, ]; pub const COUNT: usize = Self::ALL.len(); pub const ALL: &[Self] = &[ @@ -258,7 +261,7 @@ mod _p4_peripheral_clocks { } // -- PWM/Counter -- Peripheral::Ledc => { - // TODO(esp32p4): LEDC uses SOC_CLK_CTRL3 in IDF, but PAC may differ. + // TODO: LEDC uses SOC_CLK_CTRL3 in IDF, but PAC may differ. // Only reset wiring is handled here for now. } Peripheral::Pcnt => { @@ -364,7 +367,7 @@ mod _p4_peripheral_clocks { } // -- LCD/Camera -- Peripheral::LcdCam => { - // TODO(esp32p4): LCD_CAM uses SOC_CLK_CTRL3 which may not be in PAC. + // TODO: LCD_CAM uses SOC_CLK_CTRL3 which may not be in PAC. } } } @@ -571,8 +574,19 @@ impl Peripheral { #[cfg(esp32p4)] impl Peripheral { - pub const fn try_from(_value: u8) -> Option { - None + /// Map a numeric peripheral id back to the enum variant. + /// + /// Our P4 `Peripheral` is `#[repr(u8)]` with values 0..=43 assigned + /// densely (see `_p4_peripheral_clocks`), so a simple range check + /// plus transmute is correct. Drivers like DMA call + /// `Peripheral::try_from(N).unwrap()` from a const context to + /// build a `GenericPeripheralGuard`; if this returned `None` + /// the const-eval would panic and the user app would fail to build. + pub const fn try_from(value: u8) -> Option { + if value >= Peripheral::COUNT as u8 { + return None; + } + Some(unsafe { core::mem::transmute::(value) }) } } diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index d66cb25e677..a2a1daab216 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -4205,20 +4205,14 @@ impl Chip { "rom_md5_bsd", "pm_support_ext1_wakeup", "pm_support_touch_sensor_wakeup", - "adc_driver_supported", - "aes_driver_supported", "dma_driver_supported", - "ecc_driver_supported", "gpio_driver_supported", "i2c_master_driver_supported", "interrupts_driver_supported", "psram_driver_supported", - "rsa_driver_supported", - "sha_driver_supported", "soc_driver_supported", "spi_master_driver_supported", "systimer_driver_supported", - "twai_driver_supported", "uart_driver_supported", "usb_serial_jtag_driver_supported", "i2c_master_i2c0", @@ -4355,20 +4349,14 @@ impl Chip { "cargo:rustc-cfg=rom_md5_bsd", "cargo:rustc-cfg=pm_support_ext1_wakeup", "cargo:rustc-cfg=pm_support_touch_sensor_wakeup", - "cargo:rustc-cfg=adc_driver_supported", - "cargo:rustc-cfg=aes_driver_supported", "cargo:rustc-cfg=dma_driver_supported", - "cargo:rustc-cfg=ecc_driver_supported", "cargo:rustc-cfg=gpio_driver_supported", "cargo:rustc-cfg=i2c_master_driver_supported", "cargo:rustc-cfg=interrupts_driver_supported", "cargo:rustc-cfg=psram_driver_supported", - "cargo:rustc-cfg=rsa_driver_supported", - "cargo:rustc-cfg=sha_driver_supported", "cargo:rustc-cfg=soc_driver_supported", "cargo:rustc-cfg=spi_master_driver_supported", "cargo:rustc-cfg=systimer_driver_supported", - "cargo:rustc-cfg=twai_driver_supported", "cargo:rustc-cfg=uart_driver_supported", "cargo:rustc-cfg=usb_serial_jtag_driver_supported", "cargo:rustc-cfg=i2c_master_i2c0", diff --git a/esp-metadata/CHANGELOG.md b/esp-metadata/CHANGELOG.md index 2546e19971b..a2223aa2c8c 100644 --- a/esp-metadata/CHANGELOG.md +++ b/esp-metadata/CHANGELOG.md @@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - C5 and C61: Enable RTC timekeeping (#5449) +- ESP32-P4: emit `rom_crc_le`, `rom_crc_be`, `rom_md5_bsd` cfg flags so + `esp-rom-sys` exposes the silicon ROM CRC/MD5 wrappers and + `esp-bootloader-esp-idf` can drop its software fallback for P4. +- ESP32-P4: emit `pm_support_ext1_wakeup` and + `pm_support_touch_sensor_wakeup` (matches ESP-IDF SOC capabilities). ### Changed diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index 7922fec6413..ee0bf5c24b6 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -57,7 +57,6 @@ rc_fast_clk_default = 20_000_000 # Clock tree for ESP32-P4X (eco5 / chip revision v3.x) # 3 PLLs: CPLL (CPU, 360/400MHz), SPLL (480MHz, peripherals), MPLL (400MHz, PSRAM/media) -# Ref: esp-idf clk_tree_defs.h, clk_tree_ll.h, DS, TRM v0.5 Ch 12 clocks = { system_clocks = { clock_tree = [ # High-speed clock sources { name = "XTAL_CLK", type = "source", output = "40_000_000", always_on = true }, @@ -192,7 +191,6 @@ peripherals = [ { name = "USB_DEVICE", interrupts = { peri = "USB_DEVICE" } }, { name = "SDHOST" }, # TODO: clarify EMAC <-> PAC mapping before exposing it. - # IDF has the LL header at components/esp_hal_emac/esp32p4/include/hal/emac_ll.h # but the esp32p4 PAC has not been generated with a matching peripheral yet. # { name = "EMAC" }, { name = "LEDC", interrupts = { peri = "LEDC" } }, @@ -208,7 +206,6 @@ peripherals = [ ] # UART: 5 instances (UART0-4), 128-byte FIFO -# Ref: esp-idf uart_ll.h, TRM v0.5 Ch 46 [device.uart] support_status = "partial" instances = [ @@ -222,13 +219,11 @@ ram_size = 128 version = 2 # SYSTIMER: 2 counter units, 3 alarm comparators, 16 MHz (XTAL/2.5) -# Ref: esp-idf systimer_ll.h, TRM v0.5 Ch 17 # PAC register names verified: unit_op(n), unit_value(n), target_conf(n), # trgt(n), comp_load(n) all match esp-hal systimer module expectations. [device.systimer] # GP Timer (TIMG): 2 groups, each with 2 timers + WDT -# Ref: esp-idf timer_ll.h, TRM v0.5 Ch 18 [device.gp_timer] support_status = "partial" instances = [ @@ -237,9 +232,7 @@ instances = [ ] # SPI Master: 2 instances (GPSPI2, GPSPI3) -# Ref: esp-idf spi_ll.h, TRM v0.5 Ch 47 # SPI Master: SPI2 only (SPI2 and SPI3 have different PAC RegisterBlock types) -# Ref: esp-idf spi_ll.h, TRM v0.5 Ch 47 [device.spi_master] support_status = "partial" supports_dma = true @@ -250,7 +243,6 @@ instances = [ # I2C Master: 2 instances # P4 PAC: data register is read-only, TX uses txfifo_start_addr (fixed in i2c/master/mod.rs) -# Ref: esp-idf i2c_ll.h, TRM v0.5 Ch 48 [device.i2c_master] support_status = "partial" instances = [ @@ -280,31 +272,22 @@ gdma_version = 2 separate_in_out_interrupts = true max_priority = 5 -# TWAI (CAN): 3 instances -# Ref: esp-idf twai_ll.h, TRM v0.5 Ch 58 +# TODO: Check later with PAC and TRM both [device.twai] -support_status = "partial" - -# ADC: HP ADC + LP ADC -# Ref: TRM v0.5 Ch 38 (ADC), Ch 41 (LP ADC) -# Note: P4 ADC calibration needs special value (4 not 1) -- not yet implemented +support_status = "not_supported" +# TODO: Check later with PAC and TRM both [device.adc] -support_status = "partial" - -# Temperature sensor (LP_TSENS) -# Ref: TRM v0.5 Ch 43 (Temperature Sensor) +support_status = "not_supported" +# TODO: Test or complete me # [device.temperature_sensor] # support_status = "partial" -# Touch sensor (LP_TOUCH, 14 channels) -# Ref: TRM v0.5 Ch 42 (Touch Sensor) +# TODO: Test or complete me # [device.touch] # support_status = "partial" -# AES: hardware accelerator -# Ref: esp-idf aes_ll.h, TRM v0.5 Ch 28 [device.aes] -support_status = "partial" +support_status = "not_supported" has_split_text_registers = true endianness_configurable = false dma = true @@ -313,32 +296,26 @@ key_length = { options = [ { bits = 256, encrypt_mode = 2, decrypt_mode = 6 }, ] } -# SHA: hardware accelerator -# Ref: esp-idf sha_ll.h, TRM v0.5 Ch 34 [device.sha] -support_status = "partial" +support_status = "not_supported" dma = true algo = { sha1 = 0, sha224 = 1, sha256 = 2 } -# PSRAM: cache-mapped external RAM (HEX mode) -# Ref: esp-idf esp_psram_impl_ap_hex.c, TRM v0.5 Ch 9 [device.psram] extmem_origin = 0x48000000 -# RSA: hardware accelerator -# Ref: esp-idf mpi_ll.h, TRM v0.5 Ch 33 [device.rsa] -support_status = "partial" +support_status = "not_supported" size_increment = 32 memory_size_bytes = 384 +# TODO: complete with esp-idf ecc_ll.h and later version of TRM 0.5 -# ECC: hardware accelerator (eco5+ supported) -# Ref: esp-idf ecc_ll.h, TRM v0.5 Ch 30 -# USB Serial/JTAG controller [device.usb_serial_jtag] +# ECC: hardware accelerator (eco5+ supported) [device.ecc] -support_status = "partial" +support_status = "not_supported" + working_modes = [ { id = 0, mode = "affine_point_multiplication" }, { id = 2, mode = "affine_point_verification" }, @@ -764,10 +741,8 @@ output_signals = [ { name = "DBG_FLASH_D" }, ] -# 55 GPIO pins (0-54), IO MUX functions from esp-idf io_mux_reg.h -# ADC channels from esp-idf adc_channel.h +# 55 GPIO pins (0-54) # LP pins: GPIO0-5, GPIO12-23 (RTCIO capable) -# Ref: DS, TRM v0.5 Ch 11, esp-idf gpio_periph.c, rtc_io_channel.h pins = [ { pin = 0, lp = { 0 = "LP_GPIO0" } }, { pin = 1, lp = { 0 = "LP_GPIO1" } }, diff --git a/esp-rom-sys/CHANGELOG.md b/esp-rom-sys/CHANGELOG.md index 3332578819c..eb975fc96ca 100644 --- a/esp-rom-sys/CHANGELOG.md +++ b/esp-rom-sys/CHANGELOG.md @@ -12,6 +12,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- ESP32-P4: replace the imported pre-ECO5 ROM linker scripts with the + ECO5+ symbol addresses (sourced from ESP-IDF v6.0.1 + `esp32p4.rom.eco5*.ld`). The previous file used pre-ECO5 addresses and + silently misnamed several ROM symbols on v3.x silicon (e.g. + `esp_rom_crc32_le` linked to the address that actually hosts + `crc32_be`). Verified end-to-end via runtime hw-vs-sw comparison + (12/12 PASS) on v3.2 ECO7 silicon. ### Fixed From db7914d2c624c8531402a0bf0238420643c7f80c Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Sun, 3 May 2026 21:56:23 +0900 Subject: [PATCH 14/27] Remove uselesss comment --- esp-hal/src/clock/mod.rs | 1 - esp-hal/src/rtc_cntl/mod.rs | 3 +-- esp-hal/src/rtc_cntl/rtc/esp32p4.rs | 24 +++++++----------------- esp-hal/src/rtc_cntl/sleep/esp32p4.rs | 6 +++--- esp-hal/src/soc/esp32p4/clocks.rs | 2 -- esp-hal/src/soc/esp32p4/gpio.rs | 3 +-- esp-hal/src/soc/esp32p4/regi2c.rs | 8 +------- esp-hal/src/system.rs | 10 +++------- esp-metadata/devices/esp32p4.toml | 1 - 9 files changed, 16 insertions(+), 42 deletions(-) diff --git a/esp-hal/src/clock/mod.rs b/esp-hal/src/clock/mod.rs index a4268550996..0f719c286e6 100644 --- a/esp-hal/src/clock/mod.rs +++ b/esp-hal/src/clock/mod.rs @@ -109,7 +109,6 @@ impl CpuClock { } else if #[cfg(esp32p4)] { // ESP32-P4 v3.x (eco5): max 400 MHz via CPLL // Ref: TRM v0.5 Ch 2 -- HP CPU max frequency 400 MHz for v3.x - // esp-idf clk_tree_defs.h -- SOC_CPU_CLK_SRC_CPLL Self::_400MHz } else { Self::_240MHz diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index 96962c103d1..cfc3622eeef 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -651,8 +651,7 @@ impl Rwdt { /// ESP32-P4 LP_WDT implementation. /// P4 PAC uses config0/config1/.../feed/wprotect (no "wdt" prefix), /// and interrupt field is `lp_wdt` (not `wdt`). -/// Ref: esp-idf lp_wdt_reg.h, lpwdt_ll.h -/// TRM v0.5 Ch 19 (Watchdog Timers) +/// Ref: TRM v0.5 Ch 19 (Watchdog Timers) /// Write protection key: 0x50D8_3AA1 (same as other chips) #[cfg(esp32p4)] impl Rwdt { diff --git a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs index 1cfd0c31b7c..768ece4ecc5 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs @@ -2,9 +2,7 @@ //! //! PMU power domain init and WDT disable for bare-metal boot. //! -//! Register names validated against esp32p4 PAC (eco5) and esp-idf: -//! - esp-idf components/esp_hw_support/port/esp32p4/pmu_init.c -//! - esp-idf components/soc/esp32p4/register/hw_ver3/soc/pmu_reg.h +//! Register names validated against esp32p4 PAC (eco5) and: //! - TRM v0.5 Ch 16 (Low-Power Management) //! - TRM v0.5 Ch 19 (Watchdog Timers) //! @@ -13,14 +11,15 @@ //! eco5: power_pd_cnnt_cntl, power_pd_lpperi_cntl (hpaon/hpcpu/hpwifi removed) //! Both: power_pd_top_cntl, power_pd_hpmem_cntl //! -//! florianL21's original eco4 PMU code: esp32p4_florianl21_original.rs.bak + +// TODO: REMOVE me when validate well +// reference florianL21's original eco4 PMU code use strum::FromRepr; use crate::peripherals::{LP_WDT, PMU, TIMG0, TIMG1}; /// SOC Reset Reason. -/// Ref: esp-idf components/soc/esp32p4/include/soc/reset_reasons.h #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] #[repr(usize)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -70,9 +69,6 @@ pub enum SocResetReason { /// - CNNT: power_pd_cnnt_cntl (connectivity, eco5 new -- replaces hpaon/hpcpu/hpwifi) /// - HPMEM: power_pd_hpmem_cntl (HP memory) /// - LPPERI: power_pd_lpperi_cntl (LP peripherals, eco5 new) -/// -/// Ref: esp-idf pmu_init.c -- pmu_hp_system_init() -/// esp-idf pmu_reg.h -- PMU_POWER_PD_*_CNTL_REG fn pmu_power_domain_force_default() { let pmu = PMU::regs(); @@ -122,9 +118,7 @@ fn pmu_power_domain_force_default() { /// This is the minimum needed for the chip to not reset itself during startup. /// Full clock configuration (PLL, CPU freq) is handled separately. /// -/// Ref: esp-idf bootloader_esp32p4.c -- bootloader_super_wdt_auto_feed(), -/// bootloader_clock_configure(), esp_rtc_init() -/// TRM v0.5 Ch 19 (WDT), Ch 16 (Power Management) +/// Ref: TRM v0.5 Ch 19 (WDT), Ch 16 (Power Management) pub(crate) fn init() { // 1. Clear all PMU power domain force flags pmu_power_domain_force_default(); @@ -204,9 +198,7 @@ pub(crate) fn init() { /// Configure CPLL for the given frequency (360 or 400 MHz). /// /// eco5 (v3.x) uses different I2C register values than eco4 (v1.x). -/// Ref: esp-idf clk_tree_ll.h:375-425 -- clk_ll_cpll_set_config() -/// esp-idf regi2c_cpll.h -- I2C_CPLL_OC_REF_DIV, I2C_CPLL_OC_DIV_7_0, I2C_CPLL_OC_DCUR -/// TRM v0.5 Ch 12 -- CPLL configuration +/// Ref: TRM v0.5 Ch 12 -- CPLL configuration fn cpll_configure(freq_mhz: u32) { use crate::soc::regi2c; @@ -275,9 +267,7 @@ fn cpll_configure(freq_mhz: u32) { /// Configure SPLL (System PLL) for the given frequency (480 MHz typical). /// /// SPLL provides peripheral clocks: PLL_F240M/160M/120M/80M/20M. -/// Ref: esp-idf clk_tree_ll.h:430-480 -- clk_ll_spll_set_config() -/// esp-idf regi2c_syspll.h -- I2C_SYS_PLL_OC_REF_DIV, I2C_SYS_PLL_OC_DIV_7_0 -/// TRM v0.5 Ch 12 -- SPLL configuration +/// Ref: TRM v0.5 Ch 12 -- SPLL configuration fn spll_configure(freq_mhz: u32) { use crate::soc::regi2c; diff --git a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs index caaea33c1c2..e844030ab21 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs @@ -3,11 +3,11 @@ //! Current status: Not implemented. Sleep mode requires PMU eco5 registers //! which have different layouts from eco4. //! -//! The original florianL21 sleep code (1064 lines) is preserved as -//! esp32p4_florianl21_original.rs.bak in this directory. +//! The original florianL21 sleep code //! It references types and PMU registers that don't exist in current PAC: //! - crate::clock::Clock, crate::efuse::Efuse (old API pattern) //! - PMU hp_active/hp_modem/hp_sleep register groups //! -//! TODO: Implement sleep mode once PMU eco5 registers are validated. + +// TODO: Implement sleep mode once PMU eco5 registers are validated. // TODO: reference florianL21's implementation diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index 03a45aebc27..0a4df18c8a5 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -194,9 +194,7 @@ fn configure_lp_slow_clk_impl( }); } -// ============================================================ // Per-instance clock impl for UART (called on UartInstance enum) -// ============================================================ impl UartInstance { fn enable_function_clock_impl(self, _clocks: &mut ClockTree, _en: bool) { diff --git a/esp-hal/src/soc/esp32p4/gpio.rs b/esp-hal/src/soc/esp32p4/gpio.rs index b3773452e87..ef3f6a9d957 100644 --- a/esp-hal/src/soc/esp32p4/gpio.rs +++ b/esp-hal/src/soc/esp32p4/gpio.rs @@ -7,8 +7,7 @@ //! GPIO0-5 -> LP pin 0-5 //! GPIO12-23 -> LP pin 6-17 (offset by 6) //! -//! Ref: esp-idf rtc_io_ll.h for P4 -//! TRM v0.5 Ch 11 (GPIO) -- LP_IO_MUX section +//! Ref: TRM v0.5 Ch 11 (GPIO) -- LP_IO_MUX section //! P4 PAC: lp_gpio (0x5012_A000), lp_io_mux (0x5012_B000) /// LP GPIO base address (from PAC) diff --git a/esp-hal/src/soc/esp32p4/regi2c.rs b/esp-hal/src/soc/esp32p4/regi2c.rs index d61dabccf90..63062f91779 100644 --- a/esp-hal/src/soc/esp32p4/regi2c.rs +++ b/esp-hal/src/soc/esp32p4/regi2c.rs @@ -3,9 +3,7 @@ //! Used for PLL configuration (CPLL, SPLL, MPLL) and other analog peripherals. //! Accesses the LP_I2C_ANA_MST peripheral which bridges to internal analog I2C bus. //! -//! Ref: esp-idf components/esp_hal_regi2c/esp32p4/regi2c_impl.c -//! esp-idf components/soc/esp32p4/register/hw_ver3/soc/lp_i2c_ana_mst_reg.h -//! TRM v0.5 Ch 49 (Analog I2C Controller) +//! Ref: TRM v0.5 Ch 49 (Analog I2C Controller) // I2C slave addresses for analog blocks #[allow(dead_code)] @@ -42,7 +40,6 @@ const REGI2C_PLLA_MST_SEL: u16 = 1 << 8; const REGI2C_SAR_I2C_MST_SEL: u16 = 1 << 7; /// I2C control register bit fields -/// Ref: esp-idf regi2c_impl.c lines 32-55 const REGI2C_RTC_BUSY_BIT: u32 = 1 << 25; const REGI2C_RTC_WR_CNTL_BIT: u32 = 1 << 24; const REGI2C_RTC_DATA_SHIFT: u32 = 16; @@ -60,7 +57,6 @@ const LP_I2C_ANA_MST_ANA_CONF1_REG: u32 = LP_I2C_ANA_MST_BASE + 0x04; const LP_I2C_ANA_MST_ANA_CONF2_REG: u32 = LP_I2C_ANA_MST_BASE + 0x08; /// Select the I2C master for the given analog block. -/// Ref: esp-idf regi2c_impl.c:83-117 -- regi2c_enable_block() fn regi2c_enable_block(block: u8) { // Clear both conf registers first unsafe { @@ -99,7 +95,6 @@ fn wait_i2c_idle() { } /// Read an analog I2C register. -/// Ref: esp-idf regi2c_impl.c:119-132 -- _regi2c_impl_read() pub(crate) fn regi2c_read(block: u8, _host_id: u8, reg_add: u8) -> u8 { regi2c_enable_block(block); wait_i2c_idle(); @@ -119,7 +114,6 @@ pub(crate) fn regi2c_read(block: u8, _host_id: u8, reg_add: u8) -> u8 { } /// Write an analog I2C register. -/// Ref: esp-idf regi2c_impl.c:151-164 -- _regi2c_impl_write() pub(crate) fn regi2c_write(block: u8, _host_id: u8, reg_add: u8, data: u8) { regi2c_enable_block(block); wait_i2c_idle(); diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 3a70f97a970..179acd104bb 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -28,8 +28,7 @@ implement_peripheral_clocks!(); /// HP_RST_EN2 (0xc8): SPI/I2S/crypto/misc resets /// PERI_CLK_CTRLxx: Per-peripheral clock dividers and enables /// -/// Ref: esp-idf clk_gate_ll.h, hp_sys_clkrst_reg.h -/// TRM v0.5 Ch 12 (Reset and Clock), Ch 22 (System Registers) +/// Ref: TRM v0.5 Ch 12 (Reset and Clock), Ch 22 (System Registers) #[cfg(esp32p4)] mod _p4_peripheral_clocks { use crate::peripherals::HP_SYS_CLKRST; @@ -167,9 +166,7 @@ mod _p4_peripheral_clocks { } /// Enable or disable peripheral clock. - /// Ref: esp-idf clk_gate_ll.h -- *_ll_enable_bus_clock() functions - /// esp-idf hp_sys_clkrst_reg.h - /// TRM v0.5 Ch 12 + /// Ref: TRM v0.5 Ch 12 pub(crate) unsafe fn enable_internal_racey(peripheral: Peripheral, enable: bool) { let c = HP_SYS_CLKRST::regs(); match peripheral { @@ -373,8 +370,7 @@ mod _p4_peripheral_clocks { } /// Assert or de-assert peripheral reset. - /// Ref: esp-idf hp_sys_clkrst_reg.h -- HP_RST_EN0/1/2 - /// TRM v0.5 Ch 12 + /// Ref: TRM v0.5 Ch 12 #[allow(clippy::single_match)] pub(crate) unsafe fn assert_peri_reset_racey(peripheral: Peripheral, reset: bool) { let c = HP_SYS_CLKRST::regs(); diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index ee0bf5c24b6..7dd6b997e5f 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -135,7 +135,6 @@ clocks = { system_clocks = { clock_tree = [ # ROM bootloader reserves 0x4FF0_0000 - 0x4FF4_0000 (256 KB) # dram: usable application RAM (after ROM reserved region) # dram2_uninit: ROM reserved area, reclaimable after 2nd-stage bootloader -# Ref: esp-idf soc.h -- SOC_DIRAM_ROM_RESERVE_HIGH = 0x4FF40000 memory_map = { ranges = [ { name = "dram", start = 0x4FF4_0000, end = 0x4FFC_0000 }, { name = "dram2_uninit", start = 0x4FF0_0000, end = 0x4FF4_0000 }, From 48176ce3e9aff9743505cce216b8873534918539 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 03:19:24 +0900 Subject: [PATCH 15/27] Cleanup esp32p4x branch from useless modification --- README.md | 3 +- esp-hal/README.md | 55 +- esp-hal/src/efuse/esp32p4/fields.rs | 520 ++++++------- esp-hal/src/i2c/master/mod.rs | 6 +- esp-hal/src/interrupt/mod.rs | 8 - esp-hal/src/interrupt/riscv.rs | 2 - esp-hal/src/interrupt/riscv/clic.rs | 19 +- esp-hal/src/lib.rs | 48 +- esp-hal/src/system.rs | 563 -------------- .../src/_build_script_utils.rs | 8 +- .../src/_generated_esp32p4.rs | 698 +++++++++++++++++- esp-metadata/devices/esp32p4.toml | 159 +++- esp-println/src/lib.rs | 18 +- esp-rom-sys/CHANGELOG.md | 4 +- 14 files changed, 1194 insertions(+), 917 deletions(-) diff --git a/README.md b/README.md index 02de8391ebe..29dbf8e2f70 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,9 @@ Bare-metal (`no_std`) hardware abstraction layer for Espressif devices. Currently supports the following devices: - ESP32 Series: _ESP32_ -- ESP32-C Series: _ESP32-C2, ESP32-C3, ESP32-C6_ +- ESP32-C Series: _ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61_ - ESP32-H Series: _ESP32-H2_ +- ESP32-P Series: _ESP32-P4_ - ESP32-S Series: _ESP32-S2, ESP32-S3_ Additionally provides support for programming the low-power RISC-V cores found on the _ESP32-C6_, _ESP32-S2_, and _ESP32-S3_ via the [esp-lp-hal] package. diff --git a/esp-hal/README.md b/esp-hal/README.md index 2b6a7210295..d5c79d30d34 100644 --- a/esp-hal/README.md +++ b/esp-hal/README.md @@ -30,6 +30,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | ESP32-C6 | [ESP32-C6][c6-datasheet] | [ESP32-C6][c6-trm] | `riscv32imac-unknown-none-elf` | | ESP32-C61| [ESP32-C61][c61-datasheet] | [ESP32-C61][c61-trm] | `riscv32imac-unknown-none-elf` | | ESP32-H2 | [ESP32-H2][h2-datasheet] | [ESP32-H2][h2-trm] | `riscv32imac-unknown-none-elf` | +| ESP32-P4 | [ESP32-P4][p4-datasheet] | [ESP32-P4][p4-trm] | `riscv32imafc-unknown-none-elf`| | ESP32-S2 | [ESP32-S2][s2-datasheet] | [ESP32-S2][s2-trm] | `xtensa-esp32s2-none-elf` | | ESP32-S3 | [ESP32-S3][s3-datasheet] | [ESP32-S3][s3-trm] | `xtensa-esp32s3-none-elf` | @@ -40,6 +41,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a [c6-datasheet]: https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf [c61-datasheet]: https://www.espressif.com/sites/default/files/documentation/esp32-c61_datasheet_en.pdf [h2-datasheet]: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf +[p4-datasheet]: https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf [s2-datasheet]: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf [s3-datasheet]: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf [32-trm]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf @@ -49,6 +51,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a [c6-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf [c61-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-c61_technical_reference_manual_en.pdf [h2-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf +[p4-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf [s2-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf [s3-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf @@ -60,56 +63,56 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | ------------------------- |:-----:|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:|:--------:| | ADC | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | [❌][5422] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | | AES | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | -| ASSIST_DEBUG | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | ⚒️ | -| Analog Voltage Comparator | | | | [❌][5168] [^1] | | [❌][5423] [^1] | | | | | +| ASSIST_DEBUG | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | | ⚒️ | +| Analog Voltage Comparator | | | | [❌][5168] [^1] | | [❌][5423] [^1] | | ❌ | | | | Bit Scrambler | | | | [❌][5170] [^1] | | | | | | | | Bluetooth | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | ⚒️ | -| Camera interface | ❌ | | | | | | | | ❌ | ⚒️ | +| Camera interface | ❌ | | | | | | | ❌ | ❌ | ⚒️ | | DAC | ⚒️ | | | | | | | | ⚒️ | | | Dedicated GPIO | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | DMA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| DS | | | [❌][884] [^1] | [❌][884] [^1] | [❌][884] [^1] | | [❌][884] [^1] | | [❌][884] [^1] | [❌][884] [^1] | -| ECDSA | | | | [❌][5444] [^1] | | [❌][5444] [^1] | [❌][5444] [^1] | | | | +| DS | | | [❌][884] [^1] | [❌][884] [^1] | [❌][884] [^1] | | [❌][884] [^1] | ❌ | [❌][884] [^1] | [❌][884] [^1] | +| ECDSA | | | | [❌][5444] [^1] | | [❌][5444] [^1] | [❌][5444] [^1] | ❌ | | | | ECC | | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | | | -| Ethernet | ❌ | | | | | | | | | | -| ETM | | | | [❌][5167] [^1] | ⚒️ | [❌][5419] [^1] | ⚒️ | | | | +| Ethernet | ❌ | | | | | | | ❌ | | | +| ETM | | | | [❌][5167] [^1] | ⚒️ | [❌][5419] [^1] | ⚒️ | ❌ | | | | GPIO | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ⚒️ | ✔️ | ✔️ | -| HMAC | | | ⚒️ | [❌][5166] [^1] | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| HMAC | | | ⚒️ | [❌][5166] [^1] | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | I2C master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | -| I2C slave | [❌][1909] [^1] | | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | | [❌][1909] [^1] | [❌][1909] [^1] | -| I2S | ⚒️ | | ⚒️ | [❌][5172] [^1] | ⚒️ | [❌][5415] [^1] | ⚒️ | | ⚒️ | ⚒️ | +| I2C slave | [❌][1909] [^1] | | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | ❌ | [❌][1909] [^1] | [❌][1909] [^1] | +| I2S | ⚒️ | | ⚒️ | [❌][5172] [^1] | ⚒️ | [❌][5415] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | | IEEE 802.15.4 | | | | ⚒️ | ⚒️ | | ⚒️ | | | | | Interrupts | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | IOMUX | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | Key Manager | | | | [❌][5171] [^1] | | | | | | | -| LEDC | ⚒️ | ⚒️ | ⚒️ | [❌][5161] [^1] | ⚒️ | [❌][5418] [^1] | ⚒️ | | ⚒️ | ⚒️ | -| LP I2C master | | | | ⚒️ | ⚒️ | | | | | | -| LP UART | | | | [❌][5155] [^1] | ⚒️ | | | | | | -| MCPWM | ⚒️ | | | [❌][5154] [^1] | ⚒️ | | ⚒️ | | | ⚒️ | +| LEDC | ⚒️ | ⚒️ | ⚒️ | [❌][5161] [^1] | ⚒️ | [❌][5418] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | +| LP I2C master | | | | ⚒️ | ⚒️ | | | ❌ | | | +| LP UART | | | | [❌][5155] [^1] | ⚒️ | | | ❌ | | | +| MCPWM | ⚒️ | | | [❌][5154] [^1] | ⚒️ | | ⚒️ | ❌ | | ⚒️ | | PARL_IO | | | | ⚒️ | ⚒️ | | ⚒️ | | | | -| PCNT | ⚒️ | | | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | +| PCNT | ⚒️ | | | ⚒️ | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | PHY | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | | PSRAM | ⚒️ | | | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | -| RGB display | ⚒️ | | | | | | | | ❌ | ⚒️ | +| RGB display | ⚒️ | | | | | | | ❌ | ❌ | ⚒️ | | RMT | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | -| RNG | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | +| RNG | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | ⚒️ | ⚒️ | | RSA | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | -| RTC Timekeeping | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | -| SDIO host | ⚒️ | | | | | | | | | ⚒️ | -| SDIO slave | ⚒️ | | | [❌][5169] [^1] | ⚒️ | [❌][5417] [^1] | | | | | +| RTC Timekeeping | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | ⚒️ | ⚒️ | +| SDIO host | ⚒️ | | | | | | | ❌ | | ⚒️ | +| SDIO slave | ⚒️ | | | [❌][5169] [^1] | ⚒️ | [❌][5417] [^1] | | ❌ | | | | SHA | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | ⚒️ | ⚒️ | -| Light/deep sleep | ⚒️ | ⚒️ | ⚒️ | [❌][5165] [^1] | ⚒️ | [❌][5424] [^1] | ⚒️ | | ⚒️ | ⚒️ | +| Light/deep sleep | ⚒️ | ⚒️ | ⚒️ | [❌][5165] [^1] | ⚒️ | [❌][5424] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | | SPI master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | -| SPI slave | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | +| SPI slave | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | ⚒️ | ⚒️ | | SYSTIMER | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | -| Temperature sensor | ⚒️ | ⚒️ | ⚒️ | [❌][5153] [^1] | ⚒️ | [❌][5421] [^1] | ⚒️ | | ⚒️ | ⚒️ | +| Temperature sensor | ⚒️ | ⚒️ | ⚒️ | [❌][5153] [^1] | ⚒️ | [❌][5421] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | | Timers | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | -| Touch | ⚒️ | | | [❌][5164] [^1] | | | | | [❌][1905] [^1] | [❌][1905] [^1] | +| Touch | ⚒️ | | | [❌][5164] [^1] | | | | ❌ | [❌][1905] [^1] | [❌][1905] [^1] | | TWAI / CAN / CANFD | ⚒️ | | ⚒️ | [❌][5163] [^1] | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | UART | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | -| UHCI | ❌ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | ❌ | ⚒️ | +| UHCI | ❌ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ❌ | ❌ | ⚒️ | | ULP (FSM) | ⚒️ | | | | | | | | ⚒️ | ⚒️ | -| ULP (RISC-V) | | | | [❌][5160] [^1] | ⚒️ | | | | ⚒️ | ⚒️ | +| ULP (RISC-V) | | | | [❌][5160] [^1] | ⚒️ | | | ❌ | ⚒️ | ⚒️ | | USB OTG FS | | | | | | | | | ⚒️ | ⚒️ | | USB Serial/JTAG | | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | | WIFI | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | | ⚒️ | ⚒️ | diff --git a/esp-hal/src/efuse/esp32p4/fields.rs b/esp-hal/src/efuse/esp32p4/fields.rs index aea83773f07..704017b5ef1 100644 --- a/esp-hal/src/efuse/esp32p4/fields.rs +++ b/esp-hal/src/efuse/esp32p4/fields.rs @@ -9,219 +9,219 @@ //! ESP-IDF Commit: 0de2912f use crate::efuse::EfuseField; -/// `[]` Disable programming of individual eFuses +/// Disable programming of individual eFuses pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32); -/// `[]` wr_dis of RD_DIS +/// wr_dis of RD_DIS pub const WR_DIS_RD_DIS: EfuseField = EfuseField::new(0, 0, 0, 1); -/// `[]` wr_dis of KM_RND_SWITCH_CYCLE +/// wr_dis of KM_RND_SWITCH_CYCLE pub const WR_DIS_KM_RND_SWITCH_CYCLE: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of KM_DEPLOY_ONLY_ONCE +/// wr_dis of KM_DEPLOY_ONLY_ONCE pub const WR_DIS_KM_DEPLOY_ONLY_ONCE: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of FORCE_USE_KEY_MANAGER_KEY +/// wr_dis of FORCE_USE_KEY_MANAGER_KEY pub const WR_DIS_FORCE_USE_KEY_MANAGER_KEY: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of FORCE_DISABLE_SW_INIT_KEY +/// wr_dis of FORCE_DISABLE_SW_INIT_KEY pub const WR_DIS_FORCE_DISABLE_SW_INIT_KEY: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of KM_XTS_KEY_LENGTH_256 +/// wr_dis of KM_XTS_KEY_LENGTH_256 pub const WR_DIS_KM_XTS_KEY_LENGTH_256: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of KM_DEPLOY_ONLY_ONCE_H +/// wr_dis of KM_DEPLOY_ONLY_ONCE_H pub const WR_DIS_KM_DEPLOY_ONLY_ONCE_H: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of FORCE_USE_KEY_MANAGER_KEY_H +/// wr_dis of FORCE_USE_KEY_MANAGER_KEY_H pub const WR_DIS_FORCE_USE_KEY_MANAGER_KEY_H: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of LOCK_KM_KEY +/// wr_dis of LOCK_KM_KEY pub const WR_DIS_LOCK_KM_KEY: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of KM_DISABLE_DEPLOY_MODE_H +/// wr_dis of KM_DISABLE_DEPLOY_MODE_H pub const WR_DIS_KM_DISABLE_DEPLOY_MODE_H: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of KM_DISABLE_DEPLOY_MODE +/// wr_dis of KM_DISABLE_DEPLOY_MODE pub const WR_DIS_KM_DISABLE_DEPLOY_MODE: EfuseField = EfuseField::new(0, 0, 1, 1); -/// `[]` wr_dis of DIS_USB_JTAG +/// wr_dis of DIS_USB_JTAG pub const WR_DIS_DIS_USB_JTAG: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of DIS_FORCE_DOWNLOAD +/// wr_dis of DIS_FORCE_DOWNLOAD pub const WR_DIS_DIS_FORCE_DOWNLOAD: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of SPI_DOWNLOAD_MSPI_DIS +/// wr_dis of SPI_DOWNLOAD_MSPI_DIS pub const WR_DIS_SPI_DOWNLOAD_MSPI_DIS: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of DIS_TWAI +/// wr_dis of DIS_TWAI pub const WR_DIS_DIS_TWAI: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of JTAG_SEL_ENABLE +/// wr_dis of JTAG_SEL_ENABLE pub const WR_DIS_JTAG_SEL_ENABLE: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of DIS_PAD_JTAG +/// wr_dis of DIS_PAD_JTAG pub const WR_DIS_DIS_PAD_JTAG: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT +/// wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT pub const WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of WDT_DELAY_SEL +/// wr_dis of WDT_DELAY_SEL pub const WR_DIS_WDT_DELAY_SEL: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of HYS_EN_PAD +/// wr_dis of HYS_EN_PAD pub const WR_DIS_HYS_EN_PAD: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of PXA0_TIEH_SEL_0 +/// wr_dis of PXA0_TIEH_SEL_0 pub const WR_DIS_PXA0_TIEH_SEL_0: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of DIS_WDT +/// wr_dis of DIS_WDT pub const WR_DIS_DIS_WDT: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of DIS_SWD +/// wr_dis of DIS_SWD pub const WR_DIS_DIS_SWD: EfuseField = EfuseField::new(0, 0, 2, 1); -/// `[]` wr_dis of PVT_GLITCH_EN +/// wr_dis of PVT_GLITCH_EN pub const WR_DIS_PVT_GLITCH_EN: EfuseField = EfuseField::new(0, 0, 3, 1); -/// `[]` wr_dis of PVT_GLITCH_MODE +/// wr_dis of PVT_GLITCH_MODE pub const WR_DIS_PVT_GLITCH_MODE: EfuseField = EfuseField::new(0, 0, 3, 1); -/// `[]` wr_dis of SPI_BOOT_CRYPT_CNT +/// wr_dis of SPI_BOOT_CRYPT_CNT pub const WR_DIS_SPI_BOOT_CRYPT_CNT: EfuseField = EfuseField::new(0, 0, 4, 1); -/// `[]` wr_dis of SECURE_BOOT_KEY_REVOKE0 +/// wr_dis of SECURE_BOOT_KEY_REVOKE0 pub const WR_DIS_SECURE_BOOT_KEY_REVOKE0: EfuseField = EfuseField::new(0, 0, 5, 1); -/// `[]` wr_dis of SECURE_BOOT_KEY_REVOKE1 +/// wr_dis of SECURE_BOOT_KEY_REVOKE1 pub const WR_DIS_SECURE_BOOT_KEY_REVOKE1: EfuseField = EfuseField::new(0, 0, 6, 1); -/// `[]` wr_dis of SECURE_BOOT_KEY_REVOKE2 +/// wr_dis of SECURE_BOOT_KEY_REVOKE2 pub const WR_DIS_SECURE_BOOT_KEY_REVOKE2: EfuseField = EfuseField::new(0, 0, 7, 1); /// `[WR_DIS.KEY0_PURPOSE]` wr_dis of KEY_PURPOSE_0 pub const WR_DIS_KEY_PURPOSE_0: EfuseField = EfuseField::new(0, 0, 8, 1); -/// `[]` wr_dis of KEY_PURPOSE_0_H +/// wr_dis of KEY_PURPOSE_0_H pub const WR_DIS_KEY_PURPOSE_0_H: EfuseField = EfuseField::new(0, 0, 8, 1); /// `[WR_DIS.KEY1_PURPOSE]` wr_dis of KEY_PURPOSE_1 pub const WR_DIS_KEY_PURPOSE_1: EfuseField = EfuseField::new(0, 0, 9, 1); -/// `[]` wr_dis of KEY_PURPOSE_1_H +/// wr_dis of KEY_PURPOSE_1_H pub const WR_DIS_KEY_PURPOSE_1_H: EfuseField = EfuseField::new(0, 0, 9, 1); /// `[WR_DIS.KEY2_PURPOSE]` wr_dis of KEY_PURPOSE_2 pub const WR_DIS_KEY_PURPOSE_2: EfuseField = EfuseField::new(0, 0, 10, 1); -/// `[]` wr_dis of KEY_PURPOSE_2_H +/// wr_dis of KEY_PURPOSE_2_H pub const WR_DIS_KEY_PURPOSE_2_H: EfuseField = EfuseField::new(0, 0, 10, 1); /// `[WR_DIS.KEY3_PURPOSE]` wr_dis of KEY_PURPOSE_3 pub const WR_DIS_KEY_PURPOSE_3: EfuseField = EfuseField::new(0, 0, 11, 1); -/// `[]` wr_dis of KEY_PURPOSE_3_H +/// wr_dis of KEY_PURPOSE_3_H pub const WR_DIS_KEY_PURPOSE_3_H: EfuseField = EfuseField::new(0, 0, 11, 1); /// `[WR_DIS.KEY4_PURPOSE]` wr_dis of KEY_PURPOSE_4 pub const WR_DIS_KEY_PURPOSE_4: EfuseField = EfuseField::new(0, 0, 12, 1); -/// `[]` wr_dis of KEY_PURPOSE_4_H +/// wr_dis of KEY_PURPOSE_4_H pub const WR_DIS_KEY_PURPOSE_4_H: EfuseField = EfuseField::new(0, 0, 12, 1); /// `[WR_DIS.KEY5_PURPOSE]` wr_dis of KEY_PURPOSE_5 pub const WR_DIS_KEY_PURPOSE_5: EfuseField = EfuseField::new(0, 0, 13, 1); -/// `[]` wr_dis of KEY_PURPOSE_5_H +/// wr_dis of KEY_PURPOSE_5_H pub const WR_DIS_KEY_PURPOSE_5_H: EfuseField = EfuseField::new(0, 0, 13, 1); -/// `[]` wr_dis of ECC_FORCE_CONST_TIME +/// wr_dis of ECC_FORCE_CONST_TIME pub const WR_DIS_ECC_FORCE_CONST_TIME: EfuseField = EfuseField::new(0, 0, 14, 1); -/// `[]` wr_dis of SEC_DPA_LEVEL +/// wr_dis of SEC_DPA_LEVEL pub const WR_DIS_SEC_DPA_LEVEL: EfuseField = EfuseField::new(0, 0, 14, 1); -/// `[]` wr_dis of XTS_DPA_CLK_ENABLE +/// wr_dis of XTS_DPA_CLK_ENABLE pub const WR_DIS_XTS_DPA_CLK_ENABLE: EfuseField = EfuseField::new(0, 0, 14, 1); -/// `[]` wr_dis of XTS_DPA_PSEUDO_LEVEL +/// wr_dis of XTS_DPA_PSEUDO_LEVEL pub const WR_DIS_XTS_DPA_PSEUDO_LEVEL: EfuseField = EfuseField::new(0, 0, 14, 1); -/// `[]` wr_dis of SECURE_BOOT_EN +/// wr_dis of SECURE_BOOT_EN pub const WR_DIS_SECURE_BOOT_EN: EfuseField = EfuseField::new(0, 0, 15, 1); -/// `[]` wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE +/// wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE pub const WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE: EfuseField = EfuseField::new(0, 0, 16, 1); -/// `[]` wr_dis of HP_PWR_SRC_SEL +/// wr_dis of HP_PWR_SRC_SEL pub const WR_DIS_HP_PWR_SRC_SEL: EfuseField = EfuseField::new(0, 0, 17, 1); -/// `[]` wr_dis of FLASH_ECC_EN +/// wr_dis of FLASH_ECC_EN pub const WR_DIS_FLASH_ECC_EN: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of DIS_USB_OTG_DOWNLOAD_MODE +/// wr_dis of DIS_USB_OTG_DOWNLOAD_MODE pub const WR_DIS_DIS_USB_OTG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of FLASH_TPUW +/// wr_dis of FLASH_TPUW pub const WR_DIS_FLASH_TPUW: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of DIS_DOWNLOAD_MODE +/// wr_dis of DIS_DOWNLOAD_MODE pub const WR_DIS_DIS_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of DIS_DIRECT_BOOT +/// wr_dis of DIS_DIRECT_BOOT pub const WR_DIS_DIS_DIRECT_BOOT: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT +/// wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT pub const WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE +/// wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE pub const WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of ENABLE_SECURITY_DOWNLOAD +/// wr_dis of ENABLE_SECURITY_DOWNLOAD pub const WR_DIS_ENABLE_SECURITY_DOWNLOAD: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of UART_PRINT_CONTROL +/// wr_dis of UART_PRINT_CONTROL pub const WR_DIS_UART_PRINT_CONTROL: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of FORCE_SEND_RESUME +/// wr_dis of FORCE_SEND_RESUME pub const WR_DIS_FORCE_SEND_RESUME: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of SECURE_VERSION +/// wr_dis of SECURE_VERSION pub const WR_DIS_SECURE_VERSION: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE +/// wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE pub const WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE: EfuseField = EfuseField::new(0, 0, 18, 1); -/// `[]` wr_dis of HUK_GEN_STATE +/// wr_dis of HUK_GEN_STATE pub const WR_DIS_HUK_GEN_STATE: EfuseField = EfuseField::new(0, 0, 19, 1); -/// `[]` wr_dis of BLOCK1 +/// wr_dis of BLOCK1 pub const WR_DIS_BLK1: EfuseField = EfuseField::new(0, 0, 20, 1); /// `[WR_DIS.MAC_FACTORY]` wr_dis of MAC pub const WR_DIS_MAC: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of WAFER_VERSION_MINOR +/// wr_dis of WAFER_VERSION_MINOR pub const WR_DIS_WAFER_VERSION_MINOR: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of WAFER_VERSION_MAJOR_LO +/// wr_dis of WAFER_VERSION_MAJOR_LO pub const WR_DIS_WAFER_VERSION_MAJOR_LO: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of DISABLE_WAFER_VERSION_MAJOR +/// wr_dis of DISABLE_WAFER_VERSION_MAJOR pub const WR_DIS_DISABLE_WAFER_VERSION_MAJOR: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of DISABLE_BLK_VERSION_MAJOR +/// wr_dis of DISABLE_BLK_VERSION_MAJOR pub const WR_DIS_DISABLE_BLK_VERSION_MAJOR: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of BLK_VERSION_MINOR +/// wr_dis of BLK_VERSION_MINOR pub const WR_DIS_BLK_VERSION_MINOR: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of BLK_VERSION_MAJOR +/// wr_dis of BLK_VERSION_MAJOR pub const WR_DIS_BLK_VERSION_MAJOR: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of PSRAM_CAP +/// wr_dis of PSRAM_CAP pub const WR_DIS_PSRAM_CAP: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of TEMP +/// wr_dis of TEMP pub const WR_DIS_TEMP: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of PSRAM_VENDOR +/// wr_dis of PSRAM_VENDOR pub const WR_DIS_PSRAM_VENDOR: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of PKG_VERSION +/// wr_dis of PKG_VERSION pub const WR_DIS_PKG_VERSION: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of BLOCK2 +/// wr_dis of BLOCK2 pub const WR_DIS_SYS_DATA_PART1: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of WAFER_VERSION_MAJOR_HI +/// wr_dis of WAFER_VERSION_MAJOR_HI pub const WR_DIS_WAFER_VERSION_MAJOR_HI: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO1_DREF +/// wr_dis of LDO_VO1_DREF pub const WR_DIS_LDO_VO1_DREF: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO2_DREF +/// wr_dis of LDO_VO2_DREF pub const WR_DIS_LDO_VO2_DREF: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO1_MUL +/// wr_dis of LDO_VO1_MUL pub const WR_DIS_LDO_VO1_MUL: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO2_MUL +/// wr_dis of LDO_VO2_MUL pub const WR_DIS_LDO_VO2_MUL: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO3_K +/// wr_dis of LDO_VO3_K pub const WR_DIS_LDO_VO3_K: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO3_VOS +/// wr_dis of LDO_VO3_VOS pub const WR_DIS_LDO_VO3_VOS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO3_C +/// wr_dis of LDO_VO3_C pub const WR_DIS_LDO_VO3_C: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO4_K +/// wr_dis of LDO_VO4_K pub const WR_DIS_LDO_VO4_K: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO4_VOS +/// wr_dis of LDO_VO4_VOS pub const WR_DIS_LDO_VO4_VOS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LDO_VO4_C +/// wr_dis of LDO_VO4_C pub const WR_DIS_LDO_VO4_C: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of ACTIVE_HP_DBIAS +/// wr_dis of ACTIVE_HP_DBIAS pub const WR_DIS_ACTIVE_HP_DBIAS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of ACTIVE_LP_DBIAS +/// wr_dis of ACTIVE_LP_DBIAS pub const WR_DIS_ACTIVE_LP_DBIAS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of DSLP_DBG +/// wr_dis of DSLP_DBG pub const WR_DIS_DSLP_DBG: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of DSLP_LP_DBIAS +/// wr_dis of DSLP_LP_DBIAS pub const WR_DIS_DSLP_LP_DBIAS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of LP_DCDC_DBIAS_VOL_GAP +/// wr_dis of LP_DCDC_DBIAS_VOL_GAP pub const WR_DIS_LP_DCDC_DBIAS_VOL_GAP: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of PVT_400M_BIAS +/// wr_dis of PVT_400M_BIAS pub const WR_DIS_PVT_400M_BIAS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of PVT_40M_BIAS +/// wr_dis of PVT_40M_BIAS pub const WR_DIS_PVT_40M_BIAS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of PVT_100M_BIAS +/// wr_dis of PVT_100M_BIAS pub const WR_DIS_PVT_100M_BIAS: EfuseField = EfuseField::new(0, 0, 20, 1); -/// `[]` wr_dis of OPTIONAL_UNIQUE_ID +/// wr_dis of OPTIONAL_UNIQUE_ID pub const WR_DIS_OPTIONAL_UNIQUE_ID: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN0 +/// wr_dis of ADC1_AVE_INITCODE_ATTEN0 pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN1 +/// wr_dis of ADC1_AVE_INITCODE_ATTEN1 pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN2 +/// wr_dis of ADC1_AVE_INITCODE_ATTEN2 pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_AVE_INITCODE_ATTEN3 +/// wr_dis of ADC1_AVE_INITCODE_ATTEN3 pub const WR_DIS_ADC1_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN0 +/// wr_dis of ADC2_AVE_INITCODE_ATTEN0 pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN1 +/// wr_dis of ADC2_AVE_INITCODE_ATTEN1 pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN2 +/// wr_dis of ADC2_AVE_INITCODE_ATTEN2 pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC2_AVE_INITCODE_ATTEN3 +/// wr_dis of ADC2_AVE_INITCODE_ATTEN3 pub const WR_DIS_ADC2_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN0 +/// wr_dis of ADC1_HI_DOUT_ATTEN0 pub const WR_DIS_ADC1_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN1 +/// wr_dis of ADC1_HI_DOUT_ATTEN1 pub const WR_DIS_ADC1_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN2 +/// wr_dis of ADC1_HI_DOUT_ATTEN2 pub const WR_DIS_ADC1_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(0, 0, 21, 1); -/// `[]` wr_dis of ADC1_HI_DOUT_ATTEN3 +/// wr_dis of ADC1_HI_DOUT_ATTEN3 pub const WR_DIS_ADC1_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(0, 0, 21, 1); /// `[WR_DIS.USER_DATA]` wr_dis of BLOCK_USR_DATA pub const WR_DIS_BLOCK_USR_DATA: EfuseField = EfuseField::new(0, 0, 22, 1); @@ -241,51 +241,51 @@ pub const WR_DIS_BLOCK_KEY4: EfuseField = EfuseField::new(0, 0, 27, 1); pub const WR_DIS_BLOCK_KEY5: EfuseField = EfuseField::new(0, 0, 28, 1); /// `[WR_DIS.SYS_DATA_PART2]` wr_dis of BLOCK_SYS_DATA2 pub const WR_DIS_BLOCK_SYS_DATA2: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN0 +/// wr_dis of ADC2_HI_DOUT_ATTEN0 pub const WR_DIS_ADC2_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN1 +/// wr_dis of ADC2_HI_DOUT_ATTEN1 pub const WR_DIS_ADC2_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN2 +/// wr_dis of ADC2_HI_DOUT_ATTEN2 pub const WR_DIS_ADC2_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_HI_DOUT_ATTEN3 +/// wr_dis of ADC2_HI_DOUT_ATTEN3 pub const WR_DIS_ADC2_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH5_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH5_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH6_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH6_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH6_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC1_CH7_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC1_CH7_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC1_CH7_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_CH0_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC2_CH0_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC2_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_CH1_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC2_CH1_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC2_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_CH2_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC2_CH2_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC2_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_CH3_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC2_CH3_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC2_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_CH4_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC2_CH4_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC2_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of ADC2_CH5_ATTEN0_INITCODE_DIFF +/// wr_dis of ADC2_CH5_ATTEN0_INITCODE_DIFF pub const WR_DIS_ADC2_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of TEMPERATURE_SENSOR +/// wr_dis of TEMPERATURE_SENSOR pub const WR_DIS_TEMPERATURE_SENSOR: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of USB_DEVICE_EXCHG_PINS +/// wr_dis of USB_DEVICE_EXCHG_PINS pub const WR_DIS_USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of USB_OTG11_EXCHG_PINS +/// wr_dis of USB_OTG11_EXCHG_PINS pub const WR_DIS_USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(0, 0, 29, 1); -/// `[]` wr_dis of SOFT_DIS_JTAG +/// wr_dis of SOFT_DIS_JTAG pub const WR_DIS_SOFT_DIS_JTAG: EfuseField = EfuseField::new(0, 0, 31, 1); -/// `[]` Disable reading from BlOCK4-10 +/// Disable reading from BlOCK4-10 pub const RD_DIS: EfuseField = EfuseField::new(0, 1, 32, 7); /// `[RD_DIS.KEY0]` rd_dis of BLOCK_KEY0 pub const RD_DIS_BLOCK_KEY0: EfuseField = EfuseField::new(0, 1, 32, 1); @@ -301,127 +301,127 @@ pub const RD_DIS_BLOCK_KEY4: EfuseField = EfuseField::new(0, 1, 36, 1); pub const RD_DIS_BLOCK_KEY5: EfuseField = EfuseField::new(0, 1, 37, 1); /// `[RD_DIS.SYS_DATA_PART2]` rd_dis of BLOCK_SYS_DATA2 pub const RD_DIS_BLOCK_SYS_DATA2: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN0 +/// rd_dis of ADC2_HI_DOUT_ATTEN0 pub const RD_DIS_ADC2_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN1 +/// rd_dis of ADC2_HI_DOUT_ATTEN1 pub const RD_DIS_ADC2_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN2 +/// rd_dis of ADC2_HI_DOUT_ATTEN2 pub const RD_DIS_ADC2_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_HI_DOUT_ATTEN3 +/// rd_dis of ADC2_HI_DOUT_ATTEN3 pub const RD_DIS_ADC2_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH5_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH5_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH6_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH6_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH6_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC1_CH7_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC1_CH7_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC1_CH7_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_CH0_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC2_CH0_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC2_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_CH1_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC2_CH1_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC2_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_CH2_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC2_CH2_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC2_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_CH3_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC2_CH3_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC2_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_CH4_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC2_CH4_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC2_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of ADC2_CH5_ATTEN0_INITCODE_DIFF +/// rd_dis of ADC2_CH5_ATTEN0_INITCODE_DIFF pub const RD_DIS_ADC2_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of TEMPERATURE_SENSOR +/// rd_dis of TEMPERATURE_SENSOR pub const RD_DIS_TEMPERATURE_SENSOR: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of USB_DEVICE_EXCHG_PINS +/// rd_dis of USB_DEVICE_EXCHG_PINS pub const RD_DIS_USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` rd_dis of USB_OTG11_EXCHG_PINS +/// rd_dis of USB_OTG11_EXCHG_PINS pub const RD_DIS_USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(0, 1, 38, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// Represents the starting flash sector (flash sector size is 0x1000) of the recovery /// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this /// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1: EfuseField = EfuseField::new(0, 1, 39, 2); -/// `[]` Set this bit to disable function of usb switch to jtag in module of usb device +/// Set this bit to disable function of usb switch to jtag in module of usb device pub const DIS_USB_JTAG: EfuseField = EfuseField::new(0, 1, 41, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// Represents the starting flash sector (flash sector size is 0x1000) of the recovery /// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this /// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2: EfuseField = EfuseField::new(0, 1, 42, 1); -/// `[]` Set this bit to disable the function that forces chip into download mode +/// Set this bit to disable the function that forces chip into download mode pub const DIS_FORCE_DOWNLOAD: EfuseField = EfuseField::new(0, 1, 44, 1); -/// `[]` Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during +/// Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during /// boot_mode_download pub const SPI_DOWNLOAD_MSPI_DIS: EfuseField = EfuseField::new(0, 1, 45, 1); -/// `[]` Set this bit to disable TWAI function +/// Set this bit to disable TWAI function pub const DIS_TWAI: EfuseField = EfuseField::new(0, 1, 46, 1); -/// `[]` Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping +/// Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping /// gpio25 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 pub const JTAG_SEL_ENABLE: EfuseField = EfuseField::new(0, 1, 47, 1); -/// `[]` Set odd bits to disable JTAG in the soft way. JTAG can be enabled in HMAC module +/// Set odd bits to disable JTAG in the soft way. JTAG can be enabled in HMAC module pub const SOFT_DIS_JTAG: EfuseField = EfuseField::new(0, 1, 48, 3); -/// `[]` Set this bit to disable JTAG in the hard way. JTAG is disabled permanently +/// Set this bit to disable JTAG in the hard way. JTAG is disabled permanently pub const DIS_PAD_JTAG: EfuseField = EfuseField::new(0, 1, 51, 1); -/// `[]` Set this bit to disable flash manual encrypt function (except in SPI boot mode) +/// Set this bit to disable flash manual encrypt function (except in SPI boot mode) pub const DIS_DOWNLOAD_MANUAL_ENCRYPT: EfuseField = EfuseField::new(0, 1, 52, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// Represents the starting flash sector (flash sector size is 0x1000) of the recovery /// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this /// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6: EfuseField = EfuseField::new(0, 1, 53, 4); -/// `[]` 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) +/// 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) /// <---> usb_device 1: intphy(24/25) <---> usb_otg11 pub const USB_PHY_SEL: EfuseField = EfuseField::new(0, 1, 57, 1); -/// `[]` Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is +/// Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is /// valid pub const HUK_GEN_STATE: EfuseField = EfuseField::new(0, 1, 58, 5); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// Represents the starting flash sector (flash sector size is 0x1000) of the recovery /// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this /// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7: EfuseField = EfuseField::new(0, 1, 63, 1); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// Represents the starting flash sector (flash sector size is 0x1000) of the recovery /// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this /// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10: EfuseField = EfuseField::new(0, 2, 64, 3); -/// `[]` Represents the starting flash sector (flash sector size is 0x1000) of the recovery +/// Represents the starting flash sector (flash sector size is 0x1000) of the recovery /// bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this /// feature is disabled pub const RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11: EfuseField = EfuseField::new(0, 2, 67, 1); -/// `[]` Set the bits to control key manager random number switch cycle. 0: control by register. 1: +/// Set the bits to control key manager random number switch cycle. 0: control by register. 1: /// 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles pub const KM_RND_SWITCH_CYCLE: EfuseField = EfuseField::new(0, 2, 68, 1); -/// `[]` EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: +/// EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: /// {EFUSE_KM_DEPLOY_ONLY_ONCE_H; EFUSE_KM_DEPLOY_ONLY_ONCE`[3:0]`}. Set each bit to control whether /// corresponding key can only be deployed once. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; /// bit2: hmac; bit3: ds; bit4:psram pub const KM_DEPLOY_ONLY_ONCE: EfuseField = EfuseField::new(0, 3, 118, 5); -/// `[]` EFUSE_FORCE_USE_KEY_MANAGER_KEY and EFUSE_FORCE_USE_KEY_MANAGER_KEY_H together form one +/// EFUSE_FORCE_USE_KEY_MANAGER_KEY and EFUSE_FORCE_USE_KEY_MANAGER_KEY_H together form one /// field: {EFUSE_FORCE_USE_KEY_MANAGER_KEY_H; EFUSE_FORCE_USE_KEY_MANAGER_KEY`[3:0]`}. Set each bit /// to control whether corresponding key must come from key manager. 1 is true; 0 is false. bit 0: /// ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram pub const FORCE_USE_KEY_MANAGER_KEY: EfuseField = EfuseField::new(0, 3, 119, 5); -/// `[]` Set this bit to disable software written init key; and force use efuse_init_key +/// Set this bit to disable software written init key; and force use efuse_init_key pub const FORCE_DISABLE_SW_INIT_KEY: EfuseField = EfuseField::new(0, 2, 77, 1); -/// `[]` Set this bit to config flash encryption xts-512 key; else use xts-256 key when using the +/// Set this bit to config flash encryption xts-512 key; else use xts-256 key when using the /// key manager pub const KM_XTS_KEY_LENGTH_256: EfuseField = EfuseField::new(0, 2, 78, 1); -/// `[]` Set this bit to permanently turn on ECC const-time mode +/// Set this bit to permanently turn on ECC const-time mode pub const ECC_FORCE_CONST_TIME: EfuseField = EfuseField::new(0, 2, 79, 1); -/// `[]` Select lp wdt timeout threshold at startup = initial timeout value * (2 ^ +/// Select lp wdt timeout threshold at startup = initial timeout value * (2 ^ /// (EFUSE_WDT_DELAY_SEL + 1)) pub const WDT_DELAY_SEL: EfuseField = EfuseField::new(0, 2, 81, 1); -/// `[]` Set this bit to enable SPI boot encrypt/decrypt. Odd number of 1: enable. even number of 1: +/// Set this bit to enable SPI boot encrypt/decrypt. Odd number of 1: enable. even number of 1: /// disable {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"} pub const SPI_BOOT_CRYPT_CNT: EfuseField = EfuseField::new(0, 2, 82, 3); -/// `[]` Revoke 1st secure boot key +/// Revoke 1st secure boot key pub const SECURE_BOOT_KEY_REVOKE0: EfuseField = EfuseField::new(0, 2, 85, 1); -/// `[]` Revoke 2nd secure boot key +/// Revoke 2nd secure boot key pub const SECURE_BOOT_KEY_REVOKE1: EfuseField = EfuseField::new(0, 2, 86, 1); -/// `[]` Revoke 3rd secure boot key +/// Revoke 3rd secure boot key pub const SECURE_BOOT_KEY_REVOKE2: EfuseField = EfuseField::new(0, 2, 87, 1); /// `[KEY0_PURPOSE]` Purpose of Key0 pub const KEY_PURPOSE_0: EfuseField = EfuseField::new(0, 4, 155, 5); @@ -435,153 +435,153 @@ pub const KEY_PURPOSE_3: EfuseField = EfuseField::new(0, 4, 158, 5); pub const KEY_PURPOSE_4: EfuseField = EfuseField::new(0, 4, 159, 5); /// `[KEY5_PURPOSE]` Purpose of Key5 pub const KEY_PURPOSE_5: EfuseField = EfuseField::new(0, 5, 164, 5); -/// `[]` Configures the clock random divide mode to determine the dpa secure level +/// Configures the clock random divide mode to determine the dpa secure level pub const SEC_DPA_LEVEL: EfuseField = EfuseField::new(0, 3, 112, 2); -/// `[]` Sets this bit to enable xts clock anti-dpa attack function +/// Sets this bit to enable xts clock anti-dpa attack function pub const XTS_DPA_CLK_ENABLE: EfuseField = EfuseField::new(0, 3, 115, 1); -/// `[]` Set this bit to enable secure boot +/// Set this bit to enable secure boot pub const SECURE_BOOT_EN: EfuseField = EfuseField::new(0, 3, 116, 1); -/// `[]` Set this bit to enable revoking aggressive secure boot +/// Set this bit to enable revoking aggressive secure boot pub const SECURE_BOOT_AGGRESSIVE_REVOKE: EfuseField = EfuseField::new(0, 3, 117, 1); -/// `[]` Set this bit to enable ECC for flash boot +/// Set this bit to enable ECC for flash boot pub const FLASH_ECC_EN: EfuseField = EfuseField::new(0, 3, 122, 1); -/// `[]` Set this bit to disable download via USB-OTG +/// Set this bit to disable download via USB-OTG pub const DIS_USB_OTG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 3, 123, 1); -/// `[]` Configures flash waiting time after power-up; in unit of ms. When the value less than 15; +/// Configures flash waiting time after power-up; in unit of ms. When the value less than 15; /// the waiting time is the configurable value. Otherwise; the waiting time is 30 pub const FLASH_TPUW: EfuseField = EfuseField::new(0, 3, 124, 4); -/// `[]` Set this bit to disable download mode (boot_mode`[3:0]` = 0; 1; 2; 4; 5; 6; 7) +/// Set this bit to disable download mode (boot_mode`[3:0]` = 0; 1; 2; 4; 5; 6; 7) pub const DIS_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 4, 128, 1); -/// `[]` Set this bit to disable direct boot mode +/// Set this bit to disable direct boot mode pub const DIS_DIRECT_BOOT: EfuseField = EfuseField::new(0, 4, 129, 1); -/// `[]` Set this bit to disable USB-Serial-JTAG print during rom boot +/// Set this bit to disable USB-Serial-JTAG print during rom boot pub const DIS_USB_SERIAL_JTAG_ROM_PRINT: EfuseField = EfuseField::new(0, 4, 130, 1); -/// `[]` set this bit to lock the key manager key after deploy +/// set this bit to lock the key manager key after deploy pub const LOCK_KM_KEY: EfuseField = EfuseField::new(0, 4, 131, 1); -/// `[]` Set this bit to disable the USB-Serial-JTAG download function +/// Set this bit to disable the USB-Serial-JTAG download function pub const DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE: EfuseField = EfuseField::new(0, 4, 132, 1); -/// `[]` Set this bit to enable security download mode +/// Set this bit to enable security download mode pub const ENABLE_SECURITY_DOWNLOAD: EfuseField = EfuseField::new(0, 4, 133, 1); -/// `[]` Set the type of UART printing; 00: force enable printing; 01: enable printing when GPIO8 is +/// Set the type of UART printing; 00: force enable printing; 01: enable printing when GPIO8 is /// reset at low level; 10: enable printing when GPIO8 is reset at high level; 11: force disable /// printing pub const UART_PRINT_CONTROL: EfuseField = EfuseField::new(0, 4, 134, 2); -/// `[]` Set this bit to force ROM code to send a resume command during SPI boot +/// Set this bit to force ROM code to send a resume command during SPI boot pub const FORCE_SEND_RESUME: EfuseField = EfuseField::new(0, 4, 136, 1); -/// `[]` Secure version used by ESP-IDF anti-rollback feature +/// Secure version used by ESP-IDF anti-rollback feature pub const SECURE_VERSION: EfuseField = EfuseField::new(0, 4, 137, 16); -/// `[]` Represents whether secure boot do fast verification on wake is disabled. 0: enabled 1: +/// Represents whether secure boot do fast verification on wake is disabled. 0: enabled 1: /// disabled pub const SECURE_BOOT_DISABLE_FAST_WAKE: EfuseField = EfuseField::new(0, 4, 153, 1); -/// `[]` Set bits to enable hysteresis function of PAD0~27 +/// Set bits to enable hysteresis function of PAD0~27 pub const HYS_EN_PAD: EfuseField = EfuseField::new(0, 4, 154, 1); -/// `[]` Output LDO VO0 tieh source select. 0: 1'b1 1: sdmmc1 2: reg 3:sdmmc0 +/// Output LDO VO0 tieh source select. 0: 1'b1 1: sdmmc1 2: reg 3:sdmmc0 pub const PXA0_TIEH_SEL_0: EfuseField = EfuseField::new(0, 5, 160, 2); -/// `[]` Represents whether to enable PVT power glitch monitor function.1:Enable. 0:Disable +/// Represents whether to enable PVT power glitch monitor function.1:Enable. 0:Disable pub const PVT_GLITCH_EN: EfuseField = EfuseField::new(0, 5, 162, 1); -/// `[]` EFUSE_KM_DISABLE_DEPLOY_MODE and EFUSE_KM_DISABLE_DEPLOY_MODE_H together form one field: +/// EFUSE_KM_DISABLE_DEPLOY_MODE and EFUSE_KM_DISABLE_DEPLOY_MODE_H together form one field: /// {EFUSE_KM_DISABLE_DEPLOY_MODE_H; EFUSE_KM_DISABLE_DEPLOY_MODE`[3:0]`}. Set each bit to control /// whether corresponding key's deploy mode of new value deployment is disabled. 1 is true; 0 is /// false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram pub const KM_DISABLE_DEPLOY_MODE: EfuseField = EfuseField::new(0, 5, 167, 5); -/// `[]` Sets this bit to control the xts pseudo-round anti-dpa attack function. 0: controlled by +/// Sets this bit to control the xts pseudo-round anti-dpa attack function. 0: controlled by /// register. 1-3: the higher the value is; the more pseudo-rounds are inserted to the xts-aes /// calculation pub const XTS_DPA_PSEUDO_LEVEL: EfuseField = EfuseField::new(0, 5, 176, 2); -/// `[]` HP system power source select. 0:LDO 1: DCDC +/// HP system power source select. 0:LDO 1: DCDC pub const HP_PWR_SRC_SEL: EfuseField = EfuseField::new(0, 5, 178, 1); -/// `[]` Represents whether secure boot using SHA-384 is enabled. 0: disable 1: enable +/// Represents whether secure boot using SHA-384 is enabled. 0: disable 1: enable pub const SECURE_BOOT_SHA384_EN: EfuseField = EfuseField::new(0, 5, 179, 1); -/// `[]` Set this bit to disable watch dog +/// Set this bit to disable watch dog pub const DIS_WDT: EfuseField = EfuseField::new(0, 5, 180, 1); -/// `[]` Set bit to disable super-watchdog +/// Set bit to disable super-watchdog pub const DIS_SWD: EfuseField = EfuseField::new(0, 5, 181, 1); -/// `[]` Use to configure glitch mode +/// Use to configure glitch mode pub const PVT_GLITCH_MODE: EfuseField = EfuseField::new(0, 5, 182, 2); /// `[MAC_FACTORY]` MAC address pub const MAC0: EfuseField = EfuseField::new(1, 0, 0, 32); pub const MAC1: EfuseField = EfuseField::new(1, 0, 32, 16); -/// `[]` Minor chip version +/// Minor chip version pub const WAFER_VERSION_MINOR: EfuseField = EfuseField::new(1, 2, 64, 4); -/// `[]` Major chip version (lower 2 bits) +/// Major chip version (lower 2 bits) pub const WAFER_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 87, 3); -/// `[]` Disables check of wafer version major +/// Disables check of wafer version major pub const DISABLE_WAFER_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 70, 1); -/// `[]` Disables check of blk version major +/// Disables check of blk version major pub const DISABLE_BLK_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 71, 1); -/// `[]` BLK_VERSION_MINOR of BLOCK2 +/// BLK_VERSION_MINOR of BLOCK2 pub const BLK_VERSION_MINOR: EfuseField = EfuseField::new(1, 2, 72, 3); -/// `[]` BLK_VERSION_MAJOR of BLOCK2 +/// BLK_VERSION_MAJOR of BLOCK2 pub const BLK_VERSION_MAJOR: EfuseField = EfuseField::new(1, 2, 75, 2); -/// `[]` PSRAM capacity +/// PSRAM capacity pub const PSRAM_CAP: EfuseField = EfuseField::new(1, 2, 77, 3); -/// `[]` Operating temperature of the ESP chip +/// Operating temperature of the ESP chip pub const TEMP: EfuseField = EfuseField::new(1, 2, 80, 2); -/// `[]` PSRAM vendor +/// PSRAM vendor pub const PSRAM_VENDOR: EfuseField = EfuseField::new(1, 2, 82, 2); -/// `[]` Package version +/// Package version pub const PKG_VERSION: EfuseField = EfuseField::new(1, 2, 84, 3); -/// `[]` Output VO1 parameter +/// Output VO1 parameter pub const LDO_VO1_DREF: EfuseField = EfuseField::new(1, 2, 88, 4); -/// `[]` Output VO2 parameter +/// Output VO2 parameter pub const LDO_VO2_DREF: EfuseField = EfuseField::new(1, 2, 92, 4); -/// `[]` Output VO1 parameter +/// Output VO1 parameter pub const LDO_VO1_MUL: EfuseField = EfuseField::new(1, 3, 96, 3); -/// `[]` Output VO2 parameter +/// Output VO2 parameter pub const LDO_VO2_MUL: EfuseField = EfuseField::new(1, 3, 99, 3); -/// `[]` Output VO3 calibration parameter +/// Output VO3 calibration parameter pub const LDO_VO3_K: EfuseField = EfuseField::new(1, 3, 102, 8); -/// `[]` Output VO3 calibration parameter +/// Output VO3 calibration parameter pub const LDO_VO3_VOS: EfuseField = EfuseField::new(1, 3, 110, 6); -/// `[]` Output VO3 calibration parameter +/// Output VO3 calibration parameter pub const LDO_VO3_C: EfuseField = EfuseField::new(1, 3, 116, 6); -/// `[]` Output VO4 calibration parameter +/// Output VO4 calibration parameter pub const LDO_VO4_K: EfuseField = EfuseField::new(1, 3, 122, 8); -/// `[]` Output VO4 calibration parameter +/// Output VO4 calibration parameter pub const LDO_VO4_VOS: EfuseField = EfuseField::new(1, 4, 130, 6); -/// `[]` Output VO4 calibration parameter +/// Output VO4 calibration parameter pub const LDO_VO4_C: EfuseField = EfuseField::new(1, 4, 136, 6); -/// `[]` Active HP DBIAS of fixed voltage +/// Active HP DBIAS of fixed voltage pub const ACTIVE_HP_DBIAS: EfuseField = EfuseField::new(1, 4, 144, 4); -/// `[]` Active LP DBIAS of fixed voltage +/// Active LP DBIAS of fixed voltage pub const ACTIVE_LP_DBIAS: EfuseField = EfuseField::new(1, 4, 148, 4); -/// `[]` DSLP BDG of fixed voltage +/// DSLP BDG of fixed voltage pub const DSLP_DBG: EfuseField = EfuseField::new(1, 4, 156, 4); -/// `[]` DSLP LP DBIAS of fixed voltage +/// DSLP LP DBIAS of fixed voltage pub const DSLP_LP_DBIAS: EfuseField = EfuseField::new(1, 5, 160, 5); -/// `[]` DBIAS gap between LP and DCDC +/// DBIAS gap between LP and DCDC pub const LP_DCDC_DBIAS_VOL_GAP: EfuseField = EfuseField::new(1, 5, 165, 5); -/// `[]` PVT_DCM_VSET when the CPU is at 400M +/// PVT_DCM_VSET when the CPU is at 400M pub const PVT_400M_BIAS: EfuseField = EfuseField::new(1, 5, 171, 5); -/// `[]` PVT_DCM_VSET corresponding to about 0.9V fixed voltage when the CPU is at 40M +/// PVT_DCM_VSET corresponding to about 0.9V fixed voltage when the CPU is at 40M pub const PVT_40M_BIAS: EfuseField = EfuseField::new(1, 5, 176, 5); -/// `[]` PVT_DCM_VSET corresponding to about 1.0V fixed voltage when the CPU is at 100M +/// PVT_DCM_VSET corresponding to about 1.0V fixed voltage when the CPU is at 100M pub const PVT_100M_BIAS: EfuseField = EfuseField::new(1, 5, 181, 5); -/// `[]` Optional unique 128-bit ID +/// Optional unique 128-bit ID pub const OPTIONAL_UNIQUE_ID: EfuseField = EfuseField::new(2, 0, 0, 128); -/// `[]` Average initcode of ADC1 atten0 +/// Average initcode of ADC1 atten0 pub const ADC1_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(2, 4, 128, 10); -/// `[]` Average initcode of ADC1 atten1 +/// Average initcode of ADC1 atten1 pub const ADC1_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(2, 4, 138, 10); -/// `[]` Average initcode of ADC1 atten2 +/// Average initcode of ADC1 atten2 pub const ADC1_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(2, 4, 148, 10); -/// `[]` Average initcode of ADC1 atten3 +/// Average initcode of ADC1 atten3 pub const ADC1_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(2, 4, 158, 10); -/// `[]` Average initcode of ADC2 atten0 +/// Average initcode of ADC2 atten0 pub const ADC2_AVE_INITCODE_ATTEN0: EfuseField = EfuseField::new(2, 5, 168, 10); -/// `[]` Average initcode of ADC2 atten1 +/// Average initcode of ADC2 atten1 pub const ADC2_AVE_INITCODE_ATTEN1: EfuseField = EfuseField::new(2, 5, 178, 10); -/// `[]` Average initcode of ADC2 atten2 +/// Average initcode of ADC2 atten2 pub const ADC2_AVE_INITCODE_ATTEN2: EfuseField = EfuseField::new(2, 5, 188, 10); -/// `[]` Average initcode of ADC2 atten3 +/// Average initcode of ADC2 atten3 pub const ADC2_AVE_INITCODE_ATTEN3: EfuseField = EfuseField::new(2, 6, 198, 10); -/// `[]` HI_DOUT of ADC1 atten0 +/// HI_DOUT of ADC1 atten0 pub const ADC1_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(2, 6, 208, 10); -/// `[]` HI_DOUT of ADC1 atten1 +/// HI_DOUT of ADC1 atten1 pub const ADC1_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(2, 6, 218, 10); -/// `[]` HI_DOUT of ADC1 atten2 +/// HI_DOUT of ADC1 atten2 pub const ADC1_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(2, 7, 228, 10); -/// `[]` HI_DOUT of ADC1 atten3 +/// HI_DOUT of ADC1 atten3 pub const ADC1_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(2, 7, 238, 10); /// `[BLOCK_USR_DATA]` User data pub const USER_DATA: EfuseField = EfuseField::new(3, 0, 0, 256); @@ -599,45 +599,45 @@ pub const KEY3: EfuseField = EfuseField::new(7, 0, 0, 256); pub const KEY4: EfuseField = EfuseField::new(8, 0, 0, 256); /// `[BLOCK_KEY5]` Key5 or user data pub const KEY5: EfuseField = EfuseField::new(9, 0, 0, 256); -/// `[]` HI_DOUT of ADC2 atten0 +/// HI_DOUT of ADC2 atten0 pub const ADC2_HI_DOUT_ATTEN0: EfuseField = EfuseField::new(10, 0, 0, 10); -/// `[]` HI_DOUT of ADC2 atten1 +/// HI_DOUT of ADC2 atten1 pub const ADC2_HI_DOUT_ATTEN1: EfuseField = EfuseField::new(10, 0, 10, 10); -/// `[]` HI_DOUT of ADC2 atten2 +/// HI_DOUT of ADC2 atten2 pub const ADC2_HI_DOUT_ATTEN2: EfuseField = EfuseField::new(10, 0, 20, 10); -/// `[]` HI_DOUT of ADC2 atten3 +/// HI_DOUT of ADC2 atten3 pub const ADC2_HI_DOUT_ATTEN3: EfuseField = EfuseField::new(10, 0, 30, 10); -/// `[]` Gap between ADC1_ch0 and average initcode +/// Gap between ADC1_ch0 and average initcode pub const ADC1_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 40, 4); -/// `[]` Gap between ADC1_ch1 and average initcode +/// Gap between ADC1_ch1 and average initcode pub const ADC1_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 44, 4); -/// `[]` Gap between ADC1_ch2 and average initcode +/// Gap between ADC1_ch2 and average initcode pub const ADC1_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 48, 4); -/// `[]` Gap between ADC1_ch3 and average initcode +/// Gap between ADC1_ch3 and average initcode pub const ADC1_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 52, 4); -/// `[]` Gap between ADC1_ch4 and average initcode +/// Gap between ADC1_ch4 and average initcode pub const ADC1_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 56, 4); -/// `[]` Gap between ADC1_ch5 and average initcode +/// Gap between ADC1_ch5 and average initcode pub const ADC1_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 1, 60, 4); -/// `[]` Gap between ADC1_ch6 and average initcode +/// Gap between ADC1_ch6 and average initcode pub const ADC1_CH6_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 64, 4); -/// `[]` Gap between ADC1_ch7 and average initcode +/// Gap between ADC1_ch7 and average initcode pub const ADC1_CH7_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 68, 4); -/// `[]` Gap between ADC2_ch0 and average initcode +/// Gap between ADC2_ch0 and average initcode pub const ADC2_CH0_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 72, 4); -/// `[]` Gap between ADC2_ch1 and average initcode +/// Gap between ADC2_ch1 and average initcode pub const ADC2_CH1_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 76, 4); -/// `[]` Gap between ADC2_ch2 and average initcode +/// Gap between ADC2_ch2 and average initcode pub const ADC2_CH2_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 80, 4); -/// `[]` Gap between ADC2_ch3 and average initcode +/// Gap between ADC2_ch3 and average initcode pub const ADC2_CH3_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 84, 4); -/// `[]` Gap between ADC2_ch4 and average initcode +/// Gap between ADC2_ch4 and average initcode pub const ADC2_CH4_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 88, 4); -/// `[]` Gap between ADC2_ch5 and average initcode +/// Gap between ADC2_ch5 and average initcode pub const ADC2_CH5_ATTEN0_INITCODE_DIFF: EfuseField = EfuseField::new(10, 2, 92, 4); -/// `[]` Temperature calibration data +/// Temperature calibration data pub const TEMPERATURE_SENSOR: EfuseField = EfuseField::new(10, 3, 96, 10); -/// `[]` Enable usb device exchange pins of D+ and D- +/// Enable usb device exchange pins of D+ and D- pub const USB_DEVICE_EXCHG_PINS: EfuseField = EfuseField::new(10, 7, 228, 1); -/// `[]` Enable usb otg11 exchange pins of D+ and D- +/// Enable usb otg11 exchange pins of D+ and D- pub const USB_OTG11_EXCHG_PINS: EfuseField = EfuseField::new(10, 7, 229, 1); diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index eb893969a33..b533c1e2b41 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -3363,10 +3363,10 @@ fn write_fifo(register_block: &RegisterBlock, data: u8) { } else if #[cfg(esp32p4)] { // P4: data register is read-only (RX FIFO only). TX uses txfifo_start_addr. // PAC txfifo_start_addr is also read-only in SVD, use direct MMIO. + // TODO: file an esp-pacs issue/PR so the P4 SVD marks the TX FIFO + // port writable like other chips' I2C PAC. Once that lands, this + // branch can collapse into the general `else` arm below. let base = register_block as *const _ as usize; - // SAFETY: `register_block` is a borrow of a live I2C PAC register block. - // offset 0x100 is the TX FIFO write port inside the same block, so the - // computed pointer is valid MMIO for the peripheral we already hold. unsafe { ((base + 0x100) as *mut u32).write_volatile(data as u32); } diff --git a/esp-hal/src/interrupt/mod.rs b/esp-hal/src/interrupt/mod.rs index 0d7ba96fca3..d999cd860cc 100644 --- a/esp-hal/src/interrupt/mod.rs +++ b/esp-hal/src/interrupt/mod.rs @@ -211,9 +211,6 @@ impl InterruptStatus { #[cfg(esp32p4)] { let base = crate::soc::registers::INTERRUPT_MAP_BASE + 0x200; - // SAFETY: fixed MMIO address of a read-only interrupt-status - // register; `idx` is bounded by STATUS_WORDS (4) which stays - // inside the 0x200..0x210 status-register window. unsafe { ((base as *const u32).add(idx)).read_volatile() } } #[cfg(not(esp32p4))] @@ -233,7 +230,6 @@ impl InterruptStatus { #[cfg(esp32p4)] { let base = crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU + 0x200; - // SAFETY: same as Core0 path above, against the Core1 block. unsafe { ((base as *const u32).add(idx)).read_volatile() } } #[cfg(not(esp32p4))] @@ -395,9 +391,6 @@ pub(super) fn map_raw(core: Cpu, interrupt: Interrupt, cpu_interrupt: u32) { #[cfg(multi_core)] Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU, }; - // SAFETY: `base` points at the per-core INT_MAP register array; `interrupt` - // is a peripheral-interrupt index which is bounded by the PAC's enum and - // always maps to a valid register slot inside the 120-entry array. unsafe { let reg = (base as *mut u32).add(interrupt as usize); reg.write_volatile(cpu_interrupt); @@ -433,7 +426,6 @@ pub(crate) fn mapped_to_raw(cpu: Cpu, interrupt: u32) -> Option { #[cfg(multi_core)] Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU, }; - // SAFETY: matches map_raw -- same bounded INT_MAP array, read-only volatile. unsafe { let reg = (base as *const u32).add(interrupt as usize); reg.read_volatile() & 0x3F // 6-bit field diff --git a/esp-hal/src/interrupt/riscv.rs b/esp-hal/src/interrupt/riscv.rs index 49d24fb99a2..ac64f343d0c 100644 --- a/esp-hal/src/interrupt/riscv.rs +++ b/esp-hal/src/interrupt/riscv.rs @@ -428,8 +428,6 @@ fn cpu_wait_mode_on() -> bool { // TODO: add HP_SYS_CLKRST.CPU_WAITI_CTRL0 (offset 0xF4) to the // esp32p4 PAC and replace this raw MMIO with the PAC accessor. const HP_SYS_CLKRST_CPU_WAITI_CTRL0: *const u32 = 0x500E_60F4 as *const u32; - // SAFETY: fixed MMIO address of a read-only status register. The - // volatile read has no side effects. let reg = unsafe { core::ptr::read_volatile(HP_SYS_CLKRST_CPU_WAITI_CTRL0) }; (reg & (1 << Cpu::current() as u32)) == 0 } else { diff --git a/esp-hal/src/interrupt/riscv/clic.rs b/esp-hal/src/interrupt/riscv/clic.rs index de1ae701bac..4b3f9be6a50 100644 --- a/esp-hal/src/interrupt/riscv/clic.rs +++ b/esp-hal/src/interrupt/riscv/clic.rs @@ -1,3 +1,16 @@ +// PAC drift workaround: every `cfg_if!` block in this file gates the +// same silicon-level register write between two PAC naming conventions. +// The pinned `esp32p4` PAC emits CLIC fields with `int_attr_*` prefix +// and consolidates per-interrupt sub-fields under a single `int_ctrl` +// register, while the other CLIC chips (ESP32-C5/C6/C61/H2) split them +// into `int_attr`/`int_ie`/`int_ip`/`int_ctl` per index. The hardware +// is the same; only the SVD-derived names differ. +// +// TODO: file an esp-pacs issue / PR to normalise the CLIC SVD across +// RISC-V chips so the P4 names match the C5/C6/C61/H2 convention. +// Once that lands and we bump the esp32p4 PAC pin, every cfg_if! here +// can be removed in one pass. + use super::{InterruptKind, Priority, RunLevel}; use crate::{interrupt::ElevatedRunLevel, soc::pac::CLIC}; @@ -5,8 +18,7 @@ use crate::{interrupt::ElevatedRunLevel, soc::pac::CLIC}; pub(super) fn init() { let clic = unsafe { CLIC::steal() }; - // Set 3 level bits = 8 priority levels - // P4 PAC: int_config_nlbits() (not mnlbits()) + // 3 level bits = 8 priority levels. cfg_if::cfg_if! { if #[cfg(esp32p4)] { clic.int_config() @@ -17,8 +29,7 @@ pub(super) fn init() { } } - // Enable hardware vectoring - // ESP32-P4 uses consolidated int_ctrl registers; C5/C61 use separate int_attr. + // Enable hardware vectoring on every interrupt line. cfg_if::cfg_if! { if #[cfg(esp32p4)] { for int in clic.int_ctrl_iter() { diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index b7272c29caa..156792c16ff 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -197,16 +197,8 @@ fn main() -> ! { #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![allow(asm_sub_register, async_fn_in_trait, stable_features)] #![cfg_attr(xtensa, feature(asm_experimental_arch))] -// `define_clock_tree_types!()` reads doc strings from the chip's -// `esp-metadata/devices/.toml` `[device.clock_tree]` section. -// Other chips (C2/C3/C5/C6/C61/H2/S2/S3, ESP32) populate those strings; -// our esp32p4.toml `[device.clock_tree]` is still partial, so the macro -// emits undocumented public items for P4 with `unstable`. Downgrade -// missing_docs to a warning for P4 only. -// -// TODO: fill the doc strings in `esp-metadata/devices/esp32p4.toml` -// `[device.clock_tree]` so we can promote this back to `deny`. See -// other chips' TOMLs for the field convention. +// TODO(esp32p4): fill `[device.clock_tree]` doc strings in esp32p4.toml, +// then promote back to `deny`. Until then, downgrade to warn for P4 only. #![cfg_attr(not(esp32p4), deny(missing_docs))] #![cfg_attr(esp32p4, warn(missing_docs))] #![deny(rust_2018_idioms, rustdoc::all)] @@ -732,9 +724,13 @@ pub fn init(config: Config) -> Peripherals { #[cfg(soc_cpu_has_branch_predictor)] { - const MHCR_RS: u32 = 1 << 4; - const MHCR_BFE: u32 = 1 << 5; - const MHCR_BTB: u32 = 1 << 12; + // Enable branch predictor + // Note that the branch predictor will start cache requests and needs to be disabled when + // the cache is disabled. + // MHCR: CSR 0x7c1 + const MHCR_RS: u32 = 1 << 4; // R/W, address return stack set bit + const MHCR_BFE: u32 = 1 << 5; // R/W, allow predictive jump set bit + const MHCR_BTB: u32 = 1 << 12; // R/W, branch target prediction enable bit unsafe { core::arch::asm!("csrrs x0, 0x7c1, {0}", in(reg) MHCR_RS | MHCR_BFE | MHCR_BTB); } @@ -750,45 +746,35 @@ pub fn init(config: Config) -> Peripherals { crate::clock::init(config.clock_config()); + // RTC domain must be enabled before we try to disable let mut rtc = crate::rtc_cntl::Rtc::new(peripherals.LPWR.reborrow()); #[cfg(sleep_driver_supported)] - { - crate::rtc_cntl::sleep::RtcSleepConfig::base_settings(&rtc); - } + crate::rtc_cntl::sleep::RtcSleepConfig::base_settings(&rtc); + // Disable watchdog timers #[cfg(swd)] - { - rtc.swd.disable(); - } + rtc.swd.disable(); rtc.rwdt.disable(); #[cfg(timergroup_timg0)] - { - crate::timer::timg::Wdt::>::new().disable(); - } + crate::timer::timg::Wdt::>::new().disable(); #[cfg(timergroup_timg1)] - { - crate::timer::timg::Wdt::>::new().disable(); - } + crate::timer::timg::Wdt::>::new().disable(); crate::time::implem::time_init(); #[cfg(gpio_driver_supported)] - { - crate::gpio::interrupt::bind_default_interrupt_handler(); - } + crate::gpio::interrupt::bind_default_interrupt_handler(); unsafe { esp_rom_sys::init_syscall_table(); } #[cfg(all(riscv, write_vec_table_monitoring))] - { - crate::soc::setup_trap_section_protection(); - } + crate::soc::setup_trap_section_protection(); peripherals } diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 179acd104bb..bc9cb3e5ee1 100644 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -11,553 +11,8 @@ cfg_if::cfg_if! { } // Implements the Peripheral enum based on esp-metadata/device.soc/peripheral_clocks -// ESP32-P4: manual Peripheral enum with HP_SYS_CLKRST clock gate registers. -// The generated macro produces an empty #[repr(u8)] enum (no clock nodes in metadata), -// so this manual definition covers all 43 peripherals with their enable/reset registers. -#[cfg(not(esp32p4))] implement_peripheral_clocks!(); -/// ESP32-P4 peripheral clock gates and resets. -/// -/// All controlled via HP_SYS_CLKRST registers: -/// SOC_CLK_CTRL0 (0x14): Flash/PSRAM/GDMA system clocks -/// SOC_CLK_CTRL1 (0x18): Peripheral system clocks -/// SOC_CLK_CTRL2 (0x1c): APB clocks -/// HP_RST_EN0 (0xc0): Core/cache/DMA resets -/// HP_RST_EN1 (0xc4): Timer/UART/I2C/misc resets -/// HP_RST_EN2 (0xc8): SPI/I2S/crypto/misc resets -/// PERI_CLK_CTRLxx: Per-peripheral clock dividers and enables -/// -/// Ref: TRM v0.5 Ch 12 (Reset and Clock), Ch 22 (System Registers) -#[cfg(esp32p4)] -mod _p4_peripheral_clocks { - use crate::peripherals::HP_SYS_CLKRST; - - #[doc(hidden)] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[repr(u8)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - #[allow(non_camel_case_types)] - pub enum Peripheral { - // -- UARTs (5x) -- SOC_CLK_CTRL1 sys + SOC_CLK_CTRL2 apb + HP_RST_EN1 - Uart0 = 0, - Uart1 = 1, - Uart2 = 2, - Uart3 = 3, - Uart4 = 4, - // -- SPI (2x) -- SOC_CLK_CTRL1 sys + SOC_CLK_CTRL2 apb + HP_RST_EN2 - Spi2 = 5, - Spi3 = 6, - // -- I2C (2x) -- SOC_CLK_CTRL2 apb + HP_RST_EN1 - I2c0 = 7, - I2c1 = 8, - // -- I2S (3x) -- SOC_CLK_CTRL2 apb + HP_RST_EN2 - I2s0 = 9, - I2s1 = 10, - I2s2 = 11, - // -- Timers -- SOC_CLK_CTRL2 apb + HP_RST_EN1 - Systimer = 12, - Timg0 = 13, - Timg1 = 14, - // -- GPIO/IOMUX -- PERI_CLK_CTRL26 + HP_RST_EN1 - Iomux = 15, - // -- PWM/Counter -- SOC_CLK_CTRL2 apb + HP_RST_EN1 - Ledc = 16, - Pcnt = 17, - Mcpwm0 = 18, - Mcpwm1 = 19, - Rmt = 20, - // -- CAN (TWAI) -- SOC_CLK_CTRL2 apb + HP_RST_EN1 - Twai0 = 21, - Twai1 = 22, - Twai2 = 23, - // -- USB -- SOC_CLK_CTRL1 sys - UsbOtg11 = 24, // Full-Speed - UsbOtg20 = 25, // High-Speed - UsbDevice = 26, // Serial/JTAG - // -- Connectivity -- SOC_CLK_CTRL1 sys - Emac = 27, - Sdmmc = 28, - Uhci = 29, - // -- Crypto -- SOC_CLK_CTRL1 crypto_sys + HP_RST_EN2 - Aes = 30, - Sha = 31, - Rsa = 32, - Ecc = 33, - Ecdsa = 34, - Hmac = 35, - Ds = 36, - // -- DMA -- SOC_CLK_CTRL1 sys + HP_RST_EN0/1 - // P4 has several DMA controllers (IDF public naming: see async_memcpy docs): - Dma = 37, // GDMA-AHB - Gdma = 38, // DMA block at 0x50081000 (SOC_DW_GDMA_SUPPORTED), unused - AhbPdma = 39, // alias for Dma (legacy) - AxiPdma = 40, - // -- ADC -- SOC_CLK_CTRL2 apb + HP_RST_EN2 - Adc = 41, - // -- Parallel IO -- SOC_CLK_CTRL1 sys + SOC_CLK_CTRL2 apb + HP_RST_EN2 - Parlio = 42, - // -- Camera/Display -- SOC_CLK_CTRL1 sys + HP_RST_EN2 - LcdCam = 43, - } - - impl Peripheral { - // NOTE (ESP32-P4): UsbDevice (USB-JTAG-Serial) kept enabled when the - // esp-println `jtag-serial` backend or the esp-hal `usb_serial_jtag` - // console driver is the boot log channel. Disabling its clock during - // init silences all subsequent println output and looks like a hang. - // TODO: gate this on a console feature; for now we keep it always on - // because the EV board and probe firmware both use USB-JTAG-Serial. - pub const KEEP_ENABLED: &[Peripheral] = &[ - Peripheral::Systimer, - Peripheral::Iomux, - Peripheral::UsbDevice, - // TODO: This should be removed before merged. - // UART0: bootloader uses GPIO37/38 for boot log while testing - Peripheral::Uart0, - ]; - pub const COUNT: usize = Self::ALL.len(); - pub const ALL: &[Self] = &[ - Self::Uart0, - Self::Uart1, - Self::Uart2, - Self::Uart3, - Self::Uart4, - Self::Spi2, - Self::Spi3, - Self::I2c0, - Self::I2c1, - Self::I2s0, - Self::I2s1, - Self::I2s2, - Self::Systimer, - Self::Timg0, - Self::Timg1, - Self::Iomux, - Self::Ledc, - Self::Pcnt, - Self::Mcpwm0, - Self::Mcpwm1, - Self::Rmt, - Self::Twai0, - Self::Twai1, - Self::Twai2, - Self::UsbOtg11, - Self::UsbOtg20, - Self::UsbDevice, - Self::Emac, - Self::Sdmmc, - Self::Uhci, - Self::Aes, - Self::Sha, - Self::Rsa, - Self::Ecc, - Self::Ecdsa, - Self::Hmac, - Self::Ds, - Self::Dma, - Self::Gdma, - Self::AhbPdma, - Self::AxiPdma, - Self::Adc, - Self::Parlio, - Self::LcdCam, - ]; - } - - /// Enable or disable peripheral clock. - /// Ref: TRM v0.5 Ch 12 - pub(crate) unsafe fn enable_internal_racey(peripheral: Peripheral, enable: bool) { - let c = HP_SYS_CLKRST::regs(); - match peripheral { - // -- UARTs: sys_clk + apb_clk -- - Peripheral::Uart0 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.uart0_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.uart0_apb_clk_en().bit(enable)); - } - Peripheral::Uart1 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.uart1_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.uart1_apb_clk_en().bit(enable)); - } - Peripheral::Uart2 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.uart2_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.uart2_apb_clk_en().bit(enable)); - } - Peripheral::Uart3 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.uart3_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.uart3_apb_clk_en().bit(enable)); - } - Peripheral::Uart4 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.uart4_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.uart4_apb_clk_en().bit(enable)); - } - // -- SPI: sys_clk + apb_clk -- - Peripheral::Spi2 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.gpspi2_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.gpspi2_apb_clk_en().bit(enable)); - } - Peripheral::Spi3 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.gpspi3_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.gpspi3_apb_clk_en().bit(enable)); - } - // -- I2C: apb_clk only -- - Peripheral::I2c0 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.i2c0_apb_clk_en().bit(enable)); - } - Peripheral::I2c1 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.i2c1_apb_clk_en().bit(enable)); - } - // -- I2S: apb_clk -- - Peripheral::I2s0 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.i2s0_apb_clk_en().bit(enable)); - } - Peripheral::I2s1 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.i2s1_apb_clk_en().bit(enable)); - } - Peripheral::I2s2 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.i2s2_apb_clk_en().bit(enable)); - } - // -- Timers -- - Peripheral::Systimer => { - c.soc_clk_ctrl2() - .modify(|_, w| w.systimer_apb_clk_en().bit(enable)); - c.peri_clk_ctrl21() - .modify(|_, w| w.systimer_clk_en().bit(enable)); - } - Peripheral::Timg0 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.timergrp0_apb_clk_en().bit(enable)); - } - Peripheral::Timg1 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.timergrp1_apb_clk_en().bit(enable)); - } - // -- GPIO/IOMUX -- - Peripheral::Iomux => { - c.peri_clk_ctrl26() - .modify(|_, w| w.iomux_clk_en().bit(enable)); - } - // -- PWM/Counter -- - Peripheral::Ledc => { - // TODO: LEDC uses SOC_CLK_CTRL3 in IDF, but PAC may differ. - // Only reset wiring is handled here for now. - } - Peripheral::Pcnt => { - c.soc_clk_ctrl2() - .modify(|_, w| w.pcnt_apb_clk_en().bit(enable)); - } - Peripheral::Mcpwm0 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.mcpwm0_apb_clk_en().bit(enable)); - } - Peripheral::Mcpwm1 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.mcpwm1_apb_clk_en().bit(enable)); - } - Peripheral::Rmt => { - c.soc_clk_ctrl2() - .modify(|_, w| w.rmt_sys_clk_en().bit(enable)); - } - // -- TWAI (CAN) -- - Peripheral::Twai0 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.twai0_apb_clk_en().bit(enable)); - } - Peripheral::Twai1 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.twai1_apb_clk_en().bit(enable)); - } - Peripheral::Twai2 => { - c.soc_clk_ctrl2() - .modify(|_, w| w.twai2_apb_clk_en().bit(enable)); - } - // -- USB -- - Peripheral::UsbOtg11 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.usb_otg11_sys_clk_en().bit(enable)); - } - Peripheral::UsbOtg20 => { - c.soc_clk_ctrl1() - .modify(|_, w| w.usb_otg20_sys_clk_en().bit(enable)); - } - Peripheral::UsbDevice => { - c.soc_clk_ctrl2() - .modify(|_, w| w.usb_device_apb_clk_en().bit(enable)); - } - // -- Connectivity -- - Peripheral::Emac => { - c.soc_clk_ctrl1() - .modify(|_, w| w.emac_sys_clk_en().bit(enable)); - } - Peripheral::Sdmmc => { - c.soc_clk_ctrl1() - .modify(|_, w| w.sdmmc_sys_clk_en().bit(enable)); - } - Peripheral::Uhci => { - c.soc_clk_ctrl1() - .modify(|_, w| w.uhci_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.uhci_apb_clk_en().bit(enable)); - } - // -- Crypto (shared sys clock) -- - Peripheral::Aes - | Peripheral::Sha - | Peripheral::Rsa - | Peripheral::Ecc - | Peripheral::Ecdsa - | Peripheral::Hmac - | Peripheral::Ds => { - c.soc_clk_ctrl1() - .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); - } - // -- DMA -- - // GDMA-AHB (GDMA v2 compatible, used by esp-hal) - Peripheral::Dma => { - c.soc_clk_ctrl1() - .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); - } - // the DMA block at 0x50081000 (SOC_DW_GDMA_SUPPORTED in Kconfig), - // may not used by esp-hal's DMA driver. - // TODO: Investigate more on 0x50081000 DMA block. - Peripheral::Gdma => { - c.soc_clk_ctrl1() - .modify(|_, w| w.gdma_sys_clk_en().bit(enable)); - } - Peripheral::AhbPdma => { - c.soc_clk_ctrl1() - .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); - } - Peripheral::AxiPdma => { - c.soc_clk_ctrl1() - .modify(|_, w| w.axi_pdma_sys_clk_en().bit(enable)); - } - // -- ADC -- - Peripheral::Adc => { - c.soc_clk_ctrl2() - .modify(|_, w| w.adc_apb_clk_en().bit(enable)); - } - // -- Parallel IO -- - Peripheral::Parlio => { - c.soc_clk_ctrl1() - .modify(|_, w| w.parlio_sys_clk_en().bit(enable)); - c.soc_clk_ctrl2() - .modify(|_, w| w.parlio_apb_clk_en().bit(enable)); - } - // -- LCD/Camera -- - Peripheral::LcdCam => { - // TODO: LCD_CAM uses SOC_CLK_CTRL3 which may not be in PAC. - } - } - } - - /// Assert or de-assert peripheral reset. - /// Ref: TRM v0.5 Ch 12 - #[allow(clippy::single_match)] - pub(crate) unsafe fn assert_peri_reset_racey(peripheral: Peripheral, reset: bool) { - let c = HP_SYS_CLKRST::regs(); - match peripheral { - // -- UARTs: HP_RST_EN1 (core + apb reset) -- - Peripheral::Uart0 => { - c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart0_core() - .bit(reset) - .rst_en_uart0_apb() - .bit(reset) - }); - } - Peripheral::Uart1 => { - c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart1_core() - .bit(reset) - .rst_en_uart1_apb() - .bit(reset) - }); - } - Peripheral::Uart2 => { - c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart2_core() - .bit(reset) - .rst_en_uart2_apb() - .bit(reset) - }); - } - Peripheral::Uart3 => { - c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart3_core() - .bit(reset) - .rst_en_uart3_apb() - .bit(reset) - }); - } - Peripheral::Uart4 => { - c.hp_rst_en1().modify(|_, w| { - w.rst_en_uart4_core() - .bit(reset) - .rst_en_uart4_apb() - .bit(reset) - }); - } - // -- SPI: HP_RST_EN2 -- - Peripheral::Spi2 => { - c.hp_rst_en2().modify(|_, w| w.rst_en_spi2().bit(reset)); - } - Peripheral::Spi3 => { - c.hp_rst_en2().modify(|_, w| w.rst_en_spi3().bit(reset)); - } - // -- I2C: HP_RST_EN1 -- - Peripheral::I2c0 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_i2c0().bit(reset)); - } - Peripheral::I2c1 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_i2c1().bit(reset)); - } - // -- I2S: HP_RST_EN2 -- - Peripheral::I2s0 => { - c.hp_rst_en2().modify(|_, w| w.rst_en_i2s0_apb().bit(reset)); - } - Peripheral::I2s1 => { - c.hp_rst_en2().modify(|_, w| w.rst_en_i2s1_apb().bit(reset)); - } - Peripheral::I2s2 => { - c.hp_rst_en2().modify(|_, w| w.rst_en_i2s2_apb().bit(reset)); - } - // -- Timers: HP_RST_EN1 -- - Peripheral::Systimer => { - c.hp_rst_en1().modify(|_, w| w.rst_en_stimer().bit(reset)); - } - Peripheral::Timg0 => { - c.hp_rst_en1() - .modify(|_, w| w.rst_en_timergrp0().bit(reset)); - } - Peripheral::Timg1 => { - c.hp_rst_en1() - .modify(|_, w| w.rst_en_timergrp1().bit(reset)); - } - // -- IOMUX: HP_RST_EN1 -- - Peripheral::Iomux => { - c.hp_rst_en1().modify(|_, w| w.rst_en_iomux().bit(reset)); - } - // -- PWM/Counter: HP_RST_EN1 -- - Peripheral::Ledc => { - c.hp_rst_en1().modify(|_, w| w.rst_en_ledc().bit(reset)); - } - Peripheral::Pcnt => { - c.hp_rst_en1().modify(|_, w| w.rst_en_pcnt().bit(reset)); - } - Peripheral::Mcpwm0 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_pwm0().bit(reset)); - } - Peripheral::Mcpwm1 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_pwm1().bit(reset)); - } - Peripheral::Rmt => { - c.hp_rst_en1().modify(|_, w| w.rst_en_rmt().bit(reset)); - } - // -- TWAI: HP_RST_EN1 (named can0/1/2) -- - Peripheral::Twai0 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_can0().bit(reset)); - } - Peripheral::Twai1 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_can1().bit(reset)); - } - Peripheral::Twai2 => { - c.hp_rst_en1().modify(|_, w| w.rst_en_can2().bit(reset)); - } - // -- USB: reset via LP domain registers, not HP_RST_EN -- - Peripheral::UsbOtg11 | Peripheral::UsbOtg20 | Peripheral::UsbDevice => { - return; - } - // -- Connectivity -- - Peripheral::Emac => { - return; - } // EMAC reset via dedicated register, not HP_RST_EN - Peripheral::Sdmmc => { - return; - } // SDMMC reset not in HP_RST_EN - Peripheral::Uhci => { - c.hp_rst_en1().modify(|_, w| w.rst_en_uhci().bit(reset)); - } - // -- Crypto: HP_RST_EN2 -- - Peripheral::Aes => { - c.hp_rst_en2().modify(|_, w| w.rst_en_aes().bit(reset)); - } - Peripheral::Sha => { - c.hp_rst_en2().modify(|_, w| w.rst_en_sha().bit(reset)); - } - Peripheral::Rsa => { - c.hp_rst_en2().modify(|_, w| w.rst_en_rsa().bit(reset)); - } - Peripheral::Ecc => { - c.hp_rst_en2().modify(|_, w| w.rst_en_ecc().bit(reset)); - } - Peripheral::Ecdsa => { - c.hp_rst_en2().modify(|_, w| w.rst_en_ecdsa().bit(reset)); - } - Peripheral::Hmac => { - c.hp_rst_en2().modify(|_, w| w.rst_en_hmac().bit(reset)); - } - Peripheral::Ds => { - c.hp_rst_en2().modify(|_, w| w.rst_en_ds().bit(reset)); - } - // -- DMA: HP_RST_EN0/1 -- - Peripheral::Dma => { - c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); - } - Peripheral::Gdma => { - c.hp_rst_en0().modify(|_, w| w.rst_en_gdma().bit(reset)); - } - Peripheral::AhbPdma => { - c.hp_rst_en1().modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); - } - Peripheral::AxiPdma => { - c.hp_rst_en1().modify(|_, w| w.rst_en_axi_pdma().bit(reset)); - } - // -- ADC: HP_RST_EN2 -- - Peripheral::Adc => { - c.hp_rst_en2().modify(|_, w| w.rst_en_adc().bit(reset)); - } - // -- Parallel IO: HP_RST_EN2 -- - Peripheral::Parlio => { - c.hp_rst_en2().modify(|_, w| { - w.rst_en_parlio() - .bit(reset) - .rst_en_parlio_rx() - .bit(reset) - .rst_en_parlio_tx() - .bit(reset) - }); - } - // -- LCD/Camera: HP_RST_EN2 -- - Peripheral::LcdCam => { - c.hp_rst_en2().modify(|_, w| w.rst_en_lcdcam().bit(reset)); - } - } - } -} - -#[cfg(esp32p4)] -pub use _p4_peripheral_clocks::*; - -#[cfg(not(esp32p4))] impl Peripheral { pub const fn try_from(value: u8) -> Option { if value >= Peripheral::COUNT as u8 { @@ -568,24 +23,6 @@ impl Peripheral { } } -#[cfg(esp32p4)] -impl Peripheral { - /// Map a numeric peripheral id back to the enum variant. - /// - /// Our P4 `Peripheral` is `#[repr(u8)]` with values 0..=43 assigned - /// densely (see `_p4_peripheral_clocks`), so a simple range check - /// plus transmute is correct. Drivers like DMA call - /// `Peripheral::try_from(N).unwrap()` from a const context to - /// build a `GenericPeripheralGuard`; if this returned `None` - /// the const-eval would panic and the user app would fail to build. - pub const fn try_from(value: u8) -> Option { - if value >= Peripheral::COUNT as u8 { - return None; - } - Some(unsafe { core::mem::transmute::(value) }) - } -} - struct RefCounts { counts: [usize; Peripheral::COUNT], } diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index a2a1daab216..a8e09dc239d 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -4253,7 +4253,10 @@ impl Chip { "i2c_master_fifo_size=\"32\"", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", + "lp_i2c_master_fifo_size=\"32\"", + "lp_uart_ram_size=\"32\"", "psram_extmem_origin=\"1207959552\"", + "rng_apb_cycle_wait_num=\"16\"", "rsa_size_increment=\"32\"", "rsa_memory_size_bytes=\"384\"", "sha_dma", @@ -4397,7 +4400,10 @@ impl Chip { "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", + "cargo:rustc-cfg=lp_i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=lp_uart_ram_size=\"32\"", "cargo:rustc-cfg=psram_extmem_origin=\"1207959552\"", + "cargo:rustc-cfg=rng_apb_cycle_wait_num=\"16\"", "cargo:rustc-cfg=rsa_size_increment=\"32\"", "cargo:rustc-cfg=rsa_memory_size_bytes=\"384\"", "cargo:rustc-cfg=sha_dma", @@ -6546,7 +6552,7 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(dma_max_priority, values(\"9\",\"5\"))"); println!("cargo:rustc-check-cfg=cfg(dma_gdma_version, values(\"1\",\"2\"))"); println!("cargo:rustc-check-cfg=cfg(phy_backed_up_digital_register_count, values(\"21\"))"); - println!("cargo:rustc-check-cfg=cfg(lp_i2c_master_fifo_size, values(\"16\"))"); + println!("cargo:rustc-check-cfg=cfg(lp_i2c_master_fifo_size, values(\"16\",\"32\"))"); println!("cargo:rustc-check-cfg=cfg(lp_uart_ram_size, values(\"32\"))"); println!("cargo:rustc-check-cfg=cfg(parl_io_version, values(\"2\",\"1\"))"); println!("cargo:rustc-check-cfg=cfg(soc_cpu_csr_prv_mode, values(\"2064\",\"3088\"))"); diff --git a/esp-metadata-generated/src/_generated_esp32p4.rs b/esp-metadata-generated/src/_generated_esp32p4.rs index fc9dc0644d7..f9c9924d69c 100644 --- a/esp-metadata-generated/src/_generated_esp32p4.rs +++ b/esp-metadata-generated/src/_generated_esp32p4.rs @@ -61,6 +61,12 @@ macro_rules! property { ("aes.endianness_configurable") => { false }; + ("assist_debug.has_sp_monitor") => { + false + }; + ("assist_debug.has_region_monitor") => { + false + }; ("dma.kind") => { "gdma" }; @@ -202,6 +208,18 @@ macro_rules! property { ("interrupts.disabled_interrupt") => { 0 }; + ("lp_i2c_master.fifo_size") => { + 32 + }; + ("lp_i2c_master.fifo_size", str) => { + stringify!(32) + }; + ("lp_uart.ram_size") => { + 32 + }; + ("lp_uart.ram_size", str) => { + stringify!(32) + }; ("psram.octal_spi") => { false }; @@ -211,6 +229,15 @@ macro_rules! property { ("psram.extmem_origin", str) => { stringify!(1207959552) }; + ("rng.apb_cycle_wait_num") => { + 16 + }; + ("rng.apb_cycle_wait_num", str) => { + stringify!(16) + }; + ("rng.trng_supported") => { + false + }; ("rsa.size_increment") => { 32 }; @@ -226,6 +253,12 @@ macro_rules! property { ("sha.dma") => { true }; + ("sleep.light_sleep") => { + false + }; + ("sleep.deep_sleep") => { + false + }; ("soc.cpu_has_branch_predictor") => { false }; @@ -271,6 +304,9 @@ macro_rules! property { ("spi_master.has_clk_pre_div") => { false }; + ("spi_slave.supports_dma") => { + false + }; ("uart.ram_size") => { 128 }; @@ -289,6 +325,9 @@ macro_rules! property { ("uart.has_sclk_divider") => { false }; + ("uhci.combined_uart_selector_field") => { + false + }; } #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] @@ -2251,17 +2290,642 @@ macro_rules! implement_peripheral_clocks { #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum Peripheral {} + pub enum Peripheral { + /// ADC peripheral clock signal + Adc, + /// AES peripheral clock signal + Aes, + /// AHB_PDMA peripheral clock signal + AhbPdma, + /// AXI_PDMA peripheral clock signal + AxiPdma, + /// DMA peripheral clock signal + Dma, + /// DS peripheral clock signal + Ds, + /// ECC peripheral clock signal + Ecc, + /// ECDSA peripheral clock signal + Ecdsa, + /// EMAC peripheral clock signal + Emac, + /// GDMA peripheral clock signal + Gdma, + /// HMAC peripheral clock signal + Hmac, + /// I2C0 peripheral clock signal + I2c0, + /// I2C1 peripheral clock signal + I2c1, + /// I2S0 peripheral clock signal + I2s0, + /// I2S1 peripheral clock signal + I2s1, + /// I2S2 peripheral clock signal + I2s2, + /// IOMUX peripheral clock signal + Iomux, + /// LCD_CAM peripheral clock signal + LcdCam, + /// LEDC peripheral clock signal + Ledc, + /// MCPWM0 peripheral clock signal + Mcpwm0, + /// MCPWM1 peripheral clock signal + Mcpwm1, + /// PARL_IO peripheral clock signal + ParlIo, + /// PCNT peripheral clock signal + Pcnt, + /// RMT peripheral clock signal + Rmt, + /// RSA peripheral clock signal + Rsa, + /// SDMMC peripheral clock signal + Sdmmc, + /// SHA peripheral clock signal + Sha, + /// SPI2 peripheral clock signal + Spi2, + /// SPI3 peripheral clock signal + Spi3, + /// SYSTIMER peripheral clock signal + Systimer, + /// TIMG0 peripheral clock signal + Timg0, + /// TIMG1 peripheral clock signal + Timg1, + /// TWAI0 peripheral clock signal + Twai0, + /// TWAI1 peripheral clock signal + Twai1, + /// TWAI2 peripheral clock signal + Twai2, + /// UART0 peripheral clock signal + Uart0, + /// UART1 peripheral clock signal + Uart1, + /// UART2 peripheral clock signal + Uart2, + /// UART3 peripheral clock signal + Uart3, + /// UART4 peripheral clock signal + Uart4, + /// UHCI peripheral clock signal + Uhci, + /// USB_DEVICE peripheral clock signal + UsbDevice, + /// USB_OTG11 peripheral clock signal + UsbOtg11, + /// USB_OTG20 peripheral clock signal + UsbOtg20, + } impl Peripheral { - const KEEP_ENABLED: &[Peripheral] = &[]; + const KEEP_ENABLED: &[Peripheral] = + &[Self::Iomux, Self::Systimer, Self::Uart0, Self::UsbDevice]; const COUNT: usize = Self::ALL.len(); - const ALL: &[Self] = &[]; + const ALL: &[Self] = &[ + Self::Adc, + Self::Aes, + Self::AhbPdma, + Self::AxiPdma, + Self::Dma, + Self::Ds, + Self::Ecc, + Self::Ecdsa, + Self::Emac, + Self::Gdma, + Self::Hmac, + Self::I2c0, + Self::I2c1, + Self::I2s0, + Self::I2s1, + Self::I2s2, + Self::Iomux, + Self::LcdCam, + Self::Ledc, + Self::Mcpwm0, + Self::Mcpwm1, + Self::ParlIo, + Self::Pcnt, + Self::Rmt, + Self::Rsa, + Self::Sdmmc, + Self::Sha, + Self::Spi2, + Self::Spi3, + Self::Systimer, + Self::Timg0, + Self::Timg1, + Self::Twai0, + Self::Twai1, + Self::Twai2, + Self::Uart0, + Self::Uart1, + Self::Uart2, + Self::Uart3, + Self::Uart4, + Self::Uhci, + Self::UsbDevice, + Self::UsbOtg11, + Self::UsbOtg20, + ]; } unsafe fn enable_internal_racey(peripheral: Peripheral, enable: bool) { - match peripheral {} + match peripheral { + Peripheral::Adc => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.adc_apb_clk_en().bit(enable)); + } + Peripheral::Aes => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::AhbPdma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); + } + Peripheral::AxiPdma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.axi_pdma_sys_clk_en().bit(enable)); + } + Peripheral::Dma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.ahb_pdma_sys_clk_en().bit(enable)); + } + Peripheral::Ds => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::Ecc => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::Ecdsa => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::Emac => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.emac_sys_clk_en().bit(enable)); + } + Peripheral::Gdma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.gdma_sys_clk_en().bit(enable)); + } + Peripheral::Hmac => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::I2c0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.i2c0_apb_clk_en().bit(enable)); + } + Peripheral::I2c1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.i2c1_apb_clk_en().bit(enable)); + } + Peripheral::I2s0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.i2s0_apb_clk_en().bit(enable)); + } + Peripheral::I2s1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.i2s1_apb_clk_en().bit(enable)); + } + Peripheral::I2s2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.i2s2_apb_clk_en().bit(enable)); + } + Peripheral::Iomux => { + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl26() + .modify(|_, w| w.iomux_clk_en().bit(enable)); + } + Peripheral::LcdCam => { + let _ = enable; + } + Peripheral::Ledc => { + let _ = enable; + } + Peripheral::Mcpwm0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.mcpwm0_apb_clk_en().bit(enable)); + } + Peripheral::Mcpwm1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.mcpwm1_apb_clk_en().bit(enable)); + } + Peripheral::ParlIo => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.parlio_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.parlio_apb_clk_en().bit(enable)); + } + Peripheral::Pcnt => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.pcnt_apb_clk_en().bit(enable)); + } + Peripheral::Rmt => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.rmt_sys_clk_en().bit(enable)); + } + Peripheral::Rsa => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::Sdmmc => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.sdmmc_sys_clk_en().bit(enable)); + } + Peripheral::Sha => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.crypto_sys_clk_en().bit(enable)); + } + Peripheral::Spi2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.gpspi2_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.gpspi2_apb_clk_en().bit(enable)); + } + Peripheral::Spi3 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.gpspi3_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.gpspi3_apb_clk_en().bit(enable)); + } + Peripheral::Systimer => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.systimer_apb_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .peri_clk_ctrl21() + .modify(|_, w| w.systimer_clk_en().bit(enable)); + } + Peripheral::Timg0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.timergrp0_apb_clk_en().bit(enable)); + } + Peripheral::Timg1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.timergrp1_apb_clk_en().bit(enable)); + } + Peripheral::Twai0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.twai0_apb_clk_en().bit(enable)); + } + Peripheral::Twai1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.twai1_apb_clk_en().bit(enable)); + } + Peripheral::Twai2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.twai2_apb_clk_en().bit(enable)); + } + Peripheral::Uart0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.uart0_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.uart0_apb_clk_en().bit(enable)); + } + Peripheral::Uart1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.uart1_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.uart1_apb_clk_en().bit(enable)); + } + Peripheral::Uart2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.uart2_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.uart2_apb_clk_en().bit(enable)); + } + Peripheral::Uart3 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.uart3_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.uart3_apb_clk_en().bit(enable)); + } + Peripheral::Uart4 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.uart4_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.uart4_apb_clk_en().bit(enable)); + } + Peripheral::Uhci => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.uhci_sys_clk_en().bit(enable)); + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.uhci_apb_clk_en().bit(enable)); + } + Peripheral::UsbDevice => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl2() + .modify(|_, w| w.usb_device_apb_clk_en().bit(enable)); + } + Peripheral::UsbOtg11 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.usb_otg11_sys_clk_en().bit(enable)); + } + Peripheral::UsbOtg20 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .soc_clk_ctrl1() + .modify(|_, w| w.usb_otg20_sys_clk_en().bit(enable)); + } + } } unsafe fn assert_peri_reset_racey(peripheral: Peripheral, reset: bool) { - match peripheral {} + match peripheral { + Peripheral::Adc => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_adc().bit(reset)); + } + Peripheral::Aes => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_aes().bit(reset)); + } + Peripheral::AhbPdma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); + } + Peripheral::AxiPdma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_axi_pdma().bit(reset)); + } + Peripheral::Dma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_ahb_pdma().bit(reset)); + } + Peripheral::Ds => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_ds().bit(reset)); + } + Peripheral::Ecc => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_ecc().bit(reset)); + } + Peripheral::Ecdsa => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_ecdsa().bit(reset)); + } + Peripheral::Emac => { + let _ = reset; + } + Peripheral::Gdma => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en0() + .modify(|_, w| w.rst_en_gdma().bit(reset)); + } + Peripheral::Hmac => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_hmac().bit(reset)); + } + Peripheral::I2c0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_i2c0().bit(reset)); + } + Peripheral::I2c1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_i2c1().bit(reset)); + } + Peripheral::I2s0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_i2s0_apb().bit(reset)); + } + Peripheral::I2s1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_i2s1_apb().bit(reset)); + } + Peripheral::I2s2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_i2s2_apb().bit(reset)); + } + Peripheral::Iomux => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_iomux().bit(reset)); + } + Peripheral::LcdCam => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_lcdcam().bit(reset)); + } + Peripheral::Ledc => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_ledc().bit(reset)); + } + Peripheral::Mcpwm0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_pwm0().bit(reset)); + } + Peripheral::Mcpwm1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_pwm1().bit(reset)); + } + Peripheral::ParlIo => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| { + w.rst_en_parlio() + .bit(reset) + .rst_en_parlio_rx() + .bit(reset) + .rst_en_parlio_tx() + .bit(reset) + }); + } + Peripheral::Pcnt => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_pcnt().bit(reset)); + } + Peripheral::Rmt => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_rmt().bit(reset)); + } + Peripheral::Rsa => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_rsa().bit(reset)); + } + Peripheral::Sdmmc => { + let _ = reset; + } + Peripheral::Sha => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_sha().bit(reset)); + } + Peripheral::Spi2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_spi2().bit(reset)); + } + Peripheral::Spi3 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en2() + .modify(|_, w| w.rst_en_spi3().bit(reset)); + } + Peripheral::Systimer => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_stimer().bit(reset)); + } + Peripheral::Timg0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_timergrp0().bit(reset)); + } + Peripheral::Timg1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_timergrp1().bit(reset)); + } + Peripheral::Twai0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_can0().bit(reset)); + } + Peripheral::Twai1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_can1().bit(reset)); + } + Peripheral::Twai2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_can2().bit(reset)); + } + Peripheral::Uart0 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| { + w.rst_en_uart0_core() + .bit(reset) + .rst_en_uart0_apb() + .bit(reset) + }); + } + Peripheral::Uart1 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| { + w.rst_en_uart1_core() + .bit(reset) + .rst_en_uart1_apb() + .bit(reset) + }); + } + Peripheral::Uart2 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| { + w.rst_en_uart2_core() + .bit(reset) + .rst_en_uart2_apb() + .bit(reset) + }); + } + Peripheral::Uart3 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| { + w.rst_en_uart3_core() + .bit(reset) + .rst_en_uart3_apb() + .bit(reset) + }); + } + Peripheral::Uart4 => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| { + w.rst_en_uart4_core() + .bit(reset) + .rst_en_uart4_apb() + .bit(reset) + }); + } + Peripheral::Uhci => { + crate::peripherals::HP_SYS_CLKRST::regs() + .hp_rst_en1() + .modify(|_, w| w.rst_en_uhci().bit(reset)); + } + Peripheral::UsbDevice => { + let _ = reset; + } + Peripheral::UsbOtg11 => { + let _ = reset; + } + Peripheral::UsbOtg20 => { + let _ = reset; + } + } } }; } @@ -2385,6 +3049,30 @@ macro_rules! for_each_spi_master { SPI3_CS2] [SPI3_D, SPI3_Q, SPI3_WP, SPI3_HOLD], true))); }; } +/// This macro can be used to generate code for each peripheral instance of the SPI slave driver. +/// +/// For an explanation on the general syntax, as well as usage of individual/repeated +/// matchers, refer to [the crate-level documentation][crate#for_each-macros]. +/// +/// This macro has one option for its "Individual matcher" case: +/// +/// Syntax: `($instance:ident, $sys:ident, $sclk:ident, $mosi:ident, $miso:ident, $cs:ident)` +/// +/// Macro fragments: +/// +/// - `$instance`: the name of the SPI instance +/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum. +/// - `$sclk`, `$mosi`, `$miso`, `$cs`: signal names. +/// +/// Example data: `(SPI2, Spi2, FSPICLK, FSPID, FSPIQ, FSPICS0)` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] +macro_rules! for_each_spi_slave { + ($($pattern:tt => $code:tt;)*) => { + macro_rules! _for_each_inner_spi_slave { $(($pattern) => $code;)* ($other : tt) + => {} } _for_each_inner_spi_slave!((all)); + }; +} #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))] macro_rules! for_each_peripheral { diff --git a/esp-metadata/devices/esp32p4.toml b/esp-metadata/devices/esp32p4.toml index 7dd6b997e5f..55b026ed1e2 100644 --- a/esp-metadata/devices/esp32p4.toml +++ b/esp-metadata/devices/esp32p4.toml @@ -129,6 +129,89 @@ clocks = { system_clocks = { clock_tree = [ { name = "RC_FAST_CLK", outputs = "RC_FAST_CLK" }, ] }, ] }, +] }, peripheral_clocks = { templates = [ + # ESP32-P4 peripheral clock and reset gates -- all live in HP_SYS_CLKRST. + # Clock enables: SOC_CLK_CTRL0/1/2 + PERI_CLK_CTRL{21,26}. + # Resets: HP_RST_EN0/1/2. + # Each peripheral overrides {{default_clk_en_template}} / {{default_rst_template}} + # to select the right shared register + bit field. + { name = "clk_en_template", value = "{{default_clk_en_template}}" }, + { name = "rst_template", value = "{{default_rst_template}}" }, + { name = "default_clk_en_template", value = "let _ = enable;" }, + { name = "default_rst_template", value = "let _ = reset;" }, + # Reusable clock-enable building blocks (composed via {{default_clk_en_template}} = "{{X}}"). + { name = "sys_clk_template", value = "{{control}}::regs().soc_clk_ctrl1().modify(|_, w| w.{{sys_field}}().bit(enable));" }, + { name = "apb_clk_template", value = "{{control}}::regs().soc_clk_ctrl2().modify(|_, w| w.{{apb_field}}().bit(enable));" }, + { name = "sys_apb_clk_template", value = "{{sys_clk_template}} {{apb_clk_template}}" }, + { name = "crypto_clk_template", value = "{{control}}::regs().soc_clk_ctrl1().modify(|_, w| w.crypto_sys_clk_en().bit(enable));" }, + # Reusable reset building blocks. Reset bit name is supplied via {{rst_field}}. + { name = "rst_en0_template", value = "{{control}}::regs().hp_rst_en0().modify(|_, w| w.{{rst_field}}().bit(reset));" }, + { name = "rst_en1_template", value = "{{control}}::regs().hp_rst_en1().modify(|_, w| w.{{rst_field}}().bit(reset));" }, + { name = "rst_en2_template", value = "{{control}}::regs().hp_rst_en2().modify(|_, w| w.{{rst_field}}().bit(reset));" }, + { name = "control", value = "crate::peripherals::HP_SYS_CLKRST" }, +], peripheral_clocks = [ + # Ref: TRM v0.5 Ch 12 (Reset and Clock), Ch 22 (System Registers). + # UARTs -- sys_clk + apb_clk; reset asserts both core+apb together. + { name = "Uart0", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "uart0_sys_clk_en", apb_field = "uart0_apb_clk_en", default_rst_template = "{{control}}::regs().hp_rst_en1().modify(|_, w| w.rst_en_uart0_core().bit(reset).rst_en_uart0_apb().bit(reset));" }, keep_enabled = true }, + { name = "Uart1", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "uart1_sys_clk_en", apb_field = "uart1_apb_clk_en", default_rst_template = "{{control}}::regs().hp_rst_en1().modify(|_, w| w.rst_en_uart1_core().bit(reset).rst_en_uart1_apb().bit(reset));" } }, + { name = "Uart2", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "uart2_sys_clk_en", apb_field = "uart2_apb_clk_en", default_rst_template = "{{control}}::regs().hp_rst_en1().modify(|_, w| w.rst_en_uart2_core().bit(reset).rst_en_uart2_apb().bit(reset));" } }, + { name = "Uart3", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "uart3_sys_clk_en", apb_field = "uart3_apb_clk_en", default_rst_template = "{{control}}::regs().hp_rst_en1().modify(|_, w| w.rst_en_uart3_core().bit(reset).rst_en_uart3_apb().bit(reset));" } }, + { name = "Uart4", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "uart4_sys_clk_en", apb_field = "uart4_apb_clk_en", default_rst_template = "{{control}}::regs().hp_rst_en1().modify(|_, w| w.rst_en_uart4_core().bit(reset).rst_en_uart4_apb().bit(reset));" } }, + # SPI -- sys_clk + apb_clk; reset in HP_RST_EN2. + { name = "Spi2", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "gpspi2_sys_clk_en", apb_field = "gpspi2_apb_clk_en", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_spi2" } }, + { name = "Spi3", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "gpspi3_sys_clk_en", apb_field = "gpspi3_apb_clk_en", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_spi3" } }, + # I2C master -- apb_clk only; reset in HP_RST_EN1. + { name = "I2c0", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "i2c0_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_i2c0" } }, + { name = "I2c1", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "i2c1_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_i2c1" } }, + # I2S -- apb_clk; reset in HP_RST_EN2. + { name = "I2s0", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "i2s0_apb_clk_en", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_i2s0_apb" } }, + { name = "I2s1", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "i2s1_apb_clk_en", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_i2s1_apb" } }, + { name = "I2s2", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "i2s2_apb_clk_en", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_i2s2_apb" } }, + # Timers -- Systimer also needs PERI_CLK_CTRL21.systimer_clk_en gate. + { name = "Systimer", template_params = { default_clk_en_template = "{{control}}::regs().soc_clk_ctrl2().modify(|_, w| w.systimer_apb_clk_en().bit(enable)); {{control}}::regs().peri_clk_ctrl21().modify(|_, w| w.systimer_clk_en().bit(enable));", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_stimer" }, keep_enabled = true }, + { name = "Timg0", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "timergrp0_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_timergrp0" } }, + { name = "Timg1", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "timergrp1_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_timergrp1" } }, + # IO MUX -- gated via PERI_CLK_CTRL26; KEEP_ENABLED because GPIO depends on it. + { name = "Iomux", template_params = { default_clk_en_template = "{{control}}::regs().peri_clk_ctrl26().modify(|_, w| w.iomux_clk_en().bit(enable));", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_iomux" }, keep_enabled = true }, + # PWM/Counter/RMT -- LCD/CAM clock gate lives in SOC_CLK_CTRL3 (not modelled in current PAC), keep stub. + { name = "Ledc", template_params = { default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_ledc" } }, + { name = "Pcnt", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "pcnt_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_pcnt" } }, + { name = "Mcpwm0", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "mcpwm0_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_pwm0" } }, + { name = "Mcpwm1", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "mcpwm1_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_pwm1" } }, + # NOTE: `rmt_sys_clk_en` despite the name lives on SOC_CLK_CTRL2, not CTRL1. + { name = "Rmt", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "rmt_sys_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_rmt" } }, + # TWAI (CAN) -- reset bits named can0/can1/can2 in PAC. + { name = "Twai0", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "twai0_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_can0" } }, + { name = "Twai1", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "twai1_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_can1" } }, + { name = "Twai2", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "twai2_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_can2" } }, + # USB -- reset is via LP-domain registers, leave rst as no-op here. + { name = "UsbOtg11", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "usb_otg11_sys_clk_en" } }, + { name = "UsbOtg20", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "usb_otg20_sys_clk_en" } }, + { name = "UsbDevice", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "usb_device_apb_clk_en" }, keep_enabled = true }, + # Connectivity -- EMAC and SDMMC reset live in dedicated registers, no HP_RST_EN gate. + { name = "Emac", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "emac_sys_clk_en" } }, + { name = "Sdmmc", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "sdmmc_sys_clk_en" } }, + { name = "Uhci", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "uhci_sys_clk_en", apb_field = "uhci_apb_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_uhci" } }, + # Crypto -- shared crypto_sys_clk_en bit; each peripheral has its own reset bit. + { name = "Aes", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_aes" } }, + { name = "Sha", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_sha" } }, + { name = "Rsa", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_rsa" } }, + { name = "Ecc", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_ecc" } }, + { name = "Ecdsa", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_ecdsa" } }, + { name = "Hmac", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_hmac" } }, + { name = "Ds", template_params = { default_clk_en_template = "{{crypto_clk_template}}", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_ds" } }, + # DMA -- P4 has multiple controllers (AHB-PDMA / AXI-PDMA / GDMA-DW). `Dma` is the GDMA-AHB + # variant esp-hal's DMA driver targets. `Gdma` covers the DW block at 0x5008_1000. + { name = "Dma", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "ahb_pdma_sys_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_ahb_pdma" } }, + { name = "Gdma", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "gdma_sys_clk_en", default_rst_template = "{{rst_en0_template}}", rst_field = "rst_en_gdma" } }, + { name = "AhbPdma", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "ahb_pdma_sys_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_ahb_pdma" } }, + { name = "AxiPdma", template_params = { default_clk_en_template = "{{sys_clk_template}}", sys_field = "axi_pdma_sys_clk_en", default_rst_template = "{{rst_en1_template}}", rst_field = "rst_en_axi_pdma" } }, + # ADC. + { name = "Adc", template_params = { default_clk_en_template = "{{apb_clk_template}}", apb_field = "adc_apb_clk_en", default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_adc" } }, + # Parallel IO -- reset asserts the parlio block plus its rx/tx subreset bits in one write. + { name = "ParlIo", template_params = { default_clk_en_template = "{{sys_apb_clk_template}}", sys_field = "parlio_sys_clk_en", apb_field = "parlio_apb_clk_en", default_rst_template = "{{control}}::regs().hp_rst_en2().modify(|_, w| w.rst_en_parlio().bit(reset).rst_en_parlio_rx().bit(reset).rst_en_parlio_tx().bit(reset));" } }, + # LCD/CAM -- clock gate lives in SOC_CLK_CTRL3 (not modelled), only reset is wired up. + { name = "LcdCam", template_params = { default_rst_template = "{{rst_en2_template}}", rst_field = "rst_en_lcdcam" } }, ] } } # HP L2MEM: 0x4FF0_0000 - 0x4FFC_0000 (768 KB) @@ -277,13 +360,75 @@ support_status = "not_supported" # TODO: Check later with PAC and TRM both [device.adc] support_status = "not_supported" -# TODO: Test or complete me -# [device.temperature_sensor] -# support_status = "partial" - -# TODO: Test or complete me -# [device.touch] -# support_status = "partial" +# Below: peripherals P4 silicon physically has, but no esp-hal driver +# is wired up in this PR. All marked `not_supported` so the README's +# chip-support table accurately shows ❌ rather than empty cells. +# When the upstream driver lands or our local code path is added, +# flip the relevant entry to `partial`. +# Refs: +# .investigation/PERIPHERAL_TESTABILITY_w_logicpro.md +# .investigation/README_TABLE_AUDIT_P4.md + +[device.assist_debug] +support_status = "not_supported" +[device.avc] +support_status = "not_supported" # P4 ANA_CMPR (CH0/CH1) +[device.camera] +support_status = "not_supported" # LCD_CAM block, camera path +# [device.dedicated_gpio] requires a `channels` table -- skip for now +# until we map the P4 CPU GPIO instance list. README will show this row +# blank for P4, accurate to the current driver state. +[device.ds] +support_status = "not_supported" # Digital Signature +[device.ecdsa] +support_status = "not_supported" +[device.ethernet] +support_status = "not_supported" # EMAC, RMII via GPIO 30/47/53 etc. +[device.etm] +support_status = "not_supported" # Event Task Matrix +[device.hmac] +support_status = "not_supported" +[device.i2c_slave] +support_status = "not_supported" +[device.i2s] +support_status = "not_supported" # 3 instances (I2S0/1/2) +[device.ledc] +support_status = "not_supported" +[device.lp_i2c_master] +support_status = "not_supported" +fifo_size = 32 # placeholder until LP I2C driver lands; from c6 reference +[device.lp_uart] +support_status = "not_supported" +ram_size = 32 # placeholder; LP UART RAM size on P4 needs verification +[device.mcpwm] +support_status = "not_supported" # 2 instances (MCPWM0/1) +[device.pcnt] +support_status = "not_supported" +[device.rgb_display] +support_status = "not_supported" # LCD path of LCD_CAM block +# [device.rmt] requires ram_start / channel_ram_size / channels config - +# left out until those are mapped from P4 TRM. README row stays blank. +[device.rng] +support_status = "not_supported" # TRNG +apb_cycle_wait_num = 16 # placeholder +[device.lp_timer] +support_status = "not_supported" # RTC Timekeeping +[device.sd_host] +support_status = "not_supported" # SDIO host +[device.sd_slave] +support_status = "not_supported" +[device.sleep] +support_status = "not_supported" # PMU eco5 sleep -- placeholder TODO in esp-hal +[device.spi_slave] +support_status = "not_supported" +[device.temp_sensor] +support_status = "not_supported" # LP_TSENS +[device.touch] +support_status = "not_supported" # LP_TOUCH 14ch +[device.uhci] +support_status = "not_supported" +[device.ulp_riscv] +support_status = "not_supported" # LP-core RISC-V (formerly "swd"/"lp_core") [device.aes] support_status = "not_supported" diff --git a/esp-println/src/lib.rs b/esp-println/src/lib.rs index 31371d5ede0..1e7d1053e94 100644 --- a/esp-println/src/lib.rs +++ b/esp-println/src/lib.rs @@ -418,11 +418,23 @@ mod uart_printer { struct Device; - // ESP32-P4: ROM uart_tx_one_char at 0x4fc00054 - // Ref: esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.ld + // ESP32-P4: resolve through the linker-provided ROM symbol + // (`esp_rom_uart_tx_one_char` -> `uart_tx_one_char2 = 0x4fc0_0058`, + // see esp-rom-sys/ld/esp32p4/rom/esp32p4.rom.api.ld) instead of + // hardcoding the address. Matches the c5/c6/c61/h2 channel-aware path. #[cfg(feature = "esp32p4")] impl Functions for Device { - const TX_ONE_CHAR: usize = 0x4fc0_0054; + // Unused -- tx_byte() below resolves through the linker. + const TX_ONE_CHAR: usize = 0; + + fn tx_byte(b: u8) { + unsafe extern "C" { + fn esp_rom_uart_tx_one_char(c: u8) -> i32; + } + unsafe { + esp_rom_uart_tx_one_char(b); + } + } fn flush() { // tx_one_char waits for TX FIFO space diff --git a/esp-rom-sys/CHANGELOG.md b/esp-rom-sys/CHANGELOG.md index eb975fc96ca..9e5349b92a4 100644 --- a/esp-rom-sys/CHANGELOG.md +++ b/esp-rom-sys/CHANGELOG.md @@ -16,9 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ECO5+ symbol addresses (sourced from ESP-IDF v6.0.1 `esp32p4.rom.eco5*.ld`). The previous file used pre-ECO5 addresses and silently misnamed several ROM symbols on v3.x silicon (e.g. - `esp_rom_crc32_le` linked to the address that actually hosts - `crc32_be`). Verified end-to-end via runtime hw-vs-sw comparison - (12/12 PASS) on v3.2 ECO7 silicon. + `esp_rom_crc32_le` and `crc32_be`). ### Fixed From 61fde8158428358f15d882fc8c30b998d07b58b4 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 03:32:25 +0900 Subject: [PATCH 16/27] Annotate P4 PAC drift sites with esp-pacs TODO markers --- esp-hal/src/clock/mod.rs | 19 ++++++++++--------- esp-hal/src/rtc_cntl/mod.rs | 28 +++++++++++++++++----------- esp-hal/src/spi/master/mod.rs | 9 ++++++--- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/esp-hal/src/clock/mod.rs b/esp-hal/src/clock/mod.rs index 305e2226080..0b861387208 100644 --- a/esp-hal/src/clock/mod.rs +++ b/esp-hal/src/clock/mod.rs @@ -496,15 +496,16 @@ fn rtc_slow_cal_period() -> u64 { } } - // P4: store registers are in LP_SYS (mapped as LP_AON in esp-hal). - // LP_SYS has lp_store0..lp_store14 registers. - #[cfg(esp32p4)] - { - LP_AON::regs().lp_store1().read().bits() as u64 - } - #[cfg(not(esp32p4))] - { - LP_AON::regs().store1().read().bits() as u64 + // P4: LP_SYS (mapped as LP_AON in esp-hal) names its scratch registers + // `lp_store0..lp_store14`, while every other chip names them `store0..N`. + // TODO: file an esp-pacs issue/PR to rename the P4 fields to match. + // Once that lands this cfg branch can disappear. + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + LP_AON::regs().lp_store1().read().bits() as u64 + } else { + LP_AON::regs().store1().read().bits() as u64 + } } } diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index cfc3622eeef..2d4ea32cb81 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -415,17 +415,23 @@ impl<'d> Rtc<'d> { // ESP32-S3: TRM v1.5 chapter 8.3 // ESP32-H2: TRM v0.5 chapter 8.2.3 - // P4: store registers are in LP_SYS (mapped as LP_AON). - // RTC_DISABLE_ROM_LOG = (1<<0)|(1<<16) - // esp-idf rtc_suppress_rom_log() uses LP_STORE4 - #[cfg(esp32p4)] - LP_AON::regs() - .lp_store4() - .modify(|r, w| unsafe { w.bits(r.bits() | Self::RTC_DISABLE_ROM_LOG) }); - #[cfg(not(esp32p4))] - LP_AON::regs() - .store4() - .modify(|r, w| unsafe { w.bits(r.bits() | Self::RTC_DISABLE_ROM_LOG) }); + // P4: LP_SYS (mapped as LP_AON) names its scratch registers + // `lp_store0..lp_store14`, while every other chip names them + // `store0..N`. esp-idf's `rtc_suppress_rom_log()` writes + // RTC_DISABLE_ROM_LOG = (1<<0) | (1<<16) to STORE4. + // TODO: file an esp-pacs issue/PR to rename the P4 fields to match; + // once that lands this cfg branch can collapse to a single line. + cfg_if::cfg_if! { + if #[cfg(esp32p4)] { + LP_AON::regs() + .lp_store4() + .modify(|r, w| unsafe { w.bits(r.bits() | Self::RTC_DISABLE_ROM_LOG) }); + } else { + LP_AON::regs() + .store4() + .modify(|r, w| unsafe { w.bits(r.bits() | Self::RTC_DISABLE_ROM_LOG) }); + } + } } /// Register an interrupt handler for the RTC. diff --git a/esp-hal/src/spi/master/mod.rs b/esp-hal/src/spi/master/mod.rs index 4ff465b8611..7e68365f074 100644 --- a/esp-hal/src/spi/master/mod.rs +++ b/esp-hal/src/spi/master/mod.rs @@ -2390,11 +2390,14 @@ impl Driver { fn update(&self) { cfg_if::cfg_if! { if #[cfg(esp32p4)] { - // P4 PAC: cmd.update() is write-only (no read method). - // Write update bit and wait a short time instead of polling. + // P4 PAC: cmd().update() is write-only -- no `read()` accessor, + // so we can't poll for the bit clearing like the other chips. + // Spin for ~10 cycles to let the hardware latch instead. + // TODO: file an esp-pacs issue/PR so the P4 SVD marks the SPI + // cmd().update field readable like other chips. Once that lands + // this branch can collapse into the general `else` arm below. let reg_block = self.regs(); reg_block.cmd().modify(|_, w| w.update().set_bit()); - // Small delay for SPI register sync for _ in 0..10 { core::hint::spin_loop(); } } else if #[cfg(not(any(esp32, esp32s2)))] { let reg_block = self.regs(); From 05fbcfcf6f7d34e830367f6f51bdef3c321a7b2c Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 03:50:44 +0900 Subject: [PATCH 17/27] formatting for new esp32p4 support files --- esp-hal/src/psram/esp32p4.rs | 34 +++++++++++++-------------- esp-hal/src/rtc_cntl/rtc/esp32p4.rs | 27 +++++++++------------ esp-hal/src/rtc_cntl/sleep/esp32p4.rs | 1 - esp-hal/src/soc/esp32p4/clocks.rs | 1 - esp-hal/src/soc/esp32p4/gpio.rs | 2 +- 5 files changed, 28 insertions(+), 37 deletions(-) diff --git a/esp-hal/src/psram/esp32p4.rs b/esp-hal/src/psram/esp32p4.rs index bbded01c310..0ff6dcee4b8 100644 --- a/esp-hal/src/psram/esp32p4.rs +++ b/esp-hal/src/psram/esp32p4.rs @@ -80,17 +80,16 @@ pub enum PsramMode { /// | `Mhz80` | 320 | 4 | 2 | 2 | 18 | Conservative SI margin | /// | `Mhz200` | 400 | 2 | 4 | 1 | 26 | IDF default | /// | `Mhz250` | 500 | 2 | 6 | 3 | 34 | Overclock, **silicon rev v3+ only** | -/// #[derive(Copy, Clone, Debug, Default, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[instability::unstable] pub enum SpiRamFreq { /// 20 MHz bus (MPLL 400 / div 20). Lowest-power option; /// rarely used outside debug. - Mhz20 = 20, + Mhz20 = 20, /// 80 MHz bus (MPLL 320 / div 4). Conservative; widest timing /// margin. - Mhz80 = 80, + Mhz80 = 80, /// 200 MHz bus (MPLL 400 / div 2). IDF default for AP HEX PSRAM. /// Validated on the EV board. #[default] @@ -139,7 +138,6 @@ pub struct PsramConfig { pub core_clock: Option, /// PSRAM bus frequency. Default: 200 MHz. pub ram_frequency: SpiRamFreq, - // TODO: ECC enable. // The MSPI0 controller has a ECC engine. // pub ecc: bool, // or any other enum. @@ -339,30 +337,30 @@ const IOMUX_MSPI_BASE: u32 = 0x500E_1200; enum PsramPad { /// DQ0. Matches IDF `IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG` (legacy SPI /// MOSI naming retained on the IOMUX register itself). - Dq0 = 0x1C, + Dq0 = 0x1C, /// DQ1. IDF `IOMUX_MSPI_PIN_PSRAM_Q_PIN0_REG` (legacy SPI MISO). - Dq1 = 0x20, + Dq1 = 0x20, /// DQ2. IDF `IOMUX_MSPI_PIN_PSRAM_WP_PIN0_REG` (legacy WP). - Dq2 = 0x24, + Dq2 = 0x24, /// DQ3. IDF `IOMUX_MSPI_PIN_PSRAM_HOLD_PIN0_REG` (legacy HOLD). /// In OPI/HEX DDR mode the controller does not treat this as a /// hold/freeze input -- it is a plain data line. - Dq3 = 0x28, - Dq4 = 0x2C, - Dq5 = 0x30, - Dq6 = 0x34, - Dq7 = 0x38, + Dq3 = 0x28, + Dq4 = 0x2C, + Dq5 = 0x30, + Dq6 = 0x34, + Dq7 = 0x38, Dqs0 = 0x3C, - Dq8 = 0x40, - Dq9 = 0x44, + Dq8 = 0x40, + Dq9 = 0x44, Dq10 = 0x48, Dq11 = 0x4C, Dq12 = 0x50, Dq13 = 0x54, Dq14 = 0x58, Dq15 = 0x5C, - Ck = 0x60, - Cs = 0x64, + Ck = 0x60, + Cs = 0x64, Dqs1 = 0x68, } @@ -713,8 +711,8 @@ fn psram_detect_size() -> usize { /// /// ESP32-P4 has TWO independent MMUs: /// - Flash MMU (id 0): registers in `SPI_MEM_C` (FLASH_SPI0) -/// - PSRAM MMU (id 1): registers in `SPI_MEM_S` (PSRAM_MSPI0) at the -/// `MMU_ITEM_INDEX_REG` / `MMU_ITEM_CONTENT_REG` offsets we use here. +/// - PSRAM MMU (id 1): registers in `SPI_MEM_S` (PSRAM_MSPI0) at the `MMU_ITEM_INDEX_REG` / +/// `MMU_ITEM_CONTENT_REG` offsets we use here. /// /// Each PSRAM MMU entry is a 32-bit word: /// - bits [9:0] : physical page number (`SOC_MMU_PSRAM_VALID_VAL_MASK = 0x3FF`) diff --git a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs index 768ece4ecc5..5f0b0c1091d 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32p4.rs @@ -10,7 +10,6 @@ //! eco4: power_pd_hpaon_cntl, power_pd_hpcpu_cntl, power_pd_hpwifi_cntl //! eco5: power_pd_cnnt_cntl, power_pd_lpperi_cntl (hpaon/hpcpu/hpwifi removed) //! Both: power_pd_top_cntl, power_pd_hpmem_cntl -//! // TODO: REMOVE me when validate well // reference florianL21's original eco4 PMU code @@ -123,8 +122,7 @@ pub(crate) fn init() { // 1. Clear all PMU power domain force flags pmu_power_domain_force_default(); - // 2. Disable TIMG0 watchdog - // TIMG WDT write protect key: 0x50D8_3AA1 + // 2. Disable TIMG0 watchdog TIMG WDT write protect key: 0x50D8_3AA1 let tg0 = TIMG0::regs(); tg0.wdtwprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); tg0.wdtconfig0().modify(|_, w| w.wdt_en().clear_bit()); @@ -136,15 +134,15 @@ pub(crate) fn init() { tg1.wdtconfig0().modify(|_, w| w.wdt_en().clear_bit()); tg1.wdtwprotect().write(|w| unsafe { w.bits(0) }); - // 4. Disable LP_WDT (Low-Power Watchdog) - // P4 PAC: config0() (not wdtconfig0()), wprotect() (not wdtwprotect()) + // 4. Disable LP_WDT (Low-Power Watchdog) P4 PAC: config0() (not wdtconfig0()), wprotect() (not + // wdtwprotect()) let lp_wdt = LP_WDT::regs(); lp_wdt.wprotect().write(|w| unsafe { w.bits(0x50D8_3AA1) }); lp_wdt.config0().modify(|_, w| unsafe { w.bits(0) }); lp_wdt.wprotect().write(|w| unsafe { w.bits(0) }); - // 5. Disable SWD (Super Watchdog) by enabling auto-feed - // LP_WDT SWD write protect key: 0x50D8_3AA1 (same key) + // 5. Disable SWD (Super Watchdog) by enabling auto-feed LP_WDT SWD write protect key: + // 0x50D8_3AA1 (same key) lp_wdt .swd_wprotect() .write(|w| unsafe { w.bits(0x50D8_3AA1) }); @@ -153,8 +151,7 @@ pub(crate) fn init() { .modify(|_, w| w.swd_auto_feed_en().set_bit()); lp_wdt.swd_wprotect().write(|w| unsafe { w.bits(0) }); - // 6. Clear DCDC switch force flags - // PMU_POWER_DCDC_SWITCH_REG (offset 0x10c) + // 6. Clear DCDC switch force flags PMU_POWER_DCDC_SWITCH_REG (offset 0x10c) let pmu = PMU::regs(); pmu.power_dcdc_switch().modify(|_, w| { w.force_dcdc_switch_pu().bit(false); @@ -188,8 +185,8 @@ pub(crate) fn init() { core::hint::spin_loop(); } - // 9. Switch CPU clock source from XTAL to CPLL - // LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel: 0=XTAL, 1=CPLL, 2=RC_FAST + // 9. Switch CPU clock source from XTAL to CPLL LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel: + // 0=XTAL, 1=CPLL, 2=RC_FAST crate::peripherals::LP_AON_CLKRST::regs() .lp_aonclkrst_hp_clk_ctrl() .modify(|_, w| unsafe { w.lp_aonclkrst_hp_root_clk_src_sel().bits(1) }); // 1 = CPLL @@ -208,9 +205,8 @@ fn cpll_configure(freq_mhz: u32) { const I2C_CPLL_OC_DIV_7_0: u8 = 3; const I2C_CPLL_OC_DCUR: u8 = 6; - // 1. Enable CPLL power - // PMU.imm_hp_ck_power: tie_high_xpd_pll, tie_high_xpd_pll_i2c - // Note: PAC uses "pll" not "cpll" (eco4 PAC, single PLL) + // 1. Enable CPLL power PMU.imm_hp_ck_power: tie_high_xpd_pll, tie_high_xpd_pll_i2c Note: PAC + // uses "pll" not "cpll" (eco4 PAC, single PLL) let pmu = PMU::regs(); // PAC: tie_high_xpd_pll is 4-bit field (one bit per PLL: CPLL/SPLL/MPLL/PLLA). // Set all bits to enable all PLLs. Same for pll_i2c. @@ -241,8 +237,7 @@ fn cpll_configure(freq_mhz: u32) { regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_DIV_7_0, div7_0); regi2c::regi2c_write(I2C_CPLL, 0, I2C_CPLL_OC_DCUR, dcur); - // 3. Run CPLL calibration - // HP_SYS_CLKRST.ana_pll_ctrl0.cpu_pll_cal_stop + // 3. Run CPLL calibration HP_SYS_CLKRST.ana_pll_ctrl0.cpu_pll_cal_stop let clkrst = crate::peripherals::HP_SYS_CLKRST::regs(); // Start calibration: set cpu_pll_cal_stop = 0 diff --git a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs index e844030ab21..28667a723af 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32p4.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32p4.rs @@ -7,7 +7,6 @@ //! It references types and PMU registers that don't exist in current PAC: //! - crate::clock::Clock, crate::efuse::Efuse (old API pattern) //! - PMU hp_active/hp_modem/hp_sleep register groups -//! // TODO: Implement sleep mode once PMU eco5 registers are validated. // TODO: reference florianL21's implementation diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index 0a4df18c8a5..f6cd198b0d1 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -256,7 +256,6 @@ impl TimgInstance { // System clock impl functions - // Mux enable stubs (mux nodes need enable functions too) fn enable_cpu_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {} fn enable_lp_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {} diff --git a/esp-hal/src/soc/esp32p4/gpio.rs b/esp-hal/src/soc/esp32p4/gpio.rs index ef3f6a9d957..af943df6b63 100644 --- a/esp-hal/src/soc/esp32p4/gpio.rs +++ b/esp-hal/src/soc/esp32p4/gpio.rs @@ -51,7 +51,7 @@ macro_rules! p4_rtc_pin { // LP_AON (LP_SYS) doesn't have gpio_hold for P4. // P4 uses LP_IO_MUX pad hold instead. // TODO: implement LP pad hold - // For now, no-op. + // For now, no-op. let _ = enable; } From 1b0834ede276d7312a1779420ee3434ee5ae07de Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 04:12:21 +0900 Subject: [PATCH 18/27] To passing Machete cicd --- esp-rom-sys/src/reg_access.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esp-rom-sys/src/reg_access.rs b/esp-rom-sys/src/reg_access.rs index 96b1c45d085..cd5c1dbcab9 100644 --- a/esp-rom-sys/src/reg_access.rs +++ b/esp-rom-sys/src/reg_access.rs @@ -20,6 +20,9 @@ pub(crate) use esp32c61 as pac; #[cfg(esp32h2)] #[expect(unused)] pub(crate) use esp32h2 as pac; +#[cfg(esp32p4)] +#[expect(unused)] +pub(crate) use esp32p4 as pac; #[cfg(esp32s2)] #[expect(unused)] pub(crate) use esp32s2 as pac; From a8c86eeef4ea127d050fb782bb89219a17dea250 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 04:33:59 +0900 Subject: [PATCH 19/27] Lint for P4X, but not fix them all --- esp-hal/src/efuse/esp32p4/fields.rs | 3 +- esp-hal/src/psram/esp32p4.rs | 72 ++++++++--------------------- esp-hal/src/soc/esp32p4/clocks.rs | 2 + 3 files changed, 22 insertions(+), 55 deletions(-) diff --git a/esp-hal/src/efuse/esp32p4/fields.rs b/esp-hal/src/efuse/esp32p4/fields.rs index 704017b5ef1..a2f2ae7058d 100644 --- a/esp-hal/src/efuse/esp32p4/fields.rs +++ b/esp-hal/src/efuse/esp32p4/fields.rs @@ -498,8 +498,9 @@ pub const DIS_WDT: EfuseField = EfuseField::new(0, 5, 180, 1); pub const DIS_SWD: EfuseField = EfuseField::new(0, 5, 181, 1); /// Use to configure glitch mode pub const PVT_GLITCH_MODE: EfuseField = EfuseField::new(0, 5, 182, 2); -/// `[MAC_FACTORY]` MAC address +/// `[MAC_FACTORY]` MAC address (low 32 bits) pub const MAC0: EfuseField = EfuseField::new(1, 0, 0, 32); +/// `[MAC_FACTORY]` MAC address (high 16 bits) pub const MAC1: EfuseField = EfuseField::new(1, 0, 32, 16); /// Minor chip version pub const WAFER_VERSION_MINOR: EfuseField = EfuseField::new(1, 2, 64, 4); diff --git a/esp-hal/src/psram/esp32p4.rs b/esp-hal/src/psram/esp32p4.rs index 0ff6dcee4b8..5d04a7c202f 100644 --- a/esp-hal/src/psram/esp32p4.rs +++ b/esp-hal/src/psram/esp32p4.rs @@ -3,6 +3,12 @@ //! P4 has two PSRAM controllers wired to the same DQ pads //! The structure is looks same with DDR controller but not same. +// Several ROM cache helpers and MMIO wrappers are staged for follow-up +// PSRAM bring-up work (cache suspend/resume around config writes). +// They're intentionally retained so the follow-up PR can wire them in +// without re-deriving the constants. +#![allow(dead_code)] + /// PSRAM virtual address range (cached) pub const PSRAM_VADDR_START: usize = 0x4800_0000; @@ -379,7 +385,7 @@ impl PsramPad { Self::Dq5, Self::Dq6, Self::Dq7, - /// Strobe0 + // Strobe0 Self::Dqs0, // DQ8 ~ DQ15 Self::Dq8, @@ -393,7 +399,7 @@ impl PsramPad { // Ck and Cs Self::Ck, Self::Cs, - /// Strobe1 + // Strobe1 Self::Dqs1, ]; @@ -422,10 +428,12 @@ impl PsramPad { } } -/// Configure PSRAM PHY pads. Mirrors IDF `mspi_timing_ll_pin_drv_set(2)` -/// + `mspi_timing_ll_enable_dqs(true)`. Both DQS XPD bits must be on -/// for DDR reads to latch data; drive strength = 2 matches IDF default -/// for AP HEX PSRAM at 200 MHz. +/// Configure PSRAM PHY pads. +/// +/// Mirrors IDF `mspi_timing_ll_pin_drv_set(2)` + +/// `mspi_timing_ll_enable_dqs(true)`. Both DQS XPD bits must be on for +/// DDR reads to latch data; drive strength = 2 matches IDF default for +/// AP HEX PSRAM at 200 MHz. fn psram_pad_init() { unsafe { PsramPad::set_drv_all(2); @@ -516,8 +524,7 @@ fn init_mr_registers() { // Read+modify+write MR8 (high byte is reserved/absent — pass 0). let (mut mr8, mr9) = psram_mr_read(MR_ADDR_MR8_MR9); // MR9 is unused mr8 &= !(0x3 | (1 << 2) | (1 << 3) | (1 << 6)); - mr8 |= 3 // bl = 3 (32-byte burst) - | (0 << 2) // bt = 0 + mr8 |= 3 // bt = 0 | (1 << 3) // rbx = 1 | (1 << 6); // x16 = 1 psram_mr_write(MR_ADDR_MR8_MR9, mr8, mr9); // keep previous MR9 @@ -556,31 +563,10 @@ unsafe extern "C" { /// Linked from `esp32p4.rom.ld`: `esp_rom_spi_cmd_config = 0x4fc00108`. fn esp_rom_spi_cmd_config(spi_num: i32, pcmd: *mut EspRomSpiCmd); - /// `Cache_Suspend_L1_DCache = 0x4fc004f8`. Stops new D-cache fills, - /// drains in-flight transactions, returns previous-state token. - fn Cache_Suspend_L1_DCache() -> u32; - /// `Cache_Resume_L1_DCache = 0x4fc004fc`. Restores D-cache from token. - fn Cache_Resume_L1_DCache(autoload_state: u32); - /// `Cache_Suspend_L2_Cache = 0x4fc00508`. - fn Cache_Suspend_L2_Cache() -> u32; - /// `Cache_Resume_L2_Cache = 0x4fc0050c`. - fn Cache_Resume_L2_Cache(autoload_state: u32); /// `Cache_Invalidate_All = 0x4fc00404`. Invalidates all cache levels. fn Cache_Invalidate_All(); } -unsafe fn rom_cache_suspend_l1_dcache() -> u32 { - unsafe { Cache_Suspend_L1_DCache() } -} -unsafe fn rom_cache_resume_l1_dcache(s: u32) { - unsafe { Cache_Resume_L1_DCache(s) } -} -unsafe fn rom_cache_suspend_l2_cache() -> u32 { - unsafe { Cache_Suspend_L2_Cache() } -} -unsafe fn rom_cache_resume_l2_cache(s: u32) { - unsafe { Cache_Resume_L2_Cache(s) } -} unsafe fn rom_cache_invalidate_all() { unsafe { Cache_Invalidate_All() } } @@ -591,7 +577,7 @@ unsafe fn rom_cache_invalidate_all() { /// bounded variant surfaces a real failure as a returned error. After /// the bit clears, copies MISO bytes from W0..W{N} into `rx_buf`. fn mspi1_kick_and_collect(rx: &mut [u8]) -> Result<(), ()> { - const SPI_CMD: u32 = MSPI1_BASE + 0x00; + const SPI_CMD: u32 = MSPI1_BASE; const SPI_W0: u32 = MSPI1_BASE + 0x58; const SPI_USR_TRIGGER: u32 = 1 << 18; const MAX_ITERS: u32 = 1_000_000; @@ -616,7 +602,7 @@ fn mspi1_kick_and_collect(rx: &mut [u8]) -> Result<(), ()> { // Copy MISO bytes from W0..W{N}. if !rx.is_empty() { let n_bytes = rx.len(); - let n_words = (n_bytes + 3) / 4; + let n_words = n_bytes.div_ceil(4); for i in 0..n_words { let word = unsafe { mmio_read_32(SPI_W0 + (i as u32) * 4) }; for b in 0..4 { @@ -755,28 +741,6 @@ fn mmu_map_psram(mspi_base: u32, config: PsramConfig) { } } -fn cache_suspend() { - let cache = unsafe { &*crate::pac::CACHE::PTR }; - cache - .l1_dcache_ctrl() - .modify(|_, w| w.l1_dcache_shut_dbus0().set_bit()); - while !cache - .l1_dcache_autoload_ctrl() - .read() - .l1_dcache_autoload_done() - .bit_is_set() - { - core::hint::spin_loop(); - } -} - -fn cache_resume() { - let cache = unsafe { &*crate::pac::CACHE::PTR }; - cache - .l1_dcache_ctrl() - .modify(|_, w| w.l1_dcache_shut_dbus0().clear_bit()); -} - #[allow(dead_code)] pub(crate) fn cache_invalidate(addr: u32, size: u32) { let cache = unsafe { &*crate::pac::CACHE::PTR }; @@ -946,7 +910,7 @@ fn configure_psram_mspi(base: u32) { mmio_setbits_32(base + 0x44, 0b1100_1011_1100 << 16); // bits 27, 26, 23, 21..18 // SRAM_DRD_CMD / SRAM_DWR_CMD: 16-bit sync read/write commands. - mmio_write_32(base + 0x48, ((16 - 1) << 28) | 0x0000); // sync read 0x0000 + mmio_write_32(base + 0x48, (16 - 1) << 28); // sync read 0x0000 mmio_write_32(base + 0x4C, ((16 - 1) << 28) | 0x8080); // sync write 0x8080 // MEM_CTRL1: splice enables (AXI burst optimization). diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index f6cd198b0d1..7e0738d6690 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -8,6 +8,8 @@ //! Clock hierarchy: XTAL -> CPLL -> CPU_ROOT -> CPU/APB dividers //! SPLL -> PLL_F240M/160M/120M/80M/20M (peripheral clocks) #![allow(dead_code, reason = "Clock functions called from generated macro code")] +#![allow(missing_docs, reason = "Clock-tree types come from a generated macro that does not emit doc strings")] +#![allow(clippy::enum_variant_names, reason = "CPU frequency variant names follow the chip-spec MHz convention")] define_clock_tree_types!(); From a6fd7e5ee86d9e24e93a24281d621f9322f2b32a Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 10:53:47 +0900 Subject: [PATCH 20/27] Add better comment on clic.rs --- esp-hal/src/interrupt/riscv/clic.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/esp-hal/src/interrupt/riscv/clic.rs b/esp-hal/src/interrupt/riscv/clic.rs index 4b3f9be6a50..96026cd16e6 100644 --- a/esp-hal/src/interrupt/riscv/clic.rs +++ b/esp-hal/src/interrupt/riscv/clic.rs @@ -1,15 +1,9 @@ -// PAC drift workaround: every `cfg_if!` block in this file gates the -// same silicon-level register write between two PAC naming conventions. -// The pinned `esp32p4` PAC emits CLIC fields with `int_attr_*` prefix -// and consolidates per-interrupt sub-fields under a single `int_ctrl` -// register, while the other CLIC chips (ESP32-C5/C6/C61/H2) split them -// into `int_attr`/`int_ie`/`int_ip`/`int_ctl` per index. The hardware -// is the same; only the SVD-derived names differ. +// ESP32P4 follows pulp CLIC version 1.x +// TODO: keep tracking future P4 revision to check changes of CLIC. +// ref : https://github.com/pulp-platform/clic/blob/v1.0.1/src/gen/clic.hjson.tpl // -// TODO: file an esp-pacs issue / PR to normalise the CLIC SVD across -// RISC-V chips so the P4 names match the C5/C6/C61/H2 convention. -// Once that lands and we bump the esp32p4 PAC pin, every cfg_if! here -// can be removed in one pass. +// ESP32C5, C61 follow pulp CLIC version 2.x +// ref : https://github.com/pulp-platform/clic/blob/v2.0.0/src/gen/mclic.hjson use super::{InterruptKind, Priority, RunLevel}; use crate::{interrupt::ElevatedRunLevel, soc::pac::CLIC}; From a1cc3ad23d33f4b942d382d0532bb1dc66b3df09 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 17:15:33 +0900 Subject: [PATCH 21/27] Delete p4 radio clk and fix right l2mem cfg comment --- esp-hal/ld/esp32p4/memory.x | 18 ++++--- .../src/radio_clocks/clocks_ll/esp32p4.rs | 52 ------------------- 2 files changed, 10 insertions(+), 60 deletions(-) delete mode 100644 esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs diff --git a/esp-hal/ld/esp32p4/memory.x b/esp-hal/ld/esp32p4/memory.x index 05e46a6cf4a..f128ed2b2e9 100644 --- a/esp-hal/ld/esp32p4/memory.x +++ b/esp-hal/ld/esp32p4/memory.x @@ -4,29 +4,31 @@ fixed at 0x4FFAE000 to leave the v3.x ROM BSS/stack region (top ~72 KB of L2MEM) untouched. + CONFIG numbers follow TRM Figure 7.3-2 (HP L2MEM Address Layout): + CONFIG ESP_HAL_CONFIG_L2_CACHE_SIZE L2 cache L2 RAM ORIGIN ------ ---------------------------- -------- ------------- - 3 "512KB" 512 KB 0x4FF80000 - 2 "256KB" 256 KB 0x4FF40000 - 1 "128KB" (IDF default) 128 KB 0x4FF20000 - 0 "0KB" 0 KB 0x4FF00000 + 0 "512KB" 512 KB 0x4FF80000 + 1 "256KB" 256 KB 0x4FF40000 + 2 "128KB" (IDF default) 128 KB 0x4FF20000 + 3 "0KB" 0 KB 0x4FF00000 */ MEMORY { - /* CONFIG 3 */ + /* CONFIG 0 */ #IF ESP_HAL_CONFIG_L2_CACHE_SIZE_512KB RAM : ORIGIN = 0x4FF80000, LENGTH = 0x4FFAE000 - 0x4FF80000 #ENDIF - /* CONFIG 2 */ + /* CONFIG 1 */ #IF ESP_HAL_CONFIG_L2_CACHE_SIZE_256KB RAM : ORIGIN = 0x4FF40000, LENGTH = 0x4FFAE000 - 0x4FF40000 #ENDIF - /* CONFIG 1 */ + /* CONFIG 2 */ #IF ESP_HAL_CONFIG_L2_CACHE_SIZE_128KB RAM : ORIGIN = 0x4FF20000, LENGTH = 0x4FFAE000 - 0x4FF20000 #ENDIF - /* CONFIG 0 */ + /* CONFIG 3 */ #IF ESP_HAL_CONFIG_L2_CACHE_SIZE_0KB RAM : ORIGIN = 0x4FF00000, LENGTH = 0x4FFAE000 - 0x4FF00000 #ENDIF diff --git a/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs b/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs deleted file mode 100644 index 5266d23346d..00000000000 --- a/esp-radio/src/radio_clocks/clocks_ll/esp32p4.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::peripherals::PMU; - -pub(super) fn enable_phy(en: bool) { - // empty -} - -#[cfg_attr(not(feature = "unstable"), expect(unused))] -pub(super) fn enable_wifi(en: bool) { - // empty -} - -#[cfg_attr(not(feature = "unstable"), expect(unused))] -pub(super) fn enable_ieee802154(en: bool) { - // empty -} - -#[cfg_attr(not(feature = "unstable"), expect(unused))] -pub(super) fn enable_bt(en: bool) { - // empty -} - -pub(super) fn reset_wifi_mac() { - // empty -} - -pub(super) fn init_clocks() { - unsafe { - PMU::regs() - .hp_sleep_icg_modem() - .modify(|_, w| w.hp_sleep_dig_icg_modem_code().bits(0)); - PMU::regs() - .hp_modem_icg_modem() - .modify(|_, w| w.hp_modem_dig_icg_modem_code().bits(1)); - PMU::regs() - .hp_active_icg_modem() - .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(2)); - PMU::regs() - .imm_modem_icg() - .write(|w| w.update_dig_icg_modem_en().set_bit()); - PMU::regs() - .imm_sleep_sysclk() - .write(|w| w.update_dig_icg_switch().set_bit()); - } -} - -pub(super) fn ble_rtc_clk_init() { - // nothing for this target (yet) -} - -pub(super) fn reset_rpa() { - // nothing for this target (yet) -} From 1b91a7e384a73ca73c48c25cfc014ccdc62ac7d7 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 17:39:18 +0900 Subject: [PATCH 22/27] Important note about clic.rs --- esp-hal/src/interrupt/riscv/clic.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/esp-hal/src/interrupt/riscv/clic.rs b/esp-hal/src/interrupt/riscv/clic.rs index 96026cd16e6..ae6b5f688d9 100644 --- a/esp-hal/src/interrupt/riscv/clic.rs +++ b/esp-hal/src/interrupt/riscv/clic.rs @@ -1,5 +1,10 @@ -// ESP32P4 follows pulp CLIC version 1.x +// CLIC v1.x and v2.x currently coexist in this file. Depending on +// ESP32-P4 mass production results and future esp-rs/esp-pacs patches, +// this file may be split into clic_v1.rs / clic_v2.rs, or kept as is. +// // TODO: keep tracking future P4 revision to check changes of CLIC. +// +// ESP32P4 follows pulp CLIC version 1.x // ref : https://github.com/pulp-platform/clic/blob/v1.0.1/src/gen/clic.hjson.tpl // // ESP32C5, C61 follow pulp CLIC version 2.x @@ -209,7 +214,7 @@ core::arch::global_asm!( * If an interrupt occurs and is configured as (hardware) vectored, the CPU will jump to * MTVT[31:0] + 4 * interrupt_id * - * In the case of the ESP32-P4/ESP32-C5, the interrupt matrix, between the CPU interrupt lines + * In the case of the ESP32P4/ESP32C5, the interrupt matrix, between the CPU interrupt lines * and the peripherals, offers 32 lines, and the lower 16 interrupts are used for CLINT. */ .balign 0x40 From ccf1641a3f43ce0b8e0cab087f78f370881dd401 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 21:09:24 +0900 Subject: [PATCH 23/27] Tyding to latest #5473 --- esp-hal/src/soc/esp32p4/clocks.rs | 4 +-- .../src/_generated_esp32p4.rs | 34 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index 7e0738d6690..1f19aa6b04a 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -98,8 +98,8 @@ impl ClockConfig { } } - pub(crate) fn configure(self) { - self.apply(); + pub(crate) fn configure(self, clocks: &mut ClockTree) { + self.apply(clocks); } } diff --git a/esp-metadata-generated/src/_generated_esp32p4.rs b/esp-metadata-generated/src/_generated_esp32p4.rs index f9c9924d69c..669df1e3d22 100644 --- a/esp-metadata-generated/src/_generated_esp32p4.rs +++ b/esp-metadata-generated/src/_generated_esp32p4.rs @@ -2169,24 +2169,22 @@ macro_rules! define_clock_tree_types { pub lp_slow_clk: Option, } impl ClockConfig { - fn apply(&self) { - ClockTree::with(|clocks| { - if let Some(config) = self.cpu_root_clk { - configure_cpu_root_clk(clocks, config); - } - if let Some(config) = self.cpu_clk { - configure_cpu_clk(clocks, config); - } - if let Some(config) = self.apb_clk { - configure_apb_clk(clocks, config); - } - if let Some(config) = self.lp_fast_clk { - configure_lp_fast_clk(clocks, config); - } - if let Some(config) = self.lp_slow_clk { - configure_lp_slow_clk(clocks, config); - } - }); + fn apply(&self, clocks: &mut ClockTree) { + if let Some(config) = self.cpu_root_clk { + configure_cpu_root_clk(clocks, config); + } + if let Some(config) = self.cpu_clk { + configure_cpu_clk(clocks, config); + } + if let Some(config) = self.apb_clk { + configure_apb_clk(clocks, config); + } + if let Some(config) = self.lp_fast_clk { + configure_lp_fast_clk(clocks, config); + } + if let Some(config) = self.lp_slow_clk { + configure_lp_slow_clk(clocks, config); + } } } fn increment_reference_count(refcount: &mut u32) -> bool { From 23adb5d0130058b0af6be02c0ac61e0630219759 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 22:03:01 +0900 Subject: [PATCH 24/27] Apply ChangeLog considering cicd --- esp-backtrace/CHANGELOG.md | 1 + esp-bootloader-esp-idf/CHANGELOG.md | 5 +---- esp-hal/CHANGELOG.md | 3 +++ esp-metadata/CHANGELOG.md | 7 ++----- esp-println/CHANGELOG.md | 1 + esp-rom-sys/CHANGELOG.md | 6 +----- esp-sync/CHANGELOG.md | 1 + 7 files changed, 10 insertions(+), 14 deletions(-) diff --git a/esp-backtrace/CHANGELOG.md b/esp-backtrace/CHANGELOG.md index c81eb6aa5cb..80f03cc9c91 100644 --- a/esp-backtrace/CHANGELOG.md +++ b/esp-backtrace/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Initial ESP32-P4 (chip revision v3.0+) support (#5400) ### Changed diff --git a/esp-bootloader-esp-idf/CHANGELOG.md b/esp-bootloader-esp-idf/CHANGELOG.md index 292d0eb29ce..f631aec2c28 100644 --- a/esp-bootloader-esp-idf/CHANGELOG.md +++ b/esp-bootloader-esp-idf/CHANGELOG.md @@ -12,10 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- ESP32-P4: Use ROM CRC32 / MD5 functions instead of the software fallback, - matching the behavior on every other supported chip. Made possible by the - new `rom_crc_le`, `rom_crc_be`, `rom_md5_bsd` cfg flags emitted from - `esp-metadata`. +- ESP32-P4: Use ROM CRC32 / MD5 functions instead of the software fallback (#5400) ### Fixed diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 5660742d6a2..902605877dd 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - C5 and C61: Enable RTC timekeeping (#5449) - C61: usb-serial-jtag and debug-assist (#5427) - C61: dedicated gpio (#5426) +- Initial ESP32-P4 (chip revision v3.0+) support (#5400) +- P4: Initial peripheral support for GPIO, UART, I2C, SPI, DMA, USB Serial/JTAG, eFuse, SYSTIMER (#5400) +- P4: AP-HEX PSRAM driver stub with configurable HP L2MEM cache/RAM split via `ESP_HAL_CONFIG_L2_CACHE_SIZE` (#5400) ### Changed diff --git a/esp-metadata/CHANGELOG.md b/esp-metadata/CHANGELOG.md index a2223aa2c8c..490833fef81 100644 --- a/esp-metadata/CHANGELOG.md +++ b/esp-metadata/CHANGELOG.md @@ -10,11 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - C5 and C61: Enable RTC timekeeping (#5449) -- ESP32-P4: emit `rom_crc_le`, `rom_crc_be`, `rom_md5_bsd` cfg flags so - `esp-rom-sys` exposes the silicon ROM CRC/MD5 wrappers and - `esp-bootloader-esp-idf` can drop its software fallback for P4. -- ESP32-P4: emit `pm_support_ext1_wakeup` and - `pm_support_touch_sensor_wakeup` (matches ESP-IDF SOC capabilities). +- ESP32-P4: emit `rom_crc_le`, `rom_crc_be`, `rom_md5_bsd` cfg flags (#5400) +- ESP32-P4: emit `pm_support_ext1_wakeup` and `pm_support_touch_sensor_wakeup` (#5400) ### Changed diff --git a/esp-println/CHANGELOG.md b/esp-println/CHANGELOG.md index fec3ea0daf6..112e746d745 100644 --- a/esp-println/CHANGELOG.md +++ b/esp-println/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Initial ESP32-P4 (chip revision v3.0+) support (#5400) ### Changed diff --git a/esp-rom-sys/CHANGELOG.md b/esp-rom-sys/CHANGELOG.md index 9e5349b92a4..2a787d81aa5 100644 --- a/esp-rom-sys/CHANGELOG.md +++ b/esp-rom-sys/CHANGELOG.md @@ -12,11 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- ESP32-P4: replace the imported pre-ECO5 ROM linker scripts with the - ECO5+ symbol addresses (sourced from ESP-IDF v6.0.1 - `esp32p4.rom.eco5*.ld`). The previous file used pre-ECO5 addresses and - silently misnamed several ROM symbols on v3.x silicon (e.g. - `esp_rom_crc32_le` and `crc32_be`). +- ESP32-P4: replace the pre-ECO5 ROM linker scripts with ECO5+ symbol addresses sourced from ESP-IDF v6.0.1 (#5400) ### Fixed diff --git a/esp-sync/CHANGELOG.md b/esp-sync/CHANGELOG.md index 42847ee4654..959d52ecfe2 100644 --- a/esp-sync/CHANGELOG.md +++ b/esp-sync/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Initial ESP32-P4 (chip revision v3.0+) support (#5400) ### Changed From 4f1d7547b2171784bdcaa35357af115b9e800402 Mon Sep 17 00:00:00 2001 From: Jinwoo Park Date: Mon, 4 May 2026 22:24:41 +0900 Subject: [PATCH 25/27] Consider fmt-packages for P4 --- esp-hal/src/soc/esp32p4/clocks.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/esp-hal/src/soc/esp32p4/clocks.rs b/esp-hal/src/soc/esp32p4/clocks.rs index 1f19aa6b04a..dc4297358e6 100644 --- a/esp-hal/src/soc/esp32p4/clocks.rs +++ b/esp-hal/src/soc/esp32p4/clocks.rs @@ -8,8 +8,14 @@ //! Clock hierarchy: XTAL -> CPLL -> CPU_ROOT -> CPU/APB dividers //! SPLL -> PLL_F240M/160M/120M/80M/20M (peripheral clocks) #![allow(dead_code, reason = "Clock functions called from generated macro code")] -#![allow(missing_docs, reason = "Clock-tree types come from a generated macro that does not emit doc strings")] -#![allow(clippy::enum_variant_names, reason = "CPU frequency variant names follow the chip-spec MHz convention")] +#![allow( + missing_docs, + reason = "Clock-tree types come from a generated macro that does not emit doc strings" +)] +#![allow( + clippy::enum_variant_names, + reason = "CPU frequency variant names follow the chip-spec MHz convention" +)] define_clock_tree_types!(); From 7030d87ead0338550d9f8ace043bf8ebab046e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 4 May 2026 18:55:07 +0200 Subject: [PATCH 26/27] Fix esp-println and enable the hello_world examples --- esp-println/src/lib.rs | 5 ++++- examples/hello_world/Cargo.toml | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/esp-println/src/lib.rs b/esp-println/src/lib.rs index 1e7d1053e94..e31d23168b4 100644 --- a/esp-println/src/lib.rs +++ b/esp-println/src/lib.rs @@ -151,6 +151,7 @@ type PrinterImpl = noop::Printer; feature = "esp32c6", feature = "esp32c61", feature = "esp32h2", + feature = "esp32p4", feature = "esp32s3" ) ))] @@ -181,6 +182,8 @@ mod auto_printer { const USB_DEVICE_INT_RAW: *const u32 = 0x6000f008 as *const u32; #[cfg(feature = "esp32s3")] const USB_DEVICE_INT_RAW: *const u32 = 0x60038000 as *const u32; + #[cfg(feature = "esp32p4")] + const USB_DEVICE_INT_RAW: *const u32 = 0x500D2008 as *const u32; const SOF_INT_MASK: u32 = 0b10; @@ -213,6 +216,7 @@ mod auto_printer { feature = "esp32c6", feature = "esp32c61", feature = "esp32h2", + feature = "esp32p4", feature = "esp32s3" )) ))] @@ -265,7 +269,6 @@ mod serial_jtag_printer { const SERIAL_JTAG_CONF_REG: usize = 0x6003_8004; // ESP32-P4: USB_DEVICE peripheral at 0x500D_2000 per PAC. - // FIFO/CONF layout matches C6/H2 (same Synopsys USB Serial/JTAG IP). #[cfg(feature = "esp32p4")] const SERIAL_JTAG_FIFO_REG: usize = 0x500D_2000; #[cfg(feature = "esp32p4")] diff --git a/examples/hello_world/Cargo.toml b/examples/hello_world/Cargo.toml index 4e1abf6f4e0..96051ccbcea 100644 --- a/examples/hello_world/Cargo.toml +++ b/examples/hello_world/Cargo.toml @@ -49,6 +49,11 @@ esp32h2 = [ "esp-bootloader-esp-idf/esp32h2", "esp-hal/esp32h2", ] +esp32p4 = [ + "esp-backtrace/esp32p4", + "esp-bootloader-esp-idf/esp32p4", + "esp-hal/esp32p4", +] esp32s2 = [ "esp-backtrace/esp32s2", "esp-bootloader-esp-idf/esp32s2", From da20b349f4d4d791048099b06b67c5afb105fcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 4 May 2026 19:06:29 +0200 Subject: [PATCH 27/27] Enable the GPIO example --- examples/interrupt/gpio/Cargo.toml | 5 +++++ examples/interrupt/gpio/src/main.rs | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/interrupt/gpio/Cargo.toml b/examples/interrupt/gpio/Cargo.toml index fc1d1b35199..c1ab1ee0b70 100644 --- a/examples/interrupt/gpio/Cargo.toml +++ b/examples/interrupt/gpio/Cargo.toml @@ -47,6 +47,11 @@ esp32h2 = [ "esp-bootloader-esp-idf/esp32h2", "esp-hal/esp32h2", ] +esp32p4 = [ + "esp-backtrace/esp32p4", + "esp-bootloader-esp-idf/esp32p4", + "esp-hal/esp32p4", +] esp32s2 = [ "esp-backtrace/esp32s2", "esp-bootloader-esp-idf/esp32s2", diff --git a/examples/interrupt/gpio/src/main.rs b/examples/interrupt/gpio/src/main.rs index 5ad4d6c37ee..4f726071447 100644 --- a/examples/interrupt/gpio/src/main.rs +++ b/examples/interrupt/gpio/src/main.rs @@ -5,7 +5,11 @@ //! //! The following wiring is assumed: //! - LED => GPIO2 -//! - BUTTON => GPIO0 (ESP32, ESP32-S2, ESP32-S3) / GPIO28 (ESP32-C5) / GPIO9 +//! - BUTTON: +//! - ESP32, ESP32-S2, ESP32-S3: GPIO0 +//! - ESP32-C5: GPIO28 +//! - ESP32-P4: GPIO35 +//! - Others: GPIO9 #![no_std] #![no_main] @@ -42,7 +46,9 @@ fn main() -> ! { let button = peripherals.GPIO0; } else if #[cfg(any(feature = "esp32c5"))] { let button = peripherals.GPIO28; - }else { + } else if #[cfg(any(feature = "esp32p4"))] { + let button = peripherals.GPIO35; + } else { let button = peripherals.GPIO9; } }