diff --git a/SConscript b/SConscript index 44a29c3aef99..3b16bef97c60 100644 --- a/SConscript +++ b/SConscript @@ -961,6 +961,117 @@ if GetDepend(['BSP_USING_BLE']) : cwd + '/components/vfs/private_include/' ] +if GetDepend(['SOC_ESP32_C6']): + import os + + def to_c6(items): + out = [] + for item in items: + if 'esp32c3' not in item: + out.append(item) + continue + alt = item.replace('esp32c3', 'esp32c6') + if os.path.exists(os.path.join(cwd, alt)): + out.append(alt) + return out + + drop_hal = ('i2c_hal', 'ledc_hal', 'rmt_hal', 'i2s_hal', 'twai_hal', 'sdm_hal', 'spi_slave', 'temperature', 'adc_hal', 'adc_oneshot', 'spi_hal', 'xt_wdt') + for group_src in [ + esp32c3_src, + esp32c3_riscv_src, + esp32c3_mbedtls_src, + esp32c3_esp_system_src, + esp32c3_hal_src, + esp32c3_soc_src, + esp32c3_esp_hw_support_src, + esp32c3_bootloader_support_src, + esp32c3_esp_rom_src, + esp32c3_heap_src, + esp32c3_spi_flash_src, + esp32c3_newlib_src, + esp32c3_log_src, + esp32c3_driver_src, + esp32c3_pthread_src, + esp32c3_efuse_src, + esp32c3_esp_timer_src]: + picked = to_c6(group_src) + if group_src is esp32c3_driver_src: + picked = [p for p in picked if p.endswith('gpio/gpio.c') or p.endswith('gpio/rtc_io.c') or p.endswith('uart.c') or p.endswith('spi_bus_lock.c')] + elif group_src is esp32c3_hal_src: + picked = [p for p in picked if not any(name in os.path.basename(p) for name in drop_hal)] + src += picked + drop_src = ( + 'gdma.c', 'async_memcpy_impl_gdma.c', 'esp_async_memcpy.c', 'rtc_module.c', + 'sleep_mac_bb.c', 'sleep_gpio.c', 'sleep_modes.c', 'sleep_retention.c', + 'pm_impl.c', + ) + src = [p for p in src if 'adc' not in os.path.basename(p).lower() and 'i2s' not in os.path.basename(p).lower() and os.path.basename(p) not in drop_src] + src.append('components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c') + src.append('components/hal/lp_timer_hal.c') + src.append('components/esp_hw_support/modem_clock.c') + + have = set(src) + skip_name = ( + 'ieee802154', 'parlio', 'wifi', 'coexist', 'adc', + 'io_mux', 'pmu_sleep', 'i2s', 'twai', 'timer_periph', 'temperature', + 'sdm', 'rmt', 'pcnt', 'mcpwm', 'ledc', 'i2c', 'dedic', 'sdio', + 'bootloader_sha', + ) + for root in [ + 'components/hal/esp32c6', + 'components/esp_hw_support/port/esp32c6', + 'components/esp_system/port/soc/esp32c6', + 'components/soc/esp32c6', + 'components/bootloader_support/src/esp32c6', + 'components/efuse/esp32c6', + 'components/heap/port/esp32c6']: + full = os.path.join(cwd, root) + if not os.path.isdir(full): + continue + for name in os.listdir(full): + if not name.endswith(('.c', '.S', '.cpp')): + continue + if any(part in name for part in skip_name): + continue + rel = root + '/' + name + if rel not in have: + src.append(rel) + have.add(rel) + + for item in esp32c3_path: + if 'esp32c3' not in item: + path.append(item) + continue + alt = item.replace('esp32c3', 'esp32c6') + if os.path.isdir(alt): + path.append(alt) + for extra in [ + '/components/hal/esp32c6/include', + '/components/soc/esp32c6/include', + '/components/esp_hw_support/include/soc/esp32c6', + '/components/esp_rom/esp32c6/include', + '/components/esp_rom/include/esp32c6', + '/components/efuse/esp32c6/include', + '/components/esp_hw_support/port/esp32c6/private_include']: + inc = cwd + extra + if os.path.isdir(inc) and inc not in path: + path.append(inc) + + src = [p for p in src if all(part not in p.replace('\\', '/') for part in ('gdma', '/aes/dma/', '/sha/dma/'))] + src = [p for p in src if not p.endswith('.cpp')] + + if GetDepend(['BSP_ENABLE_GDBSTUB']): + src += [ + 'components/esp_gdbstub/esp32c6/gdbstub_esp32c6.c', + 'components/esp_gdbstub/riscv/gdbstub_riscv.c', + 'components/esp_gdbstub/src/gdbstub.c', + 'components/esp_gdbstub/src/packet.c', + ] + + CPPDEFINES = ['IDF_VER=\\"999\\\"', 'PROJECT_VER=\\"999\\"', '_GNU_SOURCE', 'MULTI_HEAP_FREERTOS', 'ESP_PLATFORM=1', 'IDF_TARGET=esp32c6', 'SOC_MMU_PAGE_SIZE=0x10000', '_POSIX_READER_WRITER_LOCKS', 'PROJECT_NAME=\\"rtthread\\"', 'MBEDTLS_CONFIG_FILE=\\"mbedtls/esp_config.h\\"', 'ESPRESSIF_USE', 'CONFIG_CRYPTO_MBEDTLS', 'UNITY_INCLUDE_CONFIG_H', '__ets__', 'ESP_PLATFORM'] + LIB_PATH = [] + LIB = [] + group = DefineGroup('esp-idf', src, depend = ['PKG_USING_ESP_IDF'], CPPPATH = path, LIBS = LIB, LIBPATH = LIB_PATH, CPPDEFINES = CPPDEFINES) Return('group') \ No newline at end of file diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h index ade6ef01f67d..f0004a10b845 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,16 +25,6 @@ extern "C" { */ uint32_t bootloader_read_flash_id(void); -#if SOC_CACHE_SUPPORT_WRAP -/** - * @brief Set the burst mode setting command for specified wrap mode. - * - * @param mode The specified warp mode. - * @return always ESP_OK - */ -esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode); -#endif - /** * @brief Startup flow recommended by XMC. Call at startup before any erase/write operation. * @@ -57,6 +47,20 @@ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void); */ esp_err_t bootloader_flash_reset_chip(void); +/** + * @brief Check if octal flash mode is enabled in eFuse + * + * @return True if flash is in octal mode, false else + */ +bool bootloader_flash_is_octal_mode_enabled(void); + +/** + * @brief Get the spi flash working mode. + * + * @return The mode of flash working mode, see `esp_rom_spiflash_read_mode_t` + */ +esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void); + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h index 8d161bd28cfa..75fcd6e3b9af 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -109,6 +109,17 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup */ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void); +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH +/** + * @brief Enable 32bits address flash(larger than 16MB) can map to cache. + * + * @param flash_mode SPI flash working mode. + * + * @note This can be overridden because it's attribute weak. + */ +void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode); +#endif + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h index 9045b0865544..89edb7416ebc 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h @@ -20,7 +20,7 @@ extern "C" { #define FLASH_SECTOR_SIZE 0x1000 #define FLASH_BLOCK_SIZE 0x10000 -#define MMAP_ALIGNED_MASK 0x0000FFFF +#define MMAP_ALIGNED_MASK (SPI_FLASH_MMU_PAGE_SIZE - 1) #define MMU_FLASH_MASK (~(SPI_FLASH_MMU_PAGE_SIZE - 1)) /** @@ -49,10 +49,11 @@ extern "C" { #define CMD_RDSR3 0x15 /* Not all SPI flash uses this command */ #define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */ #define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ -#define CMD_WRAP 0x77 /* Set burst with wrap command */ #define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */ #define CMD_RESETEN 0x66 #define CMD_RESET 0x99 +#define CMD_FASTRD_4B 0x0C +#define CMD_SLOWRD_4B 0x13 /* Provide a Flash API for bootloader_support code, diff --git a/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h new file mode 100644 index 000000000000..4bff3f9dea34 --- /dev/null +++ b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize spi_flash in bootloader and print flash info + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t bootloader_init_spi_flash(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index da282577a806..dc819091c42d 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -19,6 +19,9 @@ #else # include "soc/spi_mem_struct.h" # include "soc/spi_mem_reg.h" +# if CONFIG_IDF_TARGET_ESP32C6 +# include "hal/spimem_flash_ll.h" +# endif /* SPI flash controller */ # define SPIFLASH SPIMEM1 #endif @@ -771,6 +774,8 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void) if (SPI1.ext2.st != 0) #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (SPIMEM1.fsm.st != 0) +#elif CONFIG_IDF_TARGET_ESP32C6 + if (!spimem_flash_ll_host_idle(&SPIMEM1)) #else if (SPIMEM1.fsm.spi0_mst_st != 0) #endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c index e69de29bb2d1..5f7367102fa9 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c @@ -0,0 +1,214 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "string.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" +#include "esp32c6/rom/gpio.h" +#include "esp32c6/rom/spi_flash.h" +#include "esp32c6/rom/efuse.h" +#include "soc/gpio_periph.h" +#include "soc/efuse_reg.h" +#include "soc/spi_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/soc_caps.h" +#include "flash_qio_mode.h" +#include "bootloader_flash_config.h" +#include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/mmu_ll.h" + +void bootloader_flash_update_id() +{ + esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip; + chip->device_id = bootloader_read_flash_id(); +} + +void IRAM_ATTR bootloader_flash_cs_timing_config() +{ + SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S); +} + +void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) +{ + uint32_t spi_clk_div = 0; + switch (pfhdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_1: + spi_clk_div = 1; + break; + case ESP_IMAGE_SPI_SPEED_DIV_2: + spi_clk_div = 2; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + spi_clk_div = 3; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + spi_clk_div = 4; + break; + default: + break; + } + esp_rom_spiflash_config_clk(spi_clk_div, 0); +} + +static const char *TAG = "boot.esp32c6"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + size = 1; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + size = 2; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + size = 4; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + size = 8; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + size = 16; + break; + default: + size = 2; + } + cache_hal_disable(CACHE_TYPE_ALL); + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0)); + if (spi_ctrl & SPI_MEM_FREAD_QIO) { + str = "QIO"; + } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) { + str = "QOUT"; + } else if (spi_ctrl & SPI_MEM_FREAD_DIO) { + str = "DIO"; + } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) { + str = "DOUT"; + } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) { + str = "FAST READ"; + } else { + str = "SLOW READ"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_configure_spi_pins(1); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + // Since the workaround in IDF-6709, the spi_speed value in the bootloader header + // is not the real value, overwrite it. +#if CONFIG_ESPTOOLPY_FLASHFREQ_80M + bootloader_image_hdr.spi_speed = ESP_IMAGE_SPI_SPEED_DIV_1; +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/private_include/bootloader_signature.h b/components/bootloader_support/private_include/bootloader_signature.h index fceb9eb49acd..9bea96ff7c81 100644 --- a/components/bootloader_support/private_include/bootloader_signature.h +++ b/components/bootloader_support/private_include/bootloader_signature.h @@ -21,6 +21,8 @@ #include "esp32h2/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/secure_boot.h" #endif #if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_3 diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index 35b1e0895295..dfce0f8e16da 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -7,7 +7,14 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "hal/efuse_hal.h" +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/rtc_cntl_reg.h" +#else +#include "soc/lp_wdt_reg.h" +#include "soc/lp_timer_reg.h" +#include "soc/lp_analog_peri_reg.h" +#include "soc/pmu_reg.h" +#endif #if CONFIG_IDF_TARGET_ESP32 #include "hal/clk_tree_ll.h" #endif @@ -47,10 +54,14 @@ __attribute__((weak)) void bootloader_clock_configure(void) if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) { clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW; } +#if CONFIG_IDF_TARGET_ESP32C6 + clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST; +#else clk_cfg.fast_clk_src = rtc_clk_fast_src_get(); if (clk_cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_INVALID) { clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_XTAL_DIV; } +#endif rtc_clk_init(clk_cfg); } @@ -65,6 +76,19 @@ __attribute__((weak)) void bootloader_clock_configure(void) } #endif // CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +#if CONFIG_IDF_TARGET_ESP32C6 + CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_SUPER_WDT_INT_ENA); + CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA); + CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA); + CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); + CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); + CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_SLEEP_REJECT_INT_ENA); + SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); + SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR); + SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_CLR); + SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); +#else REG_WRITE(RTC_CNTL_INT_ENA_REG, 0); REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX); +#endif } diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index b4f112e383a4..cfa69170ccfa 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -58,7 +58,11 @@ void bootloader_config_wdt(void) * protect the remainder of the bootloader process. */ //Disable RWDT flashboot protection. +#if CONFIG_IDF_TARGET_ESP32C6 + wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = RWDT_DEV_GET()}; +#else wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false); wdt_hal_write_protect_enable(&rtc_wdt_ctx); diff --git a/components/bootloader_support/src/bootloader_random_esp32c6.c b/components/bootloader_support/src/bootloader_random_esp32c6.c index e69de29bb2d1..682e48544c8c 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c6.c +++ b/components/bootloader_support/src/bootloader_random_esp32c6.c @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "bootloader_random.h" +#include "soc/soc.h" +#include "soc/pcr_reg.h" +#include "soc/apb_saradc_reg.h" +#include "soc/pmu_reg.h" +#include "hal/regi2c_ctrl.h" +#include "soc/regi2c_saradc.h" +#include "esp_log.h" + +static const uint32_t SAR2_CHANNEL = 9; +static const uint32_t PATTERN_BIT_WIDTH = 6; +static const uint32_t SAR1_ATTEN = 1; +static const uint32_t SAR2_ATTEN = 1; + +void bootloader_random_enable(void) +{ + // pull SAR ADC out of reset + REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); + REG_CLR_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); + + // enable SAR ADC APB clock + REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN); + + // enable ADC_CTRL_CLK (SAR ADC function clock) + REG_SET_BIT(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN); + + // select XTAL clock (40 MHz) source for ADC_CTRL_CLK + REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_SEL, 0); + + // set the clock divider for ADC_CTRL_CLK to default value (in case it has been changed) + REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_DIV_NUM, 0); + + // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); + + // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal voltage as sampling source + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR , 2); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR , 1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); + + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x08); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x66); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x08); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x66); + + // create patterns and set them in pattern table + uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation + uint32_t pattern_two = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH; + REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); + + // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) + REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SARADC_SAR_PATT_LEN, 1); + + // Same as in C3 + REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SARADC_SAR_CLK_DIV, 15); + + // set timer expiry (timer is ADC_CTRL_CLK) + REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_TARGET, 200); + + // enable timer + REG_SET_BIT(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); +} + +void bootloader_random_disable(void) +{ + // disable timer + REG_CLR_BIT(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); + + // Write reset value of this register + REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); + + // Revert ADC I2C configuration and initial voltage source setting + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x60); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x0); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x60); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x0); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); + + // Revert PMU_RF_PWC_REG to it's initial value + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); + + // disable ADC_CTRL_CLK (SAR ADC function clock) + REG_WRITE(PCR_SARADC_CLKM_CONF_REG, 0x00404000); + + // Set PCR_SARADC_CONF_REG to initial state + REG_WRITE(PCR_SARADC_CONF_REG, 0x5); +} diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index b3c4ed1bf036..2e0bcd911b53 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -41,7 +41,12 @@ #include "esp32c2/rom/uart.h" #include "esp32c2/rom/gpio.h" #include "esp32c2/rom/secure_boot.h" - +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/efuse.h" +#include "esp32c6/rom/crc.h" +#include "esp32c6/rom/uart.h" +#include "esp32c6/rom/gpio.h" +#include "esp32c6/rom/secure_boot.h" #else // CONFIG_IDF_TARGET_* #error "Unsupported IDF_TARGET" #endif diff --git a/components/bootloader_support/src/esp32c6/bootloader_ecdsa.c b/components/bootloader_support/src/esp32c6/bootloader_ecdsa.c new file mode 100644 index 000000000000..d7c5796c4b07 --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_ecdsa.c @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "rom/ecdsa.h" + +#define ROM_FUNC_TYPECAST int(*)(const uint8_t*, const uint8_t*, int, const uint8_t*, uint8_t*) + +extern uint32_t _rom_eco_version; +int (*_rom_ets_ecdsa_verify)(const uint8_t*, const uint8_t*, int, const uint8_t*, uint8_t*); + +/* On ESP32-C6 ECO 0, the ROM interface hasn't exposed ets_ecdsa_verify symbol, so for that we have defined + * the function here and then jump to the absolute address in ROM. + * + * There is a possibility of updating the ROM in the future chip revisions without any major upgrades, + * in that case, the same binary should work as is on the new chip revision. For that, we check the _rom_eco_version + * and if its a newer one, we jump to the new ROM interface. These addresses won't change in the future + * + * ets_ecdsa_verify symbol will be present in the upcoming ROM ECO versions so even though we have defined it here, + * linker will pick the symbol address from rom.ld file + */ +int ets_ecdsa_verify(const uint8_t *key, const uint8_t *sig, ECDSA_CURVE curve_id, const uint8_t *image_digest, uint8_t *verified_digest) +{ + if (_rom_eco_version == 0) { + _rom_ets_ecdsa_verify = (ROM_FUNC_TYPECAST)0x4001a824; + return _rom_ets_ecdsa_verify(key, sig, curve_id, image_digest, verified_digest); + } else { + _rom_ets_ecdsa_verify = (ROM_FUNC_TYPECAST)0x40001490; + return _rom_ets_ecdsa_verify(key, sig, curve_id, image_digest, verified_digest); + } +} diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c new file mode 100644 index 000000000000..1e2b4ce501f7 --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -0,0 +1,181 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_image_format.h" +#include "flash_qio_mode.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" +#include "esp_rom_uart.h" +#include "esp_rom_sys.h" +#include "esp_rom_spiflash.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "soc/assist_debug_reg.h" +#include "esp_cpu.h" +#include "soc/rtc.h" +#include "soc/spi_periph.h" +#include "soc/extmem_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/pcr_reg.h" +#include "esp32c6/rom/efuse.h" +#include "esp32c6/rom/ets_sys.h" +#include "esp32c6/rom/spi_flash.h" +#include "bootloader_common.h" +#include "bootloader_init.h" +#include "bootloader_clock.h" +#include "bootloader_flash_config.h" +#include "bootloader_mem.h" +#include "esp_private/regi2c_ctrl.h" +#include "soc/regi2c_lp_bias.h" +#include "soc/regi2c_bias.h" +#include "bootloader_console.h" +#include "bootloader_flash_priv.h" +#include "bootloader_soc.h" +#include "esp_private/bootloader_flash_internal.h" +#include "esp_efuse.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/clk_tree_ll.h" +#include "soc/lp_wdt_reg.h" +#include "hal/efuse_hal.h" +#include "modem/modem_lpcon_reg.h" + +static const char *TAG = "boot.esp32c6"; + +static void wdt_reset_cpu0_info_enable(void) +{ + REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN); + REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN); + REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN); +} + +static void wdt_reset_info_dump(int cpu) +{ + (void) cpu; + // saved PC was already printed by the ROM bootloader. + // nothing to do here. +} + +static void bootloader_check_wdt_reset(void) +{ + int wdt_rst = 0; + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); + if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 || + rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) { + ESP_LOGW(TAG, "PRO CPU has been reset by WDT."); + wdt_rst = 1; + } + if (wdt_rst) { + // if reset by WDT dump info from trace port + wdt_reset_info_dump(0); + } + wdt_reset_cpu0_info_enable(); +} + +static void bootloader_super_wdt_auto_feed(void) +{ + REG_WRITE(LP_WDT_SWD_WPROTECT_REG, LP_WDT_SWD_WKEY_VALUE); + REG_SET_BIT(LP_WDT_SWD_CONFIG_REG, LP_WDT_SWD_AUTO_FEED_EN); + REG_WRITE(LP_WDT_SWD_WPROTECT_REG, 0); +} + +static inline void bootloader_hardware_init(void) +{ + // In 80MHz flash mode, ROM sets the mspi module clk divider to 2, fix it here +#if CONFIG_ESPTOOLPY_FLASHFREQ_80M && !CONFIG_APP_BUILD_TYPE_RAM + clk_ll_mspi_fast_set_hs_divider(6); + esp_rom_spiflash_config_clk(1, 0); + esp_rom_spiflash_config_clk(1, 1); + esp_rom_spiflash_fix_dummylen(0, 1); + esp_rom_spiflash_fix_dummylen(1, 1); +#endif + + /* Enable analog i2c master clock */ + SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); + SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); +} + +static inline void bootloader_ana_reset_config(void) +{ + //Enable super WDT reset. + bootloader_ana_super_wdt_reset_config(true); + //Enable BOD reset + bootloader_ana_bod_reset_config(true); +} + +esp_err_t bootloader_init(void) +{ + esp_err_t ret = ESP_OK; + + bootloader_hardware_init(); + bootloader_ana_reset_config(); + bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM + // protect memory region + bootloader_init_mem(); + /* check that static RAM is after the stack */ + assert(&_bss_start <= &_bss_end); + assert(&_data_start <= &_data_end); + // clear bss section + bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + + // init eFuse virtual mode (read eFuses to RAM) +#ifdef CONFIG_EFUSE_VIRTUAL + ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); +#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH + esp_efuse_init_virtual_mode_in_ram(); +#endif +#endif + // config clock + bootloader_clock_configure(); + // initialize console, from now on, we can use esp_log + bootloader_console_init(); + /* print 2nd bootloader banner */ + bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { + ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); + return ret; + } +#if !CONFIG_APP_BUILD_TYPE_RAM + // read bootloader header + if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { + return ret; + } + // read chip revision and check if it's compatible to bootloader + if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { + return ret; + } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // initialize spi flash + if ((ret = bootloader_init_spi_flash()) != ESP_OK) { + return ret; + } +#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + + // check whether a WDT reset happend + bootloader_check_wdt_reset(); + // config WDT + bootloader_config_wdt(); + // enable RNG early entropy source + bootloader_enable_random(); + + return ret; +} diff --git a/components/bootloader_support/src/esp32c6/bootloader_sha.c b/components/bootloader_support/src/esp32c6/bootloader_sha.c new file mode 100644 index 000000000000..861b92783bc6 --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_sha.c @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "bootloader_sha.h" +#include +#include +#include +#include + +#include "esp32c6/rom/sha.h" + +static SHA_CTX ctx; + +bootloader_sha256_handle_t bootloader_sha256_start() +{ + // Enable SHA hardware + ets_sha_enable(); + ets_sha_init(&ctx, SHA2_256); + return &ctx; // Meaningless non-NULL value +} + +void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len) +{ + assert(handle != NULL); + /* C6 secure boot key field consists of 1 byte of curve identifier and 64 bytes of ECDSA public key. + * While verifying the signature block, we need to calculate the SHA of this key field which is of 65 bytes. + * ets_sha_update handles it cleanly so we can safely remove the check: + * assert(data_len % 4) == 0 + */ + ets_sha_update(&ctx, data, data_len, false); +} + +void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) +{ + assert(handle != NULL); + + if (digest == NULL) { + bzero(&ctx, sizeof(ctx)); + return; + } + ets_sha_finish(&ctx, digest); +} diff --git a/components/bootloader_support/src/esp32c6/bootloader_soc.c b/components/bootloader_support/src/esp32c6/bootloader_soc.c new file mode 100644 index 000000000000..66358dd3fa0a --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_soc.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "soc/soc.h" +#include "soc/lp_analog_peri_reg.h" + +void bootloader_ana_super_wdt_reset_config(bool enable) +{ + //C6 doesn't support bypass super WDT reset + assert(enable); + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_SUPER_WDT_RST); +} + +void bootloader_ana_bod_reset_config(bool enable) +{ + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_BOD_RST); + + if (enable) { + REG_SET_BIT(LP_ANALOG_PERI_LP_ANA_BOD_MODE1_CNTL_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE1_RESET_ENA); + } else { + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_BOD_MODE1_CNTL_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE1_RESET_ENA); + } +} + +//Not supported but common bootloader calls the function. Do nothing +void bootloader_ana_clock_glitch_reset_config(bool enable) +{ + (void)enable; +} diff --git a/components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c b/components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c new file mode 100644 index 000000000000..cde773a96773 --- /dev/null +++ b/components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_flash_encrypt.h" +#include "esp_secure_boot.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_log.h" +#include "sdkconfig.h" + +static __attribute__((unused)) const char *TAG = "flash_encrypt"; + +esp_err_t esp_flash_encryption_enable_secure_features(void) +{ +#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC + ESP_LOGI(TAG, "Disable UART bootloader encryption..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); +#else + ESP_LOGW(TAG, "Not disabling UART bootloader encryption"); +#endif + +#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE + ESP_LOGI(TAG, "Disable UART bootloader cache..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); +#else + ESP_LOGW(TAG, "Not disabling UART bootloader cache - SECURITY COMPROMISED"); +#endif + +#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG + ESP_LOGI(TAG, "Disable JTAG..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); +#else + ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); +#endif + + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + +#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS) + // This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot + // otherwise the Flash Encryption key cannot be read protected + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); +#endif + +#ifndef CONFIG_SECURE_FLASH_SKIP_WRITE_PROTECTION_CACHE + // Set write-protection for DIS_ICACHE to prevent bricking chip in case it will be set accidentally. + // esp32c6 has DIS_ICACHE. Write-protection bit = 2. + // List of eFuses with the same write protection bit: + // SWAP_UART_SDIO_EN, DIS_ICACHE, DIS_USB_JTAG, DIS_DOWNLOAD_ICACHE, + // DIS_USB_SERIAL_JTAG, DIS_FORCE_DOWNLOAD, DIS_TWAI, JTAG_SEL_ENABLE, + // DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT. + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_DIS_ICACHE); +#endif + + return ESP_OK; +} diff --git a/components/bootloader_support/src/esp32c6/secure_boot_secure_features.c b/components/bootloader_support/src/esp32c6/secure_boot_secure_features.c new file mode 100644 index 000000000000..9ea0f69e4b9c --- /dev/null +++ b/components/bootloader_support/src/esp32c6/secure_boot_secure_features.c @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_flash_encrypt.h" +#include "esp_secure_boot.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_log.h" +#include "sdkconfig.h" + +static __attribute__((unused)) const char *TAG = "secure_boot"; + +esp_err_t esp_secure_boot_enable_secure_features(void) +{ + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + +#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE + ESP_LOGI(TAG, "Enabling Security download mode..."); + esp_err_t err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } +#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + esp_err_t err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } +#else + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); +#endif + +#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG + ESP_LOGI(TAG, "Disable hardware & software JTAG..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); + esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count); +#else + ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); +#endif + +#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE); +#endif + + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN); + +#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS + bool rd_dis_now = true; +#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED + /* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot + when Flash Encryption is being enabled */ + rd_dis_now = esp_flash_encryption_enabled(); +#endif + if (rd_dis_now) { + ESP_LOGI(TAG, "Prevent read disabling of additional efuses..."); + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); + } +#else + ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED"); +#endif + + return ESP_OK; +} diff --git a/components/driver/gpio/rtc_io.c b/components/driver/gpio/rtc_io.c index 0920b0e72957..dc19a4d80d87 100644 --- a/components/driver/gpio/rtc_io.c +++ b/components/driver/gpio/rtc_io.c @@ -177,6 +177,13 @@ esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num) return ESP_OK; } +esp_err_t rtc_gpio_force_hold_en_all(void); + +esp_err_t rtc_gpio_force_hold_all(void) +{ + return rtc_gpio_force_hold_en_all(); +} + esp_err_t rtc_gpio_force_hold_en_all(void) { RTCIO_ENTER_CRITICAL(); diff --git a/components/driver/uart.c b/components/driver/uart.c index 63c98413805f..3dfa3c8818eb 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -19,7 +19,9 @@ #include "hal/gpio_hal.h" #include "hal/clk_tree_ll.h" #include "soc/uart_periph.h" +#if !defined(SOC_ESP32_C6) #include "soc/rtc_cntl_reg.h" +#endif #include "driver/uart.h" #include "driver/gpio.h" #include "driver/uart_select.h" @@ -219,6 +221,11 @@ esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz) freq = 40 * MHZ; break; #endif +#if SOC_UART_SUPPORT_PLL_F80M_CLK + case UART_SCLK_PLL_F80M: + freq = 80 * MHZ; + break; +#endif #if SOC_UART_SUPPORT_REF_TICK case UART_SCLK_REF_TICK: freq = REF_CLK_FREQ; @@ -226,7 +233,11 @@ esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz) #endif #if SOC_UART_SUPPORT_RTC_CLK case UART_SCLK_RTC: +#if CONFIG_IDF_TARGET_ESP32C6 + freq = SOC_CLK_RC_FAST_FREQ_APPROX; +#else freq = RTC_CLK_FREQ; +#endif break; #endif #if SOC_UART_SUPPORT_XTAL_CLK diff --git a/components/efuse/esp32c6/esp_efuse_fields.c b/components/efuse/esp32c6/esp_efuse_fields.c new file mode 100644 index 000000000000..a485a9e0e723 --- /dev/null +++ b/components/efuse/esp32c6/esp_efuse_fields.c @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_efuse.h" +#include "esp_efuse_utility.h" +#include "esp_efuse_table.h" +#include "stdlib.h" +#include "esp_types.h" +#include "esp32c6/rom/efuse.h" +#include "assert.h" +#include "esp_err.h" +#include "esp_log.h" +#include "soc/efuse_periph.h" +#include "sys/param.h" + +static __attribute__((unused)) const char *TAG = "efuse"; + +// Contains functions that provide access to efuse fields which are often used in IDF. + +// Returns chip package from efuse +uint32_t esp_efuse_get_pkg_ver(void) +{ + uint32_t pkg_ver = 0; + esp_efuse_read_field_blob(ESP_EFUSE_PKG_VERSION, &pkg_ver, ESP_EFUSE_PKG_VERSION[0]->bit_count); + return pkg_ver; +} + + +esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme) +{ + int cur_log_scheme = 0; + esp_efuse_read_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &cur_log_scheme, 2); + if (!cur_log_scheme) { // not burned yet + return esp_efuse_write_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &log_scheme, 2); + } else { + return ESP_ERR_INVALID_STATE; + } +} + +esp_err_t esp_efuse_disable_rom_download_mode(void) +{ + return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE); +} + +esp_err_t esp_efuse_enable_rom_secure_download_mode(void) +{ + if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) { + return ESP_ERR_INVALID_STATE; + } + return esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD); +} diff --git a/components/efuse/esp32c6/esp_efuse_rtc_calib.c b/components/efuse/esp32c6/esp_efuse_rtc_calib.c new file mode 100644 index 000000000000..5477b095a49d --- /dev/null +++ b/components/efuse/esp32c6/esp_efuse_rtc_calib.c @@ -0,0 +1,138 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_efuse_rtc_calib.h" +#include "hal/efuse_hal.h" + +/** + * @brief Get the signed value by the raw data that read from eFuse + * @param data The raw data that read from eFuse + * @param sign_bit The index of the sign bit, start from 0 + */ +#define RTC_CALIB_GET_SIGNED_VAL(data, sign_bit) ((data & BIT##sign_bit) ? -(int)(data & ~BIT##sign_bit) : (int)data) + +int esp_efuse_rtc_calib_get_ver(void) +{ + uint32_t cali_version = 0; + uint32_t blk_ver = efuse_hal_blk_version(); + if (blk_ver == 1) { + cali_version = ESP_EFUSE_ADC_CALIB_VER1; + } else if (blk_ver >= 2) { + cali_version = ESP_EFUSE_ADC_CALIB_VER2; + } else { + ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0"); + } + + return cali_version; +} + +uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten) +{ + /* Version validation should be guaranteed in the caller */ + assert(atten >=0 && atten < 4); + (void) adc_unit; + + const esp_efuse_desc_t** init_code_efuse; + if (atten == 0) { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0; + } else if (atten == 1) { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN1; + } else if (atten == 2) { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN2; + } else { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN3; + } + + int init_code_size = esp_efuse_get_field_size(init_code_efuse); + assert(init_code_size == 10); + + uint32_t init_code = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size)); + return init_code + 1600; // version 1 logic +} + +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten) +{ + /* Version validation should be guaranteed in the caller */ + assert(atten < 4); + assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit)); + + const esp_efuse_desc_t** chan_diff_efuse = NULL; + switch (adc_channel) { + case 0: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0; + break; + case 1: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1; + break; + case 2: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2; + break; + case 3: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3; + break; + case 4: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4; + break; + case 5: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5; + break; + default: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6; + break; + } + + int chan_diff_size = esp_efuse_get_field_size(chan_diff_efuse); + assert(chan_diff_size == 4); + uint32_t chan_diff = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(chan_diff_efuse, &chan_diff, chan_diff_size)); + return RTC_CALIB_GET_SIGNED_VAL(chan_diff, 3) * (4 - atten); +} + +esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv) +{ + (void) adc_unit; + const esp_efuse_desc_t** cal_vol_efuse[4] = { + ESP_EFUSE_ADC1_CAL_VOL_ATTEN0, + ESP_EFUSE_ADC1_CAL_VOL_ATTEN1, + ESP_EFUSE_ADC1_CAL_VOL_ATTEN2, + ESP_EFUSE_ADC1_CAL_VOL_ATTEN3, + }; + const uint32_t input_vout_mv[2][4] = { + {400, 550, 750, 1370}, // Calibration V1 coefficients + {750, 1000, 1500, 2800}, // Calibration V2 coefficients + }; + + if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) || + (version > ESP_EFUSE_ADC_CALIB_VER_MAX)) { + return ESP_ERR_INVALID_ARG; + } + if (atten >= 4 || atten < 0) { + return ESP_ERR_INVALID_ARG; + } + + assert(cal_vol_efuse[atten][0]->bit_count == 10); + + uint32_t cal_vol = 0; + esp_err_t ret = esp_efuse_read_field_blob(cal_vol_efuse[atten], &cal_vol, cal_vol_efuse[atten][0]->bit_count); + if (ret != ESP_OK) { + return ret; + } + uint32_t chk_offset = (version == ESP_EFUSE_ADC_CALIB_VER1) ? 1500 : (atten == 2) ? 2900 : 2850; + *out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9); + *out_vol_mv = input_vout_mv[VER2IDX(version)][atten]; + return ESP_OK; +} + +esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal) +{ + // Currently calibration is not supported on ESP32-C6, IDF-5236 + *tsens_cal = 0; + return ESP_OK; +} diff --git a/components/efuse/esp32c6/esp_efuse_table.c b/components/efuse/esp32c6/esp_efuse_table.c new file mode 100644 index 000000000000..8b04686b3092 --- /dev/null +++ b/components/efuse/esp32c6/esp_efuse_table.c @@ -0,0 +1,1670 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_efuse.h" +#include +#include "esp_efuse_table.h" + +// md5_digest_table 0d9c0c6a65ccf2d4a7279ede32b6f797 +// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. +// If you want to change some fields, you need to change esp_efuse_table.csv file +// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. +// To show efuse_table run the command 'show_efuse_table'. + +static const esp_efuse_desc_t WR_DIS[] = { + {EFUSE_BLK0, 0, 32}, // [] Disable programming of individual eFuses, +}; + +static const esp_efuse_desc_t WR_DIS_RD_DIS[] = { + {EFUSE_BLK0, 0, 1}, // [] wr_dis of RD_DIS, +}; + +static const esp_efuse_desc_t WR_DIS_CRYPT_DPA_ENABLE[] = { + {EFUSE_BLK0, 1, 1}, // [] wr_dis of CRYPT_DPA_ENABLE, +}; + +static const esp_efuse_desc_t WR_DIS_SWAP_UART_SDIO_EN[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of SWAP_UART_SDIO_EN, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_ICACHE[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_ICACHE, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_USB_JTAG[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_USB_JTAG, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_DOWNLOAD_ICACHE[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_DOWNLOAD_ICACHE, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_USB_SERIAL_JTAG[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_USB_SERIAL_JTAG, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_FORCE_DOWNLOAD[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_FORCE_DOWNLOAD, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_TWAI[] = { + {EFUSE_BLK0, 2, 1}, // [WR_DIS.DIS_CAN] wr_dis of DIS_TWAI, +}; + +static const esp_efuse_desc_t WR_DIS_JTAG_SEL_ENABLE[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of JTAG_SEL_ENABLE, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_PAD_JTAG[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_PAD_JTAG, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = { + {EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT, +}; + +static const esp_efuse_desc_t WR_DIS_WDT_DELAY_SEL[] = { + {EFUSE_BLK0, 3, 1}, // [] wr_dis of WDT_DELAY_SEL, +}; + +static const esp_efuse_desc_t WR_DIS_SPI_BOOT_CRYPT_CNT[] = { + {EFUSE_BLK0, 4, 1}, // [] wr_dis of SPI_BOOT_CRYPT_CNT, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_KEY_REVOKE0[] = { + {EFUSE_BLK0, 5, 1}, // [] wr_dis of SECURE_BOOT_KEY_REVOKE0, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_KEY_REVOKE1[] = { + {EFUSE_BLK0, 6, 1}, // [] wr_dis of SECURE_BOOT_KEY_REVOKE1, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_KEY_REVOKE2[] = { + {EFUSE_BLK0, 7, 1}, // [] wr_dis of SECURE_BOOT_KEY_REVOKE2, +}; + +static const esp_efuse_desc_t WR_DIS_KEY_PURPOSE_0[] = { + {EFUSE_BLK0, 8, 1}, // [WR_DIS.KEY0_PURPOSE] wr_dis of KEY_PURPOSE_0, +}; + +static const esp_efuse_desc_t WR_DIS_KEY_PURPOSE_1[] = { + {EFUSE_BLK0, 9, 1}, // [WR_DIS.KEY1_PURPOSE] wr_dis of KEY_PURPOSE_1, +}; + +static const esp_efuse_desc_t WR_DIS_KEY_PURPOSE_2[] = { + {EFUSE_BLK0, 10, 1}, // [WR_DIS.KEY2_PURPOSE] wr_dis of KEY_PURPOSE_2, +}; + +static const esp_efuse_desc_t WR_DIS_KEY_PURPOSE_3[] = { + {EFUSE_BLK0, 11, 1}, // [WR_DIS.KEY3_PURPOSE] wr_dis of KEY_PURPOSE_3, +}; + +static const esp_efuse_desc_t WR_DIS_KEY_PURPOSE_4[] = { + {EFUSE_BLK0, 12, 1}, // [WR_DIS.KEY4_PURPOSE] wr_dis of KEY_PURPOSE_4, +}; + +static const esp_efuse_desc_t WR_DIS_KEY_PURPOSE_5[] = { + {EFUSE_BLK0, 13, 1}, // [WR_DIS.KEY5_PURPOSE] wr_dis of KEY_PURPOSE_5, +}; + +static const esp_efuse_desc_t WR_DIS_SEC_DPA_LEVEL[] = { + {EFUSE_BLK0, 14, 1}, // [WR_DIS.DPA_SEC_LEVEL] wr_dis of SEC_DPA_LEVEL, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_EN[] = { + {EFUSE_BLK0, 15, 1}, // [] wr_dis of SECURE_BOOT_EN, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { + {EFUSE_BLK0, 16, 1}, // [] wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE, +}; + +static const esp_efuse_desc_t WR_DIS_SPI_DOWNLOAD_MSPI_DIS[] = { + {EFUSE_BLK0, 17, 1}, // [] wr_dis of SPI_DOWNLOAD_MSPI_DIS, +}; + +static const esp_efuse_desc_t WR_DIS_FLASH_TPUW[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of FLASH_TPUW, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of DIS_DOWNLOAD_MODE, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_DIRECT_BOOT[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of DIS_DIRECT_BOOT, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + {EFUSE_BLK0, 18, 1}, // [WR_DIS.DIS_USB_PRINT] wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT, +}; + +static const esp_efuse_desc_t WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, +}; + +static const esp_efuse_desc_t WR_DIS_ENABLE_SECURITY_DOWNLOAD[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of ENABLE_SECURITY_DOWNLOAD, +}; + +static const esp_efuse_desc_t WR_DIS_UART_PRINT_CONTROL[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of UART_PRINT_CONTROL, +}; + +static const esp_efuse_desc_t WR_DIS_FORCE_SEND_RESUME[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of FORCE_SEND_RESUME, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_VERSION[] = { + {EFUSE_BLK0, 18, 1}, // [] wr_dis of SECURE_VERSION, +}; + +static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE[] = { + {EFUSE_BLK0, 19, 1}, // [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE, +}; + +static const esp_efuse_desc_t WR_DIS_DISABLE_WAFER_VERSION_MAJOR[] = { + {EFUSE_BLK0, 19, 1}, // [] wr_dis of DISABLE_WAFER_VERSION_MAJOR, +}; + +static const esp_efuse_desc_t WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = { + {EFUSE_BLK0, 19, 1}, // [] wr_dis of DISABLE_BLK_VERSION_MAJOR, +}; + +static const esp_efuse_desc_t WR_DIS_BLK1[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of BLOCK1, +}; + +static const esp_efuse_desc_t WR_DIS_MAC[] = { + {EFUSE_BLK0, 20, 1}, // [WR_DIS.MAC_FACTORY] wr_dis of MAC, +}; + +static const esp_efuse_desc_t WR_DIS_MAC_EXT[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of MAC_EXT, +}; + +static const esp_efuse_desc_t WR_DIS_ACTIVE_HP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of ACTIVE_HP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_ACTIVE_LP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of ACTIVE_LP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_LSLP_HP_DBG[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of LSLP_HP_DBG, +}; + +static const esp_efuse_desc_t WR_DIS_LSLP_HP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of LSLP_HP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_DSLP_LP_DBG[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DSLP_LP_DBG, +}; + +static const esp_efuse_desc_t WR_DIS_DSLP_LP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DSLP_LP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_DBIAS_VOL_GAP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DBIAS_VOL_GAP, +}; + +static const esp_efuse_desc_t WR_DIS_WAFER_VERSION_MINOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of WAFER_VERSION_MINOR, +}; + +static const esp_efuse_desc_t WR_DIS_WAFER_VERSION_MAJOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of WAFER_VERSION_MAJOR, +}; + +static const esp_efuse_desc_t WR_DIS_PKG_VERSION[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of PKG_VERSION, +}; + +static const esp_efuse_desc_t WR_DIS_BLK_VERSION_MINOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of BLK_VERSION_MINOR, +}; + +static const esp_efuse_desc_t WR_DIS_BLK_VERSION_MAJOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of BLK_VERSION_MAJOR, +}; + +static const esp_efuse_desc_t WR_DIS_FLASH_CAP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_CAP, +}; + +static const esp_efuse_desc_t WR_DIS_FLASH_TEMP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_TEMP, +}; + +static const esp_efuse_desc_t WR_DIS_FLASH_VENDOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_VENDOR, +}; + +static const esp_efuse_desc_t WR_DIS_SYS_DATA_PART1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of BLOCK2, +}; + +static const esp_efuse_desc_t WR_DIS_OPTIONAL_UNIQUE_ID[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of OPTIONAL_UNIQUE_ID, +}; + +static const esp_efuse_desc_t WR_DIS_TEMP_CALIB[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of TEMP_CALIB, +}; + +static const esp_efuse_desc_t WR_DIS_OCODE[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of OCODE, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH4, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH5, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH6, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_USR_DATA[] = { + {EFUSE_BLK0, 22, 1}, // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA, +}; + +static const esp_efuse_desc_t WR_DIS_CUSTOM_MAC[] = { + {EFUSE_BLK0, 22, 1}, // [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_KEY0[] = { + {EFUSE_BLK0, 23, 1}, // [WR_DIS.KEY0] wr_dis of BLOCK_KEY0, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_KEY1[] = { + {EFUSE_BLK0, 24, 1}, // [WR_DIS.KEY1] wr_dis of BLOCK_KEY1, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_KEY2[] = { + {EFUSE_BLK0, 25, 1}, // [WR_DIS.KEY2] wr_dis of BLOCK_KEY2, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_KEY3[] = { + {EFUSE_BLK0, 26, 1}, // [WR_DIS.KEY3] wr_dis of BLOCK_KEY3, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_KEY4[] = { + {EFUSE_BLK0, 27, 1}, // [WR_DIS.KEY4] wr_dis of BLOCK_KEY4, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_KEY5[] = { + {EFUSE_BLK0, 28, 1}, // [WR_DIS.KEY5] wr_dis of BLOCK_KEY5, +}; + +static const esp_efuse_desc_t WR_DIS_BLOCK_SYS_DATA2[] = { + {EFUSE_BLK0, 29, 1}, // [WR_DIS.SYS_DATA_PART2] wr_dis of BLOCK_SYS_DATA2, +}; + +static const esp_efuse_desc_t WR_DIS_USB_EXCHG_PINS[] = { + {EFUSE_BLK0, 30, 1}, // [] wr_dis of USB_EXCHG_PINS, +}; + +static const esp_efuse_desc_t WR_DIS_VDD_SPI_AS_GPIO[] = { + {EFUSE_BLK0, 30, 1}, // [] wr_dis of VDD_SPI_AS_GPIO, +}; + +static const esp_efuse_desc_t WR_DIS_SOFT_DIS_JTAG[] = { + {EFUSE_BLK0, 31, 1}, // [] wr_dis of SOFT_DIS_JTAG, +}; + +static const esp_efuse_desc_t RD_DIS[] = { + {EFUSE_BLK0, 32, 7}, // [] Disable reading from BlOCK4-10, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_KEY0[] = { + {EFUSE_BLK0, 32, 1}, // [RD_DIS.KEY0] rd_dis of BLOCK_KEY0, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_KEY1[] = { + {EFUSE_BLK0, 33, 1}, // [RD_DIS.KEY1] rd_dis of BLOCK_KEY1, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_KEY2[] = { + {EFUSE_BLK0, 34, 1}, // [RD_DIS.KEY2] rd_dis of BLOCK_KEY2, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_KEY3[] = { + {EFUSE_BLK0, 35, 1}, // [RD_DIS.KEY3] rd_dis of BLOCK_KEY3, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_KEY4[] = { + {EFUSE_BLK0, 36, 1}, // [RD_DIS.KEY4] rd_dis of BLOCK_KEY4, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_KEY5[] = { + {EFUSE_BLK0, 37, 1}, // [RD_DIS.KEY5] rd_dis of BLOCK_KEY5, +}; + +static const esp_efuse_desc_t RD_DIS_BLOCK_SYS_DATA2[] = { + {EFUSE_BLK0, 38, 1}, // [RD_DIS.SYS_DATA_PART2] rd_dis of BLOCK_SYS_DATA2, +}; + +static const esp_efuse_desc_t SWAP_UART_SDIO_EN[] = { + {EFUSE_BLK0, 39, 1}, // [] Represents whether pad of uart and sdio is swapped or not. 1: swapped. 0: not swapped, +}; + +static const esp_efuse_desc_t DIS_ICACHE[] = { + {EFUSE_BLK0, 40, 1}, // [] Represents whether icache is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_USB_JTAG[] = { + {EFUSE_BLK0, 41, 1}, // [] Represents whether the function of usb switch to jtag is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_DOWNLOAD_ICACHE[] = { + {EFUSE_BLK0, 42, 1}, // [] Represents whether icache is disabled or enabled in Download mode. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG[] = { + {EFUSE_BLK0, 43, 1}, // [] Represents whether USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_FORCE_DOWNLOAD[] = { + {EFUSE_BLK0, 44, 1}, // [] Represents whether the function that forces chip into download mode is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t SPI_DOWNLOAD_MSPI_DIS[] = { + {EFUSE_BLK0, 45, 1}, // [] Represents whether SPI0 controller during boot_mode_download is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_TWAI[] = { + {EFUSE_BLK0, 46, 1}, // [DIS_CAN] Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t JTAG_SEL_ENABLE[] = { + {EFUSE_BLK0, 47, 1}, // [] Represents whether the selection between usb_to_jtag and pad_to_jtag through strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 is enabled or disabled. 1: enabled. 0: disabled, +}; + +static const esp_efuse_desc_t SOFT_DIS_JTAG[] = { + {EFUSE_BLK0, 48, 3}, // [] Represents whether JTAG is disabled in soft way. Odd number: disabled. Even number: enabled, +}; + +static const esp_efuse_desc_t DIS_PAD_JTAG[] = { + {EFUSE_BLK0, 51, 1}, // [] Represents whether JTAG is disabled in the hard way(permanently). 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_DOWNLOAD_MANUAL_ENCRYPT[] = { + {EFUSE_BLK0, 52, 1}, // [] Represents whether flash encrypt function is disabled or enabled(except in SPI boot mode). 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t USB_EXCHG_PINS[] = { + {EFUSE_BLK0, 57, 1}, // [] Represents whether the D+ and D- pins is exchanged. 1: exchanged. 0: not exchanged, +}; + +static const esp_efuse_desc_t VDD_SPI_AS_GPIO[] = { + {EFUSE_BLK0, 58, 1}, // [] Represents whether vdd spi pin is functioned as gpio. 1: functioned. 0: not functioned, +}; + +static const esp_efuse_desc_t WDT_DELAY_SEL[] = { + {EFUSE_BLK0, 80, 2}, // [] Represents whether RTC watchdog timeout threshold is selected at startup. 1: selected. 0: not selected, +}; + +static const esp_efuse_desc_t SPI_BOOT_CRYPT_CNT[] = { + {EFUSE_BLK0, 82, 3}, // [] Enables flash encryption when 1 or 3 bits are set and disables otherwise {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"}, +}; + +static const esp_efuse_desc_t SECURE_BOOT_KEY_REVOKE0[] = { + {EFUSE_BLK0, 85, 1}, // [] Revoke 1st secure boot key, +}; + +static const esp_efuse_desc_t SECURE_BOOT_KEY_REVOKE1[] = { + {EFUSE_BLK0, 86, 1}, // [] Revoke 2nd secure boot key, +}; + +static const esp_efuse_desc_t SECURE_BOOT_KEY_REVOKE2[] = { + {EFUSE_BLK0, 87, 1}, // [] Revoke 3rd secure boot key, +}; + +static const esp_efuse_desc_t KEY_PURPOSE_0[] = { + {EFUSE_BLK0, 88, 4}, // [KEY0_PURPOSE] Represents the purpose of Key0, +}; + +static const esp_efuse_desc_t KEY_PURPOSE_1[] = { + {EFUSE_BLK0, 92, 4}, // [KEY1_PURPOSE] Represents the purpose of Key1, +}; + +static const esp_efuse_desc_t KEY_PURPOSE_2[] = { + {EFUSE_BLK0, 96, 4}, // [KEY2_PURPOSE] Represents the purpose of Key2, +}; + +static const esp_efuse_desc_t KEY_PURPOSE_3[] = { + {EFUSE_BLK0, 100, 4}, // [KEY3_PURPOSE] Represents the purpose of Key3, +}; + +static const esp_efuse_desc_t KEY_PURPOSE_4[] = { + {EFUSE_BLK0, 104, 4}, // [KEY4_PURPOSE] Represents the purpose of Key4, +}; + +static const esp_efuse_desc_t KEY_PURPOSE_5[] = { + {EFUSE_BLK0, 108, 4}, // [KEY5_PURPOSE] Represents the purpose of Key5, +}; + +static const esp_efuse_desc_t SEC_DPA_LEVEL[] = { + {EFUSE_BLK0, 112, 2}, // [DPA_SEC_LEVEL] Represents the spa secure level by configuring the clock random divide mode, +}; + +static const esp_efuse_desc_t CRYPT_DPA_ENABLE[] = { + {EFUSE_BLK0, 114, 1}, // [] Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled, +}; + +static const esp_efuse_desc_t SECURE_BOOT_EN[] = { + {EFUSE_BLK0, 116, 1}, // [] Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled, +}; + +static const esp_efuse_desc_t SECURE_BOOT_AGGRESSIVE_REVOKE[] = { + {EFUSE_BLK0, 117, 1}, // [] Represents whether revoking aggressive secure boot is enabled or disabled. 1: enabled. 0: disabled, +}; + +static const esp_efuse_desc_t FLASH_TPUW[] = { + {EFUSE_BLK0, 124, 4}, // [] Represents the flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the programmed value. Otherwise; the waiting time is 2 times the programmed value, +}; + +static const esp_efuse_desc_t DIS_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 128, 1}, // [] Represents whether Download mode is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_DIRECT_BOOT[] = { + {EFUSE_BLK0, 129, 1}, // [] Represents whether direct boot mode is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + {EFUSE_BLK0, 130, 1}, // [DIS_USB_PRINT] Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 132, 1}, // [] Represents whether the USB-Serial-JTAG download function is disabled or enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t ENABLE_SECURITY_DOWNLOAD[] = { + {EFUSE_BLK0, 133, 1}, // [] Represents whether security download is enabled or disabled. 1: enabled. 0: disabled, +}; + +static const esp_efuse_desc_t UART_PRINT_CONTROL[] = { + {EFUSE_BLK0, 134, 2}, // [] Set the default UARTboot message output mode {0: "Enable"; 1: "Enable when GPIO8 is low at reset"; 2: "Enable when GPIO8 is high at reset"; 3: "Disable"}, +}; + +static const esp_efuse_desc_t FORCE_SEND_RESUME[] = { + {EFUSE_BLK0, 141, 1}, // [] Represents whether ROM code is forced to send a resume command during SPI boot. 1: forced. 0:not forced, +}; + +static const esp_efuse_desc_t SECURE_VERSION[] = { + {EFUSE_BLK0, 142, 16}, // [] Represents the version used by ESP-IDF anti-rollback feature, +}; + +static const esp_efuse_desc_t SECURE_BOOT_DISABLE_FAST_WAKE[] = { + {EFUSE_BLK0, 158, 1}, // [] Represents whether FAST VERIFY ON WAKE is disabled or enabled when Secure Boot is enabled. 1: disabled. 0: enabled, +}; + +static const esp_efuse_desc_t DISABLE_WAFER_VERSION_MAJOR[] = { + {EFUSE_BLK0, 160, 1}, // [] Disables check of wafer version major, +}; + +static const esp_efuse_desc_t DISABLE_BLK_VERSION_MAJOR[] = { + {EFUSE_BLK0, 161, 1}, // [] Disables check of blk version major, +}; + +static const esp_efuse_desc_t MAC[] = { + {EFUSE_BLK1, 40, 8}, // [MAC_FACTORY] MAC address, + {EFUSE_BLK1, 32, 8}, // [MAC_FACTORY] MAC address, + {EFUSE_BLK1, 24, 8}, // [MAC_FACTORY] MAC address, + {EFUSE_BLK1, 16, 8}, // [MAC_FACTORY] MAC address, + {EFUSE_BLK1, 8, 8}, // [MAC_FACTORY] MAC address, + {EFUSE_BLK1, 0, 8}, // [MAC_FACTORY] MAC address, +}; + +static const esp_efuse_desc_t MAC_EXT[] = { + {EFUSE_BLK1, 56, 8}, // [] Stores the extended bits of MAC address, + {EFUSE_BLK1, 48, 8}, // [] Stores the extended bits of MAC address, +}; + +static const esp_efuse_desc_t ACTIVE_HP_DBIAS[] = { + {EFUSE_BLK1, 64, 5}, // [] Stores the active hp dbias, +}; + +static const esp_efuse_desc_t ACTIVE_LP_DBIAS[] = { + {EFUSE_BLK1, 69, 5}, // [] Stores the active lp dbias, +}; + +static const esp_efuse_desc_t LSLP_HP_DBG[] = { + {EFUSE_BLK1, 74, 2}, // [] Stores the lslp hp dbg, +}; + +static const esp_efuse_desc_t LSLP_HP_DBIAS[] = { + {EFUSE_BLK1, 76, 4}, // [] Stores the lslp hp dbias, +}; + +static const esp_efuse_desc_t DSLP_LP_DBG[] = { + {EFUSE_BLK1, 80, 3}, // [] Stores the dslp lp dbg, +}; + +static const esp_efuse_desc_t DSLP_LP_DBIAS[] = { + {EFUSE_BLK1, 83, 4}, // [] Stores the dslp lp dbias, +}; + +static const esp_efuse_desc_t DBIAS_VOL_GAP[] = { + {EFUSE_BLK1, 87, 5}, // [] Stores the hp and lp dbias vol gap, +}; + +static const esp_efuse_desc_t WAFER_VERSION_MINOR[] = { + {EFUSE_BLK1, 114, 4}, // [], +}; + +static const esp_efuse_desc_t WAFER_VERSION_MAJOR[] = { + {EFUSE_BLK1, 118, 2}, // [], +}; + +static const esp_efuse_desc_t PKG_VERSION[] = { + {EFUSE_BLK1, 120, 3}, // [] Package version, +}; + +static const esp_efuse_desc_t BLK_VERSION_MINOR[] = { + {EFUSE_BLK1, 123, 3}, // [] BLK_VERSION_MINOR of BLOCK2, +}; + +static const esp_efuse_desc_t BLK_VERSION_MAJOR[] = { + {EFUSE_BLK1, 126, 2}, // [] BLK_VERSION_MAJOR of BLOCK2, +}; + +static const esp_efuse_desc_t FLASH_CAP[] = { + {EFUSE_BLK1, 128, 3}, // [], +}; + +static const esp_efuse_desc_t FLASH_TEMP[] = { + {EFUSE_BLK1, 131, 2}, // [], +}; + +static const esp_efuse_desc_t FLASH_VENDOR[] = { + {EFUSE_BLK1, 133, 3}, // [], +}; + +static const esp_efuse_desc_t OPTIONAL_UNIQUE_ID[] = { + {EFUSE_BLK2, 0, 128}, // [] Optional unique 128-bit ID, +}; + +static const esp_efuse_desc_t TEMP_CALIB[] = { + {EFUSE_BLK2, 128, 9}, // [] Temperature calibration data, +}; + +static const esp_efuse_desc_t OCODE[] = { + {EFUSE_BLK2, 137, 8}, // [] ADC OCode, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0[] = { + {EFUSE_BLK2, 145, 10}, // [] ADC1 init code at atten0, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN1[] = { + {EFUSE_BLK2, 155, 10}, // [] ADC1 init code at atten1, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN2[] = { + {EFUSE_BLK2, 165, 10}, // [] ADC1 init code at atten2, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN3[] = { + {EFUSE_BLK2, 175, 10}, // [] ADC1 init code at atten3, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN0[] = { + {EFUSE_BLK2, 185, 10}, // [] ADC1 calibration voltage at atten0, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN1[] = { + {EFUSE_BLK2, 195, 10}, // [] ADC1 calibration voltage at atten1, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN2[] = { + {EFUSE_BLK2, 205, 10}, // [] ADC1 calibration voltage at atten2, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN3[] = { + {EFUSE_BLK2, 215, 10}, // [] ADC1 calibration voltage at atten3, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH0[] = { + {EFUSE_BLK2, 225, 4}, // [] ADC1 init code at atten0 ch0, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH1[] = { + {EFUSE_BLK2, 229, 4}, // [] ADC1 init code at atten0 ch1, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH2[] = { + {EFUSE_BLK2, 233, 4}, // [] ADC1 init code at atten0 ch2, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH3[] = { + {EFUSE_BLK2, 237, 4}, // [] ADC1 init code at atten0 ch3, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH4[] = { + {EFUSE_BLK2, 241, 4}, // [] ADC1 init code at atten0 ch4, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH5[] = { + {EFUSE_BLK2, 245, 4}, // [] ADC1 init code at atten0 ch5, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH6[] = { + {EFUSE_BLK2, 249, 4}, // [] ADC1 init code at atten0 ch6, +}; + +static const esp_efuse_desc_t USER_DATA[] = { + {EFUSE_BLK3, 0, 256}, // [BLOCK_USR_DATA] User data, +}; + +static const esp_efuse_desc_t USER_DATA_MAC_CUSTOM[] = { + {EFUSE_BLK3, 200, 48}, // [MAC_CUSTOM CUSTOM_MAC] Custom MAC, +}; + +static const esp_efuse_desc_t KEY0[] = { + {EFUSE_BLK4, 0, 256}, // [BLOCK_KEY0] Key0 or user data, +}; + +static const esp_efuse_desc_t KEY1[] = { + {EFUSE_BLK5, 0, 256}, // [BLOCK_KEY1] Key1 or user data, +}; + +static const esp_efuse_desc_t KEY2[] = { + {EFUSE_BLK6, 0, 256}, // [BLOCK_KEY2] Key2 or user data, +}; + +static const esp_efuse_desc_t KEY3[] = { + {EFUSE_BLK7, 0, 256}, // [BLOCK_KEY3] Key3 or user data, +}; + +static const esp_efuse_desc_t KEY4[] = { + {EFUSE_BLK8, 0, 256}, // [BLOCK_KEY4] Key4 or user data, +}; + +static const esp_efuse_desc_t KEY5[] = { + {EFUSE_BLK9, 0, 256}, // [BLOCK_KEY5] Key5 or user data, +}; + +static const esp_efuse_desc_t SYS_DATA_PART2[] = { + {EFUSE_BLK10, 0, 256}, // [BLOCK_SYS_DATA2] System data part 2 (reserved), +}; + + + + + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS[] = { + &WR_DIS[0], // [] Disable programming of individual eFuses + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[] = { + &WR_DIS_RD_DIS[0], // [] wr_dis of RD_DIS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CRYPT_DPA_ENABLE[] = { + &WR_DIS_CRYPT_DPA_ENABLE[0], // [] wr_dis of CRYPT_DPA_ENABLE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SWAP_UART_SDIO_EN[] = { + &WR_DIS_SWAP_UART_SDIO_EN[0], // [] wr_dis of SWAP_UART_SDIO_EN + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_ICACHE[] = { + &WR_DIS_DIS_ICACHE[0], // [] wr_dis of DIS_ICACHE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_JTAG[] = { + &WR_DIS_DIS_USB_JTAG[0], // [] wr_dis of DIS_USB_JTAG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_ICACHE[] = { + &WR_DIS_DIS_DOWNLOAD_ICACHE[0], // [] wr_dis of DIS_DOWNLOAD_ICACHE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG[] = { + &WR_DIS_DIS_USB_SERIAL_JTAG[0], // [] wr_dis of DIS_USB_SERIAL_JTAG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_FORCE_DOWNLOAD[] = { + &WR_DIS_DIS_FORCE_DOWNLOAD[0], // [] wr_dis of DIS_FORCE_DOWNLOAD + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_TWAI[] = { + &WR_DIS_DIS_TWAI[0], // [WR_DIS.DIS_CAN] wr_dis of DIS_TWAI + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_JTAG_SEL_ENABLE[] = { + &WR_DIS_JTAG_SEL_ENABLE[0], // [] wr_dis of JTAG_SEL_ENABLE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_PAD_JTAG[] = { + &WR_DIS_DIS_PAD_JTAG[0], // [] wr_dis of DIS_PAD_JTAG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = { + &WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[0], // [] wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WDT_DELAY_SEL[] = { + &WR_DIS_WDT_DELAY_SEL[0], // [] wr_dis of WDT_DELAY_SEL + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[] = { + &WR_DIS_SPI_BOOT_CRYPT_CNT[0], // [] wr_dis of SPI_BOOT_CRYPT_CNT + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0[] = { + &WR_DIS_SECURE_BOOT_KEY_REVOKE0[0], // [] wr_dis of SECURE_BOOT_KEY_REVOKE0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1[] = { + &WR_DIS_SECURE_BOOT_KEY_REVOKE1[0], // [] wr_dis of SECURE_BOOT_KEY_REVOKE1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2[] = { + &WR_DIS_SECURE_BOOT_KEY_REVOKE2[0], // [] wr_dis of SECURE_BOOT_KEY_REVOKE2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_0[] = { + &WR_DIS_KEY_PURPOSE_0[0], // [WR_DIS.KEY0_PURPOSE] wr_dis of KEY_PURPOSE_0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_1[] = { + &WR_DIS_KEY_PURPOSE_1[0], // [WR_DIS.KEY1_PURPOSE] wr_dis of KEY_PURPOSE_1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_2[] = { + &WR_DIS_KEY_PURPOSE_2[0], // [WR_DIS.KEY2_PURPOSE] wr_dis of KEY_PURPOSE_2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_3[] = { + &WR_DIS_KEY_PURPOSE_3[0], // [WR_DIS.KEY3_PURPOSE] wr_dis of KEY_PURPOSE_3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_4[] = { + &WR_DIS_KEY_PURPOSE_4[0], // [WR_DIS.KEY4_PURPOSE] wr_dis of KEY_PURPOSE_4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_5[] = { + &WR_DIS_KEY_PURPOSE_5[0], // [WR_DIS.KEY5_PURPOSE] wr_dis of KEY_PURPOSE_5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SEC_DPA_LEVEL[] = { + &WR_DIS_SEC_DPA_LEVEL[0], // [WR_DIS.DPA_SEC_LEVEL] wr_dis of SEC_DPA_LEVEL + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[] = { + &WR_DIS_SECURE_BOOT_EN[0], // [] wr_dis of SECURE_BOOT_EN + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { + &WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[0], // [] wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[] = { + &WR_DIS_SPI_DOWNLOAD_MSPI_DIS[0], // [] wr_dis of SPI_DOWNLOAD_MSPI_DIS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TPUW[] = { + &WR_DIS_FLASH_TPUW[0], // [] wr_dis of FLASH_TPUW + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MODE[] = { + &WR_DIS_DIS_DOWNLOAD_MODE[0], // [] wr_dis of DIS_DOWNLOAD_MODE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DIRECT_BOOT[] = { + &WR_DIS_DIS_DIRECT_BOOT[0], // [] wr_dis of DIS_DIRECT_BOOT + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + &WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT[0], // [WR_DIS.DIS_USB_PRINT] wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + &WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[0], // [] wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ENABLE_SECURITY_DOWNLOAD[] = { + &WR_DIS_ENABLE_SECURITY_DOWNLOAD[0], // [] wr_dis of ENABLE_SECURITY_DOWNLOAD + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_UART_PRINT_CONTROL[] = { + &WR_DIS_UART_PRINT_CONTROL[0], // [] wr_dis of UART_PRINT_CONTROL + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FORCE_SEND_RESUME[] = { + &WR_DIS_FORCE_SEND_RESUME[0], // [] wr_dis of FORCE_SEND_RESUME + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_VERSION[] = { + &WR_DIS_SECURE_VERSION[0], // [] wr_dis of SECURE_VERSION + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE[] = { + &WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE[0], // [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_WAFER_VERSION_MAJOR[] = { + &WR_DIS_DISABLE_WAFER_VERSION_MAJOR[0], // [] wr_dis of DISABLE_WAFER_VERSION_MAJOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = { + &WR_DIS_DISABLE_BLK_VERSION_MAJOR[0], // [] wr_dis of DISABLE_BLK_VERSION_MAJOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[] = { + &WR_DIS_BLK1[0], // [] wr_dis of BLOCK1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[] = { + &WR_DIS_MAC[0], // [WR_DIS.MAC_FACTORY] wr_dis of MAC + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[] = { + &WR_DIS_MAC_EXT[0], // [] wr_dis of MAC_EXT + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_HP_DBIAS[] = { + &WR_DIS_ACTIVE_HP_DBIAS[0], // [] wr_dis of ACTIVE_HP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_LP_DBIAS[] = { + &WR_DIS_ACTIVE_LP_DBIAS[0], // [] wr_dis of ACTIVE_LP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBG[] = { + &WR_DIS_LSLP_HP_DBG[0], // [] wr_dis of LSLP_HP_DBG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBIAS[] = { + &WR_DIS_LSLP_HP_DBIAS[0], // [] wr_dis of LSLP_HP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBG[] = { + &WR_DIS_DSLP_LP_DBG[0], // [] wr_dis of DSLP_LP_DBG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBIAS[] = { + &WR_DIS_DSLP_LP_DBIAS[0], // [] wr_dis of DSLP_LP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DBIAS_VOL_GAP[] = { + &WR_DIS_DBIAS_VOL_GAP[0], // [] wr_dis of DBIAS_VOL_GAP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[] = { + &WR_DIS_WAFER_VERSION_MINOR[0], // [] wr_dis of WAFER_VERSION_MINOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MAJOR[] = { + &WR_DIS_WAFER_VERSION_MAJOR[0], // [] wr_dis of WAFER_VERSION_MAJOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PKG_VERSION[] = { + &WR_DIS_PKG_VERSION[0], // [] wr_dis of PKG_VERSION + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[] = { + &WR_DIS_BLK_VERSION_MINOR[0], // [] wr_dis of BLK_VERSION_MINOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MAJOR[] = { + &WR_DIS_BLK_VERSION_MAJOR[0], // [] wr_dis of BLK_VERSION_MAJOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CAP[] = { + &WR_DIS_FLASH_CAP[0], // [] wr_dis of FLASH_CAP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TEMP[] = { + &WR_DIS_FLASH_TEMP[0], // [] wr_dis of FLASH_TEMP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[] = { + &WR_DIS_FLASH_VENDOR[0], // [] wr_dis of FLASH_VENDOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[] = { + &WR_DIS_SYS_DATA_PART1[0], // [] wr_dis of BLOCK2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[] = { + &WR_DIS_OPTIONAL_UNIQUE_ID[0], // [] wr_dis of OPTIONAL_UNIQUE_ID + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[] = { + &WR_DIS_TEMP_CALIB[0], // [] wr_dis of TEMP_CALIB + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OCODE[] = { + &WR_DIS_OCODE[0], // [] wr_dis of OCODE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN1[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN1[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN2[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN2[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN3[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN3[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN0[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN0[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN1[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN1[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN2[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN2[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN3[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN3[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH6 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[] = { + &WR_DIS_BLOCK_USR_DATA[0], // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[] = { + &WR_DIS_CUSTOM_MAC[0], // [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY0[] = { + &WR_DIS_BLOCK_KEY0[0], // [WR_DIS.KEY0] wr_dis of BLOCK_KEY0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY1[] = { + &WR_DIS_BLOCK_KEY1[0], // [WR_DIS.KEY1] wr_dis of BLOCK_KEY1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY2[] = { + &WR_DIS_BLOCK_KEY2[0], // [WR_DIS.KEY2] wr_dis of BLOCK_KEY2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY3[] = { + &WR_DIS_BLOCK_KEY3[0], // [WR_DIS.KEY3] wr_dis of BLOCK_KEY3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY4[] = { + &WR_DIS_BLOCK_KEY4[0], // [WR_DIS.KEY4] wr_dis of BLOCK_KEY4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY5[] = { + &WR_DIS_BLOCK_KEY5[0], // [WR_DIS.KEY5] wr_dis of BLOCK_KEY5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA2[] = { + &WR_DIS_BLOCK_SYS_DATA2[0], // [WR_DIS.SYS_DATA_PART2] wr_dis of BLOCK_SYS_DATA2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_USB_EXCHG_PINS[] = { + &WR_DIS_USB_EXCHG_PINS[0], // [] wr_dis of USB_EXCHG_PINS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_VDD_SPI_AS_GPIO[] = { + &WR_DIS_VDD_SPI_AS_GPIO[0], // [] wr_dis of VDD_SPI_AS_GPIO + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SOFT_DIS_JTAG[] = { + &WR_DIS_SOFT_DIS_JTAG[0], // [] wr_dis of SOFT_DIS_JTAG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[] = { + &RD_DIS[0], // [] Disable reading from BlOCK4-10 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY0[] = { + &RD_DIS_BLOCK_KEY0[0], // [RD_DIS.KEY0] rd_dis of BLOCK_KEY0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY1[] = { + &RD_DIS_BLOCK_KEY1[0], // [RD_DIS.KEY1] rd_dis of BLOCK_KEY1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY2[] = { + &RD_DIS_BLOCK_KEY2[0], // [RD_DIS.KEY2] rd_dis of BLOCK_KEY2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY3[] = { + &RD_DIS_BLOCK_KEY3[0], // [RD_DIS.KEY3] rd_dis of BLOCK_KEY3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY4[] = { + &RD_DIS_BLOCK_KEY4[0], // [RD_DIS.KEY4] rd_dis of BLOCK_KEY4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY5[] = { + &RD_DIS_BLOCK_KEY5[0], // [RD_DIS.KEY5] rd_dis of BLOCK_KEY5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_SYS_DATA2[] = { + &RD_DIS_BLOCK_SYS_DATA2[0], // [RD_DIS.SYS_DATA_PART2] rd_dis of BLOCK_SYS_DATA2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SWAP_UART_SDIO_EN[] = { + &SWAP_UART_SDIO_EN[0], // [] Represents whether pad of uart and sdio is swapped or not. 1: swapped. 0: not swapped + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_ICACHE[] = { + &DIS_ICACHE[0], // [] Represents whether icache is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[] = { + &DIS_USB_JTAG[0], // [] Represents whether the function of usb switch to jtag is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[] = { + &DIS_DOWNLOAD_ICACHE[0], // [] Represents whether icache is disabled or enabled in Download mode. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG[] = { + &DIS_USB_SERIAL_JTAG[0], // [] Represents whether USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[] = { + &DIS_FORCE_DOWNLOAD[0], // [] Represents whether the function that forces chip into download mode is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS[] = { + &SPI_DOWNLOAD_MSPI_DIS[0], // [] Represents whether SPI0 controller during boot_mode_download is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_TWAI[] = { + &DIS_TWAI[0], // [DIS_CAN] Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[] = { + &JTAG_SEL_ENABLE[0], // [] Represents whether the selection between usb_to_jtag and pad_to_jtag through strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 is enabled or disabled. 1: enabled. 0: disabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[] = { + &SOFT_DIS_JTAG[0], // [] Represents whether JTAG is disabled in soft way. Odd number: disabled. Even number: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[] = { + &DIS_PAD_JTAG[0], // [] Represents whether JTAG is disabled in the hard way(permanently). 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = { + &DIS_DOWNLOAD_MANUAL_ENCRYPT[0], // [] Represents whether flash encrypt function is disabled or enabled(except in SPI boot mode). 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_USB_EXCHG_PINS[] = { + &USB_EXCHG_PINS[0], // [] Represents whether the D+ and D- pins is exchanged. 1: exchanged. 0: not exchanged + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_AS_GPIO[] = { + &VDD_SPI_AS_GPIO[0], // [] Represents whether vdd spi pin is functioned as gpio. 1: functioned. 0: not functioned + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[] = { + &WDT_DELAY_SEL[0], // [] Represents whether RTC watchdog timeout threshold is selected at startup. 1: selected. 0: not selected + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_CRYPT_CNT[] = { + &SPI_BOOT_CRYPT_CNT[0], // [] Enables flash encryption when 1 or 3 bits are set and disables otherwise {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0[] = { + &SECURE_BOOT_KEY_REVOKE0[0], // [] Revoke 1st secure boot key + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1[] = { + &SECURE_BOOT_KEY_REVOKE1[0], // [] Revoke 2nd secure boot key + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2[] = { + &SECURE_BOOT_KEY_REVOKE2[0], // [] Revoke 3rd secure boot key + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_0[] = { + &KEY_PURPOSE_0[0], // [KEY0_PURPOSE] Represents the purpose of Key0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_1[] = { + &KEY_PURPOSE_1[0], // [KEY1_PURPOSE] Represents the purpose of Key1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_2[] = { + &KEY_PURPOSE_2[0], // [KEY2_PURPOSE] Represents the purpose of Key2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_3[] = { + &KEY_PURPOSE_3[0], // [KEY3_PURPOSE] Represents the purpose of Key3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_4[] = { + &KEY_PURPOSE_4[0], // [KEY4_PURPOSE] Represents the purpose of Key4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_5[] = { + &KEY_PURPOSE_5[0], // [KEY5_PURPOSE] Represents the purpose of Key5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SEC_DPA_LEVEL[] = { + &SEC_DPA_LEVEL[0], // [DPA_SEC_LEVEL] Represents the spa secure level by configuring the clock random divide mode + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_CRYPT_DPA_ENABLE[] = { + &CRYPT_DPA_ENABLE[0], // [] Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[] = { + &SECURE_BOOT_EN[0], // [] Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { + &SECURE_BOOT_AGGRESSIVE_REVOKE[0], // [] Represents whether revoking aggressive secure boot is enabled or disabled. 1: enabled. 0: disabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[] = { + &FLASH_TPUW[0], // [] Represents the flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the programmed value. Otherwise; the waiting time is 2 times the programmed value + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[] = { + &DIS_DOWNLOAD_MODE[0], // [] Represents whether Download mode is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[] = { + &DIS_DIRECT_BOOT[0], // [] Represents whether direct boot mode is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + &DIS_USB_SERIAL_JTAG_ROM_PRINT[0], // [DIS_USB_PRINT] Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + &DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[0], // [] Represents whether the USB-Serial-JTAG download function is disabled or enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[] = { + &ENABLE_SECURITY_DOWNLOAD[0], // [] Represents whether security download is enabled or disabled. 1: enabled. 0: disabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[] = { + &UART_PRINT_CONTROL[0], // [] Set the default UARTboot message output mode {0: "Enable"; 1: "Enable when GPIO8 is low at reset"; 2: "Enable when GPIO8 is high at reset"; 3: "Disable"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[] = { + &FORCE_SEND_RESUME[0], // [] Represents whether ROM code is forced to send a resume command during SPI boot. 1: forced. 0:not forced + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[] = { + &SECURE_VERSION[0], // [] Represents the version used by ESP-IDF anti-rollback feature + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_DISABLE_FAST_WAKE[] = { + &SECURE_BOOT_DISABLE_FAST_WAKE[0], // [] Represents whether FAST VERIFY ON WAKE is disabled or enabled when Secure Boot is enabled. 1: disabled. 0: enabled + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DISABLE_WAFER_VERSION_MAJOR[] = { + &DISABLE_WAFER_VERSION_MAJOR[0], // [] Disables check of wafer version major + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[] = { + &DISABLE_BLK_VERSION_MAJOR[0], // [] Disables check of blk version major + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_MAC[] = { + &MAC[0], // [MAC_FACTORY] MAC address + &MAC[1], // [MAC_FACTORY] MAC address + &MAC[2], // [MAC_FACTORY] MAC address + &MAC[3], // [MAC_FACTORY] MAC address + &MAC[4], // [MAC_FACTORY] MAC address + &MAC[5], // [MAC_FACTORY] MAC address + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[] = { + &MAC_EXT[0], // [] Stores the extended bits of MAC address + &MAC_EXT[1], // [] Stores the extended bits of MAC address + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_HP_DBIAS[] = { + &ACTIVE_HP_DBIAS[0], // [] Stores the active hp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_LP_DBIAS[] = { + &ACTIVE_LP_DBIAS[0], // [] Stores the active lp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBG[] = { + &LSLP_HP_DBG[0], // [] Stores the lslp hp dbg + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBIAS[] = { + &LSLP_HP_DBIAS[0], // [] Stores the lslp hp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBG[] = { + &DSLP_LP_DBG[0], // [] Stores the dslp lp dbg + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBIAS[] = { + &DSLP_LP_DBIAS[0], // [] Stores the dslp lp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DBIAS_VOL_GAP[] = { + &DBIAS_VOL_GAP[0], // [] Stores the hp and lp dbias vol gap + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[] = { + &WAFER_VERSION_MINOR[0], // [] + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[] = { + &WAFER_VERSION_MAJOR[0], // [] + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[] = { + &PKG_VERSION[0], // [] Package version + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[] = { + &BLK_VERSION_MINOR[0], // [] BLK_VERSION_MINOR of BLOCK2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[] = { + &BLK_VERSION_MAJOR[0], // [] BLK_VERSION_MAJOR of BLOCK2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[] = { + &FLASH_CAP[0], // [] + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FLASH_TEMP[] = { + &FLASH_TEMP[0], // [] + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[] = { + &FLASH_VENDOR[0], // [] + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[] = { + &OPTIONAL_UNIQUE_ID[0], // [] Optional unique 128-bit ID + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[] = { + &TEMP_CALIB[0], // [] Temperature calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_OCODE[] = { + &OCODE[0], // [] ADC OCode + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[] = { + &ADC1_INIT_CODE_ATTEN0[0], // [] ADC1 init code at atten0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[] = { + &ADC1_INIT_CODE_ATTEN1[0], // [] ADC1 init code at atten1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[] = { + &ADC1_INIT_CODE_ATTEN2[0], // [] ADC1 init code at atten2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[] = { + &ADC1_INIT_CODE_ATTEN3[0], // [] ADC1 init code at atten3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[] = { + &ADC1_CAL_VOL_ATTEN0[0], // [] ADC1 calibration voltage at atten0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN1[] = { + &ADC1_CAL_VOL_ATTEN1[0], // [] ADC1 calibration voltage at atten1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[] = { + &ADC1_CAL_VOL_ATTEN2[0], // [] ADC1 calibration voltage at atten2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[] = { + &ADC1_CAL_VOL_ATTEN3[0], // [] ADC1 calibration voltage at atten3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0[] = { + &ADC1_INIT_CODE_ATTEN0_CH0[0], // [] ADC1 init code at atten0 ch0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1[] = { + &ADC1_INIT_CODE_ATTEN0_CH1[0], // [] ADC1 init code at atten0 ch1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2[] = { + &ADC1_INIT_CODE_ATTEN0_CH2[0], // [] ADC1 init code at atten0 ch2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3[] = { + &ADC1_INIT_CODE_ATTEN0_CH3[0], // [] ADC1 init code at atten0 ch3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4[] = { + &ADC1_INIT_CODE_ATTEN0_CH4[0], // [] ADC1 init code at atten0 ch4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5[] = { + &ADC1_INIT_CODE_ATTEN0_CH5[0], // [] ADC1 init code at atten0 ch5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6[] = { + &ADC1_INIT_CODE_ATTEN0_CH6[0], // [] ADC1 init code at atten0 ch6 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[] = { + &USER_DATA[0], // [BLOCK_USR_DATA] User data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[] = { + &USER_DATA_MAC_CUSTOM[0], // [MAC_CUSTOM CUSTOM_MAC] Custom MAC + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY0[] = { + &KEY0[0], // [BLOCK_KEY0] Key0 or user data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY1[] = { + &KEY1[0], // [BLOCK_KEY1] Key1 or user data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY2[] = { + &KEY2[0], // [BLOCK_KEY2] Key2 or user data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY3[] = { + &KEY3[0], // [BLOCK_KEY3] Key3 or user data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY4[] = { + &KEY4[0], // [BLOCK_KEY4] Key4 or user data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_KEY5[] = { + &KEY5[0], // [BLOCK_KEY5] Key5 or user data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART2[] = { + &SYS_DATA_PART2[0], // [BLOCK_SYS_DATA2] System data part 2 (reserved) + NULL +}; diff --git a/components/efuse/esp32c6/esp_efuse_table.csv b/components/efuse/esp32c6/esp_efuse_table.csv new file mode 100644 index 000000000000..7f0f52ec395f --- /dev/null +++ b/components/efuse/esp32c6/esp_efuse_table.csv @@ -0,0 +1,201 @@ + +# field_name, | efuse_block, | bit_start, | bit_count, |comment # +# | (EFUSE_BLK0 | (0..255) | (1-256) | # +# | EFUSE_BLK1 | | | # +# | ...) | | | # +########################################################################## +# !!!!!!!!!!! # +# After editing this file, run the command manually "idf.py efuse-common-table" +# this will generate new source files, next rebuild all the sources. +# !!!!!!!!!!! # + +# This file was generated by regtools.py based on the efuses.yaml file with the version: df46b69f0ed3913114ba53d3a0b2b843 + +WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses +WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS +WR_DIS.CRYPT_DPA_ENABLE, EFUSE_BLK0, 1, 1, [] wr_dis of CRYPT_DPA_ENABLE +WR_DIS.SWAP_UART_SDIO_EN, EFUSE_BLK0, 2, 1, [] wr_dis of SWAP_UART_SDIO_EN +WR_DIS.DIS_ICACHE, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_ICACHE +WR_DIS.DIS_USB_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_USB_JTAG +WR_DIS.DIS_DOWNLOAD_ICACHE, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_DOWNLOAD_ICACHE +WR_DIS.DIS_USB_SERIAL_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_USB_SERIAL_JTAG +WR_DIS.DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_FORCE_DOWNLOAD +WR_DIS.DIS_TWAI, EFUSE_BLK0, 2, 1, [WR_DIS.DIS_CAN] wr_dis of DIS_TWAI +WR_DIS.JTAG_SEL_ENABLE, EFUSE_BLK0, 2, 1, [] wr_dis of JTAG_SEL_ENABLE +WR_DIS.DIS_PAD_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_PAD_JTAG +WR_DIS.DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT +WR_DIS.WDT_DELAY_SEL, EFUSE_BLK0, 3, 1, [] wr_dis of WDT_DELAY_SEL +WR_DIS.SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 4, 1, [] wr_dis of SPI_BOOT_CRYPT_CNT +WR_DIS.SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 5, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE0 +WR_DIS.SECURE_BOOT_KEY_REVOKE1, EFUSE_BLK0, 6, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE1 +WR_DIS.SECURE_BOOT_KEY_REVOKE2, EFUSE_BLK0, 7, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE2 +WR_DIS.KEY_PURPOSE_0, EFUSE_BLK0, 8, 1, [WR_DIS.KEY0_PURPOSE] wr_dis of KEY_PURPOSE_0 +WR_DIS.KEY_PURPOSE_1, EFUSE_BLK0, 9, 1, [WR_DIS.KEY1_PURPOSE] wr_dis of KEY_PURPOSE_1 +WR_DIS.KEY_PURPOSE_2, EFUSE_BLK0, 10, 1, [WR_DIS.KEY2_PURPOSE] wr_dis of KEY_PURPOSE_2 +WR_DIS.KEY_PURPOSE_3, EFUSE_BLK0, 11, 1, [WR_DIS.KEY3_PURPOSE] wr_dis of KEY_PURPOSE_3 +WR_DIS.KEY_PURPOSE_4, EFUSE_BLK0, 12, 1, [WR_DIS.KEY4_PURPOSE] wr_dis of KEY_PURPOSE_4 +WR_DIS.KEY_PURPOSE_5, EFUSE_BLK0, 13, 1, [WR_DIS.KEY5_PURPOSE] wr_dis of KEY_PURPOSE_5 +WR_DIS.SEC_DPA_LEVEL, EFUSE_BLK0, 14, 1, [WR_DIS.DPA_SEC_LEVEL] wr_dis of SEC_DPA_LEVEL +WR_DIS.SECURE_BOOT_EN, EFUSE_BLK0, 15, 1, [] wr_dis of SECURE_BOOT_EN +WR_DIS.SECURE_BOOT_AGGRESSIVE_REVOKE, EFUSE_BLK0, 16, 1, [] wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE +WR_DIS.SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 17, 1, [] wr_dis of SPI_DOWNLOAD_MSPI_DIS +WR_DIS.FLASH_TPUW, EFUSE_BLK0, 18, 1, [] wr_dis of FLASH_TPUW +WR_DIS.DIS_DOWNLOAD_MODE, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_DOWNLOAD_MODE +WR_DIS.DIS_DIRECT_BOOT, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_DIRECT_BOOT +WR_DIS.DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 18, 1, [WR_DIS.DIS_USB_PRINT] wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT +WR_DIS.DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE +WR_DIS.ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 18, 1, [] wr_dis of ENABLE_SECURITY_DOWNLOAD +WR_DIS.UART_PRINT_CONTROL, EFUSE_BLK0, 18, 1, [] wr_dis of UART_PRINT_CONTROL +WR_DIS.FORCE_SEND_RESUME, EFUSE_BLK0, 18, 1, [] wr_dis of FORCE_SEND_RESUME +WR_DIS.SECURE_VERSION, EFUSE_BLK0, 18, 1, [] wr_dis of SECURE_VERSION +WR_DIS.SECURE_BOOT_DISABLE_FAST_WAKE, EFUSE_BLK0, 19, 1, [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE +WR_DIS.DISABLE_WAFER_VERSION_MAJOR, EFUSE_BLK0, 19, 1, [] wr_dis of DISABLE_WAFER_VERSION_MAJOR +WR_DIS.DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK0, 19, 1, [] wr_dis of DISABLE_BLK_VERSION_MAJOR +WR_DIS.BLK1, EFUSE_BLK0, 20, 1, [] wr_dis of BLOCK1 +WR_DIS.MAC, EFUSE_BLK0, 20, 1, [WR_DIS.MAC_FACTORY] wr_dis of MAC +WR_DIS.MAC_EXT, EFUSE_BLK0, 20, 1, [] wr_dis of MAC_EXT +WR_DIS.ACTIVE_HP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of ACTIVE_HP_DBIAS +WR_DIS.ACTIVE_LP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of ACTIVE_LP_DBIAS +WR_DIS.LSLP_HP_DBG, EFUSE_BLK0, 20, 1, [] wr_dis of LSLP_HP_DBG +WR_DIS.LSLP_HP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of LSLP_HP_DBIAS +WR_DIS.DSLP_LP_DBG, EFUSE_BLK0, 20, 1, [] wr_dis of DSLP_LP_DBG +WR_DIS.DSLP_LP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of DSLP_LP_DBIAS +WR_DIS.DBIAS_VOL_GAP, EFUSE_BLK0, 20, 1, [] wr_dis of DBIAS_VOL_GAP +WR_DIS.WAFER_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MINOR +WR_DIS.WAFER_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MAJOR +WR_DIS.PKG_VERSION, EFUSE_BLK0, 20, 1, [] wr_dis of PKG_VERSION +WR_DIS.BLK_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of BLK_VERSION_MINOR +WR_DIS.BLK_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of BLK_VERSION_MAJOR +WR_DIS.FLASH_CAP, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_CAP +WR_DIS.FLASH_TEMP, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_TEMP +WR_DIS.FLASH_VENDOR, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_VENDOR +WR_DIS.SYS_DATA_PART1, EFUSE_BLK0, 21, 1, [] wr_dis of BLOCK2 +WR_DIS.OPTIONAL_UNIQUE_ID, EFUSE_BLK0, 21, 1, [] wr_dis of OPTIONAL_UNIQUE_ID +WR_DIS.TEMP_CALIB, EFUSE_BLK0, 21, 1, [] wr_dis of TEMP_CALIB +WR_DIS.OCODE, EFUSE_BLK0, 21, 1, [] wr_dis of OCODE +WR_DIS.ADC1_INIT_CODE_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0 +WR_DIS.ADC1_INIT_CODE_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN1 +WR_DIS.ADC1_INIT_CODE_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN2 +WR_DIS.ADC1_INIT_CODE_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN3 +WR_DIS.ADC1_CAL_VOL_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN0 +WR_DIS.ADC1_CAL_VOL_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN1 +WR_DIS.ADC1_CAL_VOL_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN2 +WR_DIS.ADC1_CAL_VOL_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN3 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH0 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH1 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH2 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH3 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH4, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH4 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH5, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH5 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH6, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH6 +WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA +WR_DIS.CUSTOM_MAC, EFUSE_BLK0, 22, 1, [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC +WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0 +WR_DIS.BLOCK_KEY1, EFUSE_BLK0, 24, 1, [WR_DIS.KEY1] wr_dis of BLOCK_KEY1 +WR_DIS.BLOCK_KEY2, EFUSE_BLK0, 25, 1, [WR_DIS.KEY2] wr_dis of BLOCK_KEY2 +WR_DIS.BLOCK_KEY3, EFUSE_BLK0, 26, 1, [WR_DIS.KEY3] wr_dis of BLOCK_KEY3 +WR_DIS.BLOCK_KEY4, EFUSE_BLK0, 27, 1, [WR_DIS.KEY4] wr_dis of BLOCK_KEY4 +WR_DIS.BLOCK_KEY5, EFUSE_BLK0, 28, 1, [WR_DIS.KEY5] wr_dis of BLOCK_KEY5 +WR_DIS.BLOCK_SYS_DATA2, EFUSE_BLK0, 29, 1, [WR_DIS.SYS_DATA_PART2] wr_dis of BLOCK_SYS_DATA2 +WR_DIS.USB_EXCHG_PINS, EFUSE_BLK0, 30, 1, [] wr_dis of USB_EXCHG_PINS +WR_DIS.VDD_SPI_AS_GPIO, EFUSE_BLK0, 30, 1, [] wr_dis of VDD_SPI_AS_GPIO +WR_DIS.SOFT_DIS_JTAG, EFUSE_BLK0, 31, 1, [] wr_dis of SOFT_DIS_JTAG +RD_DIS, EFUSE_BLK0, 32, 7, [] Disable reading from BlOCK4-10 +RD_DIS.BLOCK_KEY0, EFUSE_BLK0, 32, 1, [RD_DIS.KEY0] rd_dis of BLOCK_KEY0 +RD_DIS.BLOCK_KEY1, EFUSE_BLK0, 33, 1, [RD_DIS.KEY1] rd_dis of BLOCK_KEY1 +RD_DIS.BLOCK_KEY2, EFUSE_BLK0, 34, 1, [RD_DIS.KEY2] rd_dis of BLOCK_KEY2 +RD_DIS.BLOCK_KEY3, EFUSE_BLK0, 35, 1, [RD_DIS.KEY3] rd_dis of BLOCK_KEY3 +RD_DIS.BLOCK_KEY4, EFUSE_BLK0, 36, 1, [RD_DIS.KEY4] rd_dis of BLOCK_KEY4 +RD_DIS.BLOCK_KEY5, EFUSE_BLK0, 37, 1, [RD_DIS.KEY5] rd_dis of BLOCK_KEY5 +RD_DIS.BLOCK_SYS_DATA2, EFUSE_BLK0, 38, 1, [RD_DIS.SYS_DATA_PART2] rd_dis of BLOCK_SYS_DATA2 +SWAP_UART_SDIO_EN, EFUSE_BLK0, 39, 1, [] Represents whether pad of uart and sdio is swapped or not. 1: swapped. 0: not swapped +DIS_ICACHE, EFUSE_BLK0, 40, 1, [] Represents whether icache is disabled or enabled. 1: disabled. 0: enabled +DIS_USB_JTAG, EFUSE_BLK0, 41, 1, [] Represents whether the function of usb switch to jtag is disabled or enabled. 1: disabled. 0: enabled +DIS_DOWNLOAD_ICACHE, EFUSE_BLK0, 42, 1, [] Represents whether icache is disabled or enabled in Download mode. 1: disabled. 0: enabled +DIS_USB_SERIAL_JTAG, EFUSE_BLK0, 43, 1, [] Represents whether USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled +DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 44, 1, [] Represents whether the function that forces chip into download mode is disabled or enabled. 1: disabled. 0: enabled +SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 45, 1, [] Represents whether SPI0 controller during boot_mode_download is disabled or enabled. 1: disabled. 0: enabled +DIS_TWAI, EFUSE_BLK0, 46, 1, [DIS_CAN] Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled +JTAG_SEL_ENABLE, EFUSE_BLK0, 47, 1, [] Represents whether the selection between usb_to_jtag and pad_to_jtag through strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 is enabled or disabled. 1: enabled. 0: disabled +SOFT_DIS_JTAG, EFUSE_BLK0, 48, 3, [] Represents whether JTAG is disabled in soft way. Odd number: disabled. Even number: enabled +DIS_PAD_JTAG, EFUSE_BLK0, 51, 1, [] Represents whether JTAG is disabled in the hard way(permanently). 1: disabled. 0: enabled +DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 52, 1, [] Represents whether flash encrypt function is disabled or enabled(except in SPI boot mode). 1: disabled. 0: enabled +USB_EXCHG_PINS, EFUSE_BLK0, 57, 1, [] Represents whether the D+ and D- pins is exchanged. 1: exchanged. 0: not exchanged +VDD_SPI_AS_GPIO, EFUSE_BLK0, 58, 1, [] Represents whether vdd spi pin is functioned as gpio. 1: functioned. 0: not functioned +WDT_DELAY_SEL, EFUSE_BLK0, 80, 2, [] Represents whether RTC watchdog timeout threshold is selected at startup. 1: selected. 0: not selected +SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 82, 3, [] Enables flash encryption when 1 or 3 bits are set and disables otherwise {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"} +SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 85, 1, [] Revoke 1st secure boot key +SECURE_BOOT_KEY_REVOKE1, EFUSE_BLK0, 86, 1, [] Revoke 2nd secure boot key +SECURE_BOOT_KEY_REVOKE2, EFUSE_BLK0, 87, 1, [] Revoke 3rd secure boot key +KEY_PURPOSE_0, EFUSE_BLK0, 88, 4, [KEY0_PURPOSE] Represents the purpose of Key0 +KEY_PURPOSE_1, EFUSE_BLK0, 92, 4, [KEY1_PURPOSE] Represents the purpose of Key1 +KEY_PURPOSE_2, EFUSE_BLK0, 96, 4, [KEY2_PURPOSE] Represents the purpose of Key2 +KEY_PURPOSE_3, EFUSE_BLK0, 100, 4, [KEY3_PURPOSE] Represents the purpose of Key3 +KEY_PURPOSE_4, EFUSE_BLK0, 104, 4, [KEY4_PURPOSE] Represents the purpose of Key4 +KEY_PURPOSE_5, EFUSE_BLK0, 108, 4, [KEY5_PURPOSE] Represents the purpose of Key5 +SEC_DPA_LEVEL, EFUSE_BLK0, 112, 2, [DPA_SEC_LEVEL] Represents the spa secure level by configuring the clock random divide mode +CRYPT_DPA_ENABLE, EFUSE_BLK0, 114, 1, [] Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled +SECURE_BOOT_EN, EFUSE_BLK0, 116, 1, [] Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled +SECURE_BOOT_AGGRESSIVE_REVOKE, EFUSE_BLK0, 117, 1, [] Represents whether revoking aggressive secure boot is enabled or disabled. 1: enabled. 0: disabled +FLASH_TPUW, EFUSE_BLK0, 124, 4, [] Represents the flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the programmed value. Otherwise; the waiting time is 2 times the programmed value +DIS_DOWNLOAD_MODE, EFUSE_BLK0, 128, 1, [] Represents whether Download mode is disabled or enabled. 1: disabled. 0: enabled +DIS_DIRECT_BOOT, EFUSE_BLK0, 129, 1, [] Represents whether direct boot mode is disabled or enabled. 1: disabled. 0: enabled +DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 130, 1, [DIS_USB_PRINT] Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled +DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, EFUSE_BLK0, 132, 1, [] Represents whether the USB-Serial-JTAG download function is disabled or enabled. 1: disabled. 0: enabled +ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 133, 1, [] Represents whether security download is enabled or disabled. 1: enabled. 0: disabled +UART_PRINT_CONTROL, EFUSE_BLK0, 134, 2, [] Set the default UARTboot message output mode {0: "Enable"; 1: "Enable when GPIO8 is low at reset"; 2: "Enable when GPIO8 is high at reset"; 3: "Disable"} +FORCE_SEND_RESUME, EFUSE_BLK0, 141, 1, [] Represents whether ROM code is forced to send a resume command during SPI boot. 1: forced. 0:not forced +SECURE_VERSION, EFUSE_BLK0, 142, 16, [] Represents the version used by ESP-IDF anti-rollback feature +SECURE_BOOT_DISABLE_FAST_WAKE, EFUSE_BLK0, 158, 1, [] Represents whether FAST VERIFY ON WAKE is disabled or enabled when Secure Boot is enabled. 1: disabled. 0: enabled +DISABLE_WAFER_VERSION_MAJOR, EFUSE_BLK0, 160, 1, [] Disables check of wafer version major +DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK0, 161, 1, [] Disables check of blk version major +MAC, EFUSE_BLK1, 40, 8, [MAC_FACTORY] MAC address +, EFUSE_BLK1, 32, 8, [MAC_FACTORY] MAC address +, EFUSE_BLK1, 24, 8, [MAC_FACTORY] MAC address +, EFUSE_BLK1, 16, 8, [MAC_FACTORY] MAC address +, EFUSE_BLK1, 8, 8, [MAC_FACTORY] MAC address +, EFUSE_BLK1, 0, 8, [MAC_FACTORY] MAC address +MAC_EXT, EFUSE_BLK1, 56, 8, [] Stores the extended bits of MAC address +, EFUSE_BLK1, 48, 8, [] Stores the extended bits of MAC address +ACTIVE_HP_DBIAS, EFUSE_BLK1, 64, 5, [] Stores the active hp dbias +ACTIVE_LP_DBIAS, EFUSE_BLK1, 69, 5, [] Stores the active lp dbias +LSLP_HP_DBG, EFUSE_BLK1, 74, 2, [] Stores the lslp hp dbg +LSLP_HP_DBIAS, EFUSE_BLK1, 76, 4, [] Stores the lslp hp dbias +DSLP_LP_DBG, EFUSE_BLK1, 80, 3, [] Stores the dslp lp dbg +DSLP_LP_DBIAS, EFUSE_BLK1, 83, 4, [] Stores the dslp lp dbias +DBIAS_VOL_GAP, EFUSE_BLK1, 87, 5, [] Stores the hp and lp dbias vol gap +WAFER_VERSION_MINOR, EFUSE_BLK1, 114, 4, [] +WAFER_VERSION_MAJOR, EFUSE_BLK1, 118, 2, [] +PKG_VERSION, EFUSE_BLK1, 120, 3, [] Package version +BLK_VERSION_MINOR, EFUSE_BLK1, 123, 3, [] BLK_VERSION_MINOR of BLOCK2 +BLK_VERSION_MAJOR, EFUSE_BLK1, 126, 2, [] BLK_VERSION_MAJOR of BLOCK2 +FLASH_CAP, EFUSE_BLK1, 128, 3, [] +FLASH_TEMP, EFUSE_BLK1, 131, 2, [] +FLASH_VENDOR, EFUSE_BLK1, 133, 3, [] +OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, [] Optional unique 128-bit ID +TEMP_CALIB, EFUSE_BLK2, 128, 9, [] Temperature calibration data +OCODE, EFUSE_BLK2, 137, 8, [] ADC OCode +ADC1_INIT_CODE_ATTEN0, EFUSE_BLK2, 145, 10, [] ADC1 init code at atten0 +ADC1_INIT_CODE_ATTEN1, EFUSE_BLK2, 155, 10, [] ADC1 init code at atten1 +ADC1_INIT_CODE_ATTEN2, EFUSE_BLK2, 165, 10, [] ADC1 init code at atten2 +ADC1_INIT_CODE_ATTEN3, EFUSE_BLK2, 175, 10, [] ADC1 init code at atten3 +ADC1_CAL_VOL_ATTEN0, EFUSE_BLK2, 185, 10, [] ADC1 calibration voltage at atten0 +ADC1_CAL_VOL_ATTEN1, EFUSE_BLK2, 195, 10, [] ADC1 calibration voltage at atten1 +ADC1_CAL_VOL_ATTEN2, EFUSE_BLK2, 205, 10, [] ADC1 calibration voltage at atten2 +ADC1_CAL_VOL_ATTEN3, EFUSE_BLK2, 215, 10, [] ADC1 calibration voltage at atten3 +ADC1_INIT_CODE_ATTEN0_CH0, EFUSE_BLK2, 225, 4, [] ADC1 init code at atten0 ch0 +ADC1_INIT_CODE_ATTEN0_CH1, EFUSE_BLK2, 229, 4, [] ADC1 init code at atten0 ch1 +ADC1_INIT_CODE_ATTEN0_CH2, EFUSE_BLK2, 233, 4, [] ADC1 init code at atten0 ch2 +ADC1_INIT_CODE_ATTEN0_CH3, EFUSE_BLK2, 237, 4, [] ADC1 init code at atten0 ch3 +ADC1_INIT_CODE_ATTEN0_CH4, EFUSE_BLK2, 241, 4, [] ADC1 init code at atten0 ch4 +ADC1_INIT_CODE_ATTEN0_CH5, EFUSE_BLK2, 245, 4, [] ADC1 init code at atten0 ch5 +ADC1_INIT_CODE_ATTEN0_CH6, EFUSE_BLK2, 249, 4, [] ADC1 init code at atten0 ch6 +USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data +USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC +KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data +KEY1, EFUSE_BLK5, 0, 256, [BLOCK_KEY1] Key1 or user data +KEY2, EFUSE_BLK6, 0, 256, [BLOCK_KEY2] Key2 or user data +KEY3, EFUSE_BLK7, 0, 256, [BLOCK_KEY3] Key3 or user data +KEY4, EFUSE_BLK8, 0, 256, [BLOCK_KEY4] Key4 or user data +KEY5, EFUSE_BLK9, 0, 256, [BLOCK_KEY5] Key5 or user data +SYS_DATA_PART2, EFUSE_BLK10, 0, 256, [BLOCK_SYS_DATA2] System data part 2 (reserved) diff --git a/components/efuse/esp32c6/esp_efuse_utility.c b/components/efuse/esp32c6/esp_efuse_utility.c new file mode 100644 index 000000000000..57c8b48b322b --- /dev/null +++ b/components/efuse/esp32c6/esp_efuse_utility.c @@ -0,0 +1,202 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "assert.h" +#include "esp_efuse_utility.h" +#include "soc/efuse_periph.h" +#include "hal/efuse_hal.h" +#include "hal/misc.h" + +static const char *TAG = "efuse"; + +#ifdef CONFIG_EFUSE_VIRTUAL +extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK]; +#endif // CONFIG_EFUSE_VIRTUAL + +/*Range addresses to read blocks*/ +const esp_efuse_range_addr_t range_read_addr_blocks[] = { + {EFUSE_RD_WR_DIS_REG, EFUSE_RD_REPEAT_DATA4_REG}, // range address of EFUSE_BLK0 REPEAT + {EFUSE_RD_MAC_SPI_SYS_0_REG, EFUSE_RD_MAC_SPI_SYS_5_REG}, // range address of EFUSE_BLK1 MAC_SPI_8M + {EFUSE_RD_SYS_PART1_DATA0_REG, EFUSE_RD_SYS_PART1_DATA7_REG}, // range address of EFUSE_BLK2 SYS_DATA + {EFUSE_RD_USR_DATA0_REG, EFUSE_RD_USR_DATA7_REG}, // range address of EFUSE_BLK3 USR_DATA + {EFUSE_RD_KEY0_DATA0_REG, EFUSE_RD_KEY0_DATA7_REG}, // range address of EFUSE_BLK4 KEY0 + {EFUSE_RD_KEY1_DATA0_REG, EFUSE_RD_KEY1_DATA7_REG}, // range address of EFUSE_BLK5 KEY1 + {EFUSE_RD_KEY2_DATA0_REG, EFUSE_RD_KEY2_DATA7_REG}, // range address of EFUSE_BLK6 KEY2 + {EFUSE_RD_KEY3_DATA0_REG, EFUSE_RD_KEY3_DATA7_REG}, // range address of EFUSE_BLK7 KEY3 + {EFUSE_RD_KEY4_DATA0_REG, EFUSE_RD_KEY4_DATA7_REG}, // range address of EFUSE_BLK8 KEY4 + {EFUSE_RD_KEY5_DATA0_REG, EFUSE_RD_KEY5_DATA7_REG}, // range address of EFUSE_BLK9 KEY5 + {EFUSE_RD_SYS_PART2_DATA0_REG, EFUSE_RD_SYS_PART2_DATA7_REG} // range address of EFUSE_BLK10 KEY6 +}; + +static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 }; + +/*Range addresses to write blocks (it is not real regs, it is buffer) */ +const esp_efuse_range_addr_t range_write_addr_blocks[] = { + {(uint32_t) &write_mass_blocks[EFUSE_BLK0][0], (uint32_t) &write_mass_blocks[EFUSE_BLK0][5]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK1][0], (uint32_t) &write_mass_blocks[EFUSE_BLK1][5]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK2][0], (uint32_t) &write_mass_blocks[EFUSE_BLK2][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK3][0], (uint32_t) &write_mass_blocks[EFUSE_BLK3][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK4][0], (uint32_t) &write_mass_blocks[EFUSE_BLK4][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK5][0], (uint32_t) &write_mass_blocks[EFUSE_BLK5][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK6][0], (uint32_t) &write_mass_blocks[EFUSE_BLK6][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK7][0], (uint32_t) &write_mass_blocks[EFUSE_BLK7][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK8][0], (uint32_t) &write_mass_blocks[EFUSE_BLK8][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK9][0], (uint32_t) &write_mass_blocks[EFUSE_BLK9][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK10][0], (uint32_t) &write_mass_blocks[EFUSE_BLK10][7]}, +}; + +#ifndef CONFIG_EFUSE_VIRTUAL +// Update Efuse timing configuration +static esp_err_t esp_efuse_set_timing(void) +{ + // efuse clock is fixed. + // An argument (0) is for compatibility and will be ignored. + efuse_hal_set_timing(0); + return ESP_OK; +} +#endif // ifndef CONFIG_EFUSE_VIRTUAL + +// Efuse read operation: copies data from physical efuses to efuse read registers. +void esp_efuse_utility_clear_program_registers(void) +{ + efuse_hal_read(); + efuse_hal_clear_program_registers(); +} + +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + +// Burn values written to the efuse write registers +esp_err_t esp_efuse_utility_burn_chip(void) +{ + esp_err_t error = ESP_OK; +#ifdef CONFIG_EFUSE_VIRTUAL + ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); + for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { + int subblock = 0; + for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { + virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block); + } + } +#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH + esp_efuse_utility_write_efuses_to_flash(); +#endif +#else // CONFIG_EFUSE_VIRTUAL + if (esp_efuse_set_timing() != ESP_OK) { + ESP_LOGE(TAG, "Efuse fields are not burnt"); + } else { + // Permanently update values written to the efuse write registers + // It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks. + for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { + bool need_burn_block = false; + for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { + if (REG_READ(addr_wr_block) != 0) { + need_burn_block = true; + break; + } + } + if (!need_burn_block) { + continue; + } + if (error) { + // It is done for a use case: BLOCK2 (Flash encryption key) could have an error (incorrect written data) + // in this case we can not burn any data into BLOCK0 because it might set read/write protections of BLOCK2. + ESP_LOGE(TAG, "BLOCK%d can not be burned because a previous block got an error, skipped.", num_block); + continue; + } + efuse_hal_clear_program_registers(); + if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { + uint8_t block_rs[12]; + efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); + hal_memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); + } + unsigned r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t); + unsigned data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); + + uint32_t backup_write_data[8 + 3]; // 8 words are data and 3 words are RS coding data + hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); + int repeat_burn_op = 1; + bool correct_written_data; + bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_before) { + ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); + } + bool coding_error_occurred; + + do { + ESP_LOGI(TAG, "BURN BLOCK%d", num_block); + efuse_hal_program(num_block); // BURN a block + + bool coding_error_after; + for (unsigned i = 0; i < 5; i++) { + efuse_hal_read(); + coding_error_after = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_after == true) { + break; + } + } + coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + if (coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); + } + + correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + if (!correct_written_data || coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); + hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); + } + + } while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3); + + if (coding_error_occurred) { + ESP_LOGW(TAG, "Coding error was not fixed"); + if (num_block == 0) { + ESP_LOGE(TAG, "BLOCK0 got a coding error, which might be critical for security"); + error = ESP_FAIL; + } + } + if (!correct_written_data) { + ESP_LOGE(TAG, "Written data are incorrect"); + error = ESP_FAIL; + } + } + } +#endif // CONFIG_EFUSE_VIRTUAL + esp_efuse_utility_reset(); + return error; +} + +// After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values. +// This function reads EFUSE_BLKx_WDATAx_REG registers, and checks possible to write these data with RS coding scheme. +// The RS coding scheme does not require data changes for the encoded data. esp32s2 has special registers for this. +// They will be filled during the burn operation. +esp_err_t esp_efuse_utility_apply_new_coding_scheme() +{ + // start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE. + for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) { + if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { + for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { + if (REG_READ(addr_wr_block)) { + int num_reg = 0; + for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, ++num_reg) { + if (esp_efuse_utility_read_reg(num_block, num_reg)) { + ESP_LOGE(TAG, "Bits are not empty. Write operation is forbidden."); + return ESP_ERR_CODING; + } + } + break; + } + } + } + } + return ESP_OK; +} diff --git a/components/efuse/esp32c6/include/esp_efuse_chip.h b/components/efuse/esp32c6/include/esp_efuse_chip.h new file mode 100644 index 000000000000..85eb5d83624f --- /dev/null +++ b/components/efuse/esp32c6/include/esp_efuse_chip.h @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of eFuse blocks ESP32C6 + */ +typedef enum { + EFUSE_BLK0 = 0, /**< Number of eFuse BLOCK0. REPEAT_DATA */ + + EFUSE_BLK1 = 1, /**< Number of eFuse BLOCK1. MAC_SPI_8M_SYS */ + + EFUSE_BLK2 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */ + EFUSE_BLK_SYS_DATA_PART1 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */ + + EFUSE_BLK3 = 3, /**< Number of eFuse BLOCK3. USER_DATA*/ + EFUSE_BLK_USER_DATA = 3, /**< Number of eFuse BLOCK3. USER_DATA*/ + + EFUSE_BLK4 = 4, /**< Number of eFuse BLOCK4. KEY0 */ + EFUSE_BLK_KEY0 = 4, /**< Number of eFuse BLOCK4. KEY0 */ + + EFUSE_BLK5 = 5, /**< Number of eFuse BLOCK5. KEY1 */ + EFUSE_BLK_KEY1 = 5, /**< Number of eFuse BLOCK5. KEY1 */ + + EFUSE_BLK6 = 6, /**< Number of eFuse BLOCK6. KEY2 */ + EFUSE_BLK_KEY2 = 6, /**< Number of eFuse BLOCK6. KEY2 */ + + EFUSE_BLK7 = 7, /**< Number of eFuse BLOCK7. KEY3 */ + EFUSE_BLK_KEY3 = 7, /**< Number of eFuse BLOCK7. KEY3 */ + + EFUSE_BLK8 = 8, /**< Number of eFuse BLOCK8. KEY4 */ + EFUSE_BLK_KEY4 = 8, /**< Number of eFuse BLOCK8. KEY4 */ + + EFUSE_BLK9 = 9, /**< Number of eFuse BLOCK9. KEY5 */ + EFUSE_BLK_KEY5 = 9, /**< Number of eFuse BLOCK9. KEY5 */ + EFUSE_BLK_KEY_MAX = 10, + + EFUSE_BLK10 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */ + EFUSE_BLK_SYS_DATA_PART2 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */ + + EFUSE_BLK_MAX +} esp_efuse_block_t; + +/** + * @brief Type of coding scheme + */ +typedef enum { + EFUSE_CODING_SCHEME_NONE = 0, /**< None */ + EFUSE_CODING_SCHEME_RS = 3, /**< Reed-Solomon coding */ +} esp_efuse_coding_scheme_t; + +/** + * @brief Type of key purpose + */ +typedef enum { + ESP_EFUSE_KEY_PURPOSE_USER = 0, /**< User purposes (software-only use) */ + ESP_EFUSE_KEY_PURPOSE_RESERVED = 1, /**< Reserved */ + ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4, /**< XTS_AES_128_KEY (flash/PSRAM encryption) */ + ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5, /**< HMAC Downstream mode */ + ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6, /**< JTAG soft enable key (uses HMAC Downstream mode) */ + ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7, /**< Digital Signature peripheral key (uses HMAC Downstream mode) */ + ESP_EFUSE_KEY_PURPOSE_HMAC_UP = 8, /**< HMAC Upstream mode */ + ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9, /**< SECURE_BOOT_DIGEST0 (Secure Boot key digest) */ + ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10, /**< SECURE_BOOT_DIGEST1 (Secure Boot key digest) */ + ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11, /**< SECURE_BOOT_DIGEST2 (Secure Boot key digest) */ + ESP_EFUSE_KEY_PURPOSE_MAX, /**< MAX PURPOSE */ +} esp_efuse_purpose_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h new file mode 100644 index 000000000000..9e65f777b5c8 --- /dev/null +++ b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//This is the ADC calibration value version burnt in efuse +#define ESP_EFUSE_ADC_CALIB_VER1 1 +#define ESP_EFUSE_ADC_CALIB_VER2 2 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER2 +#define VER2IDX(ver) ((ver) - 1) // Version number to index number of the array +/** + * @brief Get the RTC calibration efuse version + * + * @return Version of the stored efuse + */ +int esp_efuse_rtc_calib_get_ver(void); + +/** + * @brief Get the init code in the efuse, for the corresponding attenuation. + * + * @param version Version of the stored efuse + * @param adc_unit ADC unit. Not used, for compatibility. On esp32c6, for calibration v1, both ADC units use the same init code (calibrated by ADC1) + * @param atten Attenuation of the init code + * @return The init code stored in efuse + */ +uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten); + +/** + * @brief Get the channel specific calibration compensation + * + * @param version Version of the stored efuse + * @param adc_unit ADC unit. Not used, for compatibility. On esp32c6, for calibration v1, both ADC units use the same init code (calibrated by ADC1) + * @param adc_channel ADC channel number + * @param atten Attenuation of the init code + * @return The channel calibration compensation value + */ +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten); + +/** + * @brief Get the calibration digits stored in the efuse, and the corresponding voltage. + * + * @param version Version of the stored efuse + * @param adc_unit ADC unit (not used on ESP32C6, for compatibility) + * @param atten Attenuation to use + * @param out_digi Output buffer of the digits + * @param out_vol_mv Output of the voltage, in mV + * @return + * - ESP_ERR_INVALID_ARG: If efuse version or attenuation is invalid + * - ESP_OK: if success + */ +esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv); + +/** + * @brief Get the temperature sensor calibration number delta_T stored in the efuse. + * + * @param tsens_cal Pointer of the specification of temperature sensor calibration number in efuse. + * + * @return ESP_OK if get the calibration value successfully. + * ESP_ERR_INVALID_ARG if can't get the calibration value. + */ +esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal); + +#ifdef __cplusplus +} +#endif diff --git a/components/efuse/esp32c6/include/esp_efuse_table.h b/components/efuse/esp32c6/include/esp_efuse_table.h new file mode 100644 index 000000000000..c0dec3c99b8c --- /dev/null +++ b/components/efuse/esp32c6/include/esp_efuse_table.h @@ -0,0 +1,252 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_efuse.h" + +// md5_digest_table 0d9c0c6a65ccf2d4a7279ede32b6f797 +// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. +// If you want to change some fields, you need to change esp_efuse_table.csv file +// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. +// To show efuse_table run the command 'show_efuse_table'. + + +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CRYPT_DPA_ENABLE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SWAP_UART_SDIO_EN[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_ICACHE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_ICACHE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_FORCE_DOWNLOAD[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_TWAI[]; +#define ESP_EFUSE_WR_DIS_DIS_CAN ESP_EFUSE_WR_DIS_DIS_TWAI +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_JTAG_SEL_ENABLE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_PAD_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WDT_DELAY_SEL[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_0[]; +#define ESP_EFUSE_WR_DIS_KEY0_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_0 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_1[]; +#define ESP_EFUSE_WR_DIS_KEY1_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_1 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_2[]; +#define ESP_EFUSE_WR_DIS_KEY2_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_2 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_3[]; +#define ESP_EFUSE_WR_DIS_KEY3_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_3 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_4[]; +#define ESP_EFUSE_WR_DIS_KEY4_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_4 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_5[]; +#define ESP_EFUSE_WR_DIS_KEY5_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_5 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SEC_DPA_LEVEL[]; +#define ESP_EFUSE_WR_DIS_DPA_SEC_LEVEL ESP_EFUSE_WR_DIS_SEC_DPA_LEVEL +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TPUW[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DIRECT_BOOT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT[]; +#define ESP_EFUSE_WR_DIS_DIS_USB_PRINT ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ENABLE_SECURITY_DOWNLOAD[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_UART_PRINT_CONTROL[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FORCE_SEND_RESUME[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_WAFER_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[]; +#define ESP_EFUSE_WR_DIS_MAC_FACTORY ESP_EFUSE_WR_DIS_MAC +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DBIAS_VOL_GAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PKG_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TEMP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OCODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[]; +#define ESP_EFUSE_WR_DIS_USER_DATA ESP_EFUSE_WR_DIS_BLOCK_USR_DATA +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[]; +#define ESP_EFUSE_WR_DIS_MAC_CUSTOM ESP_EFUSE_WR_DIS_CUSTOM_MAC +#define ESP_EFUSE_WR_DIS_USER_DATA_MAC_CUSTOM ESP_EFUSE_WR_DIS_CUSTOM_MAC +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY0[]; +#define ESP_EFUSE_WR_DIS_KEY0 ESP_EFUSE_WR_DIS_BLOCK_KEY0 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY1[]; +#define ESP_EFUSE_WR_DIS_KEY1 ESP_EFUSE_WR_DIS_BLOCK_KEY1 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY2[]; +#define ESP_EFUSE_WR_DIS_KEY2 ESP_EFUSE_WR_DIS_BLOCK_KEY2 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY3[]; +#define ESP_EFUSE_WR_DIS_KEY3 ESP_EFUSE_WR_DIS_BLOCK_KEY3 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY4[]; +#define ESP_EFUSE_WR_DIS_KEY4 ESP_EFUSE_WR_DIS_BLOCK_KEY4 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY5[]; +#define ESP_EFUSE_WR_DIS_KEY5 ESP_EFUSE_WR_DIS_BLOCK_KEY5 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA2[]; +#define ESP_EFUSE_WR_DIS_SYS_DATA_PART2 ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA2 +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_USB_EXCHG_PINS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_VDD_SPI_AS_GPIO[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SOFT_DIS_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY0[]; +#define ESP_EFUSE_RD_DIS_KEY0 ESP_EFUSE_RD_DIS_BLOCK_KEY0 +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY1[]; +#define ESP_EFUSE_RD_DIS_KEY1 ESP_EFUSE_RD_DIS_BLOCK_KEY1 +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY2[]; +#define ESP_EFUSE_RD_DIS_KEY2 ESP_EFUSE_RD_DIS_BLOCK_KEY2 +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY3[]; +#define ESP_EFUSE_RD_DIS_KEY3 ESP_EFUSE_RD_DIS_BLOCK_KEY3 +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY4[]; +#define ESP_EFUSE_RD_DIS_KEY4 ESP_EFUSE_RD_DIS_BLOCK_KEY4 +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY5[]; +#define ESP_EFUSE_RD_DIS_KEY5 ESP_EFUSE_RD_DIS_BLOCK_KEY5 +extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_SYS_DATA2[]; +#define ESP_EFUSE_RD_DIS_SYS_DATA_PART2 ESP_EFUSE_RD_DIS_BLOCK_SYS_DATA2 +extern const esp_efuse_desc_t* ESP_EFUSE_SWAP_UART_SDIO_EN[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_ICACHE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_TWAI[]; +#define ESP_EFUSE_DIS_CAN ESP_EFUSE_DIS_TWAI +extern const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_USB_EXCHG_PINS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_AS_GPIO[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_CRYPT_CNT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_0[]; +#define ESP_EFUSE_KEY0_PURPOSE ESP_EFUSE_KEY_PURPOSE_0 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_1[]; +#define ESP_EFUSE_KEY1_PURPOSE ESP_EFUSE_KEY_PURPOSE_1 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_2[]; +#define ESP_EFUSE_KEY2_PURPOSE ESP_EFUSE_KEY_PURPOSE_2 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_3[]; +#define ESP_EFUSE_KEY3_PURPOSE ESP_EFUSE_KEY_PURPOSE_3 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_4[]; +#define ESP_EFUSE_KEY4_PURPOSE ESP_EFUSE_KEY_PURPOSE_4 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_5[]; +#define ESP_EFUSE_KEY5_PURPOSE ESP_EFUSE_KEY_PURPOSE_5 +extern const esp_efuse_desc_t* ESP_EFUSE_SEC_DPA_LEVEL[]; +#define ESP_EFUSE_DPA_SEC_LEVEL ESP_EFUSE_SEC_DPA_LEVEL +extern const esp_efuse_desc_t* ESP_EFUSE_CRYPT_DPA_ENABLE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[]; +#define ESP_EFUSE_DIS_USB_PRINT ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[]; +extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_DISABLE_FAST_WAKE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_WAFER_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_MAC[]; +#define ESP_EFUSE_MAC_FACTORY ESP_EFUSE_MAC +extern const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DBIAS_VOL_GAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TEMP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[]; +extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_OCODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6[]; +extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[]; +#define ESP_EFUSE_BLOCK_USR_DATA ESP_EFUSE_USER_DATA +extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[]; +#define ESP_EFUSE_MAC_CUSTOM ESP_EFUSE_USER_DATA_MAC_CUSTOM +#define ESP_EFUSE_CUSTOM_MAC ESP_EFUSE_USER_DATA_MAC_CUSTOM +extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[]; +#define ESP_EFUSE_BLOCK_KEY0 ESP_EFUSE_KEY0 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[]; +#define ESP_EFUSE_BLOCK_KEY1 ESP_EFUSE_KEY1 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY2[]; +#define ESP_EFUSE_BLOCK_KEY2 ESP_EFUSE_KEY2 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY3[]; +#define ESP_EFUSE_BLOCK_KEY3 ESP_EFUSE_KEY3 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY4[]; +#define ESP_EFUSE_BLOCK_KEY4 ESP_EFUSE_KEY4 +extern const esp_efuse_desc_t* ESP_EFUSE_KEY5[]; +#define ESP_EFUSE_BLOCK_KEY5 ESP_EFUSE_KEY5 +extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART2[]; +#define ESP_EFUSE_BLOCK_SYS_DATA2 ESP_EFUSE_SYS_DATA_PART2 + +#ifdef __cplusplus +} +#endif diff --git a/components/efuse/esp32c6/private_include/esp_efuse_utility.h b/components/efuse/esp32c6/private_include/esp_efuse_utility.h new file mode 100644 index 000000000000..4720cb0a8fe2 --- /dev/null +++ b/components/efuse/esp32c6/private_include/esp_efuse_utility.h @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */ + +#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0 + +#define ESP_EFUSE_FIELD_CORRESPONDS_CODING_SCHEME(scheme, max_num_bit) + +#ifdef __cplusplus +} +#endif diff --git a/components/efuse/esp32c6/sources.cmake b/components/efuse/esp32c6/sources.cmake new file mode 100644 index 000000000000..9dffd72008d3 --- /dev/null +++ b/components/efuse/esp32c6/sources.cmake @@ -0,0 +1,4 @@ +set(EFUSE_SOC_SRCS "esp_efuse_table.c" + "esp_efuse_fields.c" + "esp_efuse_rtc_calib.c" + "esp_efuse_utility.c") diff --git a/components/efuse/src/esp_efuse_fields.c b/components/efuse/src/esp_efuse_fields.c index 9898563a7598..cc551243cefa 100644 --- a/components/efuse/src/esp_efuse_fields.c +++ b/components/efuse/src/esp_efuse_fields.c @@ -16,7 +16,9 @@ #include "esp_log.h" #include "soc/efuse_periph.h" #include "bootloader_random.h" +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/syscon_reg.h" +#endif #include "sys/param.h" static __attribute__((unused)) const char *TAG = "efuse"; diff --git a/components/esp_adc/esp32c6/include/adc_cali_schemes.h b/components/esp_adc/esp32c6/include/adc_cali_schemes.h new file mode 100644 index 000000000000..58575c1dcb13 --- /dev/null +++ b/components/esp_adc/esp32c6/include/adc_cali_schemes.h @@ -0,0 +1,4 @@ +#pragma once + +/* This package has no C6 curve-fitting coefficients. Raw readings still work. */ +#define ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED 0 diff --git a/components/esp_common/include/esp_assert.h b/components/esp_common/include/esp_assert.h index 12d2d1f0750f..9584e67fb3ba 100644 --- a/components/esp_common/include/esp_assert.h +++ b/components/esp_common/include/esp_assert.h @@ -8,6 +8,8 @@ #include "assert.h" +#define ESP_STATIC_ASSERT static_assert + /* Assert at compile time if possible, runtime otherwise */ #ifndef __cplusplus /* __builtin_choose_expr() is only in C, makes this a lot cleaner */ diff --git a/components/esp_gdbstub/esp32c6/gdbstub_esp32c6.c b/components/esp_gdbstub/esp32c6/gdbstub_esp32c6.c index e69de29bb2d1..86aea667753c 100644 --- a/components/esp_gdbstub/esp32c6/gdbstub_esp32c6.c +++ b/components/esp_gdbstub/esp32c6/gdbstub_esp32c6.c @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/uart_reg.h" +#include "esp_gdbstub_common.h" +#include "sdkconfig.h" + +#define UART_NUM CONFIG_ESP_CONSOLE_UART_NUM + +#define GDBSTUB_MEM_REGION_COUNT 8 + +#define UART_REG_FIELD_LEN 0x84 + +typedef struct { + intptr_t lower; + intptr_t upper; +} mem_bound_t; + +static const mem_bound_t mem_region_table[GDBSTUB_MEM_REGION_COUNT] = +{ + {SOC_DROM_LOW, SOC_DROM_HIGH}, + {SOC_IROM_LOW, SOC_IROM_HIGH}, + {SOC_IRAM_LOW, SOC_IRAM_HIGH}, + {SOC_DRAM_LOW, SOC_DRAM_HIGH}, + {SOC_IROM_MASK_LOW, SOC_IROM_MASK_HIGH}, + {SOC_DROM_MASK_LOW, SOC_DROM_MASK_HIGH}, + {SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH}, + /* Skip the UART registers used by this stub. */ + {DR_REG_UART_BASE + UART_REG_FIELD_LEN, SOC_PERIPHERAL_HIGH}, +}; + +static inline bool check_inside_valid_region(intptr_t addr) +{ + size_t i; + + for (i = 0; i < GDBSTUB_MEM_REGION_COUNT; i++) { + if (addr >= mem_region_table[i].lower && addr < mem_region_table[i].upper) { + return true; + } + } + return false; +} + +void esp_gdbstub_target_init(void) +{ +} + +int esp_gdbstub_getchar(void) +{ + while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_RXFIFO_CNT) == 0) { + ; + } + return REG_READ(UART_FIFO_AHB_REG(UART_NUM)); +} + +void esp_gdbstub_putchar(int c) +{ + while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_TXFIFO_CNT) >= 126) { + ; + } + REG_WRITE(UART_FIFO_AHB_REG(UART_NUM), c); +} + +void esp_gdbstub_flush(void) +{ +} + +int esp_gdbstub_readmem(intptr_t addr) +{ + uint32_t val_aligned; + uint32_t shift; + + if (!check_inside_valid_region(addr)) { + return -1; + } + val_aligned = *(uint32_t *)(addr & (~3)); + shift = (addr & 3) * 8; + return (val_aligned >> shift) & 0xff; +} + +int esp_gdbstub_writemem(unsigned int addr, unsigned char data) +{ + int *i; + + if (!check_inside_valid_region(addr)) { + return -1; + } + + i = (int *)(addr & (~3)); + if ((addr & 3) == 0) { + *i = (*i & 0xffffff00) | (data << 0); + } + if ((addr & 3) == 1) { + *i = (*i & 0xffff00ff) | (data << 8); + } + if ((addr & 3) == 2) { + *i = (*i & 0xff00ffff) | (data << 16); + } + if ((addr & 3) == 3) { + *i = (*i & 0x00ffffff) | (data << 24); + } + return 0; +} diff --git a/components/esp_gdbstub/esp32c6/gdbstub_target_config.h b/components/esp_gdbstub/esp32c6/gdbstub_target_config.h new file mode 100644 index 000000000000..d4749ddddc50 --- /dev/null +++ b/components/esp_gdbstub/esp32c6/gdbstub_target_config.h @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once diff --git a/components/esp_gdbstub/src/gdbstub.c b/components/esp_gdbstub/src/gdbstub.c index 950c16113199..81ff0aedee44 100644 --- a/components/esp_gdbstub/src/gdbstub.c +++ b/components/esp_gdbstub/src/gdbstub.c @@ -114,7 +114,11 @@ static uint32_t gdbstub_hton(uint32_t i) return __builtin_bswap32(i); } +#if CONFIG_IDF_TARGET_ESP32C6 +static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif static wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; static wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1}; diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index 3cf14aebc15b..1c00ce15d41e 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -26,7 +26,7 @@ bool periph_rtc_dig_clk8m_enable(void) portENTER_CRITICAL(&periph_spinlock); if (s_periph_ref_counts == 0) { rtc_dig_clk8m_enable(); -#if !CONFIG_IDF_TARGET_ESP32H2 +#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6 s_rtc_clk_freq = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_8MD256, 100)); if (s_rtc_clk_freq == 0) { portEXIT_CRITICAL(&periph_spinlock); @@ -41,7 +41,7 @@ bool periph_rtc_dig_clk8m_enable(void) uint32_t periph_rtc_dig_clk8m_get_freq(void) { -#if CONFIG_IDF_TARGET_ESP32H2 +#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 /* Workaround: H2 doesn't have 8MD256 clk, so calibration cannot be done, we just return its theoretic frequency */ return SOC_CLK_RC_FAST_FREQ_APPROX; #else diff --git a/components/esp_hw_support/cpu.c b/components/esp_hw_support/cpu.c index fb67935002b4..5d2054c5b95e 100644 --- a/components/esp_hw_support/cpu.c +++ b/components/esp_hw_support/cpu.c @@ -9,7 +9,9 @@ #include #include "soc/soc.h" #include "soc/soc_caps.h" +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/rtc_cntl_reg.h" +#endif #include "hal/soc_hal.h" #include "hal/mpu_hal.h" #include "esp_bit_defs.h" @@ -18,10 +20,14 @@ #include "esp_cpu.h" #include "esp_memory_utils.h" #include "esp_fault.h" +#include "esp_rom_sys.h" #if __XTENSA__ #include "xtensa/config/core-isa.h" #else #include "soc/system_reg.h" // For SYSTEM_CPU_PER_CONF_REG +#if CONFIG_IDF_TARGET_ESP32C6 +#include "soc/pcr_reg.h" +#endif #include "soc/dport_access.h" // For Dport access #include "riscv/semihosting.h" #include "riscv/csr.h" // For PMP_ENTRY. [refactor-todo] create PMP abstraction in rv_utils.h @@ -90,17 +96,28 @@ void esp_cpu_reset(int core_id) */ int rtc_cntl_rst_m = (core_id == 0) ? RTC_CNTL_SW_PROCPU_RST_M : RTC_CNTL_SW_APPCPU_RST_M; #else // SOC_CPU_CORES_NUM > 1 +#if CONFIG_IDF_TARGET_ESP32C6 + esp_rom_software_reset_cpu(core_id); + return; +#else int rtc_cntl_rst_m = RTC_CNTL_SW_PROCPU_RST_M; +#endif #endif // SOC_CPU_CORES_NUM > 1 +#if !CONFIG_IDF_TARGET_ESP32C6 SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst_m); +#endif } void esp_cpu_wait_for_intr(void) { #if __XTENSA__ xt_utils_wait_for_intr(); +#else +#if CONFIG_IDF_TARGET_ESP32C6 + if (esp_cpu_dbgr_is_attached() && DPORT_REG_GET_BIT(PCR_CPU_WAITI_CONF_REG, PCR_CPU_WAIT_MODE_FORCE_ON) == 0) { #else if (esp_cpu_dbgr_is_attached() && DPORT_REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON) == 0) { +#endif /* when SYSTEM_CPU_WAIT_MODE_FORCE_ON is disabled in WFI mode SBA access to memory does not work for debugger, so do not enter that mode when debugger is connected */ return; diff --git a/components/esp_hw_support/include/esp_chip_info.h b/components/esp_hw_support/include/esp_chip_info.h index 8f92e226b164..227d55a0fa2c 100644 --- a/components/esp_hw_support/include/esp_chip_info.h +++ b/components/esp_hw_support/include/esp_chip_info.h @@ -26,6 +26,7 @@ typedef enum { CHIP_ESP32C3 = 5, //!< ESP32-C3 CHIP_ESP32H2 = 6, //!< ESP32-H2 CHIP_ESP32C2 = 12, //!< ESP32-C2 + CHIP_ESP32C6 = 13, //!< ESP32-C6 } esp_chip_model_t; /* Chip feature flags, used in esp_chip_info_t */ diff --git a/components/esp_hw_support/include/esp_clk_tree.h b/components/esp_hw_support/include/esp_clk_tree.h new file mode 100644 index 000000000000..50dcc6441295 --- /dev/null +++ b/components/esp_hw_support/include/esp_clk_tree.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Degree of precision of frequency value to be returned by esp_clk_tree_src_get_freq_hz() + */ +typedef enum { + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, /*< Get value from the data cached by the driver; If the data is 0, then a calibration will be performed */ + ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, /*< Get its approxiamte frequency value */ + ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, /*< Always perform a calibration */ + ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, /*< Invalid degree of precision */ +} esp_clk_tree_src_freq_precision_t; + +/** + * @brief Get frequency of module clock source + * + * @param[in] clk_src Clock source available to modules, in soc_module_clk_t + * @param[in] precision Degree of precision, one of esp_clk_tree_src_freq_precision_t values + * This arg only applies to the clock sources that their frequencies can vary: + * SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_RTC_SLOW, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_RC_FAST_D256, + * SOC_MOD_CLK_XTAL32K + * For other clock sources, this field is ignored. + * @param[out] freq_value Frequency of the clock source, in Hz + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_FAIL Calibration failed + */ +esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision, +uint32_t *freq_value); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_fault.h b/components/esp_hw_support/include/esp_fault.h index 910ba59d06c2..9839617df7bd 100644 --- a/components/esp_hw_support/include/esp_fault.h +++ b/components/esp_hw_support/include/esp_fault.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/rtc_cntl_reg.h" +#endif #include "esp_rom_sys.h" #pragma once @@ -70,10 +72,17 @@ extern "C" { */ #ifndef ESP_FAULT_ASSERT_DEBUG +#if CONFIG_IDF_TARGET_ESP32C6 +#define _ESP_FAULT_RESET() do { \ + esp_rom_software_reset_system(); \ + _ESP_FAULT_ILLEGAL_INSTRUCTION; \ + } while(0) +#else #define _ESP_FAULT_RESET() do { \ REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); \ _ESP_FAULT_ILLEGAL_INSTRUCTION; \ } while(0) +#endif #else // ESP_FAULT_ASSERT_DEBUG diff --git a/components/esp_hw_support/include/esp_memory_utils.h b/components/esp_hw_support/include/esp_memory_utils.h index e66e917b8794..dfb2b68b5491 100644 --- a/components/esp_hw_support/include/esp_memory_utils.h +++ b/components/esp_hw_support/include/esp_memory_utils.h @@ -69,7 +69,13 @@ inline static bool esp_ptr_in_diram_dram(const void *p) { */ __attribute__((always_inline)) inline static bool esp_ptr_in_diram_iram(const void *p) { +#if SOC_DIRAM_IRAM_LOW == SOC_DIRAM_DRAM_LOW + /* C6 DRAM and IRAM share one address range. A normal heap block is not an IRAM alias. */ + (void)p; + return false; +#else return ((intptr_t)p >= SOC_DIRAM_IRAM_LOW && (intptr_t)p < SOC_DIRAM_IRAM_HIGH); +#endif } /** diff --git a/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h b/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h new file mode 100644 index 000000000000..c67660d1d9d0 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_clk_tree.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_CLK_RC_FAST_D256_SUPPORTED +/** + * @brief Get frequency of RC_FAST_D256_CLK + * + * @param precision Degree of precision of the returned frequency value, one of esp_clk_tree_src_freq_precision_t values + * + * @return RC_FAST_D256 clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed. + */ +uint32_t esp_clk_tree_rc_fast_d256_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); +#endif + +#if SOC_CLK_XTAL32K_SUPPORTED +/** + * @brief Get frequency of XTAL32K_CLK + * + * @param precision Degree of precision of the returned frequency value, one of esp_clk_tree_src_freq_precision_t values + * + * @return XTAL32K clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed. + */ +uint32_t esp_clk_tree_xtal32k_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); +#endif + +#if SOC_CLK_OSC_SLOW_SUPPORTED +/** + * @brief Get frequency of OSC_SLOW_CLK + * + * @param precision Degree of precision of the returned frequency value, one of esp_clk_tree_src_freq_precision_t values + * + * @return OSC_SLOW clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed. + */ +uint32_t esp_clk_tree_osc_slow_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); +#endif + +/** + * @brief Get frequency of RC_FAST_CLK + * + * @param precision Degree of precision of the returned frequency value, one of esp_clk_tree_src_freq_precision_t values + * + * @return RC_FAST clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed. + */ +uint32_t esp_clk_tree_rc_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); + +/** + * @brief Get frequency of LP_SLOW_CLK (i.e. RTC_SLOW_CLK) + * + * @param precision Degree of precision of the returned frequency value, one of esp_clk_tree_src_freq_precision_t values + * + * @return LP_SLOW clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed. + */ +uint32_t esp_clk_tree_lp_slow_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); + +/** + * @brief Get frequency of LP_FAST_CLK (i.e. RTC_FAST_CLK) + * + * @param precision Degree of precision of the returned frequency value, one of esp_clk_tree_src_freq_precision_t values + * + * @return LP_FAST clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed. + */ +uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/esp_modem_clock.h b/components/esp_hw_support/include/esp_private/esp_modem_clock.h new file mode 100644 index 000000000000..a09d450ac37e --- /dev/null +++ b/components/esp_hw_support/include/esp_private/esp_modem_clock.h @@ -0,0 +1,127 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include + +#include "esp_err.h" +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" +#include "hal/modem_clock_types.h" +#include "esp_private/esp_pmu.h" + +#if SOC_MODEM_CLOCK_IS_INDEPENDENT +#include "hal/modem_clock_hal.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable the clock of modem module + * + * Solve the clock dependency between modem modules, For example, the wifi + * module depends on the wifi mac, wifi baseband and FE, when wifi module + * clock is enabled, the wifi MAC, baseband and FE clocks will be enabled + * + * This interface and modem_clock_module_disable will jointly maintain the + * ref_cnt of each device clock source. The ref_cnt indicates how many modules + * are relying on the clock source. Each enable ops will add 1 to the ref_cnt of + * the clock source that the module depends on, and only when the ref_cnt of + * the module is from 0 to 1 will the clock enable be actually configured. + * + * !!! Do not use the hal/ll layer interface to configure the clock for the + * consistency of the hardware state maintained in the driver and the hardware + * actual state. + * + * @param module modem module + */ +void modem_clock_module_enable(periph_module_t module); + +/** + * @brief Disable the clock of modem module + * + * This interface and modem_clock_module_enable will jointly maintain the ref_cnt + * of each device clock source. The ref_cnt indicates how many modules are relying + * on the clock source. Each disable ops will minus 1 to the ref_cnt of the clock + * source that the module depends on, and only when the ref_cnt of the module is + * from 1 to 0 will the clock disable be actually configured. + * + * !!! Do not use the hal/ll layer interface to configure the clock for the + * consistency of the hardware state maintained in the driver and the hardware + * actual state. + * + * @param module modem module + */ +void modem_clock_module_disable(periph_module_t module); + +/** + * @brief Reset the mac of modem module + * + * @param module modem module, must be one of + * PERIPH_WIFI_MODULE / PERIPH_BT_MODULE /PERIPH_IEEE802154_MODULE + */ +void modem_clock_module_mac_reset(periph_module_t module); + +#if SOC_PMU_SUPPORTED +/** + * @brief Enable modem clock domain clock gate to gate it's output + * + * @param domain modem module clock domain + * @param mode PMU HP system ACTIVE, MODEM and SLEEP state + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the argument value are not correct + */ +esp_err_t modem_clock_domain_clk_gate_enable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode); + +/** + * @brief Disable modem clock domain clock gate to ungate it's output + * + * @param domain modem module clock domain + * @param mode PMU HP system ACTIVE, MODEM and SLEEP state + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the argument value are not correct + */ +esp_err_t modem_clock_domain_clk_gate_disable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode); +#endif + +/** + * @brief Select the modem module lowpower clock source and configure the clock divider + * + * @param module modem module + * @param src lowpower clock source + * @param divider divider value to lowpower clock source + */ +void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpclk_src_t src, uint32_t divider); + +/** + * @brief Disable lowpower clock source selection + */ +void modem_clock_deselect_lp_clock_source(periph_module_t module); + +/** + * @brief Reset wifi mac + */ +void modem_clock_wifi_mac_reset(void); + +/** + * @brief Enable clock registers which shared by both modem and ADC. Need a ref count to enable/disable them + * + * @param enable true: enable; false: disable + */ +void modem_clock_shared_enable(bool enable); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h new file mode 100644 index 000000000000..1d8d2c309bfe --- /dev/null +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -0,0 +1,304 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include + +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_PMU_SUPPORTED +#include "hal/pmu_hal.h" +#include "pmu_param.h" + +#define RTC_SLEEP_PD_DIG PMU_SLEEP_PD_TOP //!< Deep sleep (power down digital domain, includes all power domains + // except CPU, Modem, LP peripheral, AON,VDDSDIO, MEM and clock power domains) +#define RTC_SLEEP_PD_RTC_PERIPH PMU_SLEEP_PD_LP_PERIPH //!< Power down RTC peripherals +#define RTC_SLEEP_PD_VDDSDIO PMU_SLEEP_PD_VDDSDIO //!< Power down VDDSDIO regulator +#define RTC_SLEEP_PD_CPU PMU_SLEEP_PD_CPU //!< Power down CPU when in lightsleep, but not restart +#define RTC_SLEEP_PD_DIG_PERIPH PMU_SLEEP_PD_HP_PERIPH //!< Power down DIG peripherals +#define RTC_SLEEP_PD_INT_8M PMU_SLEEP_PD_RC_FAST //!< Power down Internal 20M oscillator +#define RTC_SLEEP_PD_XTAL PMU_SLEEP_PD_XTAL //!< Power down main XTAL +#define RTC_SLEEP_PD_MODEM PMU_SLEEP_PD_MODEM //!< Power down modem(include wifi, ble and 15.4) + +//These flags are not power domains, but will affect some sleep parameters +#define RTC_SLEEP_DIG_USE_8M BIT(16) +#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) +#define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature + +#if SOC_PM_SUPPORT_EXT0_WAKEUP +#define RTC_EXT0_TRIG_EN PMU_EXT0_WAKEUP_EN //!< EXT0 wakeup +#else +#define RTC_EXT0_TRIG_EN 0 +#endif + +#if SOC_PM_SUPPORT_EXT1_WAKEUP +#define RTC_EXT1_TRIG_EN PMU_EXT1_WAKEUP_EN //!< EXT1 wakeup +#else +#define RTC_EXT1_TRIG_EN 0 +#endif + +#define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup + +#if SOC_LP_TIMER_SUPPORTED +#define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup +#else +#define RTC_TIMER_TRIG_EN 0 +#endif + +#if SOC_WIFI_SUPPORTED +#define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only) +#else +#define RTC_WIFI_TRIG_EN 0 +#endif + +#if SOC_UART_SUPPORT_WAKEUP_INT +#define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only) +#define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) +#else +#define RTC_UART0_TRIG_EN 0 +#define RTC_UART1_TRIG_EN 0 +#endif + +#if SOC_BT_SUPPORTED +#define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only) +#else +#define RTC_BT_TRIG_EN 0 +#endif + +#define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN + +#if SOC_LP_CORE_SUPPORTED +#define RTC_LP_CORE_TRIG_EN PMU_LP_CORE_WAKEUP_EN //!< LP core wakeup +#else +#define RTC_LP_CORE_TRIG_EN 0 +#endif //SOC_LP_CORE_SUPPORTED + +#define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO +#define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO + +/** + * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip + */ +#define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN | \ + RTC_EXT1_TRIG_EN | \ + RTC_GPIO_TRIG_EN | \ + RTC_TIMER_TRIG_EN | \ + RTC_WIFI_TRIG_EN | \ + RTC_UART0_TRIG_EN | \ + RTC_UART1_TRIG_EN | \ + RTC_BT_TRIG_EN | \ + RTC_LP_CORE_TRIG_EN | \ + RTC_XTAL32K_DEAD_TRIG_EN | \ + RTC_USB_TRIG_EN | \ + RTC_BROWNOUT_DET_TRIG_EN) + +#if SOC_PM_SUPPORT_EXT0_WAKEUP +#define PMU_EXT0_WAKEUP_EN BIT(0) +#endif +#if SOC_PM_SUPPORT_EXT1_WAKEUP +#define PMU_EXT1_WAKEUP_EN BIT(1) +#endif + +#define PMU_GPIO_WAKEUP_EN BIT(2) +#define PMU_WIFI_BEACON_WAKEUP_EN BIT(3) +#define PMU_LP_TIMER_WAKEUP_EN BIT(4) +#define PMU_WIFI_SOC_WAKEUP_EN BIT(5) +#define PMU_UART0_WAKEUP_EN BIT(6) +#define PMU_UART1_WAKEUP_EN BIT(7) +#define PMU_SDIO_WAKEUP_EN BIT(8) +#define PMU_BLE_SOC_WAKEUP_EN BIT(10) +#if SOC_LP_CORE_SUPPORTED +#define PMU_LP_CORE_WAKEUP_EN BIT(11) +#endif //SOC_LP_CORE_SUPPORTED +#define PMU_USB_WAKEUP_EN BIT(14) + + +#define PMU_SLEEP_PD_TOP BIT(0) +#define PMU_SLEEP_PD_VDDSDIO BIT(1) +#define PMU_SLEEP_PD_MODEM BIT(2) +#define PMU_SLEEP_PD_HP_PERIPH BIT(3) +#define PMU_SLEEP_PD_CPU BIT(4) + +#if SOC_PM_SUPPORT_HP_AON_PD +#define PMU_SLEEP_PD_HP_AON BIT(5) +#endif + +#define PMU_SLEEP_PD_MEM_G0 BIT(6) +#define PMU_SLEEP_PD_MEM_G1 BIT(7) +#define PMU_SLEEP_PD_MEM_G2 BIT(8) +#define PMU_SLEEP_PD_MEM_G3 BIT(9) +#define PMU_SLEEP_PD_MEM (PMU_SLEEP_PD_MEM_G0|PMU_SLEEP_PD_MEM_G1|PMU_SLEEP_PD_MEM_G2|PMU_SLEEP_PD_MEM_G3) +#define PMU_SLEEP_PD_XTAL BIT(10) +#define PMU_SLEEP_PD_RC_FAST BIT(11) +#define PMU_SLEEP_PD_XTAL32K BIT(12) +#define PMU_SLEEP_PD_RC32K BIT(13) +#define PMU_SLEEP_PD_LP_PERIPH BIT(14) + +typedef struct { + pmu_hal_context_t *hal; + void *mc; +} pmu_context_t; + +pmu_context_t * PMU_instance(void); + +typedef enum pmu_hp_sysclk_src { + PMU_HP_SYSCLK_XTAL = 0, + PMU_HP_SYSCLK_PLL, + PMU_HP_SYSCLK_FOSC +} pmu_hp_sysclk_src_t; + +typedef enum pmu_sleep_protect_mode { + PMU_SLEEP_PROTECT_HP_SLEEP = 0, + PMU_SLEEP_PROTECT_XTAL, + PMU_SLEEP_PROTECT_HP_LP_SLEEP, + PMU_SLEEP_PROTECT_DISABLE +} pmu_sleep_protect_mode_t; + +typedef enum pmu_sleep_regdma_entry { + PMU_SLEEP_REGDMA_ENTRY_0 = 0, + PMU_SLEEP_REGDMA_ENTRY_1, + PMU_SLEEP_REGDMA_ENTRY_2, + PMU_SLEEP_REGDMA_ENTRY_3, + PMU_SLEEP_REGDMA_ENTRY_MAX +} pmu_sleep_regdma_entry_t; + +/** + * @brief PMU ICG modem code of HP system + */ +typedef enum { + PMU_HP_ICG_MODEM_CODE_SLEEP = 0, + PMU_HP_ICG_MODEM_CODE_MODEM = 1, + PMU_HP_ICG_MODEM_CODE_ACTIVE = 2, +} pmu_hp_icg_modem_mode_t; + + +/** + * @brief Enable_regdma_backup. + */ +void pmu_sleep_enable_regdma_backup(void); + +/** + * @brief Disable_regdma_backup. + */ +void pmu_sleep_disable_regdma_backup(void); + +/** + * @brief Get sleep PLL enable status + * + * @return true if PLL is enabled by PMU in modem state + */ +bool pmu_sleep_pll_already_enabled(void); + +/** + * @brief Calculate the hardware time overhead during sleep to compensate for sleep time + * + * @param pd_flags flags indicates the power domain that will be powered down + * @param slowclk_period re-calibrated slow clock period + * @param fastclk_period re-calibrated fast clock period + * + * @return hardware time overhead in us + */ +uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period); + +/** + * @brief Get default sleep configuration + * @param config pmu_sleep_config instance + * @param pd_flags flags indicates the power domain that will be powered down + * @param adjustment total software and hardware time overhead + * @param slowclk_period re-calibrated slow clock period in microseconds, + * Q13.19 fixed point format + * @param fastclk_period re-calibrated fast clock period in microseconds, + * Q13.19 fixed point format + * @param dslp configuration for deep sleep mode + + * @return hardware time overhead in us + */ +const pmu_sleep_config_t* pmu_sleep_config_default(pmu_sleep_config_t *config, uint32_t pd_flags, uint32_t adjustment, uint32_t slowclk_period, uint32_t fastclk_period, bool dslp); + +/** + * @brief Prepare the chip to enter sleep mode + * + * This function configures various power/analog parameters and lp/lp system configuration + * used in sleep state machines + * + * This function does not actually enter sleep mode; this is done using + * pmu_sleep_start function. Software may do some other actions between + * pmu_sleep_init and pmu_sleep_start, such as set wakeup timer and configure + * wakeup sources. + * + * @param config sleep mode configuration + * + * @param dslp is initialize for deep sleep mode + */ +void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp); + +/** + * @brief Enter deep or light sleep mode + * + * This function enters the sleep mode previously configured using pmu_sleep_init + * function. Before entering sleep, software should configure wake up sources + * appropriately (set up GPIO wakeup registers, timer wakeup registers, + * and so on). + * + * If deep sleep mode was configured using pmu_sleep_init, and sleep is not + * rejected by hardware (based on reject_opt flags), this function never returns. + * When the chip wakes up from deep sleep, CPU is reset and execution starts + * from ROM bootloader. + * + * If light sleep mode was configured using pmu_sleep_init, this function + * returns on wakeup, or if sleep is rejected by hardware. + * + * @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags + * combined with OR) + * @param reject_opt bit mask of sleep reject reasons, used to + * prevent wakeup source set before the sleep request) + * @param lslp_mem_inf_fpu If non-zero then the low power config is restored + * immediately on wake. Recommended for light sleep, + * has no effect if the system goes into deep sleep. + * + * @return non-zero if sleep was rejected by hardware + */ +uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); + +/** + * @brief Finish sleep process settings and get sleep reject status + * @return return sleep reject status + */ +bool pmu_sleep_finish(void); + +/** + * @brief Initialize PMU related power/clock/digital parameters and functions + */ +void pmu_init(void); + +/** + * @brief Enable or disable system clock in PMU HP sleep state + * + * This API only used for fix BLE 40 MHz low power clock source issue + * + * @param enable true to enable, false to disable + */ +void pmu_sleep_enable_hp_sleep_sysclk(bool enable); + +/** + * Get the time overhead used by regdma to work on the retention link during the hardware wake-up process + * @return regdma time cost during hardware wake-up stage in microseconds + */ +uint32_t pmu_sleep_get_wakup_retention_cost(void); + +#endif //#if SOC_PMU_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/gdma.h b/components/esp_hw_support/include/esp_private/gdma.h index f888cd5bc9bd..3c9fbb6f5cbd 100644 --- a/components/esp_hw_support/include/esp_private/gdma.h +++ b/components/esp_hw_support/include/esp_private/gdma.h @@ -23,6 +23,8 @@ extern "C" { */ typedef struct gdma_channel_t *gdma_channel_handle_t; +#ifndef GDMA_TYPES_DECLARED +#define GDMA_TYPES_DECLARED /** * @brief Enumeration of peripherals which have the DMA capability * @note Some peripheral might not be available on certain chip, please refer to `soc_caps.h` for detail. @@ -50,6 +52,7 @@ typedef enum { GDMA_CHANNEL_DIRECTION_TX, /*!< GDMA channel direction: TX */ GDMA_CHANNEL_DIRECTION_RX, /*!< GDMA channel direction: RX */ } gdma_channel_direction_t; +#endif /** * @brief Collection of configuration items that used for allocating GDMA channel diff --git a/components/esp_hw_support/include/esp_private/io_mux.h b/components/esp_hw_support/include/esp_private/io_mux.h new file mode 100644 index 000000000000..3c3056d76209 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/io_mux.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the clock source for IO MUX + * + * @note IO MUX clock is shared by submodules like SDM, Glitch Filter. + * The submodule drivers should call this function to detect if the user set the clock differently. + * + * @param clk_src The clock source for IO MUX + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: The IO MUX has been set to another clock source + */ +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/rtc_clk.h b/components/esp_hw_support/include/esp_private/rtc_clk.h new file mode 100644 index 000000000000..17c1a939b684 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/rtc_clk.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Switch CPU clock source to XTAL, and let cpu frequency equal to main XTAL frequency. + * + * This function does not disable BBPLL. If BBPLL requires to be disabled to save power, please call + * `rtc_clk_cpu_freq_set_xtal` instead. It does one extra check to see whether can disable the BBPLL after switching the + * CPU clock source to XTAL. + * + * Currently, this function should only be called in `esp_restart_noos` and `esp_restart_noos_dig` to switch the CPU + * clock source back to XTAL (by default) before reset. + */ +void rtc_clk_cpu_set_to_default_config(void); + +/** + * @brief Notify that the BBPLL has a new in-use consumer + * + * Currently, this function is only used for tracking whether USB Serial/JTAG is using the 48MHz PHY clock + * + * Note: Calling this function only helps to not disable the BBPLL clock in `rtc_clk_cpu_freq_set_config`. + * For light and deep sleep, whether to disable the BBPLL in the interal call to `rtc_clk_cpu_freq_set_xtal` + * varies for targets. + * On ESP32C3/S3, USB CDC device can not function properly during sleep due to the lack of APB clock. Therefore. + * `rtc_clk_cpu_freq_set_xtal` will always disable BBPLL, no matter whether BBPLL has any consumer. + * On ESP32C6/H2, USB CDC device can maintain the minimum connection with the host during sleep, so + * `rtc_clk_cpu_freq_set_xtal` will check for BBPLL consumers, and keep BBPLL if USB Serial/JTAG is in use. + */ +void rtc_clk_bbpll_add_consumer(void); + +/** + * @brief Notify that the BBPLL has lost a consumer + */ +void rtc_clk_bbpll_remove_consumer(void); + +/** + * @brief Workaround for C2, S3, C6, H2. Trigger the calibration of PLL. Should be called when the bootloader doesn't provide a good enough PLL accuracy. +*/ +void rtc_clk_recalib_bbpll(void); + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/sar_periph_ctrl.h b/components/esp_hw_support/include/esp_private/sar_periph_ctrl.h new file mode 100644 index 000000000000..b6a0fdf74198 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sar_periph_ctrl.h @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * See target/sar_periph_ctrl.c to know involved peripherals + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialise SAR related peripheral register settings + * Should only be used when running into app stage + */ +void sar_periph_ctrl_init(void); + + +/*------------------------------------------------------------------------------ +* ADC Power +*----------------------------------------------------------------------------*/ +/** + * @brief Acquire the ADC oneshot mode power + */ +void sar_periph_ctrl_adc_oneshot_power_acquire(void); + +/** + * @brief Release the ADC oneshot mode power + */ +void sar_periph_ctrl_adc_oneshot_power_release(void); + +/** + * @brief Acquire the ADC continuous mode power + */ +void sar_periph_ctrl_adc_continuous_power_acquire(void); + +/** + * @brief Release the ADC ADC continuous mode power + */ +void sar_periph_ctrl_adc_continuous_power_release(void); + + +/*------------------------------------------------------------------------------ +* PWDET Power +*----------------------------------------------------------------------------*/ +/** + * @brief Acquire the PWDET Power + */ +void sar_periph_ctrl_pwdet_power_acquire(void); + +/** + * @brief Release the PWDET Power + */ +void sar_periph_ctrl_pwdet_power_release(void); + +/** + * @brief Acquire the temperature sensor power + */ +void temperature_sensor_power_acquire(void); + +/** + * @brief Release the temperature sensor power + */ +void temperature_sensor_power_release(void); + +/** + * @brief Get the temperature value and choose the temperature sensor range. Will be both used in phy and peripheral. + * + * @param range_changed Pointer to whether range has been changed here. If you don't need this param, you can + * set NULL directly. + * + * @return temperature sensor value. + */ +int16_t temp_sensor_get_raw_value(bool *range_changed); + +/** + * @brief Synchronize the tsens_idx between sar_periph and driver + * + * @param tsens_idx index value of temperature sensor attribute + */ +void temp_sensor_sync_tsens_idx(int tsens_idx); + +/** + * @brief Enable SAR power when system wakes up + */ +void sar_periph_ctrl_power_enable(void); + +/** + * @brief Disable SAR power when system goes to sleep + */ +void sar_periph_ctrl_power_disable(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/sleep_event.h b/components/esp_hw_support/include/esp_private/sleep_event.h new file mode 100644 index 000000000000..7a7efaabfcf6 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_event.h @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + /** + * Using SLEEP_EVENT to determine the execution of specific + * code at a particular point in the sleep flow. + */ + SLEEP_EVENT_HW_EXIT_SLEEP, // CPU wake up and start to work + SLEEP_EVENT_SW_CLK_READY, // CPU frequency restore + SLEEP_EVENT_SW_EXIT_SLEEP, // End of esp_light_sleep_start + SLEEP_EVENT_SW_GOTO_SLEEP, // Beginning of esp_light_sleep_start + SLEEP_EVENT_HW_TIME_START, // Start timing the sleep time + SLEEP_EVENT_HW_GOTO_SLEEP, // Hardware is about to power off + SLEEP_EVENT_SW_CPU_TO_MEM_START, // CPU registers are starting to be saved + SLEEP_EVENT_SW_CPU_TO_MEM_END, // CPU registers have finished saving +#if CONFIG_IDF_TARGET_ESP32H2 + SLEEP_EVENT_HW_FLASH_BBPLL_EN_START, // Beginning of rtc_clk_bbpll_enable when using FLASH_PLL + SLEEP_EVENT_HW_FLASH_BBPLL_EN_STOP, // End of rtc_clk_bbpll_enable when using FLASH_PLL +#endif + SLEEP_EVENT_HW_BBPLL_EN_START, // Beginning of rtc_clk_bbpll_enable + SLEEP_EVENT_HW_BBPLL_EN_STOP, // End of rtc_clk_bbpll_enable + SLEEP_EVENT_CB_INDEX_NUM, +} esp_sleep_event_cb_index_t; + +/** + * @brief Function prototype for light sleep event callback functions (if CONFIG_FREERTOS_USE_TICKLESS_IDLE). + * @param user_arg is the user provided argument while registering callbacks. + * @param ext_arg is an externally provided parameter that is used when the callback is executed. + * @return None + */ + +typedef esp_err_t (*esp_sleep_event_cb_t)(void *user_arg, void *ext_arg); + +/** + * @brief Function entry parameter types for light sleep event callback functions (if CONFIG_FREERTOS_USE_TICKLESS_IDLE) + */ +struct _esp_sleep_event_cb_config_t { + /** + * Callback function defined by internal developers. + */ + esp_sleep_event_cb_t cb; + /** + * Input parameters of callback function defined by internal developers. + */ + void *user_arg; + /** + * Execution priority of callback function defined by internal developers. + * The smaller the priority, the earlier it executes when call esp_sleep_execute_event_callbacks. + * If functions have the same priority, the function registered first will be executed first. + */ + uint32_t prior; + /** + * Next callback configuration defined by internal developer. + */ + struct _esp_sleep_event_cb_config_t *next; +}; + +typedef struct _esp_sleep_event_cb_config_t esp_sleep_event_cb_config_t; + +struct _esp_sleep_event_cbs_config_t { + /** + * Callback configurations defined by internal developers. + */ + esp_sleep_event_cb_config_t *sleep_event_cb_config[SLEEP_EVENT_CB_INDEX_NUM]; +}; + +typedef struct _esp_sleep_event_cbs_config_t esp_sleep_event_cbs_config_t; + +/** + * @brief Register event callbacks for light sleep internal events (if CONFIG_FREERTOS_USE_TICKLESS_IDLE) + * @param event_id Designed to register the corresponding event_cb in g_sleep_event_cbs_config + * @param event_cb_conf Config struct containing event callback function and corresponding argument + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the input parameter event_cb_conf is NULL or event_id is out of range + * - ESP_ERR_NO_MEM if the remaining memory is insufficient to support malloc + * - ESP_FAIL if register the same function repeatedly + * + * @note Some of these callback functions are called from IDLE task context hence they cannot call any blocking functions + * @note Passing NULL value will not deregister the callbacks, it will silently ignore and return ESP_OK + */ +esp_err_t esp_sleep_register_event_callback(esp_sleep_event_cb_index_t event_id, const esp_sleep_event_cb_config_t *event_cb_conf); + +/** + * @brief Unregister event callbacks for light sleep internal events (if CONFIG_FREERTOS_USE_TICKLESS_IDLE) + * @param event_id Designed to unregister the corresponding event_cb in g_sleep_event_cbs_config + * @param event_cb_conf Config struct containing event callback function and corresponding argument + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the input parameter cb is NULL or event_id is out of range + */ +esp_err_t esp_sleep_unregister_event_callback(esp_sleep_event_cb_index_t event_id, esp_sleep_event_cb_t cb); + +/** + * @brief Designed to execute functions in the esp_sleep_event_cb_config_t linked list + * + * @param event_id Designed to annotate the corresponding event_cb in g_sleep_event_cbs_config + * @param ext_arg Designed to pass external parameters + * @return None + */ +void esp_sleep_execute_event_callbacks(esp_sleep_event_cb_index_t event_id, void *ext_arg); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index b793e20db768..4ba2c08527c0 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -47,6 +47,15 @@ typedef enum { ESP_PD_DOMAIN_RTC_FAST_MEM, //!< RTC fast memory #endif ESP_PD_DOMAIN_XTAL, //!< XTAL oscillator +#if SOC_PM_SUPPORT_XTAL32K_PD + ESP_PD_DOMAIN_XTAL32K, //!< External 32 kHz XTAL oscillator +#endif +#if SOC_PM_SUPPORT_RC32K_PD + ESP_PD_DOMAIN_RC32K, //!< Internal 32 kHz RC oscillator +#endif +#if SOC_PM_SUPPORT_RC_FAST_PD + ESP_PD_DOMAIN_RC_FAST, //!< Internal Fast oscillator +#endif #if SOC_PM_SUPPORT_CPU_PD ESP_PD_DOMAIN_CPU, //!< CPU core #endif diff --git a/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.h new file mode 100644 index 000000000000..5b5bf5412892 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Acquire lock for HMAC cryptography peripheral + * + * Internally also locks the SHA peripheral, as the HMAC depends on the SHA peripheral + */ +void esp_crypto_hmac_lock_acquire(void); + +/** + * @brief Release lock for HMAC cryptography peripheral + * + * Internally also releases the SHA peripheral, as the HMAC depends on the SHA peripheral + */ +void esp_crypto_hmac_lock_release(void); + +/** + * @brief Acquire lock for DS cryptography peripheral + * + * Internally also locks the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals + */ +void esp_crypto_ds_lock_acquire(void); + +/** + * @brief Release lock for DS cryptography peripheral + * + * Internally also releases the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals + */ +void esp_crypto_ds_lock_release(void); + +/** + * @brief Acquire lock for the SHA and AES cryptography peripheral. + * + */ +void esp_crypto_sha_aes_lock_acquire(void); + +/** + * @brief Release lock for the SHA and AES cryptography peripheral. + * + */ +void esp_crypto_sha_aes_lock_release(void); + + +/** + * @brief Acquire lock for the mpi cryptography peripheral. + * + */ +void esp_crypto_mpi_lock_acquire(void); + +/** + * @brief Release lock for the mpi/rsa cryptography peripheral. + * + */ +void esp_crypto_mpi_lock_release(void); + +/** + * @brief Acquire lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_acquire(void); + +/** + * @brief Release lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_release(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/soc/esp32c6/rtc.h b/components/esp_hw_support/include/soc/esp32c6/rtc.h new file mode 100644 index 000000000000..dec61ee9cf76 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp32c6/rtc.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file esp32c6/rtc.h + * + * This file contains declarations of rtc related functions. + */ + +/** + * @brief Get current value of RTC counter in microseconds + * + * Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute + * + * @return current value of RTC counter in microseconds + */ +uint64_t esp_rtc_get_time_us(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c new file mode 100644 index 000000000000..f17551378885 --- /dev/null +++ b/components/esp_hw_support/modem_clock.c @@ -0,0 +1,450 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "freertos/FreeRTOS.h" +#include "hal/clk_gate_ll.h" +#include "esp_private/esp_modem_clock.h" +#include "esp_private/esp_pmu.h" +#include "esp_sleep.h" +#include "hal/efuse_hal.h" + +// Please define the frequently called modules in the low bit, +// which will improve the execution efficiency +typedef enum { + MODEM_CLOCK_MODEM_ADC_COMMON_FE, + MODEM_CLOCK_MODEM_PRIVATE_FE, + MODEM_CLOCK_COEXIST, + MODEM_CLOCK_I2C_MASTER, +#if SOC_WIFI_SUPPORTED + MODEM_CLOCK_WIFI_MAC, + MODEM_CLOCK_WIFI_BB, +#endif + MODEM_CLOCK_ETM, +#if SOC_BT_SUPPORTED + MODEM_CLOCK_BLE_MAC, + MODEM_CLOCK_BLE_BB, +#endif +#if SOC_IEEE802154_SUPPORTED + MODEM_CLOCK_802154_MAC, +#endif + MODEM_CLOCK_DATADUMP, + MODEM_CLOCK_DEVICE_MAX +} modem_clock_device_t; + + +typedef struct modem_clock_context { + modem_clock_hal_context_t *hal; + portMUX_TYPE lock; + struct { + int16_t refs; + uint16_t reserved; /* reserved for 4 bytes aligned */ + void (*configure)(struct modem_clock_context *, bool); + } dev[MODEM_CLOCK_DEVICE_MAX]; + /* the low-power clock source for each module */ + modem_clock_lpclk_src_t lpclk_src[PERIPH_MODEM_MODULE_NUM]; +} modem_clock_context_t; + + +#if SOC_WIFI_SUPPORTED +static void IRAM_ATTR modem_clock_wifi_mac_configure(modem_clock_context_t *ctx, bool enable) +{ + if (enable) { + modem_syscon_ll_enable_wifi_apb_clock(ctx->hal->syscon_dev, enable); + modem_syscon_ll_enable_wifi_mac_clock(ctx->hal->syscon_dev, enable); + } +} + +static void IRAM_ATTR modem_clock_wifi_bb_configure(modem_clock_context_t *ctx, bool enable) +{ + if (enable) { + modem_syscon_ll_clk_wifibb_configure(ctx->hal->syscon_dev, enable); + } +} +#endif // SOC_WIFI_SUPPORTED + +#if SOC_BT_SUPPORTED +static void IRAM_ATTR modem_clock_ble_mac_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_syscon_ll_enable_modem_sec_clock(ctx->hal->syscon_dev, enable); + modem_syscon_ll_enable_ble_timer_clock(ctx->hal->syscon_dev, enable); +} + +static void IRAM_ATTR modem_clock_ble_bb_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_syscon_ll_enable_bt_apb_clock(ctx->hal->syscon_dev, enable); + modem_syscon_ll_enable_bt_clock(ctx->hal->syscon_dev, enable); +} + +#endif // SOC_BT_SUPPORTED + +#if SOC_IEEE802154_SUPPORTED +static void IRAM_ATTR modem_clock_ieee802154_mac_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_syscon_ll_enable_ieee802154_apb_clock(ctx->hal->syscon_dev, enable); + modem_syscon_ll_enable_ieee802154_mac_clock(ctx->hal->syscon_dev, enable); +} +#endif // SOC_IEEE802154_SUPPORTED + +static void IRAM_ATTR modem_clock_coex_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_lpcon_ll_enable_coex_clock(ctx->hal->lpcon_dev, enable); +} + +static void IRAM_ATTR modem_clock_modem_adc_common_fe_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_clock_hal_enable_modem_adc_common_fe_clock(ctx->hal, enable); +} + +static void IRAM_ATTR modem_clock_modem_private_fe_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_clock_hal_enable_modem_private_fe_clock(ctx->hal, enable); +} + +static void IRAM_ATTR modem_clock_i2c_master_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_lpcon_ll_enable_i2c_master_clock(ctx->hal->lpcon_dev, enable); +} + +static void IRAM_ATTR modem_clock_etm_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_syscon_ll_enable_etm_clock(ctx->hal->syscon_dev, enable); +} + +static void IRAM_ATTR modem_clock_data_dump_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_syscon_ll_enable_data_dump_clock(ctx->hal->syscon_dev, enable); + modem_syscon_ll_enable_data_dump_mux_clock(ctx->hal->syscon_dev, enable); +} + +modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(void) +{ + /* It should be explicitly defined in the internal RAM */ + static DRAM_ATTR modem_clock_hal_context_t modem_clock_hal = { .syscon_dev = &MODEM_SYSCON, .lpcon_dev = &MODEM_LPCON }; + static DRAM_ATTR modem_clock_context_t modem_clock_context = { + .hal = &modem_clock_hal, .lock = portMUX_INITIALIZER_UNLOCKED, + .dev = { + [MODEM_CLOCK_MODEM_ADC_COMMON_FE] = { .refs = 0, .configure = modem_clock_modem_adc_common_fe_configure }, + [MODEM_CLOCK_MODEM_PRIVATE_FE] = { .refs = 0, .configure = modem_clock_modem_private_fe_configure }, + [MODEM_CLOCK_COEXIST] = { .refs = 0, .configure = modem_clock_coex_configure }, + [MODEM_CLOCK_I2C_MASTER] = { .refs = 0, .configure = modem_clock_i2c_master_configure }, +#if SOC_WIFI_SUPPORTED + [MODEM_CLOCK_WIFI_MAC] = { .refs = 0, .configure = modem_clock_wifi_mac_configure }, + [MODEM_CLOCK_WIFI_BB] = { .refs = 0, .configure = modem_clock_wifi_bb_configure }, +#endif + [MODEM_CLOCK_ETM] = { .refs = 0, .configure = modem_clock_etm_configure }, +#if SOC_BT_SUPPORTED + [MODEM_CLOCK_BLE_MAC] = { .refs = 0, .configure = modem_clock_ble_mac_configure }, + [MODEM_CLOCK_BLE_BB] = { .refs = 0, .configure = modem_clock_ble_bb_configure }, +#endif +#if SOC_IEEE802154_SUPPORTED + [MODEM_CLOCK_802154_MAC] = { .refs = 0, .configure = modem_clock_ieee802154_mac_configure }, +#endif + [MODEM_CLOCK_DATADUMP] = { .refs = 0, .configure = modem_clock_data_dump_configure } + }, + .lpclk_src = { [0 ... PERIPH_MODEM_MODULE_NUM - 1] = MODEM_CLOCK_LPCLK_SRC_INVALID } + }; + return &modem_clock_context; +} + +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +esp_err_t modem_clock_domain_clk_gate_enable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode) +{ + if (domain >= MODEM_CLOCK_DOMAIN_MAX || domain < MODEM_CLOCK_DOMAIN_MODEM_APB) { + return ESP_ERR_INVALID_ARG; + } + if (mode > PMU_HP_ICG_MODEM_CODE_ACTIVE || mode < PMU_HP_ICG_MODEM_CODE_SLEEP) { + return ESP_ERR_INVALID_ARG; + } + + portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); + modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code & ~BIT(mode))); + portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + return ESP_OK; +} + +esp_err_t modem_clock_domain_clk_gate_disable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode) +{ + if (domain >= MODEM_CLOCK_DOMAIN_MAX || domain < MODEM_CLOCK_DOMAIN_MODEM_APB) { + return ESP_ERR_INVALID_ARG; + } + if (mode > PMU_HP_ICG_MODEM_CODE_ACTIVE || mode < PMU_HP_ICG_MODEM_CODE_SLEEP) { + return ESP_ERR_INVALID_ARG; + } + + portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); + modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code | BIT(mode))); + portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + return ESP_OK; +} +#endif // #if SOC_PM_SUPPORT_PMU_MODEM_STATE + +static void IRAM_ATTR modem_clock_device_enable(modem_clock_context_t *ctx, uint32_t dev_map) +{ + int16_t refs = 0; + portENTER_CRITICAL_SAFE(&ctx->lock); + for (int i = 0; dev_map; dev_map >>= 1, i++) { + if (dev_map & BIT(0)) { + refs = ctx->dev[i].refs++; + if (refs == 0) { + (*ctx->dev[i].configure)(ctx, true); + } + } + } + portEXIT_CRITICAL_SAFE(&ctx->lock); + assert(refs >= 0); +} + +static void IRAM_ATTR modem_clock_device_disable(modem_clock_context_t *ctx, uint32_t dev_map) +{ + int16_t refs = 0; + portENTER_CRITICAL_SAFE(&ctx->lock); + for (int i = 0; dev_map; dev_map >>= 1, i++) { + if (dev_map & BIT(0)) { + refs = --ctx->dev[i].refs; + if (refs == 0) { + (*ctx->dev[i].configure)(ctx, false); + } + } + } + portEXIT_CRITICAL_SAFE(&ctx->lock); + assert(refs >= 0); +} + +void IRAM_ATTR modem_clock_module_mac_reset(periph_module_t module) +{ + modem_clock_context_t *ctx = MODEM_CLOCK_instance(); + portENTER_CRITICAL_SAFE(&ctx->lock); + switch (module) + { +#if SOC_WIFI_SUPPORTED + case PERIPH_WIFI_MODULE: + modem_syscon_ll_reset_wifimac(ctx->hal->syscon_dev); + break; +#endif +#if SOC_BT_SUPPORTED + case PERIPH_BT_MODULE: + modem_syscon_ll_reset_btmac(ctx->hal->syscon_dev); + modem_syscon_ll_reset_btmac_apb(ctx->hal->syscon_dev); + modem_syscon_ll_reset_ble_timer(ctx->hal->syscon_dev); + modem_syscon_ll_reset_modem_sec(ctx->hal->syscon_dev); + break; +#endif +#if SOC_IEEE802154_SUPPORTED + case PERIPH_IEEE802154_MODULE: + modem_syscon_ll_reset_zbmac(ctx->hal->syscon_dev); + break; + default: +#endif + assert(0); + } + portEXIT_CRITICAL_SAFE(&ctx->lock); +} + +#define WIFI_CLOCK_DEPS (BIT(MODEM_CLOCK_WIFI_MAC) | BIT(MODEM_CLOCK_WIFI_BB) | BIT(MODEM_CLOCK_COEXIST)) +#define BLE_CLOCK_DEPS (BIT(MODEM_CLOCK_BLE_MAC) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST)) +#define IEEE802154_CLOCK_DEPS (BIT(MODEM_CLOCK_802154_MAC) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST)) +#define COEXIST_CLOCK_DEPS (BIT(MODEM_CLOCK_COEXIST)) +#define PHY_CLOCK_DEPS (BIT(MODEM_CLOCK_I2C_MASTER) | BIT(MODEM_CLOCK_MODEM_ADC_COMMON_FE) | BIT(MODEM_CLOCK_MODEM_PRIVATE_FE)) +#define I2C_ANA_MST_CLOCK_DEPS (BIT(MODEM_CLOCK_I2C_MASTER)) +#define MODEM_ETM_CLOCK_DEPS (BIT(MODEM_CLOCK_ETM)) +#define MODEM_ADC_COMMON_FE_CLOCK_DEPS (BIT(MODEM_CLOCK_MODEM_ADC_COMMON_FE)) + +static IRAM_ATTR uint32_t modem_clock_get_module_deps(periph_module_t module) +{ + uint32_t deps = 0; + switch (module) { + case PERIPH_ANA_I2C_MASTER_MODULE: deps = I2C_ANA_MST_CLOCK_DEPS; break; + case PERIPH_PHY_MODULE: deps = PHY_CLOCK_DEPS; break; + case PERIPH_MODEM_ADC_COMMON_FE_MODULE: deps = MODEM_ADC_COMMON_FE_CLOCK_DEPS; break; +#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + case PERIPH_COEX_MODULE: deps = COEXIST_CLOCK_DEPS; break; +#endif +#if SOC_WIFI_SUPPORTED + case PERIPH_WIFI_MODULE: deps = WIFI_CLOCK_DEPS; break; +#endif +#if SOC_BT_SUPPORTED + case PERIPH_BT_MODULE: deps = BLE_CLOCK_DEPS; break; +#endif +#if SOC_IEEE802154_SUPPORTED + case PERIPH_IEEE802154_MODULE: deps = IEEE802154_CLOCK_DEPS; break; +#endif +#if SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + case PERIPH_MODEM_ETM_MODULE: deps = MODEM_ETM_CLOCK_DEPS; break; +#endif + default: + assert(0); + } + return deps; +} + +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +/* the ICG code's bit 0, 1 and 2 indicates the ICG state + * of pmu SLEEP, MODEM and ACTIVE mode respectively */ +#define ICG_NOGATING_SLEEP (BIT(PMU_HP_ICG_MODEM_CODE_SLEEP)) +#define ICG_NOGATING_MODEM (BIT(PMU_HP_ICG_MODEM_CODE_MODEM)) +#define ICG_NOGATING_ACTIVE (BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)) + +static const DRAM_ATTR uint32_t initial_gating_mode[MODEM_CLOCK_DOMAIN_MAX] = { + [MODEM_CLOCK_DOMAIN_MODEM_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_MODEM_PERIPH] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_WIFI] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_BT] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_MODEM_FE] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_IEEE802154] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_LP_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_I2C_MASTER] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_COEX] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_WIFIPWR] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, +}; + +static IRAM_ATTR void modem_clock_module_icg_map_init_all(void) +{ + portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + for (int domain = 0; domain < MODEM_CLOCK_DOMAIN_MAX; domain++) { + uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); + modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, initial_gating_mode[domain] | code); + } + portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); +} +#endif // SOC_PM_SUPPORT_PMU_MODEM_STATE + +void IRAM_ATTR modem_clock_module_enable(periph_module_t module) +{ + assert(IS_MODEM_MODULE(module)); +#if SOC_PM_SUPPORT_PMU_MODEM_STATE + modem_clock_module_icg_map_init_all(); +#endif + uint32_t deps = modem_clock_get_module_deps(module); + modem_clock_device_enable(MODEM_CLOCK_instance(), deps); +} + +void IRAM_ATTR modem_clock_module_disable(periph_module_t module) +{ + assert(IS_MODEM_MODULE(module)); + uint32_t deps = modem_clock_get_module_deps(module); + modem_clock_device_disable(MODEM_CLOCK_instance(), deps); +} + +void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpclk_src_t src, uint32_t divider) +{ + assert(IS_MODEM_MODULE(module)); + portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + switch (module) + { +#if SOC_WIFI_SUPPORTED + case PERIPH_WIFI_MODULE: + modem_clock_hal_deselect_all_wifi_lpclk_source(MODEM_CLOCK_instance()->hal); + modem_clock_hal_select_wifi_lpclk_source(MODEM_CLOCK_instance()->hal, src); + modem_lpcon_ll_set_wifi_lpclk_divisor_value(MODEM_CLOCK_instance()->hal->lpcon_dev, divider); + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true); + break; +#endif // SOC_WIFI_SUPPORTED + +#if SOC_BT_SUPPORTED + case PERIPH_BT_MODULE: + modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal); + modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, src); + modem_clock_hal_set_ble_rtc_timer_divisor_value(MODEM_CLOCK_instance()->hal, divider); + modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, true); +#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND + if (efuse_hal_chip_revision() != 0) { + if (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + pmu_sleep_enable_hp_sleep_sysclk(true); + } + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true); + modem_clock_domain_clk_gate_disable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); + } +#endif + break; +#endif // SOC_BT_SUPPORTED + + case PERIPH_COEX_MODULE: + modem_clock_hal_deselect_all_coex_lpclk_source(MODEM_CLOCK_instance()->hal); + modem_clock_hal_select_coex_lpclk_source(MODEM_CLOCK_instance()->hal, src); + modem_lpcon_ll_set_coex_lpclk_divisor_value(MODEM_CLOCK_instance()->hal->lpcon_dev, divider); + // modem_lpcon_ll_enable_coex_clock(MODEM_CLOCK_instance()->hal->lpcon_dev, true); // TODO: IDF-5727 + break; + default: + break; + } + modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN]; + MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = src; + portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + + /* The power domain of the low-power clock source required by the modem + * module remains powered on during sleep */ + esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \ + (last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \ + : (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \ + : (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \ + : (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \ + : ESP_PD_DOMAIN_MAX); + esp_sleep_pd_domain_t pu_domain = (esp_sleep_pd_domain_t) ( \ + (src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \ + : (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \ + : (src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \ + : (src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \ + : ESP_PD_DOMAIN_MAX); + esp_sleep_pd_config(pd_domain, ESP_PD_OPTION_OFF); + esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON); +} + +void modem_clock_deselect_lp_clock_source(periph_module_t module) +{ + assert(IS_MODEM_MODULE(module)); + portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN]; + MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID; + switch (module) + { +#if SOC_WIFI_SUPPORTED + case PERIPH_WIFI_MODULE: + modem_clock_hal_deselect_all_wifi_lpclk_source(MODEM_CLOCK_instance()->hal); + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false); + break; +#endif // SOC_WIFI_SUPPORTED + +#if SOC_BT_SUPPORTED + case PERIPH_BT_MODULE: + modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal); + modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, false); +#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND + if (efuse_hal_chip_revision() != 0) { + if (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + pmu_sleep_enable_hp_sleep_sysclk(false); + } + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false); + modem_clock_domain_clk_gate_enable(MODEM_CLOCK_DOMAIN_WIFI, PMU_HP_ICG_MODEM_CODE_SLEEP); + } +#endif + break; +#endif // SOC_BT_SUPPORTED + case PERIPH_COEX_MODULE: + modem_clock_hal_deselect_all_coex_lpclk_source(MODEM_CLOCK_instance()->hal); + // modem_lpcon_ll_enable_coex_clock(MODEM_CLOCK_instance()->hal->lpcon_dev, false); // TODO: IDF-5727 + break; + default: + break; + } + portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + + esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \ + (last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \ + : (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \ + : (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \ + : (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \ + : ESP_PD_DOMAIN_MAX); + esp_sleep_pd_config(pd_domain, ESP_PD_OPTION_OFF); +} diff --git a/components/esp_hw_support/port/esp32c6/CMakeLists.txt b/components/esp_hw_support/port/esp32c6/CMakeLists.txt index e69de29bb2d1..4f251876b0ef 100644 --- a/components/esp_hw_support/port/esp32c6/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c6/CMakeLists.txt @@ -0,0 +1,24 @@ +set(srcs "rtc_clk_init.c" + "rtc_clk.c" + "pmu_param.c" + "pmu_init.c" + "pmu_sleep.c" + "rtc_time.c" + "chip_info.c" + "ocode_init.c" + ) + +if(NOT BOOTLOADER_BUILD) + list(APPEND srcs "sar_periph_ctrl.c" + "esp_crypto_lock.c") + + if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE) + list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c") + endif() + +endif() + +add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") + +target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") +target_include_directories(${COMPONENT_LIB} PUBLIC . private_include) diff --git a/components/esp_hw_support/port/esp32c6/Kconfig.hw_support b/components/esp_hw_support/port/esp32c6/Kconfig.hw_support new file mode 100644 index 000000000000..c77f67f9ac1f --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/Kconfig.hw_support @@ -0,0 +1,44 @@ +choice ESP32C6_REV_MIN + prompt "Minimum Supported ESP32-C6 Revision" + default ESP32C6_REV_MIN_0 + help + Required minimum chip revision. ESP-IDF will check for it and + reject to boot if the chip revision fails the check. + This ensures the chip used will have some modifications (features, or bugfixes). + + The complied binary will only support chips above this revision, + this will also help to reduce binary size. + + config ESP32C6_REV_MIN_0 + bool "Rev v0.0" + config ESP32C6_REV_MIN_1 + bool "Rev v0.1 (ECO1)" +endchoice + +config ESP32C6_REV_MIN_FULL + int + default 0 if ESP32C6_REV_MIN_0 + default 1 if ESP32C6_REV_MIN_1 + +config ESP_REV_MIN_FULL + int + default ESP32C6_REV_MIN_FULL + + # + # MAX Revision + # + + comment "Maximum Supported ESP32-C6 Revision (Rev v0.99)" + # Maximum revision that IDF supports. + # It can not be changed by user. + # Only Espressif can change it when a new version will be supported in IDF. + # Supports all chips starting from ESP32C6_REV_MIN_FULL to ESP32C6_REV_MAX_FULL + +config ESP32C6_REV_MAX_FULL + int + default 99 + # keep in sync the "Maximum Supported Revision" description with this value + +config ESP_REV_MAX_FULL + int + default ESP32C6_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c6/Kconfig.mac b/components/esp_hw_support/port/esp32c6/Kconfig.mac index e69de29bb2d1..d5eac1e593f8 100644 --- a/components/esp_hw_support/port/esp32c6/Kconfig.mac +++ b/components/esp_hw_support/port/esp32c6/Kconfig.mac @@ -0,0 +1,46 @@ +choice ESP32C6_UNIVERSAL_MAC_ADDRESSES + bool "Number of universally administered (by IEEE) MAC address" + default ESP32C6_UNIVERSAL_MAC_ADDRESSES_FOUR + help + Configure the number of universally administered (by IEEE) MAC addresses. + + During initialization, MAC addresses for each network interface are generated or derived from a + single base MAC address. + + If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap, + Bluetooth and Ethernet) receive a universally administered MAC address. These are generated + sequentially by adding 0, 1, 2 and 3 (respectively) to the final octet of the base MAC address. + + If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth) + receive a universally administered MAC address. These are generated sequentially by adding 0 + and 1 (respectively) to the base MAC address. The remaining two interfaces (WiFi softap and Ethernet) + receive local MAC addresses. These are derived from the universal WiFi station and Bluetooth MAC + addresses, respectively. + + When using the default (Espressif-assigned) base MAC address, either setting can be used. When using + a custom universal MAC address range, the correct setting will depend on the allocation of MAC + addresses in this range (either 2 or 4 per device.) + + Note that ESP32-C6 has no integrated Ethernet MAC. Although it's possible to use the esp_read_mac() + API to return a MAC for Ethernet, this can only be used with an external MAC peripheral. + + config ESP32C6_UNIVERSAL_MAC_ADDRESSES_TWO + bool "Two" + select ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO + select ESP_MAC_ADDR_UNIVERSE_WIFI_STA + select ESP_MAC_ADDR_UNIVERSE_BT + + config ESP32C6_UNIVERSAL_MAC_ADDRESSES_FOUR + bool "Four" + select ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR + select ESP_MAC_ADDR_UNIVERSE_IEEE802154 + select ESP_MAC_ADDR_UNIVERSE_WIFI_STA + select ESP_MAC_ADDR_UNIVERSE_WIFI_AP + select ESP_MAC_ADDR_UNIVERSE_BT + select ESP_MAC_ADDR_UNIVERSE_ETH +endchoice + +config ESP32C6_UNIVERSAL_MAC_ADDRESSES + int + default 2 if ESP32C6_UNIVERSAL_MAC_ADDRESSES_TWO + default 4 if ESP32C6_UNIVERSAL_MAC_ADDRESSES_FOUR diff --git a/components/esp_hw_support/port/esp32c6/Kconfig.rtc b/components/esp_hw_support/port/esp32c6/Kconfig.rtc new file mode 100644 index 000000000000..24a5b8fb9466 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/Kconfig.rtc @@ -0,0 +1,39 @@ +choice RTC_CLK_SRC + prompt "RTC clock source" + default RTC_CLK_SRC_INT_RC + help + Choose which clock is used as RTC clock source. + + config RTC_CLK_SRC_INT_RC + bool "Internal 136kHz RC oscillator" + config RTC_CLK_SRC_EXT_CRYS + bool "External 32kHz crystal" + select ESP_SYSTEM_RTC_EXT_XTAL + config RTC_CLK_SRC_EXT_OSC + bool "External 32kHz oscillator at 32K_XP pin" + select ESP_SYSTEM_RTC_EXT_OSC + config RTC_CLK_SRC_INT_RC32K + bool "Internal 32kHz RC oscillator" +endchoice + +config RTC_CLK_CAL_CYCLES + int "Number of cycles for RTC_SLOW_CLK calibration" + default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K + default 1024 if RTC_CLK_SRC_INT_RC + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K + range 0 32766 if RTC_CLK_SRC_INT_RC + help + When the startup code initializes RTC_SLOW_CLK, it can perform + calibration by comparing the RTC_SLOW_CLK frequency with main XTAL + frequency. This option sets the number of RTC_SLOW_CLK cycles measured + by the calibration routine. Higher numbers increase calibration + precision, which may be important for applications which spend a lot of + time in deep sleep. Lower numbers reduce startup time. + + When this option is set to 0, clock calibration will not be performed at + startup, and approximate clock frequencies will be assumed: + + - 136000 Hz if internal RC oscillator is used as clock source. For this use value 1024. + - 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more. + In case more value will help improve the definition of the launch of the crystal. + If the crystal could not start, it will be switched to internal RC. diff --git a/components/esp_hw_support/port/esp32c6/chip_info.c b/components/esp_hw_support/port/esp32c6/chip_info.c new file mode 100644 index 000000000000..3924d78f5a84 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/chip_info.c @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_chip_info.h" +#include "hal/efuse_hal.h" + +void esp_chip_info(esp_chip_info_t *out_info) +{ + memset(out_info, 0, sizeof(*out_info)); + out_info->model = CHIP_ESP32C6; + out_info->revision = efuse_hal_chip_revision(); + out_info->cores = 1; + out_info->features = CHIP_FEATURE_WIFI_BGN | CHIP_FEATURE_BLE | CHIP_FEATURE_IEEE802154; +} diff --git a/components/esp_hw_support/port/esp32c6/cpu_region_protect.c b/components/esp_hw_support/port/esp32c6/cpu_region_protect.c new file mode 100644 index 000000000000..c11435fb84d4 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/cpu_region_protect.c @@ -0,0 +1,210 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "esp_cpu.h" +#include "esp_fault.h" + +#ifdef BOOTLOADER_BUILD +// Without L bit set +#define CONDITIONAL_NONE 0x0 +#define CONDITIONAL_R PMP_R +#define CONDITIONAL_RX PMP_R | PMP_X +#define CONDITIONAL_RW PMP_R | PMP_W +#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X +#else +// With L bit set +#define CONDITIONAL_NONE NONE +#define CONDITIONAL_R R +#define CONDITIONAL_RX RX +#define CONDITIONAL_RW RW +#define CONDITIONAL_RWX RWX +#endif + +#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1)) +#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1)) + +static void esp_cpu_configure_invalid_regions(void) +{ + const unsigned PMA_NONE = PMA_L | PMA_EN; + __attribute__((unused)) const unsigned PMA_RW = PMA_L | PMA_EN | PMA_R | PMA_W; + __attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X; + __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; + + // 1. Gap at bottom of address space + PMA_ENTRY_SET_TOR(0, SOC_CPU_SUBSYSTEM_LOW, PMA_TOR | PMA_NONE); + + // 2. Gap between CPU subsystem region & IROM + PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); + + // 3. Gap between ROM & RAM + PMA_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); + + // 4. Gap between DRAM and I_Cache + PMA_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE); + + // 5. Gap between D_Cache & LP_RAM + PMA_ENTRY_SET_TOR(7, SOC_DROM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(8, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE); + + // 6. Gap between LP memory & peripheral addresses + PMA_ENTRY_SET_TOR(9, SOC_RTC_IRAM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(10, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE); + + // 7. End of address space + PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE); +} + +void esp_cpu_configure_region_protection(void) +{ + /* Notes on implementation: + * + * 1) Note: ESP32-C6 CPU doesn't support overlapping PMP regions + * + * 2) ESP32-C6 supports 16 PMA regions so we use this feature to block all the invalid address ranges + * + * 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range) + * entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries + * which can be used to provide more granular access + * + * 4) Entries are grouped in order with some static asserts to try and verify everything is + * correct. + */ + + /* There are 4 configuration scenarios for SRAM + * + * 1. Bootloader build: + * - We cannot set the lock bit as we need to reconfigure it again for the application. + * We configure PMP to cover entire valid IRAM and DRAM range. + * + * 2. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT enabled + * - We split the SRAM into IRAM and DRAM such that IRAM region cannot be written to + * and DRAM region cannot be executed. We use _iram_end and _data_start markers to set the boundaries. + * We also lock these entries so the R/W/X permissions are enforced even for machine mode + * + * 3. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT disabled + * - The IRAM-DRAM split is not enabled so we just need to ensure that access to only valid address ranges are successful + * so for that we set PMP to cover entire valid IRAM and DRAM region. + * We also lock these entries so the R/W/X permissions are enforced even for machine mode + * + * 4. CPU is in OCD debug mode + * - The IRAM-DRAM split is not enabled so that OpenOCD can write and execute from IRAM. + * We set PMP to cover entire valid IRAM and DRAM region. + * We also lock these entries so the R/W/X permissions are enforced even for machine mode + */ + const unsigned NONE = PMP_L; + __attribute__((unused)) const unsigned R = PMP_L | PMP_R; + const unsigned RW = PMP_L | PMP_R | PMP_W; + const unsigned RX = PMP_L | PMP_R | PMP_X; + const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; + + // + // Configure all the invalid address regions using PMA + // + esp_cpu_configure_invalid_regions(); + + // + // Configure all the valid address regions using PMP + // + + // 1. CPU Subsystem region - contains debug mode code and interrupt config registers + const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH); + PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX); + _Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region"); + + // 2.1 I/D-ROM + PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); + PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX); + _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); + + if (esp_cpu_dbgr_is_attached()) { + // Anti-FI check that cpu is really in ocd mode + ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); + + // 5. IRAM and DRAM + const uint32_t pmpaddr5 = PMPADDR_NAPOT(SOC_IRAM_LOW, SOC_IRAM_HIGH); + PMP_ENTRY_SET(5, pmpaddr5, PMP_NAPOT | RWX); + _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); + } else { +#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _iram_end; + // 5. IRAM and DRAM + /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits + * Bootloader might have given extra permissions and those won't be cleared + */ + PMP_ENTRY_CFG_RESET(5); + PMP_ENTRY_CFG_RESET(6); + PMP_ENTRY_CFG_RESET(7); + PMP_ENTRY_SET(5, SOC_IRAM_LOW, NONE); + PMP_ENTRY_SET(6, (int)&_iram_end, PMP_TOR | RX); + PMP_ENTRY_SET(7, SOC_DRAM_HIGH, PMP_TOR | RW); +#else + // 5. IRAM and DRAM + const uint32_t pmpaddr5 = PMPADDR_NAPOT(SOC_IRAM_LOW, SOC_IRAM_HIGH); + PMP_ENTRY_SET(5, pmpaddr5, PMP_NAPOT | CONDITIONAL_RWX); + _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); +#endif + } + +#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _instruction_reserved_end; + extern int _rodata_reserved_end; + + const uint32_t irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end)); + const uint32_t drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end)); + + // 4. I_Cache / D_Cache (flash) + PMP_ENTRY_CFG_RESET(8); + PMP_ENTRY_CFG_RESET(9); + PMP_ENTRY_CFG_RESET(10); + PMP_ENTRY_SET(8, SOC_IROM_LOW, NONE); + PMP_ENTRY_SET(9, irom_resv_end, PMP_TOR | RX); + PMP_ENTRY_SET(10, drom_resv_end, PMP_TOR | R); +#else + // 4. I_Cache / D_Cache (flash) + const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); + PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | CONDITIONAL_RX); + _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region"); +#endif + + // 6. LP memory +#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _rtc_text_end; + /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits + * Bootloader might have given extra permissions and those won't be cleared + */ + PMP_ENTRY_CFG_RESET(11); + PMP_ENTRY_CFG_RESET(12); + PMP_ENTRY_CFG_RESET(13); + PMP_ENTRY_CFG_RESET(14); + PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE); +#if CONFIG_ULP_COPROC_RESERVE_MEM + // First part of LP mem is reserved for coprocessor + PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW); +#else // CONFIG_ULP_COPROC_RESERVE_MEM + // Repeat same previous entry, to ensure next entry has correct base address (TOR) + PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW, NONE); +#endif // !CONFIG_ULP_COPROC_RESERVE_MEM + PMP_ENTRY_SET(13, (int)&_rtc_text_end, PMP_TOR | RX); + PMP_ENTRY_SET(14, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); +#else + const uint32_t pmpaddr11 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); + PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | CONDITIONAL_RWX); + _Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region"); +#endif + + + // 7. Peripheral addresses + const uint32_t pmpaddr15 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); + PMP_ENTRY_SET(15, pmpaddr15, PMP_NAPOT | RW); + _Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region"); +} diff --git a/components/esp_hw_support/port/esp32c6/esp_clk_tree.c b/components/esp_hw_support/port/esp32c6/esp_clk_tree.c new file mode 100644 index 000000000000..ef7621cef952 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/esp_clk_tree.c @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_clk_tree.h" +#include "esp_err.h" +#include "esp_check.h" +#include "soc/rtc.h" +#include "hal/clk_tree_hal.h" +#include "hal/clk_tree_ll.h" +#include "esp_private/esp_clk_tree_common.h" + +static const char *TAG = "esp_clk_tree"; + +esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision, +uint32_t *freq_value) +{ + ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src"); + ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); + ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer"); + + uint32_t clk_src_freq = 0; + switch (clk_src) { + case SOC_MOD_CLK_CPU: + clk_src_freq = clk_hal_cpu_get_freq_hz(); + break; + case SOC_MOD_CLK_XTAL: + clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ; + break; + case SOC_MOD_CLK_PLL_F80M: + clk_src_freq = CLK_LL_PLL_80M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_PLL_F160M: + clk_src_freq = CLK_LL_PLL_160M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_PLL_F240M: + clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_RTC_SLOW: + clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RTC_FAST: + clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RC_FAST: + clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_XTAL32K: + clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision); + break; + case SOC_MOD_CLK_XTAL_D2: + clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1; + break; + default: + break; + } + + ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG, + "freq shouldn't be 0, calibration failed"); + *freq_value = clk_src_freq; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c6/esp_crypto_lock.c b/components/esp_hw_support/port/esp32c6/esp_crypto_lock.c new file mode 100644 index 000000000000..4f020502940f --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/esp_crypto_lock.c @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "esp_crypto_lock.h" + +/* Lock overview: +SHA: peripheral independent, but DMA is shared with AES +AES: peripheral independent, but DMA is shared with SHA +MPI/RSA: independent +ECC: independent +HMAC: needs SHA +DS: needs HMAC (which needs SHA), AES and MPI +*/ + +/* Lock for DS peripheral */ +static _lock_t s_crypto_ds_lock; + +/* Lock for HMAC peripheral */ +static _lock_t s_crypto_hmac_lock; + +/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */ +static _lock_t s_crypto_mpi_lock; + +/* Single lock for SHA and AES, sharing a reserved GDMA channel */ +static _lock_t s_crypto_sha_aes_lock; + +/* Lock for ECC peripheral */ +static _lock_t s_crypto_ecc_lock; + +void esp_crypto_hmac_lock_acquire(void) +{ + _lock_acquire(&s_crypto_hmac_lock); + esp_crypto_sha_aes_lock_acquire(); +} + +void esp_crypto_hmac_lock_release(void) +{ + esp_crypto_sha_aes_lock_release(); + _lock_release(&s_crypto_hmac_lock); +} + +void esp_crypto_ds_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ds_lock); + esp_crypto_hmac_lock_acquire(); + esp_crypto_mpi_lock_acquire(); +} + +void esp_crypto_ds_lock_release(void) +{ + esp_crypto_mpi_lock_release(); + esp_crypto_hmac_lock_release(); + _lock_release(&s_crypto_ds_lock); +} + +void esp_crypto_sha_aes_lock_acquire(void) +{ + _lock_acquire(&s_crypto_sha_aes_lock); +} + +void esp_crypto_sha_aes_lock_release(void) +{ + _lock_release(&s_crypto_sha_aes_lock); +} + +void esp_crypto_mpi_lock_acquire(void) +{ + _lock_acquire(&s_crypto_mpi_lock); +} + +void esp_crypto_mpi_lock_release(void) +{ + _lock_release(&s_crypto_mpi_lock); +} + +void esp_crypto_ecc_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ecc_lock); +} + +void esp_crypto_ecc_lock_release(void) +{ + _lock_release(&s_crypto_ecc_lock); +} diff --git a/components/esp_hw_support/port/esp32c6/io_mux.c b/components/esp_hw_support/port/esp32c6/io_mux.c new file mode 100644 index 000000000000..ea7446b2baaf --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/io_mux.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "freertos/FreeRTOS.h" +#include "esp_private/io_mux.h" +#include "hal/gpio_ll.h" + +static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + bool clk_conflict = false; + // check is the IO MUX has been set to another clock source + portENTER_CRITICAL(&s_io_mux_spinlock); + if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { + clk_conflict = true; + } else { + s_io_mux_clk_src = clk_src; + } + portEXIT_CRITICAL(&s_io_mux_spinlock); + + if (clk_conflict) { + return ESP_ERR_INVALID_STATE; + } + + gpio_ll_iomux_set_clk_src(clk_src); + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c6/ocode_init.c b/components/esp_hw_support/port/esp32c6/ocode_init.c new file mode 100644 index 000000000000..04743d7d6a7c --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/ocode_init.c @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/regi2c_dig_reg.h" +#include "soc/regi2c_lp_bias.h" +#include "hal/efuse_hal.h" +#include "hal/efuse_ll.h" +#include "regi2c_ctrl.h" +#include "esp_hw_log.h" + + +static const char *TAG = "ocode_init"; + +static void set_ocode_by_efuse(int ocode_scheme_ver) +{ + assert(ocode_scheme_ver == 1); + unsigned int ocode = efuse_ll_get_ocode(); + + //set ext_ocode + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode); + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1); +} + +static void calibrate_ocode(void) +{ + /* + Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL). + Method: + 1. read current cpu config, save in old_config; + 2. switch cpu to xtal because PLL will be closed when o-code calibration; + 3. begin o-code calibration; + 4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout; + 5. set cpu to old-config. + */ + soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); + rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX; + if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + cal_clk = RTC_CAL_32K_OSC_SLOW; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + cal_clk = RTC_CAL_32K_XTAL; + } + + uint64_t max_delay_time_us = 10000; + uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100); + uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period); + uint64_t cycle0 = rtc_time_get(); + uint64_t timeout_cycle = cycle0 + max_delay_cycle; + uint64_t cycle1 = 0; + + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + rtc_clk_cpu_freq_set_xtal(); + + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0); + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1); + bool odone_flag = 0; + bool bg_odone_flag = 0; + while (1) { + odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG); + bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG); + cycle1 = rtc_time_get(); + if (odone_flag && bg_odone_flag) { + break; + } + if (cycle1 >= timeout_cycle) { + ESP_HW_LOGW(TAG, "o_code calibration fail\n"); + break; + } + } + rtc_clk_cpu_freq_set_config(&old_config); +} + +void esp_ocode_calib_init(void) +{ + if (efuse_hal_blk_version() >= 1) { + set_ocode_by_efuse(1); + } else { + calibrate_ocode(); + } +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_init.c b/components/esp_hw_support/port/esp32c6/pmu_init.c new file mode 100644 index 000000000000..e64111e19b3a --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/pmu_init.c @@ -0,0 +1,223 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/pmu_struct.h" +#include "hal/pmu_hal.h" +#include "pmu_param.h" +#include "esp_private/esp_pmu.h" +#include "soc/regi2c_dig_reg.h" +#include "regi2c_ctrl.h" + +static __attribute__((unused)) const char *TAG = "pmu_init"; + +typedef struct { + const pmu_hp_system_power_param_t *power; + const pmu_hp_system_clock_param_t *clock; + const pmu_hp_system_digital_param_t *digital; + pmu_hp_system_analog_param_t *analog; //param determined at runtime + const pmu_hp_system_retention_param_t *retent; +} pmu_hp_system_param_t; + +typedef struct { + const pmu_lp_system_power_param_t *power; + pmu_lp_system_analog_param_t *analog; //param determined at runtime +} pmu_lp_system_param_t; + +pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) +{ + /* It should be explicitly defined in the internal RAM, because this + * instance will be used in pmu_sleep.c */ + static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU }; + static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT(); + static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc }; + return &pmu_context; +} + +void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param) +{ + const pmu_hp_system_power_param_t *power = param->power; + const pmu_hp_system_clock_param_t *clock = param->clock; + const pmu_hp_system_digital_param_t *dig = param->digital; + const pmu_hp_system_analog_param_t *anlg = param->analog; + const pmu_hp_system_retention_param_t *ret = param->retent; + + assert(ctx->hal); + /* Default configuration of hp-system power in active, modem and sleep modes */ + pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val); + pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); + pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal); + + /* Default configuration of hp-system clock in active, modem and sleep modes */ + pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func); + pmu_ll_hp_set_icg_apb (ctx->hal->dev, mode, clock->icg_apb); + pmu_ll_hp_set_icg_modem (ctx->hal->dev, mode, clock->icg_modem.code); + pmu_ll_hp_set_sysclk_nodiv (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_nodiv); + pmu_ll_hp_set_icg_sysclk_enable (ctx->hal->dev, mode, clock->sysclk.icg_sysclk_en); + pmu_ll_hp_set_sysclk_slp_sel (ctx->hal->dev, mode, clock->sysclk.sysclk_slp_sel); + pmu_ll_hp_set_icg_sysclk_slp_sel(ctx->hal->dev, mode, clock->sysclk.icg_slp_sel); + pmu_ll_hp_set_dig_sysclk (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_sel); + + /* Default configuration of hp-system digital sub-system in active, modem + * and sleep modes */ + pmu_ll_hp_set_uart_wakeup_enable(ctx->hal->dev, mode, dig->syscntl.uart_wakeup_en); + pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, mode, dig->syscntl.lp_pad_hold_all); + pmu_ll_hp_set_hold_all_hp_pad (ctx->hal->dev, mode, dig->syscntl.hp_pad_hold_all); + pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, mode, dig->syscntl.dig_pad_slp_sel); + pmu_ll_hp_set_pause_watchdog (ctx->hal->dev, mode, dig->syscntl.dig_pause_wdt); + pmu_ll_hp_set_cpu_stall (ctx->hal->dev, mode, dig->syscntl.dig_cpu_stall); + + /* Default configuration of hp-system analog sub-system in active, modem and + * sleep modes */ + pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias); + pmu_ll_hp_set_dbg_atten (ctx->hal->dev, mode, anlg->bias.dbg_atten); + pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur); + pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep); + pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd); + pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd); + pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd); + pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_mem_dbias); + pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias); + pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias); + pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b); + + /* Default configuration of hp-system retention sub-system in active, modem + * and sleep modes */ + pmu_ll_hp_set_retention_param(ctx->hal->dev, mode, ret->retention.val); + pmu_ll_hp_set_backup_icg_func(ctx->hal->dev, mode, ret->backup_clk); + + /* Some PMU initial parameter configuration */ + pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true); + pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true); + + pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); +} + +void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) +{ + const pmu_lp_system_power_param_t *power = param->power; + const pmu_lp_system_analog_param_t *anlg = param->analog; + + assert(ctx->hal); + /* Default configuration of lp-system power in active and sleep modes */ + pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val); + pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); + pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal); + + /* Default configuration of lp-system analog sub-system in active and + * sleep modes */ + pmu_ll_lp_set_bias_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.xpd_bias); + pmu_ll_lp_set_dbg_atten (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.dbg_atten); + pmu_ll_lp_set_current_power_off (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.pd_cur); + pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.bias_sleep); + pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_xpd); + pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd); + pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_dbias); + pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias); + pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b); +} + +static inline void pmu_power_domain_force_default(pmu_context_t *ctx) +{ + assert(ctx); + // for bypass reserved power domain + const pmu_hp_power_domain_t pmu_hp_domains[] = { + PMU_HP_PD_TOP, + PMU_HP_PD_HP_AON, + PMU_HP_PD_CPU, + PMU_HP_PD_WIFI + }; + + for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) { + pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); + } + /* Isolate all memory banks while sleeping, avoid memory leakage current */ + pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0); + + pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false); + pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false); + pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false); +} + +static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +{ + assert (param->analog); + + param->power = pmu_hp_system_power_param_default(mode); + param->clock = pmu_hp_system_clock_param_default(mode); + param->digital = pmu_hp_system_digital_param_default(mode); + *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value + param->retent = pmu_hp_system_retention_param_default(mode); + + if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) { + param->analog->regulator0.dbias = get_act_hp_dbias(); + } +} + +static void pmu_hp_system_init_default(pmu_context_t *ctx) +{ + assert(ctx); + for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { + pmu_hp_system_analog_param_t analog = {}; + pmu_hp_system_param_t param = {.analog = &analog}; + + pmu_hp_system_param_default(mode, ¶m); + pmu_hp_system_init(ctx, mode, ¶m); + } +} + +static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +{ + assert (param->analog); + + param->power = pmu_lp_system_power_param_default(mode); + *param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value + + if (mode == PMU_MODE_LP_ACTIVE) { + param->analog->regulator0.dbias = get_act_lp_dbias(); + } +} + +static void pmu_lp_system_init_default(pmu_context_t *ctx) +{ + assert(ctx); + for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { + pmu_lp_system_analog_param_t analog = {}; + pmu_lp_system_param_t param = {.analog = &analog}; + + pmu_lp_system_param_default(mode, ¶m); + pmu_lp_system_init(ctx, mode, ¶m); + } +} + +void pmu_init(void) +{ + /* Peripheral reg i2c power up */ + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); + + pmu_hp_system_init_default(PMU_instance()); + pmu_lp_system_init_default(PMU_instance()); + + pmu_power_domain_force_default(PMU_instance()); +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_param.c b/components/esp_hw_support/port/esp32c6/pmu_param.c new file mode 100644 index 000000000000..41c15ab8d025 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/pmu_param.c @@ -0,0 +1,504 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "pmu_param.h" +#include "soc/pmu_icg_mapping.h" +#include "esp_private/esp_pmu.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" +#include "esp_hw_log.h" + +static __attribute__((unused)) const char *TAG = "pmu_param"; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .vdd_spi_pd_en = 0, \ + .mem_dslp = 0, \ + .mem_pd_en = 0, \ + .wifi_pd_en = 0, \ + .cpu_pd_en = 0, \ + .aon_pd_en = 0, \ + .top_pd_en = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 0, \ + .i2c_retention = 0, \ + .xpd_bb_i2c = 1, \ + .xpd_bbpll_i2c = 1, \ + .xpd_bbpll = 1 \ + }, \ + .xtal = { \ + .xpd_xtal = 1 \ + } \ +} + +#define PMU_HP_MODEM_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .vdd_spi_pd_en = 0, \ + .mem_dslp = 0, \ + .mem_pd_en = 0, \ + .wifi_pd_en = 0, \ + .cpu_pd_en = 1, \ + .aon_pd_en = 0, \ + .top_pd_en = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 0, \ + .i2c_retention = 0, \ + .xpd_bb_i2c = 1, \ + .xpd_bbpll_i2c = 1, \ + .xpd_bbpll = 1 \ + }, \ + .xtal = { \ + .xpd_xtal = 1 \ + } \ +} + +#define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .vdd_spi_pd_en = 1, \ + .mem_dslp = 0, \ + .mem_pd_en = 0, \ + .wifi_pd_en = 1, \ + .cpu_pd_en = 0, \ + .aon_pd_en = 0, \ + .top_pd_en = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 1, \ + .i2c_retention = 1, \ + .xpd_bb_i2c = 1, \ + .xpd_bbpll_i2c = 0, \ + .xpd_bbpll = 0, \ + }, \ + .xtal = { \ + .xpd_xtal = 0 \ + } \ +} + +const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_power_param_t hp_power[] = { + PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT(), + PMU_HP_MODEM_POWER_CONFIG_DEFAULT(), + PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_power)); + return &hp_power[mode]; +} + +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ + }, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + } \ +} + +#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_MODEM \ + }, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = PMU_HP_SYSCLK_PLL \ + } \ +} + +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ + }, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + } \ +} + +const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_clock_param_t hp_clock[] = { + PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT(), + PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT(), + PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_clock)); + return &hp_clock[mode]; +} + +#define PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT() { \ + .syscntl = { \ + .uart_wakeup_en = 0, \ + .lp_pad_hold_all = 0, \ + .hp_pad_hold_all = 0, \ + .dig_pad_slp_sel = 0, \ + .dig_pause_wdt = 0, \ + .dig_cpu_stall = 0 \ + } \ +} + +#define PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT() { \ + .syscntl = { \ + .uart_wakeup_en = 1, \ + .lp_pad_hold_all = 0, \ + .hp_pad_hold_all = 0, \ + .dig_pad_slp_sel = 0, \ + .dig_pause_wdt = 1, \ + .dig_cpu_stall = 1 \ + } \ +} + +#define PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() { \ + .syscntl = { \ + .uart_wakeup_en = 1, \ + .lp_pad_hold_all = 0, \ + .hp_pad_hold_all = 0, \ + .dig_pad_slp_sel = 1, \ + .dig_pause_wdt = 1, \ + .dig_cpu_stall = 1 \ + } \ +} + +const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_digital_param_t hp_digital[] = { + PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT(), + PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT(), + PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_digital)); + return &hp_digital[mode]; +} + +#define PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 1, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ + }, \ + .regulator0 = { \ + .lp_dbias_vol = 0xd, \ + .hp_dbias_vol = 0x1c,\ + .dbias_sel = 1, \ + .dbias_init = 1, \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +#define PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ + }, \ + .regulator0 = { \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +#define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ + }, \ + .regulator0 = { \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = 1 \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_analog_param_t hp_analog[] = { + PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT(), + PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT(), + PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_analog)); + return &hp_analog[mode]; +} + +#define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry) ((((dir)<<2) | (entry & 0x3)) & 0x7) + +#define PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT() { \ + .retention = { \ + .hp_sleep2active_backup_modem_clk_code = 2, \ + .hp_modem2active_backup_modem_clk_code = 2, \ + .hp_active_retention_mode = 0, \ + .hp_sleep2active_retention_en = 0, \ + .hp_modem2active_retention_en = 0, \ + .hp_sleep2active_backup_clk_sel = 0, \ + .hp_modem2active_backup_clk_sel = 1, \ + .hp_sleep2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 0), \ + .hp_modem2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 2), \ + .hp_sleep2active_backup_en = 0, \ + .hp_modem2active_backup_en = 0, \ + }, \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_GDMA) | \ + BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ + BIT(PMU_ICG_FUNC_ENA_TG0) | \ + BIT(PMU_ICG_FUNC_ENA_TG1) | \ + BIT(PMU_ICG_FUNC_ENA_HPBUS) | \ + BIT(PMU_ICG_FUNC_ENA_MSPI) | \ + BIT(PMU_ICG_FUNC_ENA_IOMUX) | \ + BIT(PMU_ICG_FUNC_ENA_SPI2) | \ + BIT(PMU_ICG_FUNC_ENA_UART0) | \ + BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ + ) \ +} + +#define PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT() { \ + .retention = { \ + .hp_sleep2modem_backup_modem_clk_code = 1, \ + .hp_modem_retention_mode = 0, \ + .hp_sleep2modem_retention_en = 0, \ + .hp_sleep2modem_backup_clk_sel = 0, \ + .hp_sleep2modem_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 1), \ + .hp_sleep2modem_backup_en = 0, \ + }, \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ + BIT(PMU_ICG_FUNC_ENA_TG0) | \ + BIT(PMU_ICG_FUNC_ENA_TG1) | \ + BIT(PMU_ICG_FUNC_ENA_HPBUS) | \ + BIT(PMU_ICG_FUNC_ENA_MSPI) | \ + BIT(PMU_ICG_FUNC_ENA_IOMUX) | \ + BIT(PMU_ICG_FUNC_ENA_SPI2) | \ + BIT(PMU_ICG_FUNC_ENA_UART0) | \ + BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ + ) \ +} + +#define PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() { \ + .retention = { \ + .hp_modem2sleep_backup_modem_clk_code = 0, \ + .hp_active2sleep_backup_modem_clk_code = 2, \ + .hp_sleep_retention_mode = 0, \ + .hp_modem2sleep_retention_en = 0, \ + .hp_active2sleep_retention_en = 0, \ + .hp_modem2sleep_backup_clk_sel = 0, \ + .hp_active2sleep_backup_clk_sel = 0, \ + .hp_modem2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 1), \ + .hp_active2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 0), \ + .hp_modem2sleep_backup_en = 0, \ + .hp_active2sleep_backup_en = 0, \ + }, \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_GDMA) | \ + BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ + BIT(PMU_ICG_FUNC_ENA_TG0) | \ + BIT(PMU_ICG_FUNC_ENA_TG1) | \ + BIT(PMU_ICG_FUNC_ENA_HPBUS) | \ + BIT(PMU_ICG_FUNC_ENA_MSPI) | \ + BIT(PMU_ICG_FUNC_ENA_IOMUX) | \ + BIT(PMU_ICG_FUNC_ENA_SPI2) | \ + BIT(PMU_ICG_FUNC_ENA_UART0) | \ + BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ + ) \ +} + +const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_retention_param_t hp_retention[] = { + PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT(), + PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT(), + PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_retention)); + return &hp_retention[mode]; +} + + +/** LP system default parameter */ + +#if CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +# define PMU_SLOW_CLK_USE_EXT_XTAL (1) +#else +# define PMU_SLOW_CLK_USE_EXT_XTAL (0) +#endif + +#define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .mem_dslp = 0, \ + .peri_pd_en = 0, \ + }, \ + .clk_power = { \ + .xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \ + .xpd_rc32k = 0, \ + .xpd_fosc = 1, \ + .pd_osc = 0 \ + } \ +} + +#define PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .mem_dslp = 1, \ + .peri_pd_en = 0, \ + }, \ + .clk_power = { \ + .xpd_xtal32k = 0, \ + .xpd_rc32k = 0, \ + .xpd_fosc = 0, \ + .pd_osc = 0 \ + }, \ + .xtal = { \ + .xpd_xtal = 0 \ + } \ +} + +const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mode_t mode) +{ + static const pmu_lp_system_power_param_t lp_power[] = { + PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT(), + PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(lp_power)); + return &lp_power[mode]; +} + +#define PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \ + .regulator0 = { \ + .slp_xpd = 0, \ + .xpd = 1, \ + .slp_dbias = 0, \ + .dbias = LP_CALI_DBIAS_DEFAULT \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +#define PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0, \ + .pd_cur = 1, \ + .bias_sleep = 1, \ + }, \ + .regulator0 = { \ + .slp_xpd = 0, \ + .xpd = 1, \ + .slp_dbias = 0, \ + .dbias = 12 \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_mode_t mode) +{ + static const pmu_lp_system_analog_param_t lp_analog[] = { + PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT(), + PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(lp_analog)); + return &lp_analog[mode]; +} + +uint32_t get_act_hp_dbias(void) +{ + /* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 1.15V + */ + uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + hp_cali_dbias = efuse_ll_get_active_hp_dbias(); + if (hp_cali_dbias != 0) { + //efuse dbias need to add 2 to meet the CPU frequency switching + if (hp_cali_dbias + 2 > 31) { + hp_cali_dbias = 31; + } else { + hp_cali_dbias += 2; + } + } else { + hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } + + return hp_cali_dbias; +} + +uint32_t get_act_lp_dbias(void) +{ + /* lp_cali_dbias is read from efuse to ensure that the lp_active_voltage is close to 1.15V + */ + uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + lp_cali_dbias = efuse_ll_get_active_lp_dbias(); + if (lp_cali_dbias != 0) { + //efuse dbias need to add 2 to meet the CPU frequency switching + if (lp_cali_dbias + 2 > 31) { + lp_cali_dbias = 31; + } else { + lp_cali_dbias += 2; + } + } else { + lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n"); + } + + return lp_cali_dbias; +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_sleep.c b/components/esp_hw_support/port/esp32c6/pmu_sleep.c new file mode 100644 index 000000000000..c85fd72c2c79 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/pmu_sleep.c @@ -0,0 +1,357 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/pmu_struct.h" +#include "hal/lp_aon_hal.h" +#include "esp_private/esp_pmu.h" +#include "pmu_param.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" +#include "esp_hw_log.h" + +static __attribute__((unused)) const char *TAG = "pmu_sleep"; + +#define HP(state) (PMU_MODE_HP_ ## state) +#define LP(state) (PMU_MODE_LP_ ## state) + +static bool s_pmu_sleep_regdma_backup_enabled; + +uint32_t get_lslp_dbg(void) +{ + uint32_t pmu_dbg_atten_lightsleep = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_dbg_atten_lightsleep = efuse_ll_get_lslp_dbg(); + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, lslp dbg not burnt in efuse\n"); + } + + return pmu_dbg_atten_lightsleep; +} + +uint32_t get_lslp_hp_dbias(void) +{ + uint32_t pmu_hp_dbias_lightsleep_0v6 = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_hp_dbias_lightsleep_0v6 = efuse_ll_get_lslp_hp_dbias(); + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, lslp hp dbias not burnt in efuse\n"); + } + + return pmu_hp_dbias_lightsleep_0v6; +} + +uint32_t get_dslp_dbg(void) +{ + uint32_t pmu_dbg_atten_deepsleep = PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_dbg_atten_deepsleep = efuse_ll_get_dslp_dbg() + EFUSE_BURN_OFFSET_DSLP_DBG; + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, dslp dbg not burnt in efuse\n"); + } + + return pmu_dbg_atten_deepsleep; +} + +uint32_t get_dslp_lp_dbias(void) +{ + uint32_t pmu_lp_dbias_deepsleep_0v7 = PMU_LP_DBIAS_DEEPSLEEP_0V7_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_lp_dbias_deepsleep_0v7 = efuse_ll_get_dslp_lp_dbias() + EFUSE_BURN_OFFSET_DSLP_LP_DBIAS; + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, dslp lp dbias not burnt in efuse\n"); + } + + return pmu_lp_dbias_deepsleep_0v7; +} + +void pmu_sleep_enable_regdma_backup(void) +{ + if(!s_pmu_sleep_regdma_backup_enabled){ + assert(PMU_instance()->hal); + /* entry 0, 1, 2 is used by pmu HP_SLEEP and HP_ACTIVE, HP_SLEEP + * and HP_MODEM or HP_MODEM and HP_ACTIVE states switching, + * respectively. entry 3 is reserved, not used yet! */ + pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal); + pmu_hal_hp_set_sleep_modem_backup_enable(PMU_instance()->hal); + pmu_hal_hp_set_modem_active_backup_enable(PMU_instance()->hal); + s_pmu_sleep_regdma_backup_enabled = true; + } +} + +void pmu_sleep_disable_regdma_backup(void) +{ + if(s_pmu_sleep_regdma_backup_enabled){ + assert(PMU_instance()->hal); + pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal); + pmu_hal_hp_set_sleep_modem_backup_disable(PMU_instance()->hal); + pmu_hal_hp_set_modem_active_backup_disable(PMU_instance()->hal); + s_pmu_sleep_regdma_backup_enabled = false; + } +} + +uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + + /* LP core hardware wait time, microsecond */ + const int lp_wakeup_wait_time_us = rtc_time_slowclk_to_us(mc->lp.wakeup_wait_cycle, slowclk_period); + const int lp_clk_switch_time_us = rtc_time_slowclk_to_us(mc->lp.clk_switch_cycle, slowclk_period); + const int lp_clk_power_on_wait_time_us = (pd_flags & PMU_SLEEP_PD_XTAL) ? mc->lp.xtal_wait_stable_time_us \ + : rtc_time_slowclk_to_us(mc->lp.clk_power_on_wait_cycle, slowclk_period); + + const int lp_hw_wait_time_us = mc->lp.min_slp_time_us + mc->lp.analog_wait_time_us + lp_clk_power_on_wait_time_us \ + + lp_wakeup_wait_time_us + lp_clk_switch_time_us + mc->lp.power_supply_wait_time_us \ + + mc->lp.power_up_wait_time_us; + + /* HP core hardware wait time, microsecond */ + const int hp_digital_power_up_wait_time_us = mc->hp.power_supply_wait_time_us + mc->hp.power_up_wait_time_us; + const int hp_regdma_wait_time_us = MAX(mc->hp.regdma_s2m_work_time_us + mc->hp.regdma_m2a_work_time_us, mc->hp.regdma_s2a_work_time_us); + const int hp_clock_wait_time_us = mc->hp.xtal_wait_stable_time_us + mc->hp.pll_wait_stable_time_us; + + const int hp_hw_wait_time_us = mc->hp.analog_wait_time_us + MAX(hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us, hp_clock_wait_time_us); + + /* 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 | + */ +#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + const int rf_on_protect_time_us = mc->hp.regdma_rf_on_work_time_us; + const int total_hw_wait_time_us = lp_hw_wait_time_us + hp_hw_wait_time_us + mc->hp.clock_domain_sync_time_us; +#else + const int rf_on_protect_time_us = 0; + const int total_hw_wait_time_us = lp_hw_wait_time_us + hp_hw_wait_time_us; +#endif + return total_hw_wait_time_us + rf_on_protect_time_us; +} + +#define rtc_time_us_to_fastclk(time_us, period) rtc_time_us_to_slowclk((time_us), (period)) + +static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default( + pmu_sleep_param_config_t *param, + pmu_sleep_power_config_t *power, /* We'll use the runtime power parameter to determine some hardware parameters */ + const uint32_t pd_flags, + const uint32_t adjustment, + const uint32_t slowclk_period, + const uint32_t fastclk_period + ) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + + param->hp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->hp.min_slp_time_us, slowclk_period); + param->hp_sys.analog_wait_target_cycle = rtc_time_us_to_fastclk(mc->hp.analog_wait_time_us, fastclk_period); + param->hp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_supply_wait_time_us, fastclk_period); + param->hp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_up_wait_time_us, fastclk_period); + param->hp_sys.pll_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.pll_wait_stable_time_us, fastclk_period); + + const int hw_wait_time_us = pmu_sleep_calculate_hw_wait_time(pd_flags, slowclk_period, fastclk_period); + const int modem_state_skip_time_us = mc->hp.regdma_m2a_work_time_us + mc->hp.system_dfs_up_work_time_us + mc->lp.min_slp_time_us; + const int modem_wakeup_wait_time_us = adjustment - hw_wait_time_us + modem_state_skip_time_us + mc->hp.regdma_rf_on_work_time_us; + param->hp_sys.modem_wakeup_wait_cycle = rtc_time_us_to_fastclk(modem_wakeup_wait_time_us, fastclk_period); + + param->lp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.min_slp_time_us, slowclk_period); + param->lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(mc->lp.analog_wait_time_us, slowclk_period); + param->lp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_supply_wait_time_us, fastclk_period); + param->lp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_up_wait_time_us, fastclk_period); + + if (power->hp_sys.xtal.xpd_xtal) { + param->hp_lp.xtal_stable_wait_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.xtal_wait_stable_time_us, slowclk_period); + } else { + param->hp_lp.xtal_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.xtal_wait_stable_time_us, fastclk_period); + } + return param; +} + +const pmu_sleep_config_t* pmu_sleep_config_default( + pmu_sleep_config_t *config, + uint32_t pd_flags, + uint32_t adjustment, + uint32_t slowclk_period, + uint32_t fastclk_period, + bool dslp + ) +{ + pmu_sleep_power_config_t power_default = PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags); + + uint32_t iram_pd_flags = 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G0) ? BIT(0) : 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G1) ? BIT(1) : 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G2) ? BIT(2) : 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 0; + config->power = power_default; + + pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags); + config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period); + + if (dslp) { + config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period); + pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags); + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = get_dslp_dbg(); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_dslp_lp_dbias(); + config->analog = analog_default; + } else { + pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags); + config->digital = digital_default; + + pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); + analog_default.hp_sys.analog.dbg_atten = get_lslp_dbg(); + analog_default.hp_sys.analog.dbias = get_lslp_hp_dbias(); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT; + + if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ + analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; + analog_default.hp_sys.analog.dbg_atten = PMU_DBG_ATTEN_ACTIVE_DEFAULT; + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + + analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_ACTIVE_DEFAULT; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); + } + + config->analog = analog_default; + } + return config; +} + +static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_config_t *power, bool dslp) +{ + pmu_ll_hp_set_dig_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.dig_power.val); + pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val); + pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal); + + pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].dig_power.val); + pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].clk_power.val); + + pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val); + pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val); + pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal); +} + +static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig) +{ + pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, HP(SLEEP), dig->syscntl.dig_pad_slp_sel); +} + +static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp) +{ + assert(ctx->hal); + pmu_ll_hp_set_dbg_atten (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbg_atten); + pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur); + pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep); + pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd); + pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias); + pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b); + + pmu_ll_lp_set_dbg_atten (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbg_atten); + pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur); + pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep); + pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd); + pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd); + pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias); + pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias); + pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b); +} + +static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp) +{ + assert(ctx->hal); + pmu_ll_hp_set_min_sleep_cycle(ctx->hal->dev, param->hp_sys.min_slp_slow_clk_cycle); + pmu_ll_lp_set_min_sleep_cycle(ctx->hal->dev, param->lp_sys.min_slp_slow_clk_cycle); + + pmu_ll_hp_set_analog_wait_target_cycle(ctx->hal->dev, param->hp_sys.analog_wait_target_cycle); + pmu_ll_lp_set_analog_wait_target_cycle(ctx->hal->dev, param->lp_sys.analog_wait_target_cycle); + + pmu_hal_hp_set_digital_power_up_wait_cycle(ctx->hal, param->hp_sys.digital_power_supply_wait_cycle, param->hp_sys.digital_power_up_wait_cycle); + pmu_hal_lp_set_digital_power_up_wait_cycle(ctx->hal, param->lp_sys.digital_power_supply_wait_cycle, param->lp_sys.digital_power_up_wait_cycle); + + pmu_ll_set_modem_wait_target_cycle(ctx->hal->dev, param->hp_sys.modem_wakeup_wait_cycle); + pmu_ll_set_xtal_stable_wait_cycle(ctx->hal->dev, param->hp_lp.xtal_stable_wait_slow_clk_cycle); + pmu_ll_set_pll_stable_wait_cycle(ctx->hal->dev, param->hp_sys.pll_stable_wait_cycle); +} + +bool pmu_sleep_pll_already_enabled(void) +{ + return (pmu_ll_get_sysclk_sleep_select_state(PMU_instance()->hal->dev) != 0); +} + +void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp) +{ + assert(PMU_instance()); + pmu_sleep_power_init(PMU_instance(), &config->power, dslp); + if(!dslp){ + pmu_sleep_digital_init(PMU_instance(), &config->digital); + } + pmu_sleep_analog_init(PMU_instance(), &config->analog, dslp); + pmu_sleep_param_init(PMU_instance(), &config->param, dslp); +} + +uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) +{ + assert(PMU_instance()->hal); + + lp_aon_hal_inform_wakeup_type(dslp); + + pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt); + pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt); + + pmu_ll_hp_clear_wakeup_intr_status(PMU_instance()->hal->dev); + pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); + pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); + + /* Start entry into sleep mode */ + pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev); + + /* In pd_cpu lightsleep and deepsleep mode, we never get here */ + while (!pmu_ll_hp_is_sleep_wakeup(PMU_instance()->hal->dev) && + !pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) { + ; + } + + return pmu_sleep_finish(); +} + +bool pmu_sleep_finish(void) +{ + return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); +} + +void pmu_sleep_enable_hp_sleep_sysclk(bool enable) +{ + pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable); +} + +uint32_t pmu_sleep_get_wakup_retention_cost(void) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + return mc->hp.regdma_s2a_work_time_us; +} diff --git a/components/esp_hw_support/port/esp32c6/private_include/ocode_init.h b/components/esp_hw_support/port/esp32c6/private_include/ocode_init.h new file mode 100644 index 000000000000..44f1f8870961 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/private_include/ocode_init.h @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize OCode + * + */ +void esp_ocode_calib_init(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h new file mode 100644 index 000000000000..950a3ac91b7b --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h @@ -0,0 +1,482 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/pmu_struct.h" +#include "hal/pmu_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HP_CALI_DBIAS_DEFAULT 25 +#define LP_CALI_DBIAS_DEFAULT 26 + +// FOR XTAL FORCE PU IN SLEEP +#define PMU_PD_CUR_SLEEP_ON 0 +#define PMU_BIASSLP_SLEEP_ON 0 + +// FOR BOTH LIGHTSLEEP & DEEPSLEEP +#define PMU_PD_CUR_SLEEP_DEFAULT 1 +#define PMU_BIASSLP_SLEEP_DEFAULT 1 +#define PMU_LP_XPD_SLEEP_DEFAULT 1 +#define PMU_LP_SLP_XPD_SLEEP_DEFAULT 0 +#define PMU_LP_SLP_DBIAS_SLEEP_DEFAULT 0 + +// FOR LIGHTSLEEP +#define PMU_HP_DRVB_LIGHTSLEEP 0 +#define PMU_LP_DRVB_LIGHTSLEEP 0 +#define PMU_HP_XPD_LIGHTSLEEP 1 + +#define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 0 +#define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1 +#define PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT 12 + +// FOR LIGHTSLEEP: XTAL FORCE PU +#define PMU_DBG_ATTEN_ACTIVE_DEFAULT 0 + +// FOR DEEPSLEEP +#define PMU_DBG_HP_DEEPSLEEP 0 +#define PMU_HP_XPD_DEEPSLEEP 0 +#define PMU_LP_DRVB_DEEPSLEEP 0 + +#define PMU_REGDMA_S2A_WORK_TIME_US 480 + +#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 +#define PMU_LP_DBIAS_DEEPSLEEP_0V7_DEFAULT 23 + +#define EFUSE_BURN_OFFSET_DSLP_DBG 8 +#define EFUSE_BURN_OFFSET_DSLP_LP_DBIAS 23 + +uint32_t get_act_hp_dbias(void); +uint32_t get_act_lp_dbias(void); + +typedef struct { + pmu_hp_dig_power_reg_t dig_power; + pmu_hp_clk_power_reg_t clk_power; + pmu_hp_xtal_reg_t xtal; +} pmu_hp_system_power_param_t; + +const pmu_hp_system_power_param_t* pmu_hp_system_power_param_default(pmu_hp_mode_t mode); + +typedef struct { + uint32_t icg_func; + uint32_t icg_apb; + pmu_hp_icg_modem_reg_t icg_modem; + pmu_hp_sysclk_reg_t sysclk; +} pmu_hp_system_clock_param_t; + +const pmu_hp_system_clock_param_t* pmu_hp_system_clock_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_hp_sys_cntl_reg_t syscntl; +} pmu_hp_system_digital_param_t; + +const pmu_hp_system_digital_param_t* pmu_hp_system_digital_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_hp_bias_reg_t bias; + pmu_hp_regulator0_reg_t regulator0; + pmu_hp_regulator1_reg_t regulator1; +} pmu_hp_system_analog_param_t; + +const pmu_hp_system_analog_param_t* pmu_hp_system_analog_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_hp_backup_reg_t retention; + uint32_t backup_clk; +} pmu_hp_system_retention_param_t; + +const pmu_hp_system_retention_param_t* pmu_hp_system_retention_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_lp_dig_power_reg_t dig_power; + pmu_lp_clk_power_reg_t clk_power; + pmu_lp_xtal_reg_t xtal; +} pmu_lp_system_power_param_t; + +const pmu_lp_system_power_param_t* pmu_lp_system_power_param_default(pmu_lp_mode_t mode); + + + +typedef struct { + pmu_lp_bias_reg_t bias; + pmu_lp_regulator0_reg_t regulator0; + pmu_lp_regulator1_reg_t regulator1; +} pmu_lp_system_analog_param_t; + +const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mode_t mode); + + + +/* Following software configuration instance type from pmu_struct.h used for the PMU state machine in sleep flow*/ +typedef union { + struct { + uint32_t reserved0 : 21; + uint32_t vdd_spi_pd_en: 1; + uint32_t mem_dslp : 1; + uint32_t mem_pd_en : 4; + uint32_t wifi_pd_en : 1; + uint32_t reserved1 : 1; + uint32_t cpu_pd_en : 1; + uint32_t aon_pd_en : 1; + uint32_t top_pd_en : 1; + }; + struct { + uint32_t reserved2 : 26; + uint32_t i2c_iso_en : 1; + uint32_t i2c_retention: 1; + uint32_t xpd_bb_i2c : 1; + uint32_t xpd_bbpll_i2c: 1; + uint32_t xpd_bbpll : 1; + uint32_t reserved3 : 1; + }; + struct { + uint32_t reserved4 : 31; + uint32_t xpd_xtal : 1; + }; + uint32_t val; +} pmu_hp_power_t; + +typedef union { + struct { + uint32_t reserved0 : 30; + uint32_t mem_dslp : 1; + uint32_t peri_pd_en: 1; + }; + struct { + uint32_t reserved1 : 28; + uint32_t xpd_xtal32k: 1; + uint32_t xpd_rc32k : 1; + uint32_t xpd_fosc : 1; + uint32_t pd_osc : 1; + }; + struct { + uint32_t reserved2 : 31; + uint32_t xpd_xtal : 1; + }; + uint32_t val; +} pmu_lp_power_t; + +typedef struct { + struct { + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; + }; + struct { + uint32_t reserved1 : 16; + uint32_t slp_mem_xpd : 1; + uint32_t slp_logic_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_mem_dbias : 4; + uint32_t slp_logic_dbias: 4; + uint32_t dbias : 5; + }; + struct { + uint32_t reserved2: 8; + uint32_t drv_b : 24; + }; +} pmu_hp_analog_t; + +typedef struct { + struct { + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; + }; + struct { + uint32_t reserved1: 21; + uint32_t slp_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_dbias: 4; + uint32_t dbias : 5; + }; + struct { + uint32_t reserved2: 28; + uint32_t drv_b : 4; + }; +} pmu_lp_analog_t; + +typedef struct { + uint32_t modem_wakeup_wait_cycle; + uint16_t analog_wait_target_cycle; + uint16_t digital_power_down_wait_cycle; + uint16_t digital_power_supply_wait_cycle; + uint16_t digital_power_up_wait_cycle; + uint16_t pll_stable_wait_cycle; + uint8_t modify_icg_cntl_wait_cycle; + uint8_t switch_icg_cntl_wait_cycle; + uint8_t min_slp_slow_clk_cycle; +} pmu_hp_param_t; + +typedef struct { + uint16_t digital_power_supply_wait_cycle; + uint8_t min_slp_slow_clk_cycle; + uint8_t analog_wait_target_cycle; + uint8_t digital_power_down_wait_cycle; + uint8_t digital_power_up_wait_cycle; +} pmu_lp_param_t; + +typedef struct { + union { + uint16_t xtal_stable_wait_slow_clk_cycle; + uint16_t xtal_stable_wait_cycle; + }; +} pmu_hp_lp_param_t; + +#define PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES (10) +#define PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES (10) + +#define PMU_HP_WAKEUP_DELAY_CYCLES (0) +#define PMU_HP_XTAL_STABLE_WAIT_CYCLES (3155) /* Not used, Fast OSC as PMU work clock source is about 201 us, corresponding to PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES */ +#define PMU_HP_PLL_STABLE_WAIT_CYCLES (2) +#define PMU_HP_ANALOG_WAIT_TARGET_CYCLES (2419) /* Fast OSC as PMU work clock source is about 154 us */ +#define PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) +#define PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES (32) +#define PMU_HP_MODEM_WAKEUP_WAIT_CYCLES (20700) /* Fast OSC as PMU work clock source is about 1318.6 us */ + +#define PMU_LP_WAKEUP_DELAY_CYCLES (0) +#define PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES (30) /* Slow OSC as PMU slow clock source is about 201 us */ +#define PMU_LP_ANALOG_WAIT_TARGET_CYCLES (23) /* Slow OSC as PMU slow clock source is about 154 us */ +#define PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */ +#define PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */ + +#define PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US (500) /* Slow OSC as PMU slow clock source in deepsleep is about 500 us */ + +typedef struct { + struct { + pmu_hp_power_t dig_power; + pmu_hp_power_t clk_power; + pmu_hp_power_t xtal; + } hp_sys; + struct { + pmu_lp_power_t dig_power; + pmu_lp_power_t clk_power; + pmu_lp_power_t xtal; + } lp_sys[PMU_MODE_LP_MAX]; +} pmu_sleep_power_config_t; + +#define PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .dig_power = { \ + .vdd_spi_pd_en = ((pd_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 0, \ + .wifi_pd_en = ((pd_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0, \ + .cpu_pd_en = ((pd_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0, \ + .aon_pd_en = ((pd_flags) & PMU_SLEEP_PD_HP_AON) ? 1 : 0, \ + .top_pd_en = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \ + .mem_pd_en = 0, \ + .mem_dslp = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 1, \ + .i2c_retention = 1, \ + .xpd_bb_i2c = 0, \ + .xpd_bbpll_i2c = 0, \ + .xpd_bbpll = 0 \ + }, \ + .xtal = { \ + .xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_ACTIVE] = { \ + .dig_power = { \ + .peri_pd_en = 0, \ + .mem_dslp = 0 \ + }, \ + .clk_power = { \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ + .xpd_fosc = 1 \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .dig_power = { \ + .peri_pd_en = ((pd_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \ + .mem_dslp = 1 \ + }, \ + .clk_power = { \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ + .xpd_fosc = ((pd_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1 \ + }, \ + .xtal = { \ + .xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \ + } \ + } \ +} + +typedef struct { + pmu_hp_sys_cntl_reg_t syscntl; +} pmu_sleep_digital_config_t; + +#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags) { \ + .syscntl = { \ + .dig_pad_slp_sel = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1, \ + } \ +} + +typedef struct { + struct { + pmu_hp_analog_t analog; + } hp_sys; + struct { + pmu_lp_analog_t analog; + } lp_sys[PMU_MODE_LP_MAX]; +} pmu_sleep_analog_config_t; + +#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .analog = { \ + .drv_b = PMU_HP_DRVB_LIGHTSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .xpd = PMU_HP_XPD_LIGHTSLEEP, \ + .dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \ + .dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .drv_b = PMU_LP_DRVB_DEEPSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ + .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \ + .xpd = PMU_LP_XPD_SLEEP_DEFAULT, \ + .dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \ + .dbias = PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT \ + } \ + } \ +} + +#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .analog = { \ + .pd_cur = PMU_PD_CUR_SLEEP_ON, \ + .bias_sleep = PMU_BIASSLP_SLEEP_ON, \ + .xpd = PMU_HP_XPD_DEEPSLEEP, \ + .dbg_atten = PMU_DBG_HP_DEEPSLEEP \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .drv_b = PMU_LP_DRVB_DEEPSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ + .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \ + .xpd = PMU_LP_XPD_SLEEP_DEFAULT, \ + .dbg_atten = PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT, \ + .dbias = PMU_LP_DBIAS_DEEPSLEEP_0V7_DEFAULT \ + } \ + } \ +} + +typedef struct { + pmu_hp_param_t hp_sys; + pmu_lp_param_t lp_sys; + pmu_hp_lp_param_t hp_lp; +} pmu_sleep_param_config_t; + +#define PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .min_slp_slow_clk_cycle = PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES, \ + .analog_wait_target_cycle = PMU_HP_ANALOG_WAIT_TARGET_CYCLES, \ + .digital_power_supply_wait_cycle = PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \ + .digital_power_up_wait_cycle = PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES, \ + .modem_wakeup_wait_cycle = PMU_HP_MODEM_WAKEUP_WAIT_CYCLES, \ + .pll_stable_wait_cycle = PMU_HP_PLL_STABLE_WAIT_CYCLES \ + }, \ + .lp_sys = { \ + .min_slp_slow_clk_cycle = PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES, \ + .analog_wait_target_cycle = PMU_LP_ANALOG_WAIT_TARGET_CYCLES, \ + .digital_power_supply_wait_cycle = PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \ + .digital_power_up_wait_cycle = PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES \ + }, \ + .hp_lp = { \ + .xtal_stable_wait_slow_clk_cycle = PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES \ + } \ +} + +typedef struct { + pmu_sleep_power_config_t power; + pmu_sleep_digital_config_t digital; + pmu_sleep_analog_config_t analog; + pmu_sleep_param_config_t param; +} pmu_sleep_config_t; + +typedef struct pmu_sleep_machine_constant { + struct { + uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ + uint8_t reserved0; + uint16_t reserved1; + uint16_t analog_wait_time_us; /* LP LDO power up wait time (unit: microsecond) */ + uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */ + uint8_t clk_switch_cycle; /* Clock switch to FOSC (unit: slow clock cycle) */ + uint8_t clk_power_on_wait_cycle; /* Clock power on wait cycle (unit: slow clock cycle) */ + uint16_t power_supply_wait_time_us; /* (unit: microsecond) */ + uint16_t power_up_wait_time_us; /* (unit: microsecond) */ + } lp; + struct { + uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ + uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ + uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ + uint16_t power_supply_wait_time_us; /* (unit: microsecond) */ + uint16_t power_up_wait_time_us; /* (unit: microsecond) */ + uint16_t regdma_s2m_work_time_us; /* Modem Subsystem (S2M switch) REGDMA restore time (unit: microsecond) */ + uint16_t regdma_s2a_work_time_us; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (S2A switch) restore time (unit: microsecond) */ + uint16_t regdma_m2a_work_time_us; /* Digital Peripheral (M2A switch) REGDMA restore time (unit: microsecond) */ + uint16_t regdma_a2s_work_time_us; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (A2S switch) backup time (unit: microsecond) */ + uint16_t regdma_rf_on_work_time_us; /* The REGDMA work time of RF enable (unit: microsecond) */ + uint16_t regdma_rf_off_work_time_us; /* The REGDMA work time of RF disable (unit: microsecond) */ + uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */ + uint16_t pll_wait_stable_time_us; /* PLL stabilization wait time (unit: microsecond) */ + } hp; +} pmu_sleep_machine_constant_t; + +#define PMU_SLEEP_MC_DEFAULT() { \ + .lp = { \ + .min_slp_time_us = 450, \ + .wakeup_wait_cycle = 4, \ + .analog_wait_time_us = 154, \ + .xtal_wait_stable_time_us = 250, \ + .clk_switch_cycle = 1, \ + .clk_power_on_wait_cycle = 1, \ + .power_supply_wait_time_us = 2, \ + .power_up_wait_time_us = 2 \ + }, \ + .hp = { \ + .min_slp_time_us = 450, \ + .clock_domain_sync_time_us = 150, \ + .system_dfs_up_work_time_us = 124, \ + .analog_wait_time_us = 154, \ + .power_supply_wait_time_us = 2, \ + .power_up_wait_time_us = 2, \ + .regdma_s2m_work_time_us = 172, \ + .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \ + .regdma_m2a_work_time_us = 278, \ + .regdma_a2s_work_time_us = 382, \ + .regdma_rf_on_work_time_us = 70, \ + .regdma_rf_off_work_time_us = 23, \ + .xtal_wait_stable_time_us = 250, \ + .pll_wait_stable_time_us = 1 \ + } \ +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc b/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc new file mode 100644 index 000000000000..b7d09bab5593 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" +#include "soc/gdma_reg.h" + + +/* GDMA Channel (Group0, Pair0) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH0_REG / GDMA_OUT_INT_ENA_CH0_REG / GDMA_IN_PERI_SEL_CH0_REG / GDMA_OUT_PERI_SEL_CH0_REG + GDMA_IN_CONF0_CH0_REG / GDMA_IN_CONF1_CH0_REG / GDMA_IN_LINK_CH0_REG / GDMA_IN_PRI_CH0_REG + GDMA_OUT_CONF0_CH0_REG / GDMA_OUT_CONF1_CH0_REG / GDMA_OUT_LINK_CH0_REG /GDMA_OUT_PRI_CH0_REG +*/ +#define G0P0_RETENTION_REGS_CNT 13 +#define G0P0_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH0_REG +static const uint32_t g0p0_regs_map[4] = {0x4C801001, 0x604C0060, 0, 0}; +static const sleep_retention_entries_config_t gdma_g0p0_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P0_RETENTION_MAP_BASE, G0P0_RETENTION_MAP_BASE, \ + G0P0_RETENTION_REGS_CNT, 0, 0, \ + g0p0_regs_map[0], g0p0_regs_map[1], \ + g0p0_regs_map[2], g0p0_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair1) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH1_REG / GDMA_OUT_INT_ENA_CH1_REG / GDMA_IN_PERI_SEL_CH1_REG / GDMA_OUT_PERI_SEL_CH1_REG + GDMA_IN_CONF0_CH1_REG / GDMA_IN_CONF1_CH1_REG / GDMA_IN_LINK_CH1_REG / GDMA_IN_PRI_CH1_REG + GDMA_OUT_CONF0_CH1_REG / GDMA_OUT_CONF1_CH1_REG / GDMA_OUT_LINK_CH1_REG /GDMA_OUT_PRI_CH1_REG +*/ +#define G0P1_RETENTION_REGS_CNT 13 +#define G0P1_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH1_REG +static const uint32_t g0p1_regs_map[4] = {0x81001, 0, 0xC00604C0, 0x604}; +static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P1_RETENTION_MAP_BASE, G0P1_RETENTION_MAP_BASE, \ + G0P1_RETENTION_REGS_CNT, 0, 0, \ + g0p1_regs_map[0], g0p1_regs_map[1], \ + g0p1_regs_map[2], g0p1_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair2) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH2_REG / GDMA_OUT_INT_ENA_CH2_REG / GDMA_IN_PERI_SEL_CH2_REG / GDMA_OUT_PERI_SEL_CH2_REG + GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG + GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG +*/ +#define G0P2_RETENTION_REGS_CNT_0 6 +#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG +#define G0P2_RETENTION_REGS_CNT_1 7 +#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG +static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000}; +static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0}; +static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \ + G0P2_RETENTION_REGS_CNT_0, 0, 0, \ + g0p2_regs_map0[0], g0p2_regs_map0[1], \ + g0p2_regs_map0[2], g0p2_regs_map0[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ + G0P2_RETENTION_REGS_CNT_1, 0, 0, \ + g0p2_regs_map1[0], g0p2_regs_map1[1], \ + g0p2_regs_map1[2], g0p2_regs_map1[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +static const struct { + const sleep_retention_entries_config_t *link_list; + uint32_t link_num; +} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP*SOC_GDMA_PAIRS_PER_GROUP] = { + [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, + [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, + [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} +}; diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk.c b/components/esp_hw_support/port/esp32c6/rtc_clk.c new file mode 100644 index 000000000000..da6ab452f120 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/rtc_clk.c @@ -0,0 +1,447 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp32c6/rom/rtc.h" +#include "soc/rtc.h" +#include "esp_private/rtc_clk.h" +#include "esp_hw_log.h" +#include "esp_rom_sys.h" +#include "hal/clk_tree_ll.h" +#include "hal/regi2c_ctrl_ll.h" +#include "soc/io_mux_reg.h" +#include "soc/lp_aon_reg.h" +#include "esp_private/sleep_event.h" + +#ifdef BOOTLOADER_BUILD +#include "hal/modem_lpcon_ll.h" +#else +#include "esp_private/esp_modem_clock.h" +#endif + +static const char *TAG = "rtc_clk"; + +// Current PLL frequency, in 480MHz. Zero if PLL is not enabled. +static int s_cur_pll_freq; + +static uint32_t s_bbpll_digi_consumers_ref_count = 0; // Currently, it only tracks whether the 48MHz PHY clock is in-use by USB Serial/JTAG + +void rtc_clk_bbpll_add_consumer(void) +{ + s_bbpll_digi_consumers_ref_count += 1; +} + +void rtc_clk_bbpll_remove_consumer(void) +{ + s_bbpll_digi_consumers_ref_count -= 1; +} + +void rtc_clk_32k_enable(bool enable) +{ + if (enable) { + clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL); + } else { + clk_ll_xtal32k_disable(); + } +} + +void rtc_clk_32k_enable_external(void) +{ + // EXT_OSC_SLOW_GPIO_NUM == GPIO_NUM_0 + PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG); + REG_SET_BIT(LP_AON_GPIO_HOLD0_REG, BIT(EXT_OSC_SLOW_GPIO_NUM)); + clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL); +} + +void rtc_clk_32k_bootstrap(uint32_t cycle) +{ + /* No special bootstrapping needed for ESP32-C6, 'cycle' argument is to keep the signature + * same as for the ESP32. Just enable the XTAL here. + */ + (void)cycle; + rtc_clk_32k_enable(true); +} + +bool rtc_clk_32k_enabled(void) +{ + return clk_ll_xtal32k_is_enabled(); +} + +void rtc_clk_rc32k_enable(bool enable) +{ + if (enable) { + clk_ll_rc32k_enable(); + esp_rom_delay_us(SOC_DELAY_RC32K_ENABLE); + } else { + clk_ll_rc32k_disable(); + } +} + +void rtc_clk_8m_enable(bool clk_8m_en) +{ + if (clk_8m_en) { + clk_ll_rc_fast_enable(); + esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE); + } else { + clk_ll_rc_fast_disable(); + } +} + +bool rtc_clk_8m_enabled(void) +{ + return clk_ll_rc_fast_is_enabled(); +} + +void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src) +{ + clk_ll_rtc_slow_set_src(clk_src); + esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH); +} + +soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void) +{ + return clk_ll_rtc_slow_get_src(); +} + +uint32_t rtc_clk_slow_freq_get_hz(void) +{ + switch (rtc_clk_slow_src_get()) { + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX; + default: return 0; + } +} + +void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src) +{ + clk_ll_rtc_fast_set_src(clk_src); + esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH); +} + +soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void) +{ + return clk_ll_rtc_fast_get_src(); +} + +static void rtc_clk_bbpll_disable(void) +{ + clk_ll_bbpll_disable(); + s_cur_pll_freq = 0; +} + +static void rtc_clk_bbpll_enable(void) +{ + clk_ll_bbpll_enable(); +} + +static void rtc_clk_enable_i2c_ana_master_clock(bool enable) +{ +#ifdef BOOTLOADER_BUILD + modem_lpcon_ll_enable_i2c_master_clock(&MODEM_LPCON, enable); +#else + if (enable) { + modem_clock_module_enable(PERIPH_ANA_I2C_MASTER_MODULE); + } else { + modem_clock_module_disable(PERIPH_ANA_I2C_MASTER_MODULE); + } +#endif +} + +static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) +{ + /* Digital part */ + clk_ll_bbpll_set_freq_mhz(pll_freq); + /* Analog part */ + rtc_clk_enable_i2c_ana_master_clock(true); + /* BBPLL CALIBRATION START */ + regi2c_ctrl_ll_bbpll_calibration_start(); + clk_ll_bbpll_set_config(pll_freq, xtal_freq); + /* WAIT CALIBRATION DONE */ + while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + esp_rom_delay_us(10); + /* BBPLL CALIBRATION STOP */ + regi2c_ctrl_ll_bbpll_calibration_stop(); + rtc_clk_enable_i2c_ana_master_clock(false); + s_cur_pll_freq = pll_freq; +} + +/** + * Switch to use XTAL as the CPU clock source. + * Must satisfy: cpu_freq = XTAL_FREQ / div. + * Does not disable the PLL. + */ +static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) +{ + clk_ll_ahb_set_ls_divider(div); + clk_ll_cpu_set_ls_divider(div); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); + esp_rom_set_cpu_ticks_per_us(cpu_freq); +} + +static void rtc_clk_cpu_freq_to_8m(void) +{ + clk_ll_ahb_set_ls_divider(1); + clk_ll_cpu_set_ls_divider(1); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); + esp_rom_set_cpu_ticks_per_us(20); +} + +/** + * Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL. + * PLL must already be enabled. + * @param cpu_freq new CPU frequency + */ +static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) +{ + clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); + esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); +} + +bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config) +{ + uint32_t source_freq_mhz; + soc_cpu_clk_src_t source; + uint32_t divider; // divider = freq of SOC_ROOT_CLK / freq of CPU_CLK + uint32_t real_freq_mhz; + + uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get(); + if (freq_mhz <= xtal_freq && freq_mhz != 0) { + divider = xtal_freq / freq_mhz; + real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */ + if (real_freq_mhz != freq_mhz) { + // no suitable divider + return false; + } + + source_freq_mhz = xtal_freq; + source = SOC_CPU_CLK_SRC_XTAL; + } else if (freq_mhz == 80) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL; + source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; + divider = 6; + } else if (freq_mhz == 120) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL; + source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; + divider = 4; + } else if (freq_mhz == 160) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL; + source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; + divider = 3; + } else { + // unsupported frequency + return false; + } + *out_config = (rtc_cpu_freq_config_t) { + .source = source, + .div = divider, + .source_freq_mhz = source_freq_mhz, + .freq_mhz = real_freq_mhz + }; + return true; +} + +__attribute__((weak)) void rtc_clk_set_cpu_switch_to_bbpll(int event_id) +{ +} + +void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) +{ + soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); + if (config->source == SOC_CPU_CLK_SRC_XTAL) { + rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); + if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { + // We don't turn off the bbpll if some consumers depend on bbpll + rtc_clk_bbpll_disable(); + } + } else if (config->source == SOC_CPU_CLK_SRC_PLL) { + if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) { + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_BBPLL_EN_START); + rtc_clk_bbpll_enable(); + rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz); + } + rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_BBPLL_EN_STOP); + } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { + rtc_clk_cpu_freq_to_8m(); + if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { + // We don't turn off the bbpll if some consumers depend on bbpll + rtc_clk_bbpll_disable(); + } + } +} + +void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) +{ + soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); + uint32_t source_freq_mhz; + uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK + uint32_t freq_mhz; + switch (source) { + case SOC_CPU_CLK_SRC_XTAL: { + div = clk_ll_cpu_get_ls_divider(); + source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get(); + freq_mhz = source_freq_mhz / div; + break; + } + case SOC_CPU_CLK_SRC_PLL: { + div = clk_ll_cpu_get_hs_divider(); + source_freq_mhz = clk_ll_bbpll_get_freq_mhz(); + freq_mhz = source_freq_mhz / div; + break; + } + case SOC_CPU_CLK_SRC_RC_FAST: + div = clk_ll_cpu_get_ls_divider(); + source_freq_mhz = 20; + freq_mhz = source_freq_mhz / div; + break; + default: + ESP_HW_LOGE(TAG, "unsupported frequency configuration"); + abort(); + } + *out_config = (rtc_cpu_freq_config_t) { + .source = source, + .source_freq_mhz = source_freq_mhz, + .div = div, + .freq_mhz = freq_mhz + }; +} + +void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) +{ + if (config->source == SOC_CPU_CLK_SRC_XTAL) { + rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); + } else if (config->source == SOC_CPU_CLK_SRC_PLL && + s_cur_pll_freq == config->source_freq_mhz) { + rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { + rtc_clk_cpu_freq_to_8m(); + } else { + /* fallback */ + rtc_clk_cpu_freq_set_config(config); + } +} + +void rtc_clk_cpu_freq_set_xtal(void) +{ + rtc_clk_cpu_set_to_default_config(); + // We don't turn off the bbpll if some consumers depend on bbpll + if (!s_bbpll_digi_consumers_ref_count) { + rtc_clk_bbpll_disable(); + } +} + +void rtc_clk_cpu_set_to_default_config(void) +{ + int freq_mhz = (int)rtc_clk_xtal_freq_get(); + + rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); +} + +void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz) +{ + rtc_clk_cpu_freq_to_pll_mhz(cpu_freq_mhz); + clk_ll_cpu_clk_src_lock_release(); +} + +rtc_xtal_freq_t rtc_clk_xtal_freq_get(void) +{ + uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); + if (xtal_freq_mhz == 0) { + ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz"); + return RTC_XTAL_FREQ_40M; + } + return (rtc_xtal_freq_t)xtal_freq_mhz; +} + +void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq) +{ + clk_ll_xtal_store_freq_mhz(xtal_freq); +} + +static uint32_t rtc_clk_ahb_freq_get(void) +{ + soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); + uint32_t soc_root_freq_mhz; + uint32_t divider; + switch (source) { + case SOC_CPU_CLK_SRC_XTAL: + soc_root_freq_mhz = rtc_clk_xtal_freq_get(); + divider = clk_ll_ahb_get_ls_divider(); + break; + case SOC_CPU_CLK_SRC_PLL: + soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz(); + divider = clk_ll_ahb_get_hs_divider(); + break; + case SOC_CPU_CLK_SRC_RC_FAST: + soc_root_freq_mhz = 20; + divider = clk_ll_ahb_get_ls_divider(); + break; + default: + // Unknown SOC_ROOT clock source + soc_root_freq_mhz = 0; + divider = 1; + ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK"); + break; + } + return soc_root_freq_mhz / divider; +} + +uint32_t rtc_clk_apb_freq_get(void) +{ + return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider() * MHZ; +} + +void rtc_dig_clk8m_enable(void) +{ + clk_ll_rc_fast_digi_enable(); + esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH); +} + +void rtc_dig_clk8m_disable(void) +{ + clk_ll_rc_fast_digi_disable(); + esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH); +} + +bool rtc_dig_8m_enabled(void) +{ + return clk_ll_rc_fast_digi_is_enabled(); +} + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +void rtc_clk_recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} + + +/* Name used in libphy.a:phy_chip_v7.o + * TODO: update the library to use rtc_clk_xtal_freq_get + */ +rtc_xtal_freq_t rtc_get_xtal(void) __attribute__((alias("rtc_clk_xtal_freq_get"))); diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c new file mode 100644 index 000000000000..6c4ab97d6980 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c @@ -0,0 +1,125 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "esp32c6/rom/ets_sys.h" +#include "esp32c6/rom/rtc.h" +#include "esp32c6/rom/uart.h" +#include "soc/rtc.h" +#include "esp_cpu.h" +#include "regi2c_ctrl.h" +#include "soc/lp_clkrst_reg.h" +#include "soc/regi2c_dig_reg.h" +#include "esp_hw_log.h" +#include "sdkconfig.h" +#include "esp_rom_uart.h" +#include "esp_private/esp_pmu.h" +#include "hal/clk_tree_ll.h" +#include "hal/pmu_ll.h" +#include "hal/modem_syscon_ll.h" +#include "hal/modem_lpcon_ll.h" +#include "soc/pmu_reg.h" +#include "pmu_param.h" + +static const char *TAG = "rtc_clk_init"; + +/** + * Initialize the ICG map of some modem clock domains in the PMU_ACTIVE state + * + * A pre-initialization interface is used to initialize the ICG map of the + * MODEM_APB, I2C_MST and LP_APB clock domains in the PMU_ACTIVE state, and + * disable the clock gating of these clock domains in the PMU_ACTIVE state, + * because the system clock source (PLL) in the system boot up process needs + * to use the i2c master peripheral. + * + * ICG map of all modem clock domains under different power states (PMU_ACTIVE, + * PMU_MODEM and PMU_SLEEP) will be initialized in esp_perip_clk_init(). + */ +static void rtc_clk_modem_clock_domain_active_state_icg_map_preinit(void) +{ + /* Configure modem ICG code in PMU_ACTIVE state */ + pmu_ll_hp_set_icg_modem(&PMU, PMU_MODE_HP_ACTIVE, PMU_HP_ICG_MODEM_CODE_ACTIVE); + + /* Disable clock gating for MODEM_APB, I2C_MST and LP_APB clock domains in PMU_ACTIVE state */ + modem_syscon_ll_set_modem_apb_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)); + modem_lpcon_ll_set_i2c_master_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)); + modem_lpcon_ll_set_lp_apb_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)); + + /* Software trigger force update modem ICG code and ICG switch */ + pmu_ll_imm_update_dig_icg_modem_code(&PMU, true); + pmu_ll_imm_update_dig_icg_switch(&PMU, true); +} + +void rtc_clk_init(rtc_clk_config_t cfg) +{ + rtc_cpu_freq_config_t old_config, new_config; + + rtc_clk_modem_clock_domain_active_state_icg_map_preinit(); + + /* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks. + * Note: this doesn't attempt to set the clocks to precise frequencies. + * Instead, we calibrate these clocks against XTAL frequency later, when necessary. + * - SCK_DCAP value controls tuning of RC_SLOW clock. + * The higher the value of DCAP is, the lower is the frequency. + * - CK8M_DFREQ value controls tuning of RC_FAST clock. + * CLK_8M_DFREQ constant gives the best temperature characteristics. + * - RC32K_DFREQ value controls tuning of RC32K clock. + */ + REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap); + REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); + + uint32_t hp_cali_dbias = get_act_hp_dbias(); + uint32_t lp_cali_dbias = get_act_lp_dbias(); + + SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); + + clk_ll_rc_fast_tick_conf(); + + rtc_xtal_freq_t xtal_freq = cfg.xtal_freq; + esp_rom_uart_tx_wait_idle(0); + rtc_clk_xtal_freq_update(xtal_freq); + + // On ESP32C6, MSPI source clock's default HS divider leads to 120MHz, which is unusable before calibration + // Therefore, before switching SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider to make it run at + // 80MHz after the switch. PLL = 480MHz, so divider is 6. + clk_ll_mspi_fast_set_hs_divider(6); + + /* Set CPU frequency */ + rtc_clk_cpu_freq_get_config(&old_config); + uint32_t freq_before = old_config.freq_mhz; + bool res = rtc_clk_cpu_freq_mhz_to_config(cfg.cpu_freq_mhz, &new_config); + if (!res) { + ESP_HW_LOGE(TAG, "invalid CPU frequency value"); + abort(); + } + rtc_clk_cpu_freq_set_config(&new_config); + + /* Re-calculate the ccount to make time calculation correct. */ + esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * cfg.cpu_freq_mhz / freq_before ); + + /* Slow & fast clocks setup */ + // We will not power off RC_FAST in bootloader stage even if it is not being used as any + // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage. + bool need_rc_fast_en = true; + if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + rtc_clk_32k_enable(true); + } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + rtc_clk_32k_enable_external(); + } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + rtc_clk_rc32k_enable(true); + } + rtc_clk_8m_enable(need_rc_fast_en); + rtc_clk_fast_src_set(cfg.fast_clk_src); + rtc_clk_slow_src_set(cfg.slow_clk_src); +} diff --git a/components/esp_hw_support/port/esp32c6/rtc_isr_stub.c b/components/esp_hw_support/port/esp32c6/rtc_isr_stub.c new file mode 100644 index 000000000000..694653e3edc6 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/rtc_isr_stub.c @@ -0,0 +1,26 @@ +#include +#include +#include "esp_err.h" +#include "esp_sleep.h" + +void rtc_isr_noniram_disable(uint32_t cpu) +{ + (void) cpu; +} + +void rtc_isr_noniram_enable(uint32_t cpu) +{ + (void) cpu; +} + +esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option) +{ + (void) domain; + (void) option; + return ESP_OK; +} + +void pmu_sleep_enable_hp_sleep_sysclk(bool enable) +{ + (void) enable; +} diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c new file mode 100644 index 000000000000..bb42b65645cf --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -0,0 +1,266 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp32c6/rom/ets_sys.h" +#include "soc/rtc.h" +#include "soc/lp_timer_reg.h" +#include "hal/lp_timer_hal.h" +#include "hal/clk_tree_ll.h" +#include "soc/timer_group_reg.h" +#include "esp_rom_sys.h" +#include "assert.h" +#include "hal/efuse_hal.h" +#include "soc/chip_revision.h" + +static const char *TAG = "rtc_time"; + +/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. + * This feature counts the number of XTAL clock cycles within a given number of + * RTC_SLOW_CLK cycles. + * + * Slow clock calibration feature has two modes of operation: one-off and cycling. + * In cycling mode (which is enabled by default on SoC reset), counting of XTAL + * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled + * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed + * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is + * enabled using TIMG_RTC_CALI_START bit. + */ + +/* On ESP32C6, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3 + * 0 or 3: calibrate RC_SLOW clock + * 1: calibrate RC_FAST clock + * 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0 + */ +#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0 +#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1 +#define TIMG_RTC_CALI_CLK_SEL_32K 2 + +/** + * @brief Clock calibration function used by rtc_clk_cal + * + * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. + * This feature counts the number of XTAL clock cycles within a given number of + * RTC_SLOW_CLK cycles. + * + * Slow clock calibration feature has two modes of operation: one-off and cycling. + * In cycling mode (which is enabled by default on SoC reset), counting of XTAL + * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled + * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed + * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is + * enabled using TIMG_RTC_CALI_START bit. + * + * @param cal_clk which clock to calibrate + * @param slowclk_cycles number of slow clock cycles to count + * @return number of XTAL clock cycles within the given number of slow clock cycles + */ +static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) +{ + assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V); + + uint32_t cali_clk_sel = 0; + soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); + soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target(); + if (cal_clk == RTC_CAL_RTC_MUX) { + cal_clk = (rtc_cal_sel_t)slow_clk_src; + } + if (cal_clk == RTC_CAL_RC_FAST) { + cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST; + } else if (cal_clk == RTC_CAL_RC_SLOW) { + cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW; + } else { + cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K; + clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk); + } + + + /* Enable requested clock (150k clock is always on) */ + // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock + // Only enable if orignally was disabled, and set back to the disable state after calibration is done + // If the clock is already on, then do nothing + bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); + if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { + clk_ll_xtal32k_digi_enable(); + } + + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); + if (cal_clk == RTC_CAL_RC_FAST) { + if (!rc_fast_enabled) { + rtc_clk_8m_enable(true); + } + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_enable(); + } + } + + bool rc32k_enabled = clk_ll_rc32k_is_enabled(); + bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); + if (cal_clk == RTC_CAL_RC32K) { + if (!rc32k_enabled) { + rtc_clk_rc32k_enable(true); + } + if (!dig_rc32k_enabled) { + clk_ll_rc32k_digi_enable(); + } + } + + /* There may be another calibration process already running during we call this function, + * so we should wait the last process is done. + */ + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) { + /** + * Set a small timeout threshold to accelerate the generation of timeout. + * The internal circuit will be reset when the timeout occurs and will not affect the next calibration. + */ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1); + while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) + && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)); + } + + /* Prepare calibration */ + REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); + CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); + REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); + /* Figure out how long to wait for calibration to finish */ + + /* Set timeout reg and expect time delay*/ + uint32_t expected_freq; + if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) { + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles)); + expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; + } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles)); + expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + } else { + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); + expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; + } + uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); + /* Start calibration */ + CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + + /* Wait for calibration to finish up to another us_time_estimate */ + esp_rom_delay_us(us_time_estimate); + uint32_t cal_val; + while (true) { + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { + cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE); + + /*The Fosc CLK of calibration circuit is divided by 32 for ECO1. + So we need to multiply the frequency of the Fosc for ECO1 and above chips by 32 times. + And ensure that this modification will not affect ECO0.*/ + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + if (cal_clk == RTC_CAL_RC_FAST) { + cal_val = cal_val >> 5; + } + } + break; + } + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { + cal_val = 0; + break; + } + } + CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + + /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ + if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { + clk_ll_xtal32k_digi_disable(); + } + + if (cal_clk == RTC_CAL_RC_FAST) { + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_disable(); + } + if (!rc_fast_enabled) { + rtc_clk_8m_enable(false); + } + } + + if (cal_clk == RTC_CAL_RC32K) { + if (!dig_rc32k_enabled) { + clk_ll_rc32k_digi_disable(); + } + if (!rc32k_enabled) { + rtc_clk_rc32k_enable(false); + } + } + + // Always set back the calibration 32kHz clock selection + if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) { + clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel); + } + + return cal_val; +} + +static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles) +{ + uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768 + uint64_t delta = expected_xtal_cycles / 2000; // 5/10000 = 0.05% error range + return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta)); +} + +uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) +{ + assert(slowclk_cycles); + rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); + + /*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 (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + if (cal_clk == RTC_CAL_RC_FAST) { + slowclk_cycles = slowclk_cycles >> 5; + } + } + + uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); + + if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) { + return 0; + } + + uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles; + uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; + uint32_t period = (uint32_t)(period_64 & UINT32_MAX); + return period; +} + +uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) +{ + assert(period); + /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. + * TODO: fix overflow. + */ + return (time_in_us << RTC_CLK_CAL_FRACT) / period; +} + +uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) +{ + return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT; +} + +uint64_t rtc_time_get(void) +{ + return lp_timer_hal_get_cycle_count(); +} + +void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more +{ + // TODO: IDF-5781 + ESP_EARLY_LOGW(TAG, "rtc_clk_wait_for_slow_cycle() has not been implemented yet"); +} + +uint32_t rtc_clk_freq_cal(uint32_t cal_val) +{ + if (cal_val == 0) { + return 0; // cal_val will be denominator, return 0 as the symbol of failure. + } + return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val; +} diff --git a/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c new file mode 100644 index 000000000000..c541f2b57016 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * Related peripherals are: + * - ADC + * - PWDET + */ + +#include "sdkconfig.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "esp_private/sar_periph_ctrl.h" +#include "esp_private/esp_modem_clock.h" +#include "hal/sar_ctrl_ll.h" + +static const char *TAG = "sar_periph_ctrl"; +extern portMUX_TYPE rtc_spinlock; + + +void sar_periph_ctrl_init(void) +{ + sar_ctrl_ll_force_power_ctrl_from_pwdet(true); + + //Add other periph power control initialisation here +} + +void sar_periph_ctrl_power_enable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + sar_ctrl_ll_force_power_ctrl_from_pwdet(true); + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + sar_ctrl_ll_force_power_ctrl_from_pwdet(false); + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +/** + * This gets incremented when s_sar_power_acquire() is called, + * and decremented when s_sar_power_release() is called. + * PWDET is powered down when the value reaches zero. + * Should be modified within critical section. + */ +static int s_pwdet_power_on_cnt; + +static void s_sar_power_acquire(void) +{ + modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); + portENTER_CRITICAL_SAFE(&rtc_spinlock); + s_pwdet_power_on_cnt++; + if (s_pwdet_power_on_cnt == 1) { + sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); + } + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +static void s_sar_power_release(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + s_pwdet_power_on_cnt--; + if (s_pwdet_power_on_cnt < 0) { + portEXIT_CRITICAL(&rtc_spinlock); + ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__); + abort(); + } else if (s_pwdet_power_on_cnt == 0) { + sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); + } + portEXIT_CRITICAL_SAFE(&rtc_spinlock); + modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); +} + + +/*------------------------------------------------------------------------------ +* PWDET Power +*----------------------------------------------------------------------------*/ +void sar_periph_ctrl_pwdet_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_pwdet_power_release(void) +{ + s_sar_power_release(); +} + + +/*------------------------------------------------------------------------------ +* ADC Power +*----------------------------------------------------------------------------*/ +void sar_periph_ctrl_adc_oneshot_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_adc_oneshot_power_release(void) +{ + s_sar_power_release(); +} + +void sar_periph_ctrl_adc_continuous_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_adc_continuous_power_release(void) +{ + s_sar_power_release(); +} diff --git a/components/esp_hw_support/port/esp32c6/spi_lock_stub.c b/components/esp_hw_support/port/esp32c6/spi_lock_stub.c new file mode 100644 index 000000000000..2154980c030e --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/spi_lock_stub.c @@ -0,0 +1,15 @@ +#include +#include "driver/spi_common.h" +#include "esp_private/spi_common_internal.h" + +bool spicommon_bus_using_iomux(spi_host_device_t host) +{ + (void) host; + return true; +} + +spi_bus_lock_handle_t spi_bus_lock_get_by_id(spi_host_device_t host_id) +{ + (void) host_id; + return 0; +} diff --git a/components/esp_hw_support/port/esp32c6/systimer.c b/components/esp_hw_support/port/esp32c6/systimer.c new file mode 100644 index 000000000000..d5ea58b1aa46 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/systimer.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/systimer.h" + +/** + * @brief systimer's clock source is fixed to XTAL (40MHz), and has a fixed fractional divider (2.5). + * So the resolution of the systimer is 40MHz/2.5 = 16MHz. + */ + +uint64_t systimer_ticks_to_us(uint64_t ticks) +{ + return ticks / 16; +} + +uint64_t systimer_us_to_ticks(uint64_t us) +{ + return us * 16; +} diff --git a/components/esp_rom/esp32c6/Kconfig.soc_caps.in b/components/esp_rom/esp32c6/Kconfig.soc_caps.in new file mode 100644 index 000000000000..df5e153a0d22 --- /dev/null +++ b/components/esp_rom/esp32c6/Kconfig.soc_caps.in @@ -0,0 +1,84 @@ +##################################################### +# This file is auto-generated from SoC caps +# using gen_soc_caps_kconfig.py, do not edit manually +##################################################### + +config ESP_ROM_HAS_CRC_LE + bool + default y + +config ESP_ROM_HAS_CRC_BE + bool + default y + +config ESP_ROM_HAS_JPEG_DECODE + bool + default y + +config ESP_ROM_UART_CLK_IS_XTAL + bool + default y + +config ESP_ROM_USB_SERIAL_DEVICE_NUM + int + default 3 + +config ESP_ROM_HAS_RETARGETABLE_LOCKING + bool + default y + +config ESP_ROM_GET_CLK_FREQ + bool + default y + +config ESP_ROM_HAS_RVFPLIB + bool + default y + +config ESP_ROM_HAS_HAL_WDT + bool + default y + +config ESP_ROM_HAS_HAL_SYSTIMER + bool + default y + +config ESP_ROM_HAS_HEAP_TLSF + bool + default y + +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + +config ESP_ROM_HAS_LAYOUT_TABLE + bool + default y + +config ESP_ROM_HAS_SPI_FLASH + bool + default y + +config ESP_ROM_HAS_REGI2C_BUG + bool + default y + +config ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT + bool + default y + +config ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE + bool + default y + +config ESP_ROM_WDT_INIT_PATCH + bool + default y + +config ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE + bool + default y + +config ESP_ROM_RAM_APP_NEEDS_MMU_INIT + bool + default y diff --git a/components/esp_rom/esp32c6/esp_rom_caps.h b/components/esp_rom/esp32c6/esp_rom_caps.h new file mode 100644 index 000000000000..1eeab3bd3e8b --- /dev/null +++ b/components/esp_rom/esp32c6/esp_rom_caps.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define ESP_ROM_HAS_CRC_LE (1) // ROM CRC library supports Little Endian +#define ESP_ROM_HAS_CRC_BE (1) // ROM CRC library supports Big Endian +#define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library +#define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM +#define ESP_ROM_USB_SERIAL_DEVICE_NUM (3) // UART uses USB_SERIAL_JTAG port in ROM. +#define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking +#define ESP_ROM_GET_CLK_FREQ (1) // Get clk frequency with rom function `ets_get_cpu_frequency` +#define ESP_ROM_HAS_RVFPLIB (1) // ROM has the rvfplib +#define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver +#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver +#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() +#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table +#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver +#define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug +#define ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT (1) // ROM has the newlib normal/full version of formatting functions (as opposed to the nano versions) +#define ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE (1) // ECO 0 does not have ets_ecdsa_verify symbol, future revision will have it +#define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock +#define ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE (1) // ROM needs to set cache MMU size according to instruction and rodata for flash mmap +#define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld new file mode 100644 index 000000000000..cf8c34778ee3 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 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_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/components/esp_rom/esp32c6/ld/esp32c6.rom.coexist.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.coexist.ld new file mode 100644 index 000000000000..5ff011973e23 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.coexist.ld @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.coexist.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rom_coexist + ***************************************/ + +/* Functions */ +esp_coex_rom_version_get = 0x40000afc; +coex_bt_release = 0x40000b00; +coex_bt_request = 0x40000b04; +coex_core_ble_conn_dyn_prio_get = 0x40000b08; +/*coex_core_event_duration_get = 0x40000b0c;*/ +coex_core_pti_get = 0x40000b10; +coex_core_release = 0x40000b14; +coex_core_request = 0x40000b18; +coex_core_status_get = 0x40000b1c; +/*coex_core_timer_idx_get = 0x40000b20;*/ +coex_event_duration_get = 0x40000b24; +coex_hw_timer_disable = 0x40000b28; +coex_hw_timer_enable = 0x40000b2c; +coex_hw_timer_set = 0x40000b30; +coex_schm_interval_set = 0x40000b34; +coex_schm_lock = 0x40000b38; +coex_schm_unlock = 0x40000b3c; +coex_status_get = 0x40000b40; +coex_wifi_release = 0x40000b44; +esp_coex_ble_conn_dynamic_prio_get = 0x40000b48; +/* Data (.data, .bss, .rodata) */ +coex_env_ptr = 0x4087ffc4; +coex_pti_tab_ptr = 0x4087ffc0; +coex_schm_env_ptr = 0x4087ffbc; +coexist_funcs = 0x4087ffb8; +g_coa_funcs_p = 0x4087ffb4; +g_coex_param_ptr = 0x4087ffb0; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld new file mode 100644 index 000000000000..bf3d88d66d2d --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.heap.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group heap + ***************************************/ + +/* Functions */ +tlsf_create = 0x400003fc; +tlsf_create_with_pool = 0x40000400; +tlsf_get_pool = 0x40000404; +tlsf_add_pool = 0x40000408; +tlsf_remove_pool = 0x4000040c; +tlsf_malloc = 0x40000410; +tlsf_memalign = 0x40000414; +tlsf_memalign_offs = 0x40000418; +tlsf_realloc = 0x4000041c; +tlsf_free = 0x40000420; +tlsf_block_size = 0x40000424; +tlsf_size = 0x40000428; +tlsf_align_size = 0x4000042c; +tlsf_block_size_min = 0x40000430; +tlsf_block_size_max = 0x40000434; +tlsf_pool_overhead = 0x40000438; +tlsf_alloc_overhead = 0x4000043c; +tlsf_walk_pool = 0x40000440; +tlsf_check = 0x40000444; +tlsf_poison_fill_pfunc_set = 0x4000044c; +multi_heap_get_block_address_impl = 0x40000454; +multi_heap_get_allocated_size_impl = 0x40000458; +multi_heap_register_impl = 0x4000045c; +multi_heap_set_lock = 0x40000460; +multi_heap_mutex_init = 0x40000464; +multi_heap_internal_lock = 0x40000468; +multi_heap_internal_unlock = 0x4000046c; +multi_heap_get_first_block = 0x40000470; +multi_heap_get_next_block = 0x40000474; +multi_heap_is_free = 0x40000478; +multi_heap_malloc_impl = 0x4000047c; +multi_heap_free_impl = 0x40000480; +multi_heap_realloc_impl = 0x40000484; +multi_heap_aligned_alloc_impl_offs = 0x40000488; +multi_heap_aligned_alloc_impl = 0x4000048c; +multi_heap_check = 0x40000490; +multi_heap_dump = 0x40000494; +multi_heap_free_size_impl = 0x40000498; +multi_heap_minimum_free_size_impl = 0x4000049c; +multi_heap_get_info_impl = 0x400004a0; +/* Data (.data, .bss, .rodata) */ +heap_tlsf_table_ptr = 0x4087ffd8; + +PROVIDE (multi_heap_malloc = multi_heap_malloc_impl); +PROVIDE (multi_heap_free = multi_heap_free_impl); +PROVIDE (multi_heap_realloc = multi_heap_realloc_impl); +PROVIDE (multi_heap_get_allocated_size = multi_heap_get_allocated_size_impl); +PROVIDE (multi_heap_register = multi_heap_register_impl); +PROVIDE (multi_heap_get_info = multi_heap_get_info_impl); +PROVIDE (multi_heap_free_size = multi_heap_free_size_impl); +PROVIDE (multi_heap_minimum_free_size = multi_heap_minimum_free_size_impl); +PROVIDE (multi_heap_get_block_address = multi_heap_get_block_address_impl); +PROVIDE (multi_heap_aligned_alloc = multi_heap_aligned_alloc_impl); +PROVIDE (multi_heap_aligned_free = multi_heap_aligned_free_impl); +PROVIDE (multi_heap_check = multi_heap_check); +PROVIDE (multi_heap_set_lock = multi_heap_set_lock); +PROVIDE (multi_heap_os_funcs_init = multi_heap_mutex_init); +PROVIDE (multi_heap_internal_lock = multi_heap_internal_lock); +PROVIDE (multi_heap_internal_unlock = multi_heap_internal_unlock); diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.ld new file mode 100644 index 000000000000..5cb4bb667988 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.ld @@ -0,0 +1,462 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * 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 = 0x40000018; +analog_super_wdt_reset_happened = 0x4000001c; +rtc_get_wakeup_cause = 0x40000020; +rtc_unhold_all_pads = 0x40000024; +ets_printf = 0x40000028; +ets_install_putc1 = 0x4000002c; +ets_install_putc2 = 0x40000030; +ets_install_uart_printf = 0x40000034; +ets_install_usb_printf = 0x40000038; +ets_get_printf_channel = 0x4000003c; +ets_delay_us = 0x40000040; +ets_get_cpu_frequency = 0x40000044; +ets_update_cpu_frequency = 0x40000048; +ets_install_lock = 0x4000004c; +UartRxString = 0x40000050; +UartGetCmdLn = 0x40000054; +uart_tx_one_char = 0x40000058; +uart_tx_one_char2 = 0x4000005c; +uart_rx_one_char = 0x40000060; +uart_rx_one_char_block = 0x40000064; +uart_rx_intr_handler = 0x40000068; +uart_rx_readbuff = 0x4000006c; +uartAttach = 0x40000070; +uart_tx_flush = 0x40000074; +uart_tx_wait_idle = 0x40000078; +uart_div_modify = 0x4000007c; +ets_write_char_uart = 0x40000080; +uart_tx_switch = 0x40000084; +roundup2 = 0x40000088; +multofup = 0x4000008c; +software_reset = 0x40000090; +software_reset_cpu = 0x40000094; +ets_clk_assist_debug_clock_enable = 0x40000098; +clear_super_wdt_reset_flag = 0x4000009c; +disable_default_watchdog = 0x400000a0; +esp_rom_set_rtc_wake_addr = 0x400000a4; +esp_rom_get_rtc_wake_addr = 0x400000a8; +send_packet = 0x400000ac; +recv_packet = 0x400000b0; +GetUartDevice = 0x400000b4; +UartDwnLdProc = 0x400000b8; +GetSecurityInfoProc = 0x400000bc; +Uart_Init = 0x400000c0; +ets_set_user_start = 0x400000c4; +/* Data (.data, .bss, .rodata) */ +ets_rom_layout_p = 0x4004fffc; +ets_ops_table_ptr = 0x4087fff8; +g_saved_pc = 0x4087fffc; + + +/*************************************** + Group miniz + ***************************************/ + +/* Functions */ +mz_adler32 = 0x400000c8; +mz_free = 0x400000cc; +tdefl_compress = 0x400000d0; +tdefl_compress_buffer = 0x400000d4; +tdefl_compress_mem_to_heap = 0x400000d8; +tdefl_compress_mem_to_mem = 0x400000dc; +tdefl_compress_mem_to_output = 0x400000e0; +tdefl_get_adler32 = 0x400000e4; +tdefl_get_prev_return_status = 0x400000e8; +tdefl_init = 0x400000ec; +tdefl_write_image_to_png_file_in_memory = 0x400000f0; +tdefl_write_image_to_png_file_in_memory_ex = 0x400000f4; +tinfl_decompress = 0x400000f8; +tinfl_decompress_mem_to_callback = 0x400000fc; +tinfl_decompress_mem_to_heap = 0x40000100; +tinfl_decompress_mem_to_mem = 0x40000104; + + +/*************************************** + Group tjpgd + ***************************************/ + +/* Functions */ +jd_prepare = 0x40000108; +jd_decomp = 0x4000010c; + + +/*************************************** + Group spiflash_legacy + ***************************************/ + +/* Functions */ +esp_rom_spiflash_wait_idle = 0x40000110; +esp_rom_spiflash_write_encrypted = 0x40000114; +esp_rom_spiflash_write_encrypted_dest = 0x40000118; +esp_rom_spiflash_write_encrypted_enable = 0x4000011c; +esp_rom_spiflash_write_encrypted_disable = 0x40000120; +esp_rom_spiflash_erase_chip = 0x40000124; +_esp_rom_spiflash_erase_sector = 0x40000128; +_esp_rom_spiflash_erase_block = 0x4000012c; +_esp_rom_spiflash_write = 0x40000130; +_esp_rom_spiflash_read = 0x40000134; +_esp_rom_spiflash_unlock = 0x40000138; +_SPIEraseArea = 0x4000013c; +_SPI_write_enable = 0x40000140; +esp_rom_spiflash_erase_sector = 0x40000144; +esp_rom_spiflash_erase_block = 0x40000148; +esp_rom_spiflash_write = 0x4000014c; +esp_rom_spiflash_read = 0x40000150; +esp_rom_spiflash_unlock = 0x40000154; +SPIEraseArea = 0x40000158; +SPI_write_enable = 0x4000015c; +esp_rom_spiflash_config_param = 0x40000160; +esp_rom_spiflash_read_user_cmd = 0x40000164; +esp_rom_spiflash_select_qio_pins = 0x40000168; +esp_rom_spi_flash_auto_sus_res = 0x4000016c; +esp_rom_spi_flash_send_resume = 0x40000170; +esp_rom_spi_flash_update_id = 0x40000174; +esp_rom_spiflash_config_clk = 0x40000178; +esp_rom_spiflash_config_readmode = 0x4000017c; +esp_rom_spiflash_read_status = 0x40000180; +esp_rom_spiflash_read_statushigh = 0x40000184; +esp_rom_spiflash_write_status = 0x40000188; +spi_cache_mode_switch = 0x4000018c; +spi_common_set_dummy_output = 0x40000190; +spi_common_set_flash_cs_timing = 0x40000194; +esp_rom_spi_set_address_bit_len = 0x40000198; +SPILock = 0x4000019c; +SPIMasterReadModeCnfig = 0x400001a0; +SPI_Common_Command = 0x400001a4; +SPI_WakeUp = 0x400001a8; +SPI_block_erase = 0x400001ac; +SPI_chip_erase = 0x400001b0; +SPI_init = 0x400001b4; +SPI_page_program = 0x400001b8; +SPI_read_data = 0x400001bc; +SPI_sector_erase = 0x400001c0; +SelectSpiFunction = 0x400001c4; +SetSpiDrvs = 0x400001c8; +Wait_SPI_Idle = 0x400001cc; +spi_dummy_len_fix = 0x400001d0; +Disable_QMode = 0x400001d4; +Enable_QMode = 0x400001d8; +spi_flash_attach = 0x400001dc; +spi_flash_get_chip_size = 0x400001e0; +spi_flash_guard_set = 0x400001e4; +spi_flash_guard_get = 0x400001e8; +spi_flash_read_encrypted = 0x400001ec; +/* Data (.data, .bss, .rodata) */ +rom_spiflash_legacy_funcs = 0x4087fff0; +rom_spiflash_legacy_data = 0x4087ffec; +g_flash_guard_ops = 0x4087fff4; + +/* Note: esp_rom_spiflash_write_disable was moved from esp32c6.rom.spiflash.ld */ +esp_rom_spiflash_write_disable = 0x40000278; + +/*************************************** + Group hal_systimer + ***************************************/ + +/* Functions */ +/* The following ROM functions are commented out because they're patched in the esp_rom_systimer.c */ +/* systimer_hal_init = 0x400003c0; */ +/* systimer_hal_deinit = 0x400003c4; */ + +systimer_hal_set_tick_rate_ops = 0x400003c8; +systimer_hal_get_counter_value = 0x400003cc; +systimer_hal_get_time = 0x400003d0; +systimer_hal_set_alarm_target = 0x400003d4; +systimer_hal_set_alarm_period = 0x400003d8; +systimer_hal_get_alarm_value = 0x400003dc; +systimer_hal_enable_alarm_int = 0x400003e0; +systimer_hal_on_apb_freq_update = 0x400003e4; +systimer_hal_counter_value_advance = 0x400003e8; +systimer_hal_enable_counter = 0x400003ec; +systimer_hal_select_alarm_mode = 0x400003f0; +systimer_hal_connect_alarm_counter = 0x400003f4; +systimer_hal_counter_can_stall_by_cpu = 0x400003f8; + + +/*************************************** + Group cache + ***************************************/ + +/* Functions */ +Cache_Get_ICache_Line_Size = 0x40000628; +Cache_Get_Mode = 0x4000062c; +Cache_Address_Through_Cache = 0x40000630; +ROM_Boot_Cache_Init = 0x40000634; +MMU_Set_Page_Mode = 0x40000638; +MMU_Get_Page_Mode = 0x4000063c; +Cache_Invalidate_ICache_Items = 0x40000640; +Cache_Op_Addr = 0x40000644; +Cache_Invalidate_Addr = 0x40000648; +Cache_Invalidate_ICache_All = 0x4000064c; +Cache_Mask_All = 0x40000650; +Cache_UnMask_Dram0 = 0x40000654; +Cache_Suspend_ICache_Autoload = 0x40000658; +Cache_Resume_ICache_Autoload = 0x4000065c; +Cache_Start_ICache_Preload = 0x40000660; +Cache_ICache_Preload_Done = 0x40000664; +Cache_End_ICache_Preload = 0x40000668; +Cache_Config_ICache_Autoload = 0x4000066c; +Cache_Enable_ICache_Autoload = 0x40000670; +Cache_Disable_ICache_Autoload = 0x40000674; +Cache_Enable_ICache_PreLock = 0x40000678; +Cache_Disable_ICache_PreLock = 0x4000067c; +Cache_Lock_ICache_Items = 0x40000680; +Cache_Unlock_ICache_Items = 0x40000684; +Cache_Lock_Addr = 0x40000688; +Cache_Unlock_Addr = 0x4000068c; +Cache_Disable_ICache = 0x40000690; +Cache_Enable_ICache = 0x40000694; +Cache_Suspend_ICache = 0x40000698; +Cache_Resume_ICache = 0x4000069c; +Cache_Freeze_ICache_Enable = 0x400006a0; +Cache_Freeze_ICache_Disable = 0x400006a4; +Cache_Set_IDROM_MMU_Size = 0x400006a8; +Cache_Get_IROM_MMU_End = 0x400006ac; +Cache_Get_DROM_MMU_End = 0x400006b0; +Cache_MMU_Init = 0x400006b4; +Cache_MSPI_MMU_Set = 0x400006b8; +Cache_Travel_Tag_Memory = 0x400006bc; +Cache_Get_Virtual_Addr = 0x400006c0; +/* Data (.data, .bss, .rodata) */ +rom_cache_op_cb = 0x4087ffcc; +rom_cache_internal_table_ptr = 0x4087ffc8; + + +/*************************************** + Group clock + ***************************************/ + +/* Functions */ +ets_clk_get_xtal_freq = 0x400006c4; +ets_clk_get_cpu_freq = 0x400006c8; +ets_clk_apb_wait_ready = 0x400006cc; +ets_clk_mspi_apb_wait_ready = 0x400006d0; + + +/*************************************** + Group gpio + ***************************************/ + +/* Functions */ +gpio_input_get = 0x400006d4; +gpio_matrix_in = 0x400006d8; +gpio_matrix_out = 0x400006dc; +gpio_output_disable = 0x400006e0; +gpio_output_enable = 0x400006e4; +gpio_output_set = 0x400006e8; +gpio_pad_hold = 0x400006ec; +gpio_pad_input_disable = 0x400006f0; +gpio_pad_input_enable = 0x400006f4; +gpio_pad_pulldown = 0x400006f8; +gpio_pad_pullup = 0x400006fc; +gpio_pad_select_gpio = 0x40000700; +gpio_pad_set_drv = 0x40000704; +gpio_pad_unhold = 0x40000708; +gpio_pin_wakeup_disable = 0x4000070c; +gpio_pin_wakeup_enable = 0x40000710; +gpio_bypass_matrix_in = 0x40000714; + + +/*************************************** + Group interrupts + ***************************************/ + +/* Functions */ +esprv_intc_int_set_priority = 0x40000718; +esprv_intc_int_set_threshold = 0x4000071c; +esprv_intc_int_enable = 0x40000720; +esprv_intc_int_disable = 0x40000724; +esprv_intc_int_set_type = 0x40000728; +PROVIDE( intr_handler_set = 0x4000072c ); +intr_matrix_set = 0x40000730; +ets_intr_lock = 0x40000734; +ets_intr_unlock = 0x40000738; +ets_isr_attach = 0x4000073c; +ets_isr_mask = 0x40000740; +ets_isr_unmask = 0x40000744; + + +/*************************************** + Group crypto + ***************************************/ + +/* Functions */ +md5_vector = 0x40000748; +MD5Init = 0x4000074c; +MD5Update = 0x40000750; +MD5Final = 0x40000754; +crc32_le = 0x40000758; +crc16_le = 0x4000075c; +crc8_le = 0x40000760; +crc32_be = 0x40000764; +crc16_be = 0x40000768; +crc8_be = 0x4000076c; +esp_crc8 = 0x40000770; +ets_sha_enable = 0x40000774; +ets_sha_disable = 0x40000778; +ets_sha_get_state = 0x4000077c; +ets_sha_init = 0x40000780; +ets_sha_process = 0x40000784; +ets_sha_starts = 0x40000788; +ets_sha_update = 0x4000078c; +ets_sha_finish = 0x40000790; +ets_sha_clone = 0x40000794; +ets_hmac_enable = 0x40000798; +ets_hmac_disable = 0x4000079c; +ets_hmac_calculate_message = 0x400007a0; +ets_hmac_calculate_downstream = 0x400007a4; +ets_hmac_invalidate_downstream = 0x400007a8; +ets_jtag_enable_temporarily = 0x400007ac; +ets_aes_enable = 0x400007b0; +ets_aes_disable = 0x400007b4; +ets_aes_setkey = 0x400007b8; +ets_aes_block = 0x400007bc; +ets_aes_setkey_dec = 0x400007c0; +ets_aes_setkey_enc = 0x400007c4; +ets_bigint_enable = 0x400007c8; +ets_bigint_disable = 0x400007cc; +ets_bigint_multiply = 0x400007d0; +ets_bigint_modmult = 0x400007d4; +ets_bigint_modexp = 0x400007d8; +ets_bigint_wait_finish = 0x400007dc; +ets_bigint_getz = 0x400007e0; +ets_ds_enable = 0x400007e4; +ets_ds_disable = 0x400007e8; +ets_ds_start_sign = 0x400007ec; +ets_ds_is_busy = 0x400007f0; +ets_ds_finish_sign = 0x400007f4; +ets_ds_encrypt_params = 0x400007f8; +ets_mgf1_sha256 = 0x400007fc; +/* Data (.data, .bss, .rodata) */ +crc32_le_table_ptr = 0x4004fff8; +crc16_le_table_ptr = 0x4004fff4; +crc8_le_table_ptr = 0x4004fff0; +crc32_be_table_ptr = 0x4004ffec; +crc16_be_table_ptr = 0x4004ffe8; +crc8_be_table_ptr = 0x4004ffe4; + + +/*************************************** + Group efuse + ***************************************/ + +/* Functions */ +ets_efuse_read = 0x40000800; +ets_efuse_program = 0x40000804; +ets_efuse_clear_program_registers = 0x40000808; +ets_efuse_write_key = 0x4000080c; +ets_efuse_get_read_register_address = 0x40000810; +ets_efuse_get_key_purpose = 0x40000814; +ets_efuse_key_block_unused = 0x40000818; +ets_efuse_find_unused_key_block = 0x4000081c; +ets_efuse_rs_calculate = 0x40000820; +ets_efuse_count_unused_key_blocks = 0x40000824; +ets_efuse_secure_boot_enabled = 0x40000828; +ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4000082c; +ets_efuse_cache_encryption_enabled = 0x40000830; +ets_efuse_download_modes_disabled = 0x40000834; +ets_efuse_find_purpose = 0x40000838; +ets_efuse_force_send_resume = 0x4000083c; +ets_efuse_get_flash_delay_us = 0x40000840; +ets_efuse_get_mac = 0x40000844; +ets_efuse_get_uart_print_control = 0x40000848; +ets_efuse_direct_boot_mode_disabled = 0x4000084c; +ets_efuse_security_download_modes_enabled = 0x40000850; +ets_efuse_set_timing = 0x40000854; +ets_efuse_jtag_disabled = 0x40000858; +ets_efuse_usb_print_is_disabled = 0x4000085c; +ets_efuse_usb_download_mode_disabled = 0x40000860; +ets_efuse_usb_device_disabled = 0x40000864; +ets_efuse_secure_boot_fast_wake_enabled = 0x40000868; + + +/*************************************** + Group secureboot + ***************************************/ + +/* Functions */ +ets_emsa_pss_verify = 0x4000086c; +ets_rsa_pss_verify = 0x40000870; +ets_secure_boot_verify_bootloader_with_keys = 0x40000874; +ets_secure_boot_verify_signature = 0x40000878; +ets_secure_boot_read_key_digests = 0x4000087c; +ets_secure_boot_revoke_public_key_digest = 0x40000880; + + +/*************************************** + Group usb_device_uart + ***************************************/ + +/* Functions */ +usb_serial_device_rx_one_char = 0x40000a80; +usb_serial_device_rx_one_char_block = 0x40000a84; +usb_serial_device_tx_flush = 0x40000a88; +usb_serial_device_tx_one_char = 0x40000a8c; + + +/*************************************** + Group lldesc + ***************************************/ + +/* Functions */ +lldesc_build_chain = 0x40000a90; + + +/*************************************** + Group sip + ***************************************/ + +/* Functions */ +sip_after_tx_complete = 0x40000a94; +sip_alloc_to_host_evt = 0x40000a98; +sip_download_begin = 0x40000a9c; +sip_get_ptr = 0x40000aa0; +sip_get_state = 0x40000aa4; +sip_init_attach = 0x40000aa8; +sip_install_rx_ctrl_cb = 0x40000aac; +sip_install_rx_data_cb = 0x40000ab0; +sip_is_active = 0x40000ab4; +sip_post_init = 0x40000ab8; +sip_reclaim_from_host_cmd = 0x40000abc; +sip_reclaim_tx_data_pkt = 0x40000ac0; +sip_send = 0x40000ac4; +sip_to_host_chain_append = 0x40000ac8; +sip_to_host_evt_send_done = 0x40000acc; + + +/*************************************** + Group slc + ***************************************/ + +/* Functions */ +slc_add_credits = 0x40000ad0; +slc_enable = 0x40000ad4; +slc_from_host_chain_fetch = 0x40000ad8; +slc_from_host_chain_recycle = 0x40000adc; +slc_has_pkt_to_host = 0x40000ae0; +slc_init_attach = 0x40000ae4; +slc_init_credit = 0x40000ae8; +slc_reattach = 0x40000aec; +slc_send_to_host_chain = 0x40000af0; +slc_set_host_io_max_window = 0x40000af4; +slc_to_host_chain_recycle = 0x40000af8; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.libgcc.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.libgcc.ld new file mode 100644 index 000000000000..b43497040095 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.libgcc.ld @@ -0,0 +1,112 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.libgcc.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group libgcc + ***************************************/ + +/* Functions */ +__absvdi2 = 0x40000884; +__absvsi2 = 0x40000888; +__adddf3 = 0x4000088c; +__addsf3 = 0x40000890; +__addvdi3 = 0x40000894; +__addvsi3 = 0x40000898; +__ashldi3 = 0x4000089c; +__ashrdi3 = 0x400008a0; +__bswapdi2 = 0x400008a4; +__bswapsi2 = 0x400008a8; +__clear_cache = 0x400008ac; +__clrsbdi2 = 0x400008b0; +__clrsbsi2 = 0x400008b4; +__clzdi2 = 0x400008b8; +__clzsi2 = 0x400008bc; +__cmpdi2 = 0x400008c0; +__ctzdi2 = 0x400008c4; +__ctzsi2 = 0x400008c8; +__divdc3 = 0x400008cc; +__divdf3 = 0x400008d0; +__divdi3 = 0x400008d4; +__divsc3 = 0x400008d8; +__divsf3 = 0x400008dc; +__divsi3 = 0x400008e0; +__eqdf2 = 0x400008e4; +__eqsf2 = 0x400008e8; +__extendsfdf2 = 0x400008ec; +__ffsdi2 = 0x400008f0; +__ffssi2 = 0x400008f4; +__fixdfdi = 0x400008f8; +__fixdfsi = 0x400008fc; +__fixsfdi = 0x40000900; +__fixsfsi = 0x40000904; +__fixunsdfsi = 0x40000908; +__fixunssfdi = 0x4000090c; +__fixunssfsi = 0x40000910; +__floatdidf = 0x40000914; +__floatdisf = 0x40000918; +__floatsidf = 0x4000091c; +__floatsisf = 0x40000920; +__floatundidf = 0x40000924; +__floatundisf = 0x40000928; +__floatunsidf = 0x4000092c; +__floatunsisf = 0x40000930; +__gcc_bcmp = 0x40000934; +__gedf2 = 0x40000938; +__gesf2 = 0x4000093c; +__gtdf2 = 0x40000940; +__gtsf2 = 0x40000944; +__ledf2 = 0x40000948; +__lesf2 = 0x4000094c; +__lshrdi3 = 0x40000950; +__ltdf2 = 0x40000954; +__ltsf2 = 0x40000958; +__moddi3 = 0x4000095c; +__modsi3 = 0x40000960; +__muldc3 = 0x40000964; +__muldf3 = 0x40000968; +__muldi3 = 0x4000096c; +__mulsc3 = 0x40000970; +__mulsf3 = 0x40000974; +__mulsi3 = 0x40000978; +__mulvdi3 = 0x4000097c; +__mulvsi3 = 0x40000980; +__nedf2 = 0x40000984; +__negdf2 = 0x40000988; +__negdi2 = 0x4000098c; +__negsf2 = 0x40000990; +__negvdi2 = 0x40000994; +__negvsi2 = 0x40000998; +__nesf2 = 0x4000099c; +__paritysi2 = 0x400009a0; +__popcountdi2 = 0x400009a4; +__popcountsi2 = 0x400009a8; +__powidf2 = 0x400009ac; +__powisf2 = 0x400009b0; +__subdf3 = 0x400009b4; +__subsf3 = 0x400009b8; +__subvdi3 = 0x400009bc; +__subvsi3 = 0x400009c0; +__truncdfsf2 = 0x400009c4; +__ucmpdi2 = 0x400009c8; +__udivdi3 = 0x400009cc; +__udivmoddi4 = 0x400009d0; +__udivsi3 = 0x400009d4; +__udiv_w_sdiv = 0x400009d8; +__umoddi3 = 0x400009dc; +__umodsi3 = 0x400009e0; +__unorddf2 = 0x400009e4; +__unordsf2 = 0x400009e8; +__extenddftf2 = 0x400009ec; +__trunctfdf2 = 0x400009f0; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld new file mode 100644 index 000000000000..7a73b4d5a7d9 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.net80211.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rom_net80211 + ***************************************/ + +/* Functions */ +esp_net80211_rom_version_get = 0x40000b4c; +ampdu_dispatch = 0x40000b50; +ampdu_dispatch_all = 0x40000b54; +ampdu_dispatch_as_many_as_possible = 0x40000b58; +ampdu_dispatch_movement = 0x40000b5c; +ampdu_dispatch_upto = 0x40000b60; +chm_is_at_home_channel = 0x40000b64; +cnx_node_is_existing = 0x40000b68; +cnx_node_search = 0x40000b6c; +ic_ebuf_recycle_rx = 0x40000b70; +ic_ebuf_recycle_tx = 0x40000b74; +ic_reset_rx_ba = 0x40000b78; +ieee80211_align_eb = 0x40000b7c; +/*ieee80211_ampdu_reorder = 0x40000b80;*/ +ieee80211_ampdu_start_age_timer = 0x40000b84; +/*ieee80211_encap_esfbuf = 0x40000b88;*/ +ieee80211_is_tx_allowed = 0x40000b8c; +ieee80211_output_pending_eb = 0x40000b90; +/*ieee80211_output_process = 0x40000b94;*/ +ieee80211_set_tx_desc = 0x40000b98; +//sta_input = 0x40000b9c; +wifi_get_macaddr = 0x40000ba0; +wifi_rf_phy_disable = 0x40000ba4; +wifi_rf_phy_enable = 0x40000ba8; +ic_ebuf_alloc = 0x40000bac; +/*ieee80211_classify = 0x40000bb0;*/ +ieee80211_copy_eb_header = 0x40000bb4; +ieee80211_recycle_cache_eb = 0x40000bb8; +ieee80211_search_node = 0x40000bbc; +ieee80211_crypto_encap = 0x40000bc0; +/* ieee80211_crypto_decap = 0x40000bc4; */ +ieee80211_decap = 0x40000bc8; +wifi_is_started = 0x40000bcc; +ieee80211_gettid = 0x40000bd0; +ieee80211_encap_esfbuf_htc = 0x40000bd4; +/* Data (.data, .bss, .rodata) */ +net80211_funcs = 0x4087ffac; +g_scan = 0x4087ffa8; +g_chm = 0x4087ffa4; +g_ic_ptr = 0x4087ffa0; +g_hmac_cnt_ptr = 0x4087ff9c; +g_tx_cacheq_ptr = 0x4087ff98; +s_netstack_free = 0x4087ff94; +mesh_rxcb = 0x4087ff90; +sta_rxcb = 0x4087ff8c; +g_itwt_fid = 0x4087ff88; +esp_test_tx_addba_request = 0x4087ff84; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.newlib-normal.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.newlib-normal.ld new file mode 100644 index 000000000000..0a7101b10bd2 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.newlib-normal.ld @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.newlib-normal.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group newlib_normal_format + ***************************************/ + +/* Functions */ +__sprint_r = 0x400005d4; +_fiprintf_r = 0x400005d8; +_fprintf_r = 0x400005dc; +_vfiprintf_r = 0x400005e0; +_vfprintf_r = 0x400005e4; +fiprintf = 0x400005e8; +fprintf = 0x400005ec; +printf = 0x400005f0; +vfiprintf = 0x400005f4; +vfprintf = 0x400005f8; +asprintf = 0x400005fc; +sprintf = 0x40000600; +snprintf = 0x40000604; +siprintf = 0x40000608; +sniprintf = 0x4000060c; +vprintf = 0x40000610; +viprintf = 0x40000614; +vsnprintf = 0x40000618; +vsniprintf = 0x4000061c; +sscanf = 0x40000620; +siscanf = 0x40000624; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.newlib.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.newlib.ld new file mode 100644 index 000000000000..fcc63288a8bf --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.newlib.ld @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.newlib.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group newlib + ***************************************/ + +/* Functions */ +esp_rom_newlib_init_common_mutexes = 0x400004a4; +memset = 0x400004a8; +memcpy = 0x400004ac; +memmove = 0x400004b0; +memcmp = 0x400004b4; +strcpy = 0x400004b8; +strncpy = 0x400004bc; +strcmp = 0x400004c0; +strncmp = 0x400004c4; +strlen = 0x400004c8; +strstr = 0x400004cc; +bzero = 0x400004d0; +_isatty_r = 0x400004d4; +sbrk = 0x400004d8; +isalnum = 0x400004dc; +isalpha = 0x400004e0; +isascii = 0x400004e4; +isblank = 0x400004e8; +iscntrl = 0x400004ec; +isdigit = 0x400004f0; +islower = 0x400004f4; +isgraph = 0x400004f8; +isprint = 0x400004fc; +ispunct = 0x40000500; +isspace = 0x40000504; +isupper = 0x40000508; +toupper = 0x4000050c; +tolower = 0x40000510; +toascii = 0x40000514; +memccpy = 0x40000518; +memchr = 0x4000051c; +memrchr = 0x40000520; +strcasecmp = 0x40000524; +strcasestr = 0x40000528; +strcat = 0x4000052c; +strdup = 0x40000530; +strchr = 0x40000534; +strcspn = 0x40000538; +strcoll = 0x4000053c; +strlcat = 0x40000540; +strlcpy = 0x40000544; +strlwr = 0x40000548; +strncasecmp = 0x4000054c; +strncat = 0x40000550; +strndup = 0x40000554; +strnlen = 0x40000558; +strrchr = 0x4000055c; +strsep = 0x40000560; +strspn = 0x40000564; +strtok_r = 0x40000568; +strupr = 0x4000056c; +longjmp = 0x40000570; +setjmp = 0x40000574; +abs = 0x40000578; +div = 0x4000057c; +labs = 0x40000580; +ldiv = 0x40000584; +qsort = 0x40000588; +rand_r = 0x4000058c; +rand = 0x40000590; +srand = 0x40000594; +utoa = 0x40000598; +itoa = 0x4000059c; +atoi = 0x400005a0; +atol = 0x400005a4; +strtol = 0x400005a8; +strtoul = 0x400005ac; +fflush = 0x400005b0; +_fflush_r = 0x400005b4; +_fwalk = 0x400005b8; +_fwalk_reent = 0x400005bc; +__smakebuf_r = 0x400005c0; +__swhatbuf_r = 0x400005c4; +__swbuf_r = 0x400005c8; +__swbuf = 0x400005cc; +__swsetup_r = 0x400005d0; +/* Data (.data, .bss, .rodata) */ +syscall_table_ptr = 0x4087ffd4; +_global_impure_ptr = 0x4087ffd0; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.phy.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.phy.ld new file mode 100644 index 000000000000..94abe7c7582c --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.phy.ld @@ -0,0 +1,245 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.phy.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rom_phy + ***************************************/ + +/* Functions */ +phy_param_addr = 0x40001104; +phy_get_romfuncs = 0x40001108; +chip761_phyrom_version = 0x4000110c; +chip761_phyrom_version_num = 0x40001110; +get_rc_dout = 0x40001114; +rc_cal = 0x40001118; +rom_enter_critical_phy = 0x4000111c; +rom_exit_critical_phy = 0x40001120; +rom_set_chan_cal_interp = 0x40001124; +rom_loopback_mode_en = 0x40001128; +rom_bb_bss_cbw40 = 0x4000112c; +abs_temp = 0x40001130; +get_data_sat = 0x40001134; +phy_byte_to_word = 0x40001138; +set_chan_reg = 0x4000113c; +i2c_master_reset = 0x40001140; +rom_set_chan_freq_sw_start = 0x40001144; +freq_module_resetn = 0x40001148; +freq_chan_en_sw = 0x4000114c; +write_chan_freq = 0x40001150; +get_freq_mem_param = 0x40001154; +get_freq_mem_addr = 0x40001158; +bt_txpwr_freq = 0x4000115c; +wr_rf_freq_mem = 0x40001160; +read_rf_freq_mem = 0x40001164; +freq_i2c_mem_write = 0x40001168; +freq_num_get_data = 0x4000116c; +freq_i2c_num_addr = 0x40001170; +freq_i2c_write_set = 0x40001174; +pll_dac_mem_update = 0x40001178; +pll_cap_mem_update = 0x4000117c; +get_rf_freq_cap = 0x40001180; +get_rf_freq_init = 0x40001184; +phy_en_hw_set_freq = 0x40001188; +phy_dis_hw_set_freq = 0x4000118c; +rom_pwdet_sar2_init = 0x40001190; +rom_en_pwdet = 0x40001194; +rom_get_sar_sig_ref = 0x40001198; +rom_pwdet_tone_start = 0x4000119c; +rom_pwdet_wait_idle = 0x400011a0; +rom_read_sar_dout = 0x400011a4; +get_tone_sar_dout = 0x400011a8; +get_fm_sar_dout = 0x400011ac; +txtone_linear_pwr = 0x400011b0; +linear_to_db = 0x400011b4; +get_power_db = 0x400011b8; +meas_tone_pwr_db = 0x400011bc; +pkdet_vol_start = 0x400011c0; +read_sar2_code = 0x400011c4; +get_sar2_vol = 0x400011c8; +get_pll_vol = 0x400011cc; +tx_pwctrl_bg_init = 0x400011d0; +phy_pwdet_always_en = 0x400011d4; +phy_pwdet_onetime_en = 0x400011d8; +esp_tx_state_out_rom = 0x400011dc; +ant_dft_cfg_rom = 0x400011e0; +ant_wifitx_cfg_rom = 0x400011e4; +ant_wifirx_cfg_rom = 0x400011e8; +ant_bttx_cfg_rom = 0x400011ec; +ant_btrx_cfg_rom = 0x400011f0; +phy_chan_dump_cfg_rom = 0x400011f4; +phy_enable_low_rate = 0x400011f8; +phy_disable_low_rate = 0x400011fc; +phy_is_low_rate_enabled = 0x40001200; +phy_dig_reg_backup_rom = 0x40001204; +phy_chan_filt_set_rom = 0x40001208; +phy_rx11blr_cfg = 0x4000120c; +set_cca_rom = 0x40001210; +set_rx_sense_rom = 0x40001214; +rx_gain_force_rom = 0x40001218; +rom_rfpll_set_freq = 0x4000121c; +mhz2ieee = 0x40001220; +chan_to_freq = 0x40001224; +restart_cal = 0x40001228; +write_rfpll_sdm = 0x4000122c; +wait_rfpll_cal_end = 0x40001230; +set_rf_freq_offset = 0x40001234; +set_rfpll_freq = 0x40001238; +set_channel_rfpll_freq = 0x4000123c; +rfpll_cap_correct = 0x40001240; +rfpll_cap_init_cal = 0x40001244; +write_pll_cap = 0x40001248; +read_pll_cap = 0x4000124c; +chip_v7_set_chan_ana = 0x40001250; +freq_set_reg = 0x40001254; +gen_rx_gain_table = 0x40001258; +bt_txdc_cal = 0x4000125c; +bt_txiq_cal = 0x40001260; +txiq_cal_init = 0x40001264; +txdc_cal_init = 0x40001268; +txdc_cal = 0x4000126c; +txiq_get_mis_pwr = 0x40001270; +txiq_cover = 0x40001274; +rfcal_txiq = 0x40001278; +get_power_atten = 0x4000127c; +pwdet_ref_code = 0x40001280; +pwdet_code_cal = 0x40001284; +rfcal_txcap = 0x40001288; +tx_cap_init = 0x4000128c; +rfcal_pwrctrl = 0x40001290; +tx_pwctrl_init_cal = 0x40001294; +tx_pwctrl_init = 0x40001298; +bt_tx_pwctrl_init = 0x4000129c; +rom_i2c_enter_critical = 0x400012a0; +rom_i2c_exit_critical = 0x400012a4; +rom_get_i2c_read_mask = 0x400012a8; +rom_get_i2c_mst0_mask = 0x400012ac; +rom_get_i2c_hostid = 0x400012b0; +rom_chip_i2c_readReg_org = 0x400012b4; +rom_chip_i2c_readReg = 0x400012b8; +rom_chip_i2c_writeReg = 0x400012c0; +rom_set_txcap_reg = 0x400012d0; +i2c_paral_set_mst0 = 0x400012d4; +i2c_paral_set_read = 0x400012d8; +i2c_paral_read = 0x400012dc; +i2c_paral_write = 0x400012e0; +i2c_paral_write_num = 0x400012e4; +i2c_paral_write_mask = 0x400012e8; +i2c_sar2_init_code = 0x400012ec; +rom_pbus_force_mode = 0x400012f0; +rom_pbus_rd_addr = 0x400012f4; +rom_pbus_rd_shift = 0x400012f8; +rom_pbus_force_test = 0x400012fc; +rom_pbus_rd = 0x40001300; +rom_pbus_set_rxgain = 0x40001304; +rom_pbus_xpd_rx_off = 0x40001308; +rom_pbus_xpd_rx_on = 0x4000130c; +rom_pbus_xpd_tx_off = 0x40001310; +rom_pbus_xpd_tx_on = 0x40001314; +rom_set_loopback_gain = 0x40001318; +rom_txcal_debuge_mode = 0x4000131c; +pbus_debugmode = 0x40001320; +pbus_workmode = 0x40001324; +pbus_set_dco = 0x40001328; +txcal_work_mode = 0x4000132c; +rom_start_tx_tone_step = 0x40001330; +rom_stop_tx_tone = 0x40001334; +disable_agc = 0x40001338; +enable_agc = 0x4000133c; +phy_disable_cca = 0x40001340; +phy_enable_cca = 0x40001344; +write_gain_mem = 0x40001348; +bb_bss_cbw40_dig = 0x4000134c; +cbw2040_cfg = 0x40001350; +mac_tx_chan_offset = 0x40001354; +tx_paon_set = 0x40001358; +pwdet_reg_init = 0x4000135c; +i2cmst_reg_init = 0x40001360; +bt_gain_offset = 0x40001364; +fe_reg_init = 0x40001368; +mac_enable_bb = 0x4000136c; +bb_wdg_cfg = 0x40001370; +fe_txrx_reset = 0x40001374; +set_rx_comp = 0x40001378; +agc_reg_init = 0x4000137c; +bb_reg_init = 0x40001380; +open_i2c_xpd = 0x40001384; +txiq_set_reg = 0x40001388; +rxiq_set_reg = 0x4000138c; +set_txclk_en = 0x40001390; +set_rxclk_en = 0x40001394; +bb_wdg_test_en = 0x40001398; +noise_floor_auto_set = 0x4000139c; +read_hw_noisefloor = 0x400013a0; +iq_corr_enable = 0x400013a4; +wifi_agc_sat_gain = 0x400013a8; +phy_bbpll_cal = 0x400013ac; +phy_ant_init = 0x400013b0; +phy_set_bbfreq_init = 0x400013b4; +wifi_fbw_sel = 0x400013b8; +bt_filter_reg = 0x400013bc; +phy_rx_sense_set = 0x400013c0; +tx_state_set = 0x400013c4; +phy_close_pa = 0x400013c8; +phy_freq_correct = 0x400013cc; +set_pbus_reg = 0x400013d0; +wifi_rifs_mode_en = 0x400013d4; +nrx_freq_set = 0x400013d8; +fe_adc_on = 0x400013dc; +phy_force_pwr_index = 0x400013e0; +rom_iq_est_enable = 0x400013e4; +rom_iq_est_disable = 0x400013e8; +rom_bb_gain_index = 0x400013ec; +rom_rfrx_gain_index = 0x400013f0; +dc_iq_est = 0x400013f4; +set_cal_rxdc = 0x400013f8; +rxiq_get_mis = 0x400013fc; +rxiq_cover_mg_mp = 0x40001400; +rfcal_rxiq = 0x40001404; +get_rfcal_rxiq_data = 0x40001408; +get_dco_comp = 0x4000140c; +pbus_rx_dco_cal = 0x40001410; +rxdc_est_min = 0x40001414; +pbus_rx_dco_cal_1step = 0x40001418; +set_lb_txiq = 0x4000141c; +set_rx_gain_cal_iq = 0x40001420; +set_rx_gain_cal_dc = 0x40001424; +spur_reg_write_one_tone = 0x40001428; +spur_cal = 0x4000142c; +spur_coef_cfg = 0x40001430; +tsens_power_up = 0x40001434; +tsens_read_init = 0x40001438; +code_to_temp = 0x4000143c; +tsens_index_to_dac = 0x40001440; +tsens_index_to_offset = 0x40001444; +tsens_dac_cal = 0x40001448; +tsens_code_read = 0x4000144c; +tsens_temp_read = 0x40001450; +temp_to_power = 0x40001454; +get_temp_init = 0x40001458; +txbbgain_to_index = 0x4000145c; +index_to_txbbgain = 0x40001460; +bt_index_to_bb = 0x40001464; +bt_bb_to_index = 0x40001468; +bt_get_tx_gain = 0x4000146c; +dig_gain_check = 0x40001470; +wifi_get_tx_gain = 0x40001474; +wifi_11g_rate_chg = 0x40001478; +bt_chan_pwr_interp = 0x4000147c; +get_rate_fcc_index = 0x40001480; +get_chan_target_power = 0x40001484; +get_tx_gain_value = 0x40001488; +wifi_get_target_power = 0x4000148c; +/* Data (.data, .bss, .rodata) */ +phy_param_rom = 0x4087fce8; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld new file mode 100644 index 000000000000..78014c5e5937 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -0,0 +1,459 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.pp.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rom_pp + ***************************************/ + +/* Functions */ +esp_pp_rom_version_get = 0x40000bd8; +ppCalTxopRTSThreshold = 0x40000bdc; +RC_GetBlockAckTime = 0x40000be0; +ebuf_list_remove = 0x40000be4; +//esf_buf_alloc = 0x40000be8; +//esf_buf_alloc_dynamic = 0x40000bec; +//esf_buf_recycle = 0x40000bf0; +GetAccess = 0x40000bf4; +hal_mac_is_low_rate_enabled = 0x40000bf8; +hal_mac_tx_get_blockack = 0x40000bfc; +//hal_mac_tx_set_ppdu = 0x40000c00; +ic_get_trc = 0x40000c04; +//ic_mac_deinit = 0x40000c08; +ic_mac_init = 0x40000c0c; +ic_interface_enabled = 0x40000c10; +is_lmac_idle = 0x40000c14; +/*lmacAdjustTimestamp = 0x40000c18;*/ +lmacDiscardAgedMSDU = 0x40000c1c; +/*lmacDiscardMSDU = 0x40000c20;*/ +/*lmacEndFrameExchangeSequence = 0x40000c24;*/ +lmacIsIdle = 0x40000c28; +lmacIsLongFrame = 0x40000c2c; +/*lmacMSDUAged = 0x40000c30;*/ +lmacPostTxComplete = 0x40000c34; +lmacProcessAllTxTimeout = 0x40000c38; +lmacProcessCollisions = 0x40000c3c; +//lmacProcessRxSucData = 0x40000c40; +lmacReachLongLimit = 0x40000c44; +lmacReachShortLimit = 0x40000c48; +lmacRecycleMPDU = 0x40000c4c; +lmacRxDone = 0x40000c50; +//lmacSetTxFrame = 0x40000c54; +//lmacTxDone = 0x40000c58; +lmacTxFrame = 0x40000c5c; +mac_tx_set_duration = 0x40000c60; +//mac_tx_set_plcp0 = 0x40000c64; +//mac_tx_set_plcp1 = 0x40000c68; +mac_tx_set_plcp2 = 0x40000c6c; +/* pm_check_state = 0x40000c70; */ +/* pm_disable_dream_timer = 0x40000c74; */ +pm_disable_sleep_delay_timer = 0x40000c78; +pm_dream = 0x40000c7c; +pm_mac_wakeup = 0x40000c80; +pm_mac_sleep = 0x40000c84; +//pm_enable_active_timer = 0x40000c88; +pm_enable_sleep_delay_timer = 0x40000c8c; +pm_local_tsf_process = 0x40000c90; +//pm_set_beacon_filter = 0x40000c94; +pm_is_in_wifi_slice_threshold = 0x40000c98; +pm_is_waked = 0x40000c9c; +//pm_keep_alive = 0x40000ca0; +/* pm_on_beacon_rx = 0x40000ca4; */ +pm_on_data_rx = 0x40000ca8; +//pm_on_tbtt = 0x40000cac; +/* pm_parse_beacon = 0x40000cb0; */ +//pm_process_tim = 0x40000cb4; +//pm_rx_beacon_process = 0x40000cb8; +/* pm_rx_data_process = 0x40000cbc; */ +//pm_sleep = 0x40000cc0; +pm_sleep_for = 0x40000cc4; +//pm_tbtt_process = 0x40000cc8; +ppAMPDU2Normal = 0x40000ccc; +/* ppAssembleAMPDU = 0x40000cd0; */ +ppCalFrameTimes = 0x40000cd4; +ppCalSubFrameLength = 0x40000cd8; +//ppCalTxAMPDULength = 0x40000cdc; +ppCheckTxAMPDUlength = 0x40000ce0; +ppDequeueRxq_Locked = 0x40000ce4; +ppDequeueTxQ = 0x40000ce8; +ppEmptyDelimiterLength = 0x40000cec; +ppEnqueueRxq = 0x40000cf0; +ppEnqueueTxDone = 0x40000cf4; +ppGetTxframe = 0x40000cf8; +//ppMapTxQueue = 0x40000cfc; +//ppProcTxSecFrame = 0x40000d00; +ppProcessRxPktHdr = 0x40000d04; +//ppProcessTxQ = 0x40000d08; +ppRecordBarRRC = 0x40000d0c; +ppRecycleAmpdu = 0x40000d10; +ppRecycleRxPkt = 0x40000d14; +//ppResortTxAMPDU = 0x40000d18; +ppResumeTxAMPDU = 0x40000d1c; +/*ppRxFragmentProc = 0x40000d20;*/ +//ppRxPkt = 0x40000d24; +ppRxProtoProc = 0x40000d28; +ppSearchTxQueue = 0x40000d2c; +ppSearchTxframe = 0x40000d30; +ppSelectNextQueue = 0x40000d34; +ppSubFromAMPDU = 0x40000d38; +//ppTask = 0x40000d3c; +//ppTxPkt = 0x40000d40; +ppTxProtoProc = 0x40000d44; +ppTxqUpdateBitmap = 0x40000d48; +/*pp_coex_tx_request = 0x40000d4c;*/ +pp_hdrsize = 0x40000d50; +pp_post = 0x40000d54; +pp_process_hmac_waiting_txq = 0x40000d58; +rcGetAmpduSched = 0x40000d5c; +rcUpdateRxDone = 0x40000d60; +rc_get_trc = 0x40000d64; +rc_get_trc_by_index = 0x40000d68; +rcAmpduLowerRate = 0x40000d6c; +rcampduuprate = 0x40000d70; +rcClearCurAMPDUSched = 0x40000d74; +rcClearCurSched = 0x40000d78; +rcClearCurStat = 0x40000d7c; +/*rcGetSched = 0x40000d80;*/ +rcLowerSched = 0x40000d84; +rcSetTxAmpduLimit = 0x40000d88; +rcTxUpdatePer = 0x40000d8c; +rcUpdateAckSnr = 0x40000d90; +/*rcUpdateRate = 0x40000d94;*/ +rcUpdateTxDone = 0x40000d98; +rcUpdateTxDoneAmpdu2 = 0x40000d9c; +rcUpSched = 0x40000da0; +rssi_margin = 0x40000da4; +rx11NRate2AMPDULimit = 0x40000da8; +TRC_AMPDU_PER_DOWN_THRESHOLD = 0x40000dac; +TRC_AMPDU_PER_UP_THRESHOLD = 0x40000db0; +trc_calc_duration = 0x40000db4; +trc_isTxAmpduOperational = 0x40000db8; +trc_onAmpduOp = 0x40000dbc; +TRC_PER_IS_GOOD = 0x40000dc0; +trc_SetTxAmpduState = 0x40000dc4; +trc_tid_isTxAmpduOperational = 0x40000dc8; +trcAmpduSetState = 0x40000dcc; +//wDevCheckBlockError = 0x40000dd0; +wDev_AppendRxBlocks = 0x40000dd4; +wDev_DiscardFrame = 0x40000dd8; +wDev_GetNoiseFloor = 0x40000ddc; +wDev_IndicateAmpdu = 0x40000de0; +//wDev_IndicateFrame = 0x40000de4; +wdev_mac_reg_load = 0x40000de8; +wdev_mac_reg_store = 0x40000dec; +wdev_mac_special_reg_load = 0x40000df0; +wdev_mac_special_reg_store = 0x40000df4; +wdev_mac_wakeup = 0x40000df8; +wdev_mac_sleep = 0x40000dfc; +hal_mac_is_dma_enable = 0x40000e00; +//wDev_ProcessFiq = 0x40000e04; +//wDev_ProcessRxSucData = 0x40000e08; +//wdevProcessRxSucDataAll = 0x40000e0c; +wdev_csi_len_align = 0x40000e10; +ppDequeueTxDone_Locked = 0x40000e14; +//ppProcTxDone = 0x40000e18; +//pm_tx_data_done_process = 0x40000e1c; +config_is_cache_tx_buf_enabled = 0x40000e20; +//ppMapWaitTxq = 0x40000e24; +ppProcessWaitingQueue = 0x40000e28; +ppDisableQueue = 0x40000e2c; +pm_allow_tx = 0x40000e30; +//wdev_is_data_in_rxlist = 0x40000e34; +ppProcTxCallback = 0x40000e38; +//mac_tx_set_hesig = 0x40000e3c; +ppCalPreFecPaddingFactor = 0x40000e40; +mac_tx_set_tb = 0x40000e44; +mac_tx_set_mplen = 0x40000e48; +hal_get_tsf_timer = 0x40000e4c; +ppTxPktForceWaked = 0x40000e50; +lmacProcessLongFrameSuccess = 0x40000e54; +lmacProcessShortFrameSuccess = 0x40000e58; +//lmacDiscardFrameExchangeSequence = 0x40000e5c; +lmacProcessTBSuccess = 0x40000e60; +/*lmacProcessTxSuccess = 0x40000e64;*/ +lmacProcessAckTimeout = 0x40000e68; +//lmacProcessTxComplete = 0x40000e6c; +//ppRemoveHTC = 0x40000e70; +get_estimated_batime = 0x40000e74; +is_use_muedca = 0x40000e78; +hal_mac_tx_clr_mplen = 0x40000e7c; +hal_mac_get_txq_state = 0x40000e80; +hal_mac_clr_txq_state = 0x40000e84; +hal_mac_get_txq_complete = 0x40000e88; +ht_get_min_subframe_len = 0x40000e8c; +rx11ACRate2AMPDULimit = 0x40000e90; +pwr_hal_clear_intr_status = 0x40000e94; +pwr_hal_clear_mac_modem_beacon_miss_intr_filter = 0x40000e98; +pwr_hal_clear_mac_modem_rx_beacon_info = 0x40000e9c; +pwr_hal_clear_mac_modem_rx_beacon_miss_counter = 0x40000ea0; +pwr_hal_clear_mac_modem_rx_beacon_sleep_counter = 0x40000ea4; +pwr_hal_clear_mac_modem_state_wakeup_protect_signal = 0x40000ea8; +pwr_hal_get_intr_raw_signal = 0x40000eac; +pwr_hal_get_intr_status = 0x40000eb0; +pwr_hal_get_mac_modem_beacon_miss_limit_exceeded_status = 0x40000eb4; +pwr_hal_get_mac_modem_rx_beacon_location_state = 0x40000eb8; +pwr_hal_get_mac_modem_rx_beacon_valid_state = 0x40000ebc; +pwr_hal_get_mac_modem_state_sleep_limit_exceeded_status = 0x40000ec0; +pwr_hal_set_beacon_filter_abort_disable = 0x40000ec4; +pwr_hal_set_beacon_filter_abort_enable = 0x40000ec8; +pwr_hal_set_beacon_filter_abort_length = 0x40000ecc; +//pwr_hal_set_beacon_filter_broadcast_wakeup_disable = 0x40000ed0; +//pwr_hal_set_beacon_filter_broadcast_wakeup_enable = 0x40000ed4; +pwr_hal_set_beacon_filter_disable = 0x40000ed8; +pwr_hal_set_beacon_filter_enable = 0x40000edc; +pwr_hal_set_beacon_filter_force_dump_disable = 0x40000ee0; +pwr_hal_set_beacon_filter_force_dump_enable = 0x40000ee4; +pwr_hal_set_beacon_filter_force_dump_limit = 0x40000ee8; +pwr_hal_set_beacon_filter_force_sync_disable = 0x40000eec; +pwr_hal_set_beacon_filter_force_sync_enable = 0x40000ef0; +pwr_hal_set_beacon_filter_force_sync_limit = 0x40000ef4; +pwr_hal_set_beacon_filter_frame_crc_state = 0x40000ef8; +pwr_hal_set_beacon_filter_soc_wakeup_and_intr_disable = 0x40000efc; +pwr_hal_set_beacon_filter_soc_wakeup_and_intr_enable = 0x40000f00; +pwr_hal_set_beacon_filter_unicast_wakeup_disable = 0x40000f04; +pwr_hal_set_beacon_filter_unicast_wakeup_enable = 0x40000f08; +pwr_hal_set_lpclk_cycle_time = 0x40000f0c; +pwr_hal_set_lpclk_sync_disable = 0x40000f10; +pwr_hal_set_lpclk_sync_enable = 0x40000f14; +pwr_hal_set_mac_modem_beacon_miss_intr_disable = 0x40000f18; +pwr_hal_set_mac_modem_beacon_miss_intr_enable = 0x40000f1c; +pwr_hal_set_mac_modem_beacon_miss_limit = 0x40000f20; +pwr_hal_set_mac_modem_beacon_miss_limit_exceeded_wakeup_disable = 0x40000f24; +pwr_hal_set_mac_modem_beacon_miss_limit_exceeded_wakeup_enable = 0x40000f28; +pwr_hal_set_mac_modem_beacon_miss_timeout = 0x40000f2c; +pwr_hal_set_mac_modem_state_sleep_limit = 0x40000f30; +pwr_hal_set_mac_modem_state_sleep_limit_exceeded_wakeup_disable = 0x40000f34; +pwr_hal_set_mac_modem_state_sleep_limit_exceeded_wakeup_enable = 0x40000f38; +pwr_hal_set_mac_modem_state_wakeup_protect_disable = 0x40000f3c; +pwr_hal_set_mac_modem_state_wakeup_protect_early_time = 0x40000f40; +pwr_hal_set_mac_modem_state_wakeup_protect_enable = 0x40000f44; +pwr_hal_set_mac_modem_tbtt_auto_period_disable = 0x40000f48; +pwr_hal_set_mac_modem_tbtt_auto_period_enable = 0x40000f4c; +pwr_hal_set_mac_modem_tbtt_auto_period_interval = 0x40000f50; +pwr_hal_set_modem_state_interface = 0x40000f54; +hal_tsf_clear_soc_wakeup_request = 0x40000f58; +tsf_hal_clear_mac_modem_rf_power_state = 0x40000f5c; +tsf_hal_clear_soc_wakeup_request = 0x40000f60; +tsf_hal_get_counter_value = 0x40000f64; +tsf_hal_get_mac_modem_rf_power_state = 0x40000f68; +tsf_hal_get_tbtt_interval = 0x40000f6c; +tsf_hal_get_time = 0x40000f70; +tsf_hal_get_timer_target = 0x40000f74; +tsf_hal_is_tsf_enabled = 0x40000f78; +tsf_hal_map_tbtt_target_to_rx_frame = 0x40000f7c; +tsf_hal_map_tsf_to_bssid = 0x40000f80; +tsf_hal_set_counter_value = 0x40000f84; +tsf_hal_set_modem_wakeup_early_time = 0x40000f88; +tsf_hal_set_rx_beacon_abort_tsf_time_deviation_sync_disable = 0x40000f8c; +tsf_hal_set_rx_beacon_abort_tsf_time_deviation_sync_enable = 0x40000f90; +tsf_hal_set_rx_beacon_fail_tsf_time_deviation_sync_disable = 0x40000f94; +tsf_hal_set_rx_beacon_fail_tsf_time_deviation_sync_enable = 0x40000f98; +tsf_hal_set_rx_beacon_success_tsf_time_deviation_sync_disable = 0x40000f9c; +tsf_hal_set_rx_beacon_success_tsf_time_deviation_sync_enable = 0x40000fa0; +tsf_hal_set_tbtt_disable = 0x40000fa4; +tsf_hal_set_tbtt_early_time = 0x40000fa8; +tsf_hal_set_tbtt_enable = 0x40000fac; +tsf_hal_set_tbtt_interval = 0x40000fb0; +tsf_hal_set_tbtt_intr_disable = 0x40000fb4; +tsf_hal_set_tbtt_intr_enable = 0x40000fb8; +tsf_hal_set_tbtt_modem_wakeup_disable = 0x40000fbc; +tsf_hal_set_tbtt_modem_wakeup_enable = 0x40000fc0; +tsf_hal_set_tbtt_rf_ctrl_disable = 0x40000fc4; +tsf_hal_set_tbtt_rf_ctrl_enable = 0x40000fc8; +tsf_hal_set_tbtt_rf_ctrl_wait_cycles = 0x40000fcc; +tsf_hal_set_tbtt_soc_wakeup_disable = 0x40000fd0; +tsf_hal_set_tbtt_soc_wakeup_enable = 0x40000fd4; +tsf_hal_set_tbtt_start_time = 0x40000fd8; +tsf_hal_set_time = 0x40000fdc; +tsf_hal_set_timer_disable = 0x40000fe0; +tsf_hal_set_timer_enable = 0x40000fe4; +tsf_hal_set_timer_intr_disable = 0x40000fe8; +tsf_hal_set_timer_intr_enable = 0x40000fec; +tsf_hal_set_timer_modem_wakeup_disable = 0x40000ff0; +tsf_hal_set_timer_modem_wakeup_enable = 0x40000ff4; +tsf_hal_set_timer_rf_ctrl_disable = 0x40000ff8; +tsf_hal_set_timer_rf_ctrl_enable = 0x40000ffc; +tsf_hal_set_timer_rf_ctrl_wait_cycles = 0x40001000; +tsf_hal_set_timer_soc_wakeup_disable = 0x40001004; +tsf_hal_set_timer_soc_wakeup_enable = 0x40001008; +tsf_hal_set_timer_target = 0x4000100c; +tsf_hal_set_tsf_disable = 0x40001010; +tsf_hal_set_tsf_enable = 0x40001014; +tsf_hal_set_tsf_time_deviation = 0x40001018; +tsf_hal_set_tsf_time_deviation_sync_disable = 0x4000101c; +tsf_hal_set_tsf_time_deviation_sync_enable = 0x40001020; +tsf_hal_unmap_tbtt_target_to_rx_frame = 0x40001024; +//ppSelectTxFormat = 0x40001028; +//ppCertSetRate = 0x4000102c; +//ppHEAMPDU2Normal = 0x40001030; +//ppCalTxHEAMPDULength = 0x40001034; +//ppCalTxHESMPDULength = 0x40001038; +rcGetRate = 0x4000103c; +rcGetDCMMaxRate = 0x40001040; +//rcGetSMPDURate = 0x40001044; +ppDirectRecycleAmpdu = 0x40001048; +//ppCheckTxHEAMPDUlength = 0x4000104c; +//rx11AXRate2AMPDULimit = 0x40001050; +//ppRegressAmpdu = 0x40001054; +//ppCalDeliNum = 0x40001058; +ppAdd2AMPDUTail = 0x4000105c; +esp_test_disable_tx_statistics = 0x40001060; +esp_test_enable_tx_statistics = 0x40001064; +esp_test_clr_tx_statistics = 0x40001068; +esp_test_get_tx_statistics = 0x4000106c; +esp_test_clr_tx_tb_statistics = 0x40001070; +esp_test_get_tx_tb_statistics = 0x40001074; +test_tx_fail_statistics = 0x40001078; +//test_tx_succ_statistics = 0x4000107c; +//esp_test_tx_process_complete = 0x40001080; +//esp_test_tx_process_txq_state = 0x40001084; +esp_test_tx_enab_statistics = 0x40001088; +esp_test_tx_tb_complete = 0x4000108c; +esp_test_tx_count_retry = 0x40001090; +esp_test_tx_count_collision = 0x40001094; +esp_test_tx_count_timeout = 0x40001098; +hal_enable_tx_statistics = 0x4000109c; +test_rx_process_complete_noeb = 0x400010a0; +test_rx_process_complete_retry = 0x400010a4; +esp_test_rx_process_complete = 0x400010a8; +esp_test_clr_rx_statistics = 0x400010ac; +esp_test_get_rx_statistics = 0x400010b0; +test_free_rx_statistics = 0x400010b4; +esp_test_set_rx_error_occurs = 0x400010b8; +esp_test_get_rx_error_occurs = 0x400010bc; +esp_test_clr_rx_error_occurs = 0x400010c0; +esp_test_disable_rx_statistics = 0x400010c4; +esp_test_enable_rx_statistics = 0x400010c8; +hal_enable_rx_statistics = 0x400010cc; +get_user_num = 0x400010d0; +mumimo_spatial_cfg_get_nsts = 0x400010d4; +mumimo_spatial_cfg_get_nsts_tot = 0x400010d8; +test_mumimo_get_heltf_num = 0x400010dc; +test_mimo_update_user_info = 0x400010e0; +test_parse_rx_mu_mimo = 0x400010e4; +test_nonmimo_update_user_info = 0x400010e8; +test_parse_rx_mu_nonmimo = 0x400010ec; +esp_test_rx_parse_mu = 0x400010f0; +esp_test_get_rx_mu_statistics = 0x400010f4; +esp_test_clr_rx_mu_statistics = 0x400010f8; +esp_test_enable_rx_mu_statistics = 0x400010fc; +esp_test_disable_rx_mu_statistics = 0x40001100; +/* Data (.data, .bss, .rodata) */ +our_instances_ptr = 0x4004ffe0; +pTxRx = 0x4087ff80; +lmacConfMib_ptr = 0x4087ff7c; +our_wait_eb = 0x4087ff78; +our_tx_eb = 0x4087ff74; +pp_wdev_funcs = 0x4087ff70; +g_osi_funcs_p = 0x4087ff6c; +wDevCtrl_ptr = 0x4087ff68; +g_wdev_last_desc_reset_ptr = 0x4004ffdc; +wDevMacSleep_ptr = 0x4087ff64; +g_lmac_cnt_ptr = 0x4087ff60; +our_controls_ptr = 0x4004ffd8; +pp_sig_cnt_ptr = 0x4087ff5c; +g_eb_list_desc_ptr = 0x4087ff58; +s_fragment_ptr = 0x4087ff54; +if_ctrl_ptr = 0x4087ff50; +g_intr_lock_mux = 0x4087ff4c; +g_wifi_global_lock = 0x4087ff48; +s_wifi_queue = 0x4087ff44; +pp_task_hdl = 0x4087ff40; +s_pp_task_create_sem = 0x4087ff3c; +s_pp_task_del_sem = 0x4087ff38; +g_wifi_menuconfig_ptr = 0x4087ff34; +xphyQueue = 0x4087ff30; +ap_no_lr_ptr = 0x4087ff2c; +rc11BSchedTbl_ptr = 0x4087ff28; +rc11NSchedTbl_ptr = 0x4087ff24; +rcLoRaSchedTbl_ptr = 0x4087ff20; +BasicOFDMSched_ptr = 0x4087ff1c; +trc_ctl_ptr = 0x4087ff18; +g_pm_cnt_ptr = 0x4087ff14; +g_pm_ptr = 0x4087ff10; +g_pm_cfg_ptr = 0x4087ff0c; +g_esp_mesh_quick_funcs_ptr = 0x4087ff08; +g_txop_queue_status_ptr = 0x4087ff04; +g_mac_sleep_en_ptr = 0x4087ff00; +g_mesh_is_root_ptr = 0x4087fefc; +g_mesh_topology_ptr = 0x4087fef8; +g_mesh_init_ps_type_ptr = 0x4087fef4; +g_mesh_is_started_ptr = 0x4087fef0; +g_config_func = 0x4087feec; +g_net80211_tx_func = 0x4087fee8; +g_timer_func = 0x4087fee4; +s_michael_mic_failure_cb = 0x4087fee0; +wifi_sta_rx_probe_req = 0x4087fedc; +g_tx_done_cb_func = 0x4087fed8; +g_per_conn_trc = 0x4087fe8c; +s_encap_amsdu_func = 0x4087fe88; +rx_beacon_count = 0x4087fe84; +rx_beacon_sw_parse = 0x4087fe80; +rx_beacon_hw_parse = 0x4087fe7c; +rx_beacon_tim_count = 0x4087fe78; +rx_beacon_tim_udata = 0x4087fe74; +rx_beacon_tim_udata_bitmap = 0x4087fe70; +rx_beacon_tim_bdata = 0x4087fe6c; +rx_beacon_tim_bdata_bitmapctl = 0x4087fe68; +rx_beacon_tim_bdata_bitmap_trans = 0x4087fe64; +rx_beacon_tim_bdata_bitmap_mbssid_self = 0x4087fe60; +rx_beacon_tim_bdata_bitmap_mbssid_other = 0x4087fe5c; +rx_beacon_dtim_tim = 0x4087fe58; +rx_beacon_dtim_tim_mcast = 0x4087fe54; +amdpu_delay_time_ms = 0x4087fd08; +ampdu_delay_packet = 0x4087fd04; +ampdu_delay = 0x4087fe51; +first_ampdu = 0x4087fe50; +s_ht_ampdu_density_us = 0x4087fd02; +s_ht_ampdu_density = 0x4087fd01; +s_running_phy_type = 0x4087fd00; +complete_ena_tb_seqno = 0x4087fe4c; +complete_ena_tb_final = 0x4087fe48; +complete_ena_tb_count = 0x4087fe44; +s_itwt_state = 0x4087fe40; +g_dbg_interp_tsf = 0x4087fe3c; +g_dbg_interp_tsf_end = 0x4087fe38; +g_dbg_closrf_tsf = 0x4087fe34; +g_dbg_closrf_idx = 0x4087fe30; +g_dbg_closrf_blk = 0x4087fe2c; +s_he_min_len_bytes = 0x4087fdf0; +s_he_dcm_min_len_bytes = 0x4087fdd0; +s_mplen_low_bitmap = 0x4087fdc0; +s_mplen_high_bitmap = 0x4087fdb0; +s_mplen_vi_bitmap = 0x4087fdac; +s_mplen_bk_bitmap = 0x4087fda8; +esp_wifi_cert_tx_mcs = 0x4087fcfc; +esp_wifi_cert_tx_bcc = 0x4087fcf8; +//esp_wifi_cert_tx_ltf = 0x4087fcf4; +//esp_wifi_cert_tx_gi = 0x4087fcf0; +esp_wifi_cert_tx_nss = 0x4087fcec; +esp_test_tx_statistics_aci_bitmap = 0x4087fda4; +esp_test_tx_statistics = 0x4087fd94; +esp_test_tx_tb_statistics = 0x4087fd84; +esp_test_tx_fail_statistics = 0x4087fd24; +esp_test_rx_statistics = 0x4087fd1c; +esp_test_rx_mu_statistics = 0x4087fd18; +esp_test_mu_print_ru_allocation = 0x4087fd14; +sigb_ru_allocation_user_num = 0x4004ffc8; +sigb_common_ru_allocation = 0x4004ff38; +mu_mimo_special_cfg_user_num_2 = 0x4004fee8; +mu_mimo_special_cfg_user_num_3 = 0x4004fe80; +mu_mimo_special_cfg_user_num_4 = 0x4004fe28; +mu_mimo_special_cfg_user_num_5 = 0x4004fdf0; +mu_mimo_special_cfg_user_num_6 = 0x4004fdd0; +mu_mimo_special_cfg_user_num_7 = 0x4004fdc0; +mu_mimo_special_cfg_user_num_8 = 0x4004fdb8; +esp_test_rx_error_occurs = 0x4087fd10; +g_pp_tx_pkt_num = 0x4087fd0c; +he_max_apep_length = 0x4004fd40; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.rvfp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.rvfp.ld new file mode 100644 index 000000000000..26a82ad1c71c --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.rvfp.ld @@ -0,0 +1,118 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.rvfp.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rvfplib + ***************************************/ + +/* Functions */ +__adddf3 = 0x400009f4; +__addsf3 = 0x400009f8; +__eqdf2 = 0x400009fc; +__eqsf2 = 0x40000a00; +__extendsfdf2 = 0x40000a04; +__fixdfdi = 0x40000a08; +__fixdfsi = 0x40000a0c; +__fixsfdi = 0x40000a10; +__fixsfsi = 0x40000a14; +__fixunsdfsi = 0x40000a18; +__fixunssfdi = 0x40000a1c; +__fixunssfsi = 0x40000a20; +__floatdidf = 0x40000a24; +__floatdisf = 0x40000a28; +__floatsidf = 0x40000a2c; +__floatsisf = 0x40000a30; +__floatundidf = 0x40000a34; +__floatundisf = 0x40000a38; +__floatunsidf = 0x40000a3c; +__floatunsisf = 0x40000a40; +__gedf2 = 0x40000a44; +__gesf2 = 0x40000a48; +__gtdf2 = 0x40000a4c; +__gtsf2 = 0x40000a50; +__ledf2 = 0x40000a54; +__lesf2 = 0x40000a58; +__ltdf2 = 0x40000a5c; +__ltsf2 = 0x40000a60; +__muldf3 = 0x40000a64; +__mulsf3 = 0x40000a68; +__nedf2 = 0x40000a6c; +__nesf2 = 0x40000a70; +__subdf3 = 0x40000a74; +__subsf3 = 0x40000a78; +__truncdfsf2 = 0x40000a7c; + +/*************************************** + Group libgcc +***************************************/ + +/* Functions */ +__absvdi2 = 0x40000884; +__absvsi2 = 0x40000888; +__addvdi3 = 0x40000894; +__addvsi3 = 0x40000898; +__ashldi3 = 0x4000089c; +__ashrdi3 = 0x400008a0; +__bswapdi2 = 0x400008a4; +__bswapsi2 = 0x400008a8; +__clear_cache = 0x400008ac; +__clrsbdi2 = 0x400008b0; +__clrsbsi2 = 0x400008b4; +__clzdi2 = 0x400008b8; +__clzsi2 = 0x400008bc; +__cmpdi2 = 0x400008c0; +__ctzdi2 = 0x400008c4; +__ctzsi2 = 0x400008c8; +__divdc3 = 0x400008cc; +__divdf3 = 0x400008d0; +__divdi3 = 0x400008d4; +__divsc3 = 0x400008d8; +__divsf3 = 0x400008dc; +__divsi3 = 0x400008e0; +__ffsdi2 = 0x400008f0; +__ffssi2 = 0x400008f4; +__gcc_bcmp = 0x40000934; +__lshrdi3 = 0x40000950; +__moddi3 = 0x4000095c; +__modsi3 = 0x40000960; +__muldc3 = 0x40000964; +__muldi3 = 0x4000096c; +__mulsc3 = 0x40000970; +__mulsi3 = 0x40000978; +__mulvdi3 = 0x4000097c; +__mulvsi3 = 0x40000980; +__negdf2 = 0x40000988; +__negdi2 = 0x4000098c; +__negsf2 = 0x40000990; +__negvdi2 = 0x40000994; +__negvsi2 = 0x40000998; +__paritysi2 = 0x400009a0; +__popcountdi2 = 0x400009a4; +__popcountsi2 = 0x400009a8; +__powidf2 = 0x400009ac; +__powisf2 = 0x400009b0; +__subvdi3 = 0x400009bc; +__subvsi3 = 0x400009c0; +__ucmpdi2 = 0x400009c8; +__udivdi3 = 0x400009cc; +__udivmoddi4 = 0x400009d0; +__udivsi3 = 0x400009d4; +__udiv_w_sdiv = 0x400009d8; +__umoddi3 = 0x400009dc; +__umodsi3 = 0x400009e0; +__unorddf2 = 0x400009e4; +__unordsf2 = 0x400009e8; +__extenddftf2 = 0x400009ec; +__trunctfdf2 = 0x400009f0; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld new file mode 100644 index 000000000000..1ff2f5846583 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM function interface esp32c6.rom.spiflash.ld for esp32c6 + * + * + * Generated from ./target/esp32c6/interface-esp32c6.yml md5sum 06c13e133e0743d09b87aba30d3e213b + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group spi_flash_cache + ***************************************/ + +/* Functions */ +spi_flash_disable_cache = 0x400001f0; +spi_flash_restore_cache = 0x400001f4; +spi_flash_cache_enabled = 0x400001f8; +esp_enable_cache_flash_wrap = 0x40000200; + + +/*************************************** + Group spi_flash_mmap + ***************************************/ + +/* Functions */ +spi_flash_mmap_os_func_set = 0x40000204; +spi_flash_mmap_page_num_init = 0x40000208; +spi_flash_mmap = 0x4000020c; +spi_flash_mmap_pages = 0x40000210; +spi_flash_munmap = 0x40000214; +spi_flash_mmap_dump = 0x40000218; +spi_flash_check_and_flush_cache = 0x4000021c; +spi_flash_mmap_get_free_pages = 0x40000220; +spi_flash_cache2phys = 0x40000224; +spi_flash_phys2cache = 0x40000228; + + +/*************************************** + Group esp_flash + ***************************************/ + +/* Functions */ +esp_flash_chip_driver_initialized = 0x4000022c; +esp_flash_read_id = 0x40000230; +esp_flash_get_size = 0x40000234; +esp_flash_erase_chip = 0x40000238; +esp_flash_erase_region = 0x4000023c; +esp_flash_get_chip_write_protect = 0x40000240; +esp_flash_set_chip_write_protect = 0x40000244; +esp_flash_get_protectable_regions = 0x40000248; +esp_flash_get_protected_region = 0x4000024c; +esp_flash_set_protected_region = 0x40000250; +esp_flash_read = 0x40000254; +esp_flash_write = 0x40000258; +esp_flash_write_encrypted = 0x4000025c; +esp_flash_read_encrypted = 0x40000260; +esp_flash_get_io_mode = 0x40000264; +esp_flash_set_io_mode = 0x40000268; +spi_flash_boot_attach = 0x4000026c; +esp_flash_read_chip_id = 0x40000270; +detect_spi_flash_chip = 0x40000274; +/* esp_rom_spiflash_write_disable = 0x40000278; */ +esp_flash_suspend_cmd_init = 0x4000027c; +/* Data (.data, .bss, .rodata) */ +esp_flash_default_chip = 0x4087ffe8; +esp_flash_api_funcs = 0x4087ffe4; + + +/*************************************** + Group spi_flash_chips + ***************************************/ + +/* Functions */ +spi_flash_chip_generic_probe = 0x40000280; +spi_flash_chip_generic_detect_size = 0x40000284; +spi_flash_chip_generic_write = 0x40000288; +spi_flash_chip_generic_write_encrypted = 0x4000028c; +spi_flash_chip_generic_set_write_protect = 0x40000290; +spi_flash_common_write_status_16b_wrsr = 0x40000294; +spi_flash_chip_generic_reset = 0x40000298; +spi_flash_chip_generic_erase_chip = 0x4000029c; +spi_flash_chip_generic_erase_sector = 0x400002a0; +spi_flash_chip_generic_erase_block = 0x400002a4; +spi_flash_chip_generic_page_program = 0x400002a8; +spi_flash_chip_generic_get_write_protect = 0x400002ac; +spi_flash_common_read_status_16b_rdsr_rdsr2 = 0x400002b0; +spi_flash_chip_generic_read_reg = 0x400002b4; +spi_flash_chip_generic_yield = 0x400002b8; +spi_flash_generic_wait_host_idle = 0x400002bc; +spi_flash_chip_generic_wait_idle = 0x400002c0; +spi_flash_chip_generic_config_host_io_mode = 0x400002c4; +spi_flash_chip_generic_read = 0x400002c8; +spi_flash_common_read_status_8b_rdsr2 = 0x400002cc; +spi_flash_chip_generic_get_io_mode = 0x400002d0; +spi_flash_common_read_status_8b_rdsr = 0x400002d4; +spi_flash_common_write_status_8b_wrsr = 0x400002d8; +spi_flash_common_write_status_8b_wrsr2 = 0x400002dc; +spi_flash_common_set_io_mode = 0x400002e0; +spi_flash_chip_generic_set_io_mode = 0x400002e4; +spi_flash_chip_generic_read_unique_id = 0x400002e8; +spi_flash_chip_generic_get_caps = 0x400002ec; +spi_flash_chip_generic_suspend_cmd_conf = 0x400002f0; +spi_flash_chip_gd_get_io_mode = 0x400002f4; +spi_flash_chip_gd_probe = 0x400002f8; +spi_flash_chip_gd_set_io_mode = 0x400002fc; +/* Data (.data, .bss, .rodata) */ +spi_flash_chip_generic_config_data = 0x4087ffe0; +spi_flash_encryption = 0x4087ffdc; + + +/*************************************** + Group memspi_host + ***************************************/ + +/* Functions */ +memspi_host_read_id_hs = 0x40000300; +memspi_host_read_status_hs = 0x40000304; +memspi_host_flush_cache = 0x40000308; +memspi_host_erase_chip = 0x4000030c; +memspi_host_erase_sector = 0x40000310; +memspi_host_erase_block = 0x40000314; +memspi_host_program_page = 0x40000318; +memspi_host_read = 0x4000031c; +memspi_host_set_write_protect = 0x40000320; +memspi_host_set_max_read_len = 0x40000324; +memspi_host_read_data_slicer = 0x40000328; +memspi_host_write_data_slicer = 0x4000032c; + + +/*************************************** + Group hal_spiflash + ***************************************/ + +/* Functions */ +spi_flash_hal_poll_cmd_done = 0x40000330; +spi_flash_hal_device_config = 0x40000334; +spi_flash_hal_configure_host_io_mode = 0x40000338; +spi_flash_hal_common_command = 0x4000033c; +spi_flash_hal_read = 0x40000340; +spi_flash_hal_erase_chip = 0x40000344; +spi_flash_hal_erase_sector = 0x40000348; +spi_flash_hal_erase_block = 0x4000034c; +spi_flash_hal_program_page = 0x40000350; +spi_flash_hal_set_write_protect = 0x40000354; +spi_flash_hal_host_idle = 0x40000358; +spi_flash_hal_check_status = 0x4000035c; +spi_flash_hal_setup_read_suspend = 0x40000360; +spi_flash_hal_setup_auto_suspend_mode = 0x40000364; +spi_flash_hal_setup_auto_resume_mode = 0x40000368; +spi_flash_hal_disable_auto_suspend_mode = 0x4000036c; +spi_flash_hal_disable_auto_resume_mode = 0x40000370; +spi_flash_hal_resume = 0x40000374; +spi_flash_hal_suspend = 0x40000378; +spi_flash_encryption_hal_enable = 0x4000037c; +spi_flash_encryption_hal_disable = 0x40000380; +spi_flash_encryption_hal_prepare = 0x40000384; +spi_flash_encryption_hal_done = 0x40000388; +spi_flash_encryption_hal_destroy = 0x4000038c; +spi_flash_encryption_hal_check = 0x40000390; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.version.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.version.ld new file mode 100644 index 000000000000..ad4d15d00fb9 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.version.ld @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ROM version variables for esp32c6 + * + * These addresses should be compatible with any ROM version for this chip. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +_rom_chip_id = 0x40000010; +_rom_eco_version = 0x40000014; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.wdt.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.wdt.ld new file mode 100644 index 000000000000..ada8eb7fc896 --- /dev/null +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.wdt.ld @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/*************************************** + Group hal_wdt + ***************************************/ + +/* Functions */ + +/* Patch init function to set clock source +wdt_hal_init = 0x40000394; +wdt_hal_deinit = 0x40000398; +*/ + +wdt_hal_config_stage = 0x4000039c; +wdt_hal_write_protect_disable = 0x400003a0; +wdt_hal_write_protect_enable = 0x400003a4; +wdt_hal_enable = 0x400003a8; +wdt_hal_disable = 0x400003ac; +wdt_hal_handle_intr = 0x400003b0; +wdt_hal_feed = 0x400003b4; +wdt_hal_set_flashboot_en = 0x400003b8; +wdt_hal_is_enabled = 0x400003bc; diff --git a/components/esp_rom/include/esp32c6/rom/aes.h b/components/esp_rom/include/esp32c6/rom/aes.h new file mode 100644 index 000000000000..0af206663742 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/aes.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_AES_H_ +#define _ROM_AES_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AES_BLOCK_SIZE 16 + +enum AES_TYPE { + AES_ENC, + AES_DEC, +}; + +enum AES_BITS { + AES128, + AES192, + AES256 +}; + +void ets_aes_enable(void); + +void ets_aes_disable(void); + +int ets_aes_setkey(enum AES_TYPE type, const void *key, enum AES_BITS bits); + +int ets_aes_setkey_enc(const void *key, enum AES_BITS bits); + +int ets_aes_setkey_dec(const void *key, enum AES_BITS bits); + +void ets_aes_block(const void *input, void *output); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_AES_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/bigint.h b/components/esp_rom/include/esp32c6/rom/bigint.h new file mode 100644 index 000000000000..ef82674b330a --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/bigint.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_BIGINT_H_ +#define _ROM_BIGINT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ets_bigint_enable(void); + +void ets_bigint_disable(void); + +int ets_bigint_multiply(const uint32_t *x, const uint32_t *y, uint32_t len_words); + +int ets_bigint_modmult(const uint32_t *x, const uint32_t *y, const uint32_t *m, uint32_t m_dash, const uint32_t *rb, uint32_t len_words); + +int ets_bigint_modexp(const uint32_t *x, const uint32_t *y, const uint32_t *m, uint32_t m_dash, const uint32_t *rb, bool constant_time, uint32_t len_words); + +void ets_bigint_wait_finish(void); + +int ets_bigint_getz(uint32_t *z, uint32_t len_words); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_BIGINT_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/cache.h b/components/esp_rom/include/esp32c6/rom/cache.h new file mode 100644 index 000000000000..15663f2ed1e5 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/cache.h @@ -0,0 +1,609 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup cache_apis, cache operation related apis + * @brief cache apis + */ + +/** @addtogroup cache_apis + * @{ + */ +#define MIN_ICACHE_SIZE 16384 +#define MAX_ICACHE_SIZE 16384 +#define MIN_ICACHE_WAYS 8 +#define MAX_ICACHE_WAYS 8 +#define MAX_CACHE_WAYS 8 +#define MIN_CACHE_LINE_SIZE 32 +#define TAG_SIZE 4 +#define MIN_ICACHE_BANK_NUM 1 +#define MAX_ICACHE_BANK_NUM 1 +#define CACHE_MEMORY_BANK_NUM 1 +#define CACHE_MEMORY_IBANK_SIZE 0x4000 + +#define MAX_ITAG_BANK_ITEMS (MAX_ICACHE_SIZE / MAX_ICACHE_BANK_NUM / MIN_CACHE_LINE_SIZE) +#define MAX_ITAG_BLOCK_ITEMS (MAX_ICACHE_SIZE / MAX_ICACHE_BANK_NUM / MAX_ICACHE_WAYS / MIN_CACHE_LINE_SIZE) +#define MAX_ITAG_BANK_SIZE (MAX_ITAG_BANK_ITEMS * TAG_SIZE) +#define MAX_ITAG_BLOCK_SIZE (MAX_ITAG_BLOCK_ITEMS * TAG_SIZE) + +typedef enum { + CACHE_SIZE_HALF = 0, /*!< 8KB for icache and dcache */ + CACHE_SIZE_FULL = 1, /*!< 16KB for icache and dcache */ +} cache_size_t; + +typedef enum { + CACHE_4WAYS_ASSOC = 0, /*!< 4 way associated cache */ + CACHE_8WAYS_ASSOC = 1, /*!< 8 way associated cache */ +} cache_ways_t; + +typedef enum { + CACHE_LINE_SIZE_16B = 0, /*!< 16 Byte cache line size */ + CACHE_LINE_SIZE_32B = 1, /*!< 32 Byte cache line size */ + CACHE_LINE_SIZE_64B = 2, /*!< 64 Byte cache line size */ +} cache_line_size_t; + +typedef enum { + CACHE_AUTOLOAD_POSITIVE = 0, /*!< cache autoload step is positive */ + CACHE_AUTOLOAD_NEGATIVE = 1, /*!< cache autoload step is negative */ +} cache_autoload_order_t; + +#define CACHE_AUTOLOAD_STEP(i) ((i) - 1) + +typedef enum { + CACHE_AUTOLOAD_MISS_TRIGGER = 0, /*!< autoload only triggered by cache miss */ + CACHE_AUTOLOAD_HIT_TRIGGER = 1, /*!< autoload only triggered by cache hit */ + CACHE_AUTOLOAD_BOTH_TRIGGER = 2, /*!< autoload triggered both by cache miss and hit */ +} cache_autoload_trigger_t; + +typedef enum { + CACHE_FREEZE_ACK_BUSY = 0, /*!< in this mode, cache ack busy to CPU if a cache miss happens*/ + CACHE_FREEZE_ACK_ERROR = 1, /*!< in this mode, cache ack wrong data to CPU and trigger an error if a cache miss happens */ +} cache_freeze_mode_t; + +typedef enum { + MMU_PAGE_MODE_64KB = 0, + MMU_PAGE_MODE_32KB = 1, + MMU_PAGE_MODE_16KB = 2, + MMU_PAGE_MODE_8KB = 3, + MMU_PAGE_MODE_INVALID, +} mmu_page_mode_t; + +struct cache_mode { + uint32_t cache_size; /*!< cache size in byte */ + uint16_t cache_line_size; /*!< cache line size in byte */ + uint8_t cache_ways; /*!< cache ways, always 4 */ + uint8_t ibus; /*!< the cache index, 0 for dcache, 1 for icache */ +}; + +struct icache_tag_item { + uint32_t valid:1; /*!< the tag item is valid or not */ + uint32_t lock:1; /*!< the cache line is locked or not */ + uint32_t fifo_cnt:3; /*!< fifo cnt, 0 ~ 3 for 4 ways cache */ + uint32_t tag:13; /*!< the tag is the high part of the cache address, however is only 16MB (8MB Ibus + 8MB Dbus) range, and without low part */ + uint32_t reserved:14; +}; + +struct autoload_config { + uint8_t order; /*!< autoload step is positive or negative */ + uint8_t trigger; /*!< autoload trigger */ + uint8_t ena0; /*!< autoload region0 enable */ + uint8_t ena1; /*!< autoload region1 enable */ + uint32_t addr0; /*!< autoload region0 start address */ + uint32_t size0; /*!< autoload region0 size */ + uint32_t addr1; /*!< autoload region1 start address */ + uint32_t size1; /*!< autoload region1 size */ +}; + +struct tag_group_info { + struct cache_mode mode; /*!< cache and cache mode */ + uint32_t filter_addr; /*!< the address that used to generate the struct */ + uint32_t vaddr_offset; /*!< virtual address offset of the cache ways */ + uint32_t tag_addr[MAX_CACHE_WAYS]; /*!< tag memory address, only [0~mode.ways-1] is valid to use */ + uint32_t cache_memory_offset[MAX_CACHE_WAYS]; /*!< cache memory address, only [0~mode.ways-1] is valid to use */ +}; + +struct lock_config { + uint32_t addr; /*!< manual lock address*/ + uint16_t size; /*!< manual lock size*/ + uint16_t group; /*!< manual lock group, 0 or 1*/ +}; + +struct cache_internal_stub_table { + uint32_t (* icache_line_size)(void); + uint32_t (* icache_addr)(uint32_t addr); + uint32_t (* dcache_addr)(uint32_t addr); + void (* invalidate_icache_items)(uint32_t addr, uint32_t items); + void (* lock_icache_items)(uint32_t addr, uint32_t items); + void (* unlock_icache_items)(uint32_t addr, uint32_t items); + uint32_t (* suspend_icache_autoload)(void); + void (* resume_icache_autoload)(uint32_t autoload); + void (* freeze_icache_enable)(cache_freeze_mode_t mode); + void (* freeze_icache_disable)(void); + int (* op_addr)(uint32_t start_addr, uint32_t size, uint32_t cache_line_size, uint32_t max_sync_num, void(* cache_Iop)(uint32_t, uint32_t)); +}; + +/* Defined in the interface file, default value is rom_default_cache_internal_table */ +extern const struct cache_internal_stub_table* rom_cache_internal_table_ptr; + +typedef void (* cache_op_start)(void); +typedef void (* cache_op_end)(void); + +typedef struct { + cache_op_start start; + cache_op_end end; +} cache_op_cb_t; + +/* Defined in the interface file, default value is NULL */ +extern const cache_op_cb_t* rom_cache_op_cb; + +#define ESP_ROM_ERR_INVALID_ARG 1 +#define MMU_SET_ADDR_ALIGNED_ERROR 2 +#define MMU_SET_PASE_SIZE_ERROR 3 +#define MMU_SET_VADDR_OUT_RANGE 4 + +#define CACHE_OP_ICACHE_Y 1 +#define CACHE_OP_ICACHE_N 0 + +/** + * @brief Initialise cache mmu, mark all entries as invalid. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_MMU_Init(void); + +/** + * @brief Init Cache for ROM boot, including resetting the Icache, initializing MMU, Enabling ICache, unmasking bus. + * + * @param None + * + * @return None + */ +void ROM_Boot_Cache_Init(void); + +/** + * @brief Set ICache mmu mapping. + * Please do not call this function in your SDK application. + * + * @param uint32_t senitive : Config this page should apply flash encryption or not + * + * @param uint32_t ext_ram : DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_INVALID for invalid. In + * esp32c6, external memory is always flash + * + * @param uint32_t vaddr : virtual address in CPU address space. + * Can be Iram0,Iram1,Irom0,Drom0 and AHB buses address. + * Should be aligned by psize. + * + * @param uint32_t paddr : physical address in external memory. + * Should be aligned by psize. + * + * @param uint32_t psize : page size of ICache, in kilobytes. Should be 64 here. + * + * @param uint32_t num : pages to be set. + * + * @param uint32_t fixed : 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page. + * + * @return uint32_t: error status + * 0 : mmu set success + * 2 : vaddr or paddr is not aligned + * 3 : psize error + * 4 : vaddr is out of range + */ +int Cache_MSPI_MMU_Set(uint32_t sensitive, uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, uint32_t psize, uint32_t num, uint32_t fixed); + +/** + * @brief Set DCache mmu mapping. + * Please do not call this function in your SDK application. + * + * @param uint32_t ext_ram : DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_INVALID for invalid. In + * esp32c6, external memory is always flash + * + * @param uint32_t vaddr : virtual address in CPU address space. + * Can be DRam0, DRam1, DRom0, DPort and AHB buses address. + * Should be aligned by psize. + * + * @param uint32_t paddr : physical address in external memory. + * Should be aligned by psize. + * + * @param uint32_t psize : page size of DCache, in kilobytes. Should be 64 here. + * + * @param uint32_t num : pages to be set. + + * @param uint32_t fixed : 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page. + * + * @return uint32_t: error status + * 0 : mmu set success + * 2 : vaddr or paddr is not aligned + * 3 : psize error + * 4 : vaddr is out of range + */ +int Cache_Dbus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, uint32_t psize, uint32_t num, uint32_t fixed); + + +/** + * @brief Get cache mode of ICache or DCache. + * Please do not call this function in your SDK application. + * + * @param struct cache_mode * mode : the pointer of cache mode struct, caller should set the icache field + * + * return none + */ +void Cache_Get_Mode(struct cache_mode * mode); + +/** + * @brief Set cache page mode. + * + * @param mmu_page_mode_t + * + * @return None + */ +void MMU_Set_Page_Mode(mmu_page_mode_t pg_mode); + +/** + * @brief Get cache page mode. + * + * @param None + * + * @return page mode + */ +mmu_page_mode_t MMU_Get_Page_Mode(void); + +/** + * @brief Invalidate the cache items for ICache. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in ICache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr: start address to invalidate + * + * @param uint32_t items: cache lines to invalidate, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) + * + * @return None + */ +void Cache_Invalidate_ICache_Items(uint32_t addr, uint32_t items); + +/** + * @brief Invalidate the Cache items in the region from ICache or DCache. + * If the region is not in Cache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : invalidated region start address. + * + * @param uint32_t size : invalidated region size. + * + * @return 0 for success + * 1 for invalid argument + */ +int Cache_Invalidate_Addr(uint32_t addr, uint32_t size); + +/** + * @brief Invalidate all cache items in ICache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Invalidate_ICache_All(void); + +/** + * @brief Mask all buses through ICache and DCache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Mask_All(void); + +/** + * @brief Suspend ICache auto preload operation, then you can resume it after some ICache operations. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return uint32_t : 0 for ICache not auto preload before suspend. + */ +uint32_t Cache_Suspend_ICache_Autoload(void); + +/** + * @brief Resume ICache auto preload operation after some ICache operations. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : 0 for ICache not auto preload before suspend. + * + * @return None. + */ +void Cache_Resume_ICache_Autoload(uint32_t autoload); + +/** + * @brief Start an ICache manual preload, will suspend auto preload of ICache. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : start address of the preload region. + * + * @param uint32_t size : size of the preload region, should not exceed the size of ICache. + * + * @param uint32_t order : the preload order, 0 for positive, other for negative + * + * @return uint32_t : 0 for ICache not auto preload before manual preload. + */ +uint32_t Cache_Start_ICache_Preload(uint32_t addr, uint32_t size, uint32_t order); + +/** + * @brief Return if the ICache manual preload done. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return uint32_t : 0 for ICache manual preload not done. + */ +uint32_t Cache_ICache_Preload_Done(void); + +/** + * @brief End the ICache manual preload to resume auto preload of ICache. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : 0 for ICache not auto preload before manual preload. + * + * @return None + */ +void Cache_End_ICache_Preload(uint32_t autoload); + +/** + * @brief Config autoload parameters of ICache. + * Please do not call this function in your SDK application. + * + * @param struct autoload_config * config : autoload parameters. + * + * @return None + */ +void Cache_Config_ICache_Autoload(const struct autoload_config * config); + +/** + * @brief Enable auto preload for ICache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Enable_ICache_Autoload(void); + +/** + * @brief Disable auto preload for ICache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Disable_ICache_Autoload(void); + +/** + * @brief Config a group of prelock parameters of ICache. + * Please do not call this function in your SDK application. + * + * @param struct lock_config * config : a group of lock parameters. + * + * @return None + */ + +void Cache_Enable_ICache_PreLock(const struct lock_config *config); + +/** + * @brief Disable a group of prelock parameters for ICache. + * However, the locked data will not be released. + * Please do not call this function in your SDK application. + * + * @param uint16_t group : 0 for group0, 1 for group1. + * + * @return None + */ +void Cache_Disable_ICache_PreLock(uint16_t group); + +/** + * @brief Lock the cache items for ICache. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in ICache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr: start address to lock + * + * @param uint32_t items: cache lines to lock, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) + * + * @return None + */ +void Cache_Lock_ICache_Items(uint32_t addr, uint32_t items); + +/** + * @brief Unlock the cache items for ICache. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in ICache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr: start address to unlock + * + * @param uint32_t items: cache lines to unlock, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) + * + * @return None + */ +void Cache_Unlock_ICache_Items(uint32_t addr, uint32_t items); + +/** + * @brief Lock the cache items in tag memory for ICache or DCache. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : start address of lock region. + * + * @param uint32_t size : size of lock region. + * + * @return 0 for success + * 1 for invalid argument + */ +int Cache_Lock_Addr(uint32_t addr, uint32_t size); + +/** + * @brief Unlock the cache items in tag memory for ICache or DCache. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : start address of unlock region. + * + * @param uint32_t size : size of unlock region. + * + * @return 0 for success + * 1 for invalid argument + */ +int Cache_Unlock_Addr(uint32_t addr, uint32_t size); + +/** + * @brief Disable ICache access for the cpu. + * This operation will make all ICache tag memory invalid, CPU can't access ICache, ICache will keep idle. + * Please do not call this function in your SDK application. + * + * @return uint32_t : auto preload enabled before + */ +uint32_t Cache_Disable_ICache(void); + +/** + * @brief Enable ICache access for the cpu. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : ICache will preload then. + * + * @return None + */ +void Cache_Enable_ICache(uint32_t autoload); + +/** + * @brief Suspend ICache access for the cpu. + * The ICache tag memory is still there, CPU can't access ICache, ICache will keep idle. + * Please do not change MMU, cache mode or tag memory(tag memory can be changed in some special case). + * Please do not call this function in your SDK application. + * + * @param None + * + * @return uint32_t : auto preload enabled before + */ +uint32_t Cache_Suspend_ICache(void); + +/** + * @brief Resume ICache access for the cpu. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : ICache will preload then. + * + * @return None + */ +void Cache_Resume_ICache(uint32_t autoload); + +/** + * @brief Get ICache cache line size + * + * @param None + * + * @return uint32_t: 16, 32, 64 Byte + */ +uint32_t Cache_Get_ICache_Line_Size(void); + +/** + * @brief Enable freeze for ICache. + * Any miss request will be rejected, including cpu miss and preload/autoload miss. + * Please do not call this function in your SDK application. + * + * @param cache_freeze_mode_t mode : 0 for assert busy 1 for assert hit + * + * @return None + */ +void Cache_Freeze_ICache_Enable(cache_freeze_mode_t mode); + +/** + * @brief Disable freeze for ICache. + * Please do not call this function in your SDK application. + * + * @return None + */ +void Cache_Freeze_ICache_Disable(void); + +/** + * @brief Travel tag memory to run a call back function. + * ICache and DCache are suspend when doing this. + * The callback will get the parameter tag_group_info, which will include a group of tag memory addresses and cache memory addresses. + * Please do not call this function in your SDK application. + * + * @param struct cache_mode * mode : the cache to check and the cache mode. + * + * @param uint32_t filter_addr : only the cache lines which may include the filter_address will be returned to the call back function. + * 0 for do not filter, all cache lines will be returned. + * + * @param void (* process)(struct tag_group_info *) : call back function, which may be called many times, a group(the addresses in the group are in the same position in the cache ways) a time. + * + * @return None + */ +void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, void (* process)(struct tag_group_info *)); + +/** + * @brief Get the virtual address from cache mode, cache tag and the virtual address offset of cache ways. + * Please do not call this function in your SDK application. + * + * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. + * + * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * + * @param uint32_t addr_offset : the virtual address offset of the cache ways. + * + * @return uint32_t : the virtual address. + */ +uint32_t Cache_Get_Virtual_Addr(struct cache_mode *mode, uint32_t tag, uint32_t vaddr_offset); + +/** + * @} + */ + +/** + * @brief Get the cache MMU IROM end address. + * Please do not call this function in your SDK application. + * + * @param void + * + * @return uint32_t : the word value of the address. + */ +uint32_t Cache_Get_IROM_MMU_End(void); + +/** + * @brief Get the cache MMU DROM end address. + * Please do not call this function in your SDK application. + * + * @param void + * + * @return uint32_t : the word value of the address. + */ +uint32_t Cache_Get_DROM_MMU_End(void); + +/** + * @brief Configure cache MMU page size according to instruction and rodata size + * + * @param irom_size The instruction cache MMU page size + * @param drom_size The rodata data cache MMU page size + */ +void Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size); + +#define Cache_Dbus_MMU_Set(ext_ram, vaddr, paddr, psize, num, fixed) \ + Cache_MSPI_MMU_Set(ets_efuse_cache_encryption_enabled() ? MMU_SENSITIVE : 0, ext_ram, vaddr, paddr, psize, num, fixed) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/crc.h b/components/esp_rom/include/esp32c6/rom/crc.h new file mode 100644 index 000000000000..de7002f7a52d --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/crc.h @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ROM_CRC_H +#define ROM_CRC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup crc_apis, uart configuration and communication related apis + * @brief crc apis + */ + +/** @addtogroup crc_apis + * @{ + */ + + +/* Standard CRC8/16/32 algorithms. */ +// CRC-8 x8+x2+x1+1 0x07 +// CRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS +// CRC32: +//G(x) = x32 +x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x1 + 1 +//If your buf is not continuous, you can use the first result to be the second parameter. + +/** + * @brief Crc32 value that is in little endian. + * + * @param uint32_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint32_t crc32_le(uint32_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc32 value that is in big endian. + * + * @param uint32_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint32_t crc32_be(uint32_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc16 value that is in little endian. + * + * @param uint16_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint16_t crc16_le(uint16_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc16 value that is in big endian. + * + * @param uint16_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint16_t crc16_be(uint16_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc8 value that is in little endian. + * + * @param uint8_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint8_t crc8_le(uint8_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc8 value that is in big endian. + * + * @param uint32_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint8_t crc8_be(uint8_t crc, uint8_t const *buf, uint32_t len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/components/esp_rom/include/esp32c6/rom/digital_signature.h b/components/esp_rom/include/esp32c6/rom/digital_signature.h new file mode 100644 index 000000000000..e2f62bb15ef5 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/digital_signature.h @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define ETS_DS_MAX_BITS 3072 + +#define ETS_DS_IV_LEN 16 + +/* Length of parameter 'C' stored in flash (not including IV) + + Comprises encrypted Y, M, rinv, md (32), mprime (4), length (4), padding (8) + + Note that if ETS_DS_MAX_BITS<4096, 'C' needs to be split up when writing to hardware +*/ +#define ETS_DS_C_LEN ((ETS_DS_MAX_BITS * 3 / 8) + 32 + 8 + 8) + +/* Encrypted ETS data. Recommended to store in flash in this format. + */ +typedef struct { + /* RSA LENGTH register parameters + * (number of words in RSA key & operands, minus one). + * + * + * This value must match the length field encrypted and stored in 'c', + * or invalid results will be returned. (The DS peripheral will + * always use the value in 'c', not this value, so an attacker can't + * alter the DS peripheral results this way, it will just truncate or + * extend the message and the resulting signature in software.) + */ + unsigned rsa_length; + + /* IV value used to encrypt 'c' */ + uint8_t iv[ETS_DS_IV_LEN]; + + /* Encrypted Digital Signature parameters. Result of AES-CBC encryption + of plaintext values. Includes an encrypted message digest. + */ + uint8_t c[ETS_DS_C_LEN]; +} ets_ds_data_t; + +typedef enum { + ETS_DS_OK, + ETS_DS_INVALID_PARAM, /* Supplied parameters are invalid */ + ETS_DS_INVALID_KEY, /* HMAC peripheral failed to supply key */ + ETS_DS_INVALID_PADDING, /* 'c' decrypted with invalid padding */ + ETS_DS_INVALID_DIGEST, /* 'c' decrypted with invalid digest */ +} ets_ds_result_t; + +void ets_ds_enable(void); + +void ets_ds_disable(void); + + +/* + * @brief Start signing a message (or padded message digest) using the Digital Signature peripheral + * + * - @param message Pointer to message (or padded digest) containing the message to sign. Should be + * (data->rsa_length + 1)*4 bytes long. @param data Pointer to DS data. Can be a pointer to data + * in flash. + * + * Caller must have already called ets_ds_enable() and ets_hmac_calculate_downstream() before calling + * this function, and is responsible for calling ets_ds_finish_sign() and then + * ets_hmac_invalidate_downstream() afterwards. + * + * @return ETS_DS_OK if signature is in progress, ETS_DS_INVALID_PARAM if param is invalid, + * EST_DS_INVALID_KEY if key or HMAC peripheral is configured incorrectly. + */ +ets_ds_result_t ets_ds_start_sign(const void *message, const ets_ds_data_t *data); + + +/* + * @brief Returns true if the DS peripheral is busy following a call to ets_ds_start_sign() + * + * A result of false indicates that a call to ets_ds_finish_sign() will not block. + * + * Only valid if ets_ds_enable() has been called. + */ +bool ets_ds_is_busy(void); + + +/* @brief Finish signing a message using the Digital Signature peripheral + * + * Must be called after ets_ds_start_sign(). Can use ets_ds_busy() to wait until + * peripheral is no longer busy. + * + * - @param signature Pointer to buffer to contain the signature. Should be + * (data->rsa_length + 1)*4 bytes long. + * - @param data Should match the 'data' parameter passed to ets_ds_start_sign() + * + * @param ETS_DS_OK if signing succeeded, ETS_DS_INVALID_PARAM if param is invalid, + * ETS_DS_INVALID_DIGEST or ETS_DS_INVALID_PADDING if there is a problem with the + * encrypted data digest or padding bytes (in case of ETS_DS_INVALID_PADDING, a + * digest is produced anyhow.) + */ +ets_ds_result_t ets_ds_finish_sign(void *signature, const ets_ds_data_t *data); + + +/* Plaintext parameters used by Digital Signature. + + Not used for signing with DS peripheral, but can be encrypted + in-device by calling ets_ds_encrypt_params() +*/ +typedef struct { + uint32_t Y[ETS_DS_MAX_BITS / 32]; + uint32_t M[ETS_DS_MAX_BITS / 32]; + uint32_t Rb[ETS_DS_MAX_BITS / 32]; + uint32_t M_prime; + uint32_t length; +} ets_ds_p_data_t; + +typedef enum { + ETS_DS_KEY_HMAC, /* The HMAC key (as stored in efuse) */ + ETS_DS_KEY_AES, /* The AES key (as derived from HMAC key by HMAC peripheral in downstream mode) */ +} ets_ds_key_t; + +/* @brief Encrypt DS parameters suitable for storing and later use with DS peripheral + * + * @param data Output buffer to store encrypted data, suitable for later use generating signatures. + * @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time. + * @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process is done and 'data' is stored. + * @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the corresponding HMAC key will be stored to efuse and then permanently erased. + * @param key_type Type of key stored in 'key' (either the AES-256 DS key, or an HMAC DS key from which the AES DS key is derived using HMAC peripheral) + * + * @return ETS_DS_INVALID_PARAM if any parameter is invalid, or ETS_DS_OK if 'data' is successfully generated from the input parameters. + */ +ets_ds_result_t ets_ds_encrypt_params(ets_ds_data_t *data, const void *iv, const ets_ds_p_data_t *p_data, const void *key, ets_ds_key_t key_type); + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/ecdsa.h b/components/esp_rom/include/esp32c6/rom/ecdsa.h new file mode 100644 index 000000000000..7be1fada95b3 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/ecdsa.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */ + +typedef enum { + ECDSA_CURVE_P192 = 1, + ECDSA_CURVE_P256 = 2 +} ECDSA_CURVE; + +int ets_ecdsa_verify(const uint8_t *key, const uint8_t *sig, ECDSA_CURVE curve_id, const uint8_t *digest, uint8_t *verified_digest); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/efuse.h b/components/esp_rom/include/esp32c6/rom/efuse.h new file mode 100644 index 000000000000..6cd9f4b377ec --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/efuse.h @@ -0,0 +1,283 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_EFUSE_H_ +#define _ROM_EFUSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** \defgroup efuse_APIs efuse APIs + * @brief ESP32 efuse read/write APIs + * @attention + * + */ + +/** @addtogroup efuse_APIs + * @{ + */ + +typedef enum { + ETS_EFUSE_KEY_PURPOSE_USER = 0, + ETS_EFUSE_KEY_PURPOSE_RESERVED = 1, + ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4, + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5, + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6, + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7, + ETS_EFUSE_KEY_PURPOSE_HMAC_UP = 8, + ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9, + ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10, + ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11, + ETS_EFUSE_KEY_PURPOSE_MAX, +} ets_efuse_purpose_t; + +typedef enum { + ETS_EFUSE_BLOCK0 = 0, + ETS_EFUSE_MAC_SPI_SYS_0 = 1, + ETS_EFUSE_BLOCK_SYS_DATA = 2, + ETS_EFUSE_BLOCK_USR_DATA = 3, + ETS_EFUSE_BLOCK_KEY0 = 4, + ETS_EFUSE_BLOCK_KEY1 = 5, + ETS_EFUSE_BLOCK_KEY2 = 6, + ETS_EFUSE_BLOCK_KEY3 = 7, + ETS_EFUSE_BLOCK_KEY4 = 8, + ETS_EFUSE_BLOCK_KEY5 = 9, + ETS_EFUSE_BLOCK_KEY6 = 10, + ETS_EFUSE_BLOCK_MAX, +} ets_efuse_block_t; + +/** + * @brief Efuse read operation: copies data from physical efuses to efuse read registers. + * + * @param null + * + * @return : 0 if success, others if apb clock is not accepted + */ +int ets_efuse_read(void); + +/** + * @brief Efuse write operation: Copies data from efuse write registers to efuse. Operates on a single block of efuses at a time. + * + * @note This function does not update read efuses, call ets_efuse_read() once all programming is complete. + * + * @return : 0 if success, others if apb clock is not accepted + */ +int ets_efuse_program(ets_efuse_block_t block); + +/** + * @brief Set all Efuse program registers to zero. + * + * Call this before writing new data to the program registers. + */ +void ets_efuse_clear_program_registers(void); + +/** + * @brief Program a block of key data to an efuse block + * + * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6. Key block must be unused (@ref ets_efuse_key_block_unused). + * @param purpose Purpose to set for this key. Purpose must be already unset. + * @param data Pointer to data to write. + * @param data_len Length of data to write. + * + * @note This function also calls ets_efuse_program() for the specified block, and for block 0 (setting the purpose) + */ +int ets_efuse_write_key(ets_efuse_block_t key_block, ets_efuse_purpose_t purpose, const void *data, size_t data_len); + + +/* @brief Return the address of a particular efuse block's first read register + * + * @param block Index of efuse block to look up + * + * @return 0 if block is invalid, otherwise a numeric read register address + * of the first word in the block. + */ +uint32_t ets_efuse_get_read_register_address(ets_efuse_block_t block); + +/** + * @brief Return the current purpose set for an efuse key block + * + * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6. + */ +ets_efuse_purpose_t ets_efuse_get_key_purpose(ets_efuse_block_t key_block); + +/** + * @brief Find a key block with the particular purpose set + * + * @param purpose Purpose to search for. + * @param[out] key_block Pointer which will be set to the key block if found. Can be NULL, if only need to test the key block exists. + * @return true if found, false if not found. If false, value at key_block pointer is unchanged. + */ +bool ets_efuse_find_purpose(ets_efuse_purpose_t purpose, ets_efuse_block_t *key_block); + +/** + * Return true if the key block is unused, false otherwise. + * + * An unused key block is all zero content, not read or write protected, + * and has purpose 0 (ETS_EFUSE_KEY_PURPOSE_USER) + * + * @param key_block key block to check. + * + * @return true if key block is unused, false if key block or used + * or the specified block index is not a key block. + */ +bool ets_efuse_key_block_unused(ets_efuse_block_t key_block); + + +/** + * @brief Search for an unused key block and return the first one found. + * + * See @ref ets_efuse_key_block_unused for a description of an unused key block. + * + * @return First unused key block, or ETS_EFUSE_BLOCK_MAX if no unused key block is found. + */ +ets_efuse_block_t ets_efuse_find_unused_key_block(void); + +/** + * @brief Return the number of unused efuse key blocks (0-6) + */ +unsigned ets_efuse_count_unused_key_blocks(void); + +/** + * @brief Calculate Reed-Solomon Encoding values for a block of efuse data. + * + * @param data Pointer to data buffer (length 32 bytes) + * @param rs_values Pointer to write encoded data to (length 12 bytes) + */ +void ets_efuse_rs_calculate(const void *data, void *rs_values); + +/** + * @brief Read if download mode disabled from Efuse + * + * @return + * - true for efuse disable download mode. + * - false for efuse doesn't disable download mode. + */ +bool ets_efuse_download_modes_disabled(void); + +/** + * @brief Read if uart print control value from Efuse + * + * @return + * - 0 for uart force print. + * - 1 for uart print when GPIO8 is low when digital reset. + * 2 for uart print when GPIO8 is high when digital reset. + * 3 for uart force slient + */ +uint32_t ets_efuse_get_uart_print_control(void); + +/** + * @brief Read if usb download mode disabled from Efuse + * + * (Also returns true if security download mode is enabled, as this mode + * disables USB download.) + * + * @return + * - true for efuse disable usb download mode. + * - false for efuse doesn't disable usb download mode. + */ +bool ets_efuse_usb_download_mode_disabled(void); + +/** + * @brief Read if security download modes enabled from Efuse + * + * @return + * - true for efuse enable security download mode. + * - false for efuse doesn't enable security download mode. + */ +bool ets_efuse_security_download_modes_enabled(void); + +/** + * @brief Return true if secure boot is enabled in EFuse + */ +bool ets_efuse_secure_boot_enabled(void); + +/** + * @brief Return true if secure boot aggressive revoke is enabled in EFuse + */ +bool ets_efuse_secure_boot_aggressive_revoke_enabled(void); + +/** + * @brief Return true if cache encryption (flash, etc) is enabled from boot via EFuse + */ +bool ets_efuse_cache_encryption_enabled(void); + +/** + * @brief Return true if EFuse indicates to send a flash resume command. + */ +bool ets_efuse_force_send_resume(void); + +/** + * @brief return the time in us ROM boot need wait flash to power on from Efuse + * + * @return + * - uint32_t the time in us. + */ +uint32_t ets_efuse_get_flash_delay_us(void); + +#define EFUSE_SPICONFIG_SPI_DEFAULTS 0 +#define EFUSE_SPICONFIG_HSPI_DEFAULTS 1 + +#define EFUSE_SPICONFIG_RET_SPICLK_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPICLK_SHIFT 0 +#define EFUSE_SPICONFIG_RET_SPICLK(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICLK_SHIFT) & EFUSE_SPICONFIG_RET_SPICLK_MASK) + +#define EFUSE_SPICONFIG_RET_SPIQ_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPIQ_SHIFT 6 +#define EFUSE_SPICONFIG_RET_SPIQ(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPIQ_SHIFT) & EFUSE_SPICONFIG_RET_SPIQ_MASK) + +#define EFUSE_SPICONFIG_RET_SPID_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPID_SHIFT 12 +#define EFUSE_SPICONFIG_RET_SPID(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPID_SHIFT) & EFUSE_SPICONFIG_RET_SPID_MASK) + +#define EFUSE_SPICONFIG_RET_SPICS0_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPICS0_SHIFT 18 +#define EFUSE_SPICONFIG_RET_SPICS0(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICS0_SHIFT) & EFUSE_SPICONFIG_RET_SPICS0_MASK) + + +#define EFUSE_SPICONFIG_RET_SPIHD_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPIHD_SHIFT 24 +#define EFUSE_SPICONFIG_RET_SPIHD(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPIHD_SHIFT) & EFUSE_SPICONFIG_RET_SPIHD_MASK) + +/** + * @brief Enable JTAG temporarily by writing a JTAG HMAC "key" into + * the JTAG_CTRL registers. + * + * Works if JTAG has been "soft" disabled by burning the EFUSE_SOFT_DIS_JTAG efuse. + * + * Will enable the HMAC module to generate a "downstream" HMAC value from a key already saved in efuse, and then write the JTAG HMAC "key" which will enable JTAG if the two keys match. + * + * @param jtag_hmac_key Pointer to a 32 byte array containing a valid key. Supplied by user. + * @param key_block Index of a key block containing the source for this key. + * + * @return ETS_FAILED if HMAC operation fails or invalid parameter, ETS_OK otherwise. ETS_OK doesn't necessarily mean that JTAG was enabled. + */ +int ets_jtag_enable_temporarily(const uint8_t *jtag_hmac_key, ets_efuse_block_t key_block); + +/** + * @brief A crc8 algorithm used for MAC addresses in efuse + * + * @param unsigned char const *p : Pointer to original data. + * + * @param unsigned int len : Data length in byte. + * + * @return unsigned char: Crc value. + */ +unsigned char esp_crc8(unsigned char const *p, unsigned int len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_EFUSE_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/esp_flash.h b/components/esp_rom/include/esp32c6/rom/esp_flash.h new file mode 100644 index 000000000000..d975036fc27e --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/esp_flash.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: Most of esp_flash APIs in ROM are compatible with headers in ESP-IDF, this function + just adds ROM-specific parts +*/ + +struct spi_flash_chip_t; +typedef struct esp_flash_t esp_flash_t; + +/* Structure to wrap "global" data used by esp_flash in ROM */ +typedef struct { + /* Default SPI flash chip, ie main chip attached to the MCU + This chip is used if the 'chip' argument passed to esp_flash_xxx API functions is ever NULL + */ + esp_flash_t *default_chip; + + /* Global API OS notification start/end/chip_check functions + + These are used by ROM if no other host functions are configured. + */ + struct { + esp_err_t (*start)(esp_flash_t *chip); + esp_err_t (*end)(esp_flash_t *chip, esp_err_t err); + esp_err_t (*chip_check)(esp_flash_t **inout_chip); + } api_funcs; +} esp_flash_rom_global_data_t; + +/** Access a pointer to the global data used by the ROM spi_flash driver + */ +esp_flash_rom_global_data_t *esp_flash_get_rom_global_data(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/ets_sys.h b/components/esp_rom/include/esp32c6/rom/ets_sys.h new file mode 100644 index 000000000000..7c04af3a54ce --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/ets_sys.h @@ -0,0 +1,432 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_ETS_SYS_H_ +#define _ROM_ETS_SYS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup ets_sys_apis, ets system related apis + * @brief ets system apis + */ + +/** @addtogroup ets_sys_apis + * @{ + */ + +/************************************************************************ + * NOTE + * Many functions in this header files can't be run in FreeRTOS. + * Please see the comment of the Functions. + * There are also some functions that doesn't work on FreeRTOS + * without listed in the header, such as: + * xtos functions start with "_xtos_" in ld file. + * + *********************************************************************** + */ + +/** \defgroup ets_apis, Espressif Task Scheduler related apis + * @brief ets apis + */ + +/** @addtogroup ets_apis + * @{ + */ + +typedef enum { + ETS_OK = 0, /**< return successful in ets*/ + ETS_FAILED = 1, /**< return failed in ets*/ + ETS_PENDING = 2, + ETS_BUSY = 3, + ETS_CANCEL = 4, +} ETS_STATUS; + +typedef ETS_STATUS ets_status_t; + +typedef uint32_t ETSSignal; +typedef uint32_t ETSParam; + +typedef struct ETSEventTag ETSEvent; /**< Event transmit/receive in ets*/ + +struct ETSEventTag { + ETSSignal sig; /**< Event signal, in same task, different Event with different signal*/ + ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ +}; + +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ + + + + + +/** + * @} + */ + +/** \defgroup ets_boot_apis, Boot routing related apis + * @brief ets boot apis + */ + +/** @addtogroup ets_apis + * @{ + */ + +extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ + +/** + * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. + * When Pro CPU booting is completed, Pro CPU will call the Entry code if not NULL. + * + * @param uint32_t start : the PRO Entry code address value in uint32_t + * + * @return None + */ +void ets_set_user_start(uint32_t start); + +/** + * @} + */ + +/** \defgroup ets_printf_apis, ets_printf related apis used in ets + * @brief ets printf apis + */ + +/** @addtogroup ets_printf_apis + * @{ + */ + +/** + * @brief Printf the strings to uart or other devices, similar with printf, simple than printf. + * Can not print float point data format, or longlong data format. + * So we maybe only use this in ROM. + * + * @param const char *fmt : See printf. + * + * @param ... : See printf. + * + * @return int : the length printed to the output device. + */ +int ets_printf(const char *fmt, ...); + +/** + * @brief Get the uart channel of ets_printf(uart_tx_one_char). + * + * @return uint8_t uart channel used by ets_printf(uart_tx_one_char). + */ +uint8_t ets_get_printf_channel(void); + +/** + * @brief Output a char to uart, which uart to output(which is in uart module in ROM) is not in scope of the function. + * Can not print float point data format, or longlong data format + * + * @param char c : char to output. + * + * @return None + */ +void ets_write_char_uart(char c); + +/** + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. + * + * @param void (*)(char) p: Output function to install. + * + * @return None + */ +void ets_install_putc1(void (*p)(char c)); + +/** + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * To install putc2, which is defaulted installed as NULL. + * + * @param void (*)(char) p: Output function to install. + * + * @return None + */ +void ets_install_putc2(void (*p)(char c)); + +/** + * @brief Install putc1 as ets_write_char_uart. + * In silent boot mode(to void interfere the UART attached MCU), we can call this function, after booting ok. + * + * @param None + * + * @return None + */ +void ets_install_uart_printf(void); + +#define ETS_PRINTF(...) ets_printf(...) + +#define ETS_ASSERT(v) do { \ + if (!(v)) { \ + ets_printf("%s %u \n", __FILE__, __LINE__); \ + while (1) {}; \ + } \ +} while (0); + +/** + * @} + */ + +/** \defgroup ets_timer_apis, ets_timer related apis used in ets + * @brief ets timer apis + */ + +/** @addtogroup ets_timer_apis + * @{ + */ +typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ + +typedef struct _ETSTIMER_ { + struct _ETSTIMER_ *timer_next; /**< timer linker*/ + uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ + ETSTimerFunc *timer_func; /**< timer handler*/ + void *timer_arg; /**< timer handler argument*/ +} ETSTimer; + +/** + * @brief Init ets timer, this timer range is 640 us to 429496 ms + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_timer_init(void); + +/** + * @brief In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_timer_deinit(void); + +/** + * @brief Arm an ets timer, this timer range is 640 us to 429496 ms. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @param uint32_t tmout : Timer value in ms, range is 1 to 429496. + * + * @param bool repeat : Timer is periodic repeated. + * + * @return None + */ +void ets_timer_arm(ETSTimer *timer, uint32_t tmout, bool repeat); + +/** + * @brief Arm an ets timer, this timer range is 640 us to 429496 ms. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @param uint32_t tmout : Timer value in us, range is 1 to 429496729. + * + * @param bool repeat : Timer is periodic repeated. + * + * @return None + */ +void ets_timer_arm_us(ETSTimer *ptimer, uint32_t us, bool repeat); + +/** + * @brief Disarm an ets timer. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @return None + */ +void ets_timer_disarm(ETSTimer *timer); + +/** + * @brief Set timer callback and argument. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @param ETSTimerFunc *pfunction : Timer callback. + * + * @param void *parg : Timer callback argument. + * + * @return None + */ +void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg); + +/** + * @brief Unset timer callback and argument to NULL. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @return None + */ +void ets_timer_done(ETSTimer *ptimer); + +/** + * @brief CPU do while loop for some time. + * In FreeRTOS task, please call FreeRTOS apis. + * + * @param uint32_t us : Delay time in us. + * + * @return None + */ +void ets_delay_us(uint32_t us); + +/** + * @brief Set the real CPU ticks per us to the ets, so that ets_delay_us will be accurate. + * Call this function when CPU frequency is changed. + * + * @param uint32_t ticks_per_us : CPU ticks per us. + * + * @return None + */ +void ets_update_cpu_frequency(uint32_t ticks_per_us); + + + +/** + * @brief Get the real CPU ticks per us to the ets. + * This function do not return real CPU ticks per us, just the record in ets. It can be used to check with the real CPU frequency. + * + * @param None + * + * @return uint32_t : CPU ticks per us record in ets. + */ +uint32_t ets_get_cpu_frequency(void); + +/** + * @} + */ + +/** \defgroup ets_intr_apis, ets interrupt configure related apis + * @brief ets intr apis + */ + +/** @addtogroup ets_intr_apis + * @{ + */ + +typedef void (* ets_isr_t)(void *);/**< interrupt handler type*/ + +/** + * @brief Attach a interrupt handler to a CPU interrupt number. + * This function equals to _xtos_set_interrupt_handler_arg(i, func, arg). + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param int i : CPU interrupt number. + * + * @param ets_isr_t func : Interrupt handler. + * + * @param void *arg : argument of the handler. + * + * @return None + */ +void ets_isr_attach(int i, ets_isr_t func, void *arg); + +/** + * @brief Mask the interrupts which show in mask bits. + * This function equals to _xtos_ints_off(mask). + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param uint32_t mask : BIT(i) means mask CPU interrupt number i. + * + * @return None + */ +void ets_isr_mask(uint32_t mask); + +/** + * @brief Unmask the interrupts which show in mask bits. + * This function equals to _xtos_ints_on(mask). + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param uint32_t mask : BIT(i) means mask CPU interrupt number i. + * + * @return None + */ +void ets_isr_unmask(uint32_t unmask); + +/** + * @brief Lock the interrupt to level 2. + * This function direct set the CPU registers. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_intr_lock(void); + +/** + * @brief Unlock the interrupt to level 0. + * This function direct set the CPU registers. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_intr_unlock(void); + + +/** + * @brief Attach an CPU interrupt to a hardware source. + * We have 4 steps to use an interrupt: + * 1.Attach hardware interrupt source to CPU. intr_matrix_set(0, ETS_WIFI_MAC_INTR_SOURCE, ETS_WMAC_INUM); + * 2.Set interrupt handler. xt_set_interrupt_handler(ETS_WMAC_INUM, func, NULL); + * 3.Enable interrupt for CPU. xt_ints_on(1 << ETS_WMAC_INUM); + * 4.Enable interrupt in the module. + * + * @param int cpu_no : The CPU which the interrupt number belongs. + * + * @param uint32_t model_num : The interrupt hardware source number, please see the interrupt hardware source table. + * + * @param uint32_t intr_num : The interrupt number CPU, please see the interrupt cpu using table. + * + * @return None + */ +void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num); + +/** + * @} + */ + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#define ETS_MEM_BAR() asm volatile ( "" : : : "memory" ) + +#ifdef ESP_PLATFORM +// Remove in IDF v6.0 (IDF-7044) +typedef enum { + OK = 0, + FAIL, + PENDING, + BUSY, + CANCEL, +} STATUS __attribute__((deprecated("Use ETS_STATUS instead"))); +#endif + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_ETS_SYS_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/gpio.h b/components/esp_rom/include/esp32c6/rom/gpio.h new file mode 100644 index 000000000000..048ef0ffcf88 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/gpio.h @@ -0,0 +1,209 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/gpio_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup gpio_apis, uart configuration and communication related apis + * @brief gpio apis + */ + +/** @addtogroup gpio_apis + * @{ + */ + +#define GPIO_REG_READ(reg) READ_PERI_REG(reg) +#define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(reg, val) +#define GPIO_ID_PIN0 0 +#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n)) +#define GPIO_PIN_ADDR(i) (GPIO_PIN0_REG + i*4) + +#define GPIO_FUNC_IN_HIGH 0x38 +#define GPIO_FUNC_IN_LOW 0x3C + +#define GPIO_ID_IS_PIN_REGISTER(reg_id) \ + ((reg_id >= GPIO_ID_PIN0) && (reg_id <= GPIO_ID_PIN(GPIO_PIN_COUNT-1))) + +#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) + +typedef enum { + GPIO_PIN_INTR_DISABLE = 0, + GPIO_PIN_INTR_POSEDGE = 1, + GPIO_PIN_INTR_NEGEDGE = 2, + GPIO_PIN_INTR_ANYEDGE = 3, + GPIO_PIN_INTR_LOLEVEL = 4, + GPIO_PIN_INTR_HILEVEL = 5 +} GPIO_INT_TYPE; + + +/** + * @brief Change GPIO(0-31) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0). + * There is no particular ordering guaranteed; so if the order of writes is significant, + * calling code should divide a single call into multiple calls. + * + * @param uint32_t set_mask : the gpios that need high level. + * + * @param uint32_t clear_mask : the gpios that need low level. + * + * @param uint32_t enable_mask : the gpios that need be changed. + * + * @param uint32_t disable_mask : the gpios that need diable output. + * + * @return None + */ +void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); + +/** + * @brief Sample the value of GPIO input pins(0-31) and returns a bitmask. + * + * @param None + * + * @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0. + */ +uint32_t gpio_input_get(void); + +/** + * @brief Set GPIO to wakeup the ESP32. + * Please do not call this function in SDK. + * + * @param uint32_t i: gpio number. + * + * @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used + * + * @return None + */ +void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); + +/** + * @brief disable GPIOs to wakeup the ESP32. + * Please do not call this function in SDK. + * + * @param None + * + * @return None + */ +void gpio_pin_wakeup_disable(void); + +/** + * @brief set gpio input to a signal, one gpio can input to several signals. + * + * @param uint32_t gpio : gpio number, 0~0x2f + * gpio == 0x3C, input 0 to signal + * gpio == 0x3A, input nothing to signal + * gpio == 0x38, input 1 to signal + * + * @param uint32_t signal_idx : signal index. + * + * @param bool inv : the signal is inv or not + * + * @return None + */ +void gpio_matrix_in(uint32_t gpio, uint32_t signal_idx, bool inv); + +/** + * @brief set signal output to gpio, one signal can output to several gpios. + * + * @param uint32_t gpio : gpio number, 0~0x2f + * + * @param uint32_t signal_idx : signal index. + * signal_idx == 0x100, cancel output put to the gpio + * + * @param bool out_inv : the signal output is invert or not + * + * @param bool oen_inv : the signal output enable is invert or not + * + * @return None + */ +void gpio_matrix_out(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv); + +/** + * @brief Select pad as a gpio function from IOMUX. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_select_gpio(uint32_t gpio_num); + +/** + * @brief Set pad driver capability. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @param uint32_t drv : 0-3 + * + * @return None + */ +void gpio_pad_set_drv(uint32_t gpio_num, uint32_t drv); + +/** + * @brief Pull up the pad from gpio number. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_pullup(uint32_t gpio_num); + +/** + * @brief Pull down the pad from gpio number. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_pulldown(uint32_t gpio_num); + +/** + * @brief Unhold the pad from gpio number. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_unhold(uint32_t gpio_num); + +/** + * @brief Hold the pad from gpio number. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_hold(uint32_t gpio_num); + +/** + * @brief enable gpio pad input. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_input_enable(uint32_t gpio_num); + +/** + * @brief disable gpio pad input. + * + * @param uint32_t gpio_num : gpio number, 0~0x2f + * + * @return None + */ +void gpio_pad_input_disable(uint32_t gpio_num); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/hmac.h b/components/esp_rom/include/esp32c6/rom/hmac.h new file mode 100644 index 000000000000..126b8a46a102 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/hmac.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_HMAC_H_ +#define _ROM_HMAC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "efuse.h" + +void ets_hmac_enable(void); + +void ets_hmac_disable(void); + +/* Use the "upstream" HMAC key (ETS_EFUSE_KEY_PURPOSE_HMAC_UP) + to digest a message. +*/ +int ets_hmac_calculate_message(ets_efuse_block_t key_block, const void *message, size_t message_len, uint8_t *hmac); + +/* Calculate a downstream HMAC message to temporarily enable JTAG, or + to generate a Digital Signature data decryption key. + + - purpose must be ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE + or ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG + + - key_block must be in range ETS_EFUSE_BLOCK_KEY0 toETS_EFUSE_BLOCK_KEY6. + This efuse block must have the corresponding purpose set in "purpose", or + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL. + + The result of this HMAC calculation is only made available "downstream" to the + corresponding hardware module, and cannot be accessed by software. +*/ +int ets_hmac_calculate_downstream(ets_efuse_block_t key_block, ets_efuse_purpose_t purpose); + +/* Invalidate a downstream HMAC value previously calculated by ets_hmac_calculate_downstream(). + * + * - purpose must match a previous call to ets_hmac_calculate_downstream(). + * + * After this function is called, the corresponding internal operation (JTAG or DS) will no longer + * have access to the generated key. + */ +int ets_hmac_invalidate_downstream(ets_efuse_purpose_t purpose); + +#ifdef __cplusplus +} +#endif + +#endif // _ROM_HMAC_H_ diff --git a/components/esp_rom/include/esp32c6/rom/libc_stubs.h b/components/esp_rom/include/esp32c6/rom/libc_stubs.h new file mode 100644 index 000000000000..494a70e8675a --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/libc_stubs.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _ROM_LIBC_STUBS_H_ +#define _ROM_LIBC_STUBS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +ESP32-C6 ROM code contains implementations of some of C library functions. +Whenever a function in ROM needs to use a syscall, it calls a pointer to the corresponding syscall +implementation defined in the following struct. + +The table itself, by default, is not allocated in RAM. A global pointer syscall_table_ptr is used to +set the address + +So, before using any of the C library functions (except for pure functions and memcpy/memset functions), +application must allocate syscall table structure for each CPU being used, and populate it with pointers +to actual implementations of corresponding syscalls. +*/ + +struct syscall_stub_table { + struct _reent *(*__getreent)(void); + void *(*_malloc_r)(struct _reent *r, size_t); + void (*_free_r)(struct _reent *r, void *); + void *(*_realloc_r)(struct _reent *r, void *, size_t); + void *(*_calloc_r)(struct _reent *r, size_t, size_t); + void (*_abort)(void); + int (*_system_r)(struct _reent *r, const char *); + int (*_rename_r)(struct _reent *r, const char *, const char *); + clock_t (*_times_r)(struct _reent *r, struct tms *); + int (*_gettimeofday_r) (struct _reent *r, struct timeval *, void *); + void (*_raise_r)(struct _reent *r); + int (*_unlink_r)(struct _reent *r, const char *); + int (*_link_r)(struct _reent *r, const char *, const char *); + int (*_stat_r)(struct _reent *r, const char *, struct stat *); + int (*_fstat_r)(struct _reent *r, int, struct stat *); + void *(*_sbrk_r)(struct _reent *r, ptrdiff_t); + int (*_getpid_r)(struct _reent *r); + int (*_kill_r)(struct _reent *r, int, int); + void (*_exit_r)(struct _reent *r, int); + int (*_close_r)(struct _reent *r, int); + int (*_open_r)(struct _reent *r, const char *, int, int); + int (*_write_r)(struct _reent *r, int, const void *, int); + int (*_lseek_r)(struct _reent *r, int, int, int); + int (*_read_r)(struct _reent *r, int, void *, int); + void (*_retarget_lock_init)(_LOCK_T *lock); + void (*_retarget_lock_init_recursive)(_LOCK_T *lock); + void (*_retarget_lock_close)(_LOCK_T lock); + void (*_retarget_lock_close_recursive)(_LOCK_T lock); + void (*_retarget_lock_acquire)(_LOCK_T lock); + void (*_retarget_lock_acquire_recursive)(_LOCK_T lock); + int (*_retarget_lock_try_acquire)(_LOCK_T lock); + int (*_retarget_lock_try_acquire_recursive)(_LOCK_T lock); + void (*_retarget_lock_release)(_LOCK_T lock); + void (*_retarget_lock_release_recursive)(_LOCK_T lock); + int (*_printf_float)(struct _reent *data, void *pdata, FILE *fp, int (*pfunc) (struct _reent *, FILE *, const char *, size_t len), va_list *ap); + int (*_scanf_float) (struct _reent *rptr, void *pdata, FILE *fp, va_list *ap); + void (*__assert_func) (const char *file, int line, const char *func, const char *failedexpr) __attribute__((__noreturn__)); + void (*__sinit) (struct _reent *r); + void (*_cleanup_r) (struct _reent *r); +}; + +extern struct syscall_stub_table *syscall_table_ptr; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* _ROM_LIBC_STUBS_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/lldesc.h b/components/esp_rom/include/esp32c6/rom/lldesc.h new file mode 100644 index 000000000000..d5cb674df165 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/lldesc.h @@ -0,0 +1,139 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_LLDESC_H_ +#define _ROM_LLDESC_H_ + +#include + +#include "sys/queue.h" +#include "esp_rom_lldesc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LLDESC_TX_MBLK_SIZE 268 /* */ +#define LLDESC_RX_SMBLK_SIZE 64 /* small block size, for small mgmt frame */ +#define LLDESC_RX_MBLK_SIZE 524 /* rx is large sinec we want to contain mgmt frame in one block*/ +#define LLDESC_RX_AMPDU_ENTRY_MBLK_SIZE 64 /* it is a small buffer which is a cycle link*/ +#define LLDESC_RX_AMPDU_LEN_MBLK_SIZE 256 /*for ampdu entry*/ +#ifdef ESP_MAC_5 +#define LLDESC_TX_MBLK_NUM 116 /* 64K / 256 */ +#define LLDESC_RX_MBLK_NUM 82 /* 64K / 512 MAX 172*/ +#define LLDESC_RX_AMPDU_ENTRY_MBLK_NUM 4 +#define LLDESC_RX_AMPDU_LEN_MLBK_NUM 12 +#else +#ifdef SBUF_RXTX +#define LLDESC_TX_MBLK_NUM_MAX (2 * 48) /* 23K / 260 - 8 */ +#define LLDESC_RX_MBLK_NUM_MAX (2 * 48) /* 23K / 524 */ +#define LLDESC_TX_MBLK_NUM_MIN (2 * 16) /* 23K / 260 - 8 */ +#define LLDESC_RX_MBLK_NUM_MIN (2 * 16) /* 23K / 524 */ +#endif +#define LLDESC_TX_MBLK_NUM 10 //(2 * 32) /* 23K / 260 - 8 */ + +#ifdef IEEE80211_RX_AMPDU +#define LLDESC_RX_MBLK_NUM 30 +#else +#define LLDESC_RX_MBLK_NUM 10 +#endif /*IEEE80211_RX_AMPDU*/ + +#define LLDESC_RX_AMPDU_ENTRY_MBLK_NUM 4 +#define LLDESC_RX_AMPDU_LEN_MLBK_NUM 8 +#endif /* !ESP_MAC_5 */ + +typedef struct tx_ampdu_entry_s { + uint32_t sub_len : 12, + dili_num : 7, + : 1, + null_byte: 2, + data : 1, + enc : 1, + seq : 8; +} tx_ampdu_entry_t; + +typedef struct lldesc_chain_s { + lldesc_t *head; + lldesc_t *tail; +} lldesc_chain_t; + +#ifdef SBUF_RXTX +enum sbuf_mask_s { + SBUF_MOVE_NO = 0, + SBUF_MOVE_TX2RX, + SBUF_MOVE_RX2TX, +} ; + +#define SBUF_MOVE_STEP 8 +#endif +#define LLDESC_SIZE sizeof(struct lldesc_s) + +/* SLC Descriptor */ +#define LLDESC_OWNER_MASK 0x80000000 +#define LLDESC_OWNER_SHIFT 31 +#define LLDESC_SW_OWNED 0 +#define LLDESC_HW_OWNED 1 + +#define LLDESC_EOF_MASK 0x40000000 +#define LLDESC_EOF_SHIFT 30 + +#define LLDESC_SOSF_MASK 0x20000000 +#define LLDESC_SOSF_SHIFT 29 + +#define LLDESC_LENGTH_MASK 0x00fff000 +#define LLDESC_LENGTH_SHIFT 12 + +#define LLDESC_SIZE_MASK 0x00000fff +#define LLDESC_SIZE_SHIFT 0 + +#define LLDESC_ADDR_MASK 0x000fffff + +void lldesc_build_chain(uint8_t *descptr, uint32_t desclen, uint8_t *mblkptr, uint32_t buflen, uint32_t blksz, uint8_t owner, + lldesc_t **head, +#ifdef TO_HOST_RESTART + lldesc_t **one_before_tail, +#endif + lldesc_t **tail); + +static inline uint32_t lldesc_get_chain_length(lldesc_t *head) +{ + lldesc_t *ds = head; + uint32_t len = 0; + + while (ds) { + len += ds->length; + ds = STAILQ_NEXT(ds, qe); + } + + return len; +} + +static inline void lldesc_config(lldesc_t *ds, uint8_t owner, uint8_t eof, uint8_t sosf, uint16_t len) +{ + ds->owner = owner; + ds->eof = eof; + ds->sosf = sosf; + ds->length = len; +} + +#define LLDESC_CONFIG(_desc, _owner, _eof, _sosf, _len) do { \ + (_desc)->owner = (_owner); \ + (_desc)->eof = (_eof); \ + (_desc)->sosf = (_sosf); \ + (_desc)->length = (_len); \ +} while(0) + +#define LLDESC_FROM_HOST_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, 0) + +#define LLDESC_MAC_RX_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, (ds)->size) + +#define LLDESC_TO_HOST_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, 0) + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_LLDESC_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/md5_hash.h b/components/esp_rom/include/esp32c6/rom/md5_hash.h new file mode 100644 index 000000000000..3c5e10d1bf66 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/md5_hash.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2003-2005, Jouni Malinen + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * MD5 internal definitions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef _ROM_MD5_HASH_H_ +#define _ROM_MD5_HASH_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct MD5Context { + uint32_t buf[4]; + uint32_t bits[2]; + uint8_t in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_MD5_HASH_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/miniz.h b/components/esp_rom/include/esp32c6/rom/miniz.h new file mode 100644 index 000000000000..f0baecabdcec --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/miniz.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" +#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32c6/rom/rom_layout.h b/components/esp_rom/include/esp32c6/rom/rom_layout.h new file mode 100644 index 000000000000..18b6d79ba7cd --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/rom_layout.h @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SUPPORT_BTDM 0 +#define SUPPORT_BTBB 0 +#define SUPPORT_WIFI 1 +#define SUPPORT_USB_DWCOTG 0 +#define SUPPORT_COEXIST 1 +#define SUPPORT_MBEDTLS 0 + +/* Structure and functions for returning ROM global layout + * + * This is for address symbols defined in the linker script, which may change during ECOs. + */ +typedef struct { + void *dram0_stack_shared_mem_start; + void *dram0_rtos_reserved_start; + void *stack_sentry; + void *stack; + +#if SUPPORT_BTDM + void *data_start_btdm; + void *data_end_btdm; + void *bss_start_btdm; + void *bss_end_btdm; + void *data_start_btdm_rom; + void *data_start_interface_btdm; + void *data_end_interface_btdm; + void *bss_start_interface_btdm; + void *bss_end_interface_btdm; +#endif + +#if SUPPORT_BTBB + void *dram_start_btbbrom; + void *dram_end_btbbrom; +#endif + +#if SUPPORT_BTDM || SUPPORT_WIFI + void *dram_start_phyrom; + void *dram_end_phyrom; +#endif + +#if SUPPORT_WIFI + void *dram_start_net80211; + void *dram_end_net80211; + void *data_start_interface_net80211; + void *data_end_interface_net80211; + void *bss_start_interface_net80211; + void *bss_end_interface_net80211; + void *dram_start_pp; + void *dram_end_pp; + void *data_start_interface_pp; + void *data_end_interface_pp; + void *bss_start_interface_pp; + void *bss_end_interface_pp; +#endif + +#if SUPPORT_COEXIST + void *dram_start_coexist; + void *dram_end_coexist; + void *data_start_interface_coexist; + void *data_end_interface_coexist; + void *bss_start_interface_coexist; + void *bss_end_interface_coexist; +#endif + +#if SUPPORT_MBEDTLS + void *dram_start_mbedtls_rom; + void *dram_end_mbedtls_rom; +#endif + +#if SUPPORT_USB_DWCOTG + void *dram_start_usb_dwcotg_rom; + void *dram_end_usb_dwcotg_rom; +#else + //Two reserved members are defined here, so the structure will not be broken, + //please keep in mind that there is no memory can be released between + //dram_start_usb_reserved_rom ~ dram_end_usb_reserved_rom. + void *dram_start_usb_reserved_rom; + void *dram_end_usb_reserved_rom; +#endif + + void *dram_start_uart_rom; + void *dram_end_uart_rom; +} ets_rom_layout_t; + +extern const ets_rom_layout_t *const ets_rom_layout_p; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/rsa_pss.h b/components/esp_rom/include/esp32c6/rom/rsa_pss.h new file mode 100644 index 000000000000..d6140879c83e --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/rsa_pss.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_RSA_PSS_H_ +#define _ROM_RSA_PSS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETS_SIG_LEN 384 /* Bytes */ +#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */ + +typedef struct { + uint8_t n[384]; /* Public key modulus */ + uint32_t e; /* Public key exponent */ + uint8_t rinv[384]; + uint32_t mdash; +} ets_rsa_pubkey_t; + +bool ets_rsa_pss_verify(const ets_rsa_pubkey_t *key, const uint8_t *sig, const uint8_t *digest, uint8_t *verified_digest); + +void ets_mgf1_sha256(const uint8_t *mgfSeed, size_t seedLen, size_t maskLen, uint8_t *mask); + +bool ets_emsa_pss_verify(const uint8_t *encoded_message, const uint8_t *mhash); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/esp_rom/include/esp32c6/rom/rtc.h b/components/esp_rom/include/esp32c6/rom/rtc.h new file mode 100644 index 000000000000..6a046fa25a49 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/rtc.h @@ -0,0 +1,254 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_assert.h" + +#include "soc/soc.h" +#include "soc/lp_aon_reg.h" +#include "soc/reset_reasons.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup rtc_apis, rtc registers and memory related apis + * @brief rtc apis + */ + +/** @addtogroup rtc_apis + * @{ + */ + +/************************************************************************************** + * Note: * + * Some Rtc memory and registers are used, in ROM or in internal library. * + * Please do not use reserved or used rtc memory or registers. * + * * + ************************************************************************************* + * LP Memory & Store Register usage + ************************************************************************************* + * rtc memory addr type size usage + * 0x3f421000(0x50000000) Slow SIZE_CP Co-Processor code/Reset Entry + * 0x3f421000+SIZE_CP Slow 8192-SIZE_CP + * + * 0x3ff80000(0x40070000) Fast 8192 deep sleep entry code + * + ************************************************************************************* + * RTC store registers usage + * LP_AON_STORE0_REG Reserved + * LP_AON_STORE1_REG RTC_SLOW_CLK calibration value + * LP_AON_STORE2_REG Boot time, low word + * LP_AON_STORE3_REG Boot time, high word + * LP_AON_STORE4_REG External XTAL frequency + * LP_AON_STORE5_REG FAST_RTC_MEMORY_LENGTH + * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY + * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC + * LP_AON_STORE8_REG Store light sleep wake stub addr + * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) + ************************************************************************************* + */ + +#define RTC_SLOW_CLK_CAL_REG LP_AON_STORE1_REG +#define RTC_BOOT_TIME_LOW_REG LP_AON_STORE2_REG +#define RTC_BOOT_TIME_HIGH_REG LP_AON_STORE3_REG +#define RTC_XTAL_FREQ_REG LP_AON_STORE4_REG +#define RTC_ENTRY_LENGTH_REG LP_AON_STORE5_REG +#define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG +#define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG +#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG +#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define SLEEP_MODE_REG LP_AON_STORE9_REG + +#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. + +typedef enum { + AWAKE = 0, // +#include +#include "ets_sys.h" +#include "ecdsa.h" +#include "rsa_pss.h" +#include "esp_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ets_secure_boot_sig_block ets_secure_boot_sig_block_t; +typedef struct ets_secure_boot_signature ets_secure_boot_signature_t; +typedef struct ets_secure_boot_key_digests ets_secure_boot_key_digests_t; + +#if CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT + +typedef struct ets_secure_boot_sig_block ets_secure_boot_sig_block_t; +typedef struct ets_secure_boot_signature ets_secure_boot_signature_t; +typedef struct ets_secure_boot_key_digests ets_secure_boot_key_digests_t; + +/* Anti-FI measure: use full words for success/fail, instead of + 0/non-zero +*/ +typedef enum { + SB_SUCCESS = 0x3A5A5AA5, + SB_FAILED = 0x7533885E, +} ets_secure_boot_status_t; + +/* Verify bootloader image (reconfigures cache to map), + with key digests provided as parameters.) + + Can be used to verify secure boot status before enabling + secure boot permanently. + + If stage_load parameter is true, bootloader is copied into staging + buffer in RAM at the same time. + + If result is SB_SUCCESS, the "simple hash" of the bootloader is + copied into verified_hash. +*/ +ets_secure_boot_status_t ets_secure_boot_verify_bootloader_with_keys(uint8_t *verified_hash, const ets_secure_boot_key_digests_t *trusted_keys, bool stage_load); + +/* Read key digests from efuse. Any revoked/missing digests will be + marked as NULL +*/ +ETS_STATUS ets_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys); + +/* Verify supplied signature against supplied digest, using + supplied trusted key digests. + + Doesn't reconfigure cache or any other hardware access except for RSA peripheral. + + If result is SB_SUCCESS, the image_digest value is copied into verified_digest. +*/ +ets_secure_boot_status_t ets_secure_boot_verify_signature(const ets_secure_boot_signature_t *sig, const uint8_t *image_digest, const ets_secure_boot_key_digests_t *trusted_keys, uint8_t *verified_digest); + +/* Revoke a public key digest in efuse. + @param index Digest to revoke. Must be 0, 1 or 2. + */ +void ets_secure_boot_revoke_public_key_digest(int index); + +#define CRC_SIGN_BLOCK_LEN 1196 +#define SIG_BLOCK_PADDING 4096 +#define ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC 0xE7 + +/* Secure Boot V2 signature block + + (Up to 3 in a signature sector are appended to the image) + */ +#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME + +struct ets_secure_boot_sig_block { + uint8_t magic_byte; + uint8_t version; + uint8_t _reserved1; + uint8_t _reserved2; + uint8_t image_digest[32]; + ets_rsa_pubkey_t key; + uint8_t signature[384]; + uint32_t block_crc; + uint8_t _padding[16]; +}; + +#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME + +struct __attribute((packed)) ets_secure_boot_sig_block { + uint8_t magic_byte; + uint8_t version; + uint8_t _reserved1; + uint8_t _reserved2; + uint8_t image_digest[32]; + struct { + struct { + uint8_t curve_id; /* ETS_ECDSA_CURVE_P192 / ETS_ECDSA_CURVE_P256 */ + uint8_t point[64]; /* X followed by Y (both little-endian), plus zero bytes if P192 */ + } key; + uint8_t signature[64]; /* r followed by s (both little-endian) */ + uint8_t padding[1031]; + } ecdsa; + uint32_t block_crc; /* note: crc covers all bytes in the structure before it, regardless of version field */ + uint8_t _padding[16]; +}; +#endif + +ESP_STATIC_ASSERT(sizeof(ets_secure_boot_sig_block_t) == 1216, "invalid sig block size"); + +#define SECURE_BOOT_NUM_BLOCKS 3 + +/* V2 Secure boot signature sector (up to 3 blocks) */ +struct ets_secure_boot_signature { + ets_secure_boot_sig_block_t block[SECURE_BOOT_NUM_BLOCKS]; + uint8_t _padding[4096 - (sizeof(ets_secure_boot_sig_block_t) * SECURE_BOOT_NUM_BLOCKS)]; +}; + +ESP_STATIC_ASSERT(sizeof(ets_secure_boot_signature_t) == 4096, "invalid sig sector size"); + +#define MAX_KEY_DIGESTS 3 + +struct ets_secure_boot_key_digests { + const void *key_digests[MAX_KEY_DIGESTS]; + bool allow_key_revoke; +}; + +#endif /* CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT */ + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/sha.h b/components/esp_rom/include/esp32c6/rom/sha.h new file mode 100644 index 000000000000..c9eda2fd99f9 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/sha.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _ROM_SHA_H_ +#define _ROM_SHA_H_ + +#include +#include +#include "ets_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SHA1 = 0, + SHA2_224, + SHA2_256, + SHA_TYPE_MAX +} SHA_TYPE; + +typedef struct SHAContext { + bool start; + bool in_hardware; // Is this context currently in peripheral? Needs to be manually cleared if multiple SHAs are interleaved + SHA_TYPE type; + uint32_t state[16]; // For SHA1/SHA224/SHA256, used 8, other used 16 + unsigned char buffer[128]; // For SHA1/SHA224/SHA256, used 64, other used 128 + uint32_t total_bits[4]; +} SHA_CTX; + +void ets_sha_enable(void); + +void ets_sha_disable(void); + +ets_status_t ets_sha_init(SHA_CTX *ctx, SHA_TYPE type); + +ets_status_t ets_sha_starts(SHA_CTX *ctx, uint16_t sha512_t); + +void ets_sha_get_state(SHA_CTX *ctx); + +void ets_sha_process(SHA_CTX *ctx, const unsigned char *input); + +void ets_sha_update(SHA_CTX *ctx, const unsigned char *input, uint32_t input_bytes, bool update_ctx); + +ets_status_t ets_sha_finish(SHA_CTX *ctx, unsigned char *output); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_SHA_H_ */ diff --git a/components/esp_rom/include/esp32c6/rom/spi_flash.h b/components/esp_rom/include/esp32c6/rom/spi_flash.h new file mode 100644 index 000000000000..2d782dee4f36 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/spi_flash.h @@ -0,0 +1,458 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_attr.h" +#include "esp_rom_spiflash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PERIPHS_SPI_FLASH_CMD SPI_MEM_CMD_REG(1) +#define PERIPHS_SPI_FLASH_ADDR SPI_MEM_ADDR_REG(1) +#define PERIPHS_SPI_FLASH_CTRL SPI_MEM_CTRL_REG(1) +#define PERIPHS_SPI_FLASH_CTRL1 SPI_MEM_CTRL1_REG(1) +#define PERIPHS_SPI_FLASH_STATUS SPI_MEM_RD_STATUS_REG(1) +#define PERIPHS_SPI_FLASH_USRREG SPI_MEM_USER_REG(1) +#define PERIPHS_SPI_FLASH_USRREG1 SPI_MEM_USER1_REG(1) +#define PERIPHS_SPI_FLASH_USRREG2 SPI_MEM_USER2_REG(1) +#define PERIPHS_SPI_FLASH_C0 SPI_MEM_W0_REG(1) +#define PERIPHS_SPI_FLASH_C1 SPI_MEM_W1_REG(1) +#define PERIPHS_SPI_FLASH_C2 SPI_MEM_W2_REG(1) +#define PERIPHS_SPI_FLASH_C3 SPI_MEM_W3_REG(1) +#define PERIPHS_SPI_FLASH_C4 SPI_MEM_W4_REG(1) +#define PERIPHS_SPI_FLASH_C5 SPI_MEM_W5_REG(1) +#define PERIPHS_SPI_FLASH_C6 SPI_MEM_W6_REG(1) +#define PERIPHS_SPI_FLASH_C7 SPI_MEM_W7_REG(1) +#define PERIPHS_SPI_FLASH_TX_CRC SPI_MEM_TX_CRC_REG(1) + +#define SPI0_R_QIO_DUMMY_CYCLELEN 5 +#define SPI0_R_QIO_ADDR_BITSLEN 23 +#define SPI0_R_FAST_DUMMY_CYCLELEN 7 +#define SPI0_R_DIO_DUMMY_CYCLELEN 3 +#define SPI0_R_FAST_ADDR_BITSLEN 23 +#define SPI0_R_SIO_ADDR_BITSLEN 23 + +#define SPI1_R_QIO_DUMMY_CYCLELEN 5 +#define SPI1_R_QIO_ADDR_BITSLEN 23 +#define SPI1_R_FAST_DUMMY_CYCLELEN 7 +#define SPI1_R_DIO_DUMMY_CYCLELEN 3 +#define SPI1_R_DIO_ADDR_BITSLEN 23 +#define SPI1_R_FAST_ADDR_BITSLEN 23 +#define SPI1_R_SIO_ADDR_BITSLEN 23 + +#define ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN 23 + +#define ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN SPI_MEM_WRSR_2B + +//SPI address register +#define ESP_ROM_SPIFLASH_BYTES_LEN 24 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM 32 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM 16 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_BITS 0xf + +typedef void (* spi_flash_func_t)(void); +typedef esp_rom_spiflash_result_t (* spi_flash_op_t)(void); +typedef esp_rom_spiflash_result_t (* spi_flash_erase_t)(uint32_t); +typedef esp_rom_spiflash_result_t (* spi_flash_rd_t)(uint32_t, uint32_t*, int); +typedef esp_rom_spiflash_result_t (* spi_flash_wr_t)(uint32_t, const uint32_t*, int); +typedef esp_rom_spiflash_result_t (* spi_flash_ewr_t)(uint32_t, const void*, uint32_t); +typedef esp_rom_spiflash_result_t (* spi_flash_wren_t)(void*); +typedef esp_rom_spiflash_result_t (* spi_flash_erase_area_t)(uint32_t, uint32_t); + +typedef struct { + uint8_t pp_addr_bit_len; + uint8_t se_addr_bit_len; + uint8_t be_addr_bit_len; + uint8_t rd_addr_bit_len; + uint32_t read_sub_len; + uint32_t write_sub_len; + spi_flash_op_t unlock; + spi_flash_erase_t erase_sector; + spi_flash_erase_t erase_block; + spi_flash_rd_t read; + spi_flash_wr_t write; + spi_flash_ewr_t encrypt_write; + spi_flash_func_t check_sus; + spi_flash_wren_t wren; + spi_flash_op_t wait_idle; + spi_flash_erase_area_t erase_area; +} spiflash_legacy_funcs_t; + +typedef struct { + uint8_t data_length; + uint8_t read_cmd0; + uint8_t read_cmd1; + uint8_t write_cmd; + uint16_t data_mask; + uint16_t data; +} esp_rom_spiflash_common_cmd_t; + +/** + * @brief SPI Read Flash status register. We use CMD 0x05 (RDSR). + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t *status : The pointer to which to return the Flash status value. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status); + +/** + * @brief SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2). + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t *status : The pointer to which to return the Flash status value. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read_statushigh(esp_rom_spiflash_chip_t *spi, uint32_t *status); + +/** + * @brief Write status to Flash status register. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t status_value : Value to . + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : write OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : write timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t *spi, uint32_t status_value); + +/** + * @brief Use a command to Read Flash status register. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t*status : The pointer to which to return the Flash status value. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read_user_cmd(uint32_t *status, uint8_t cmd); + +/** + * @brief Config SPI Flash read mode when init. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD. + * + * This function does not try to set the QIO Enable bit in the status register, caller is responsible for this. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : config error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode); + +/** + * @brief Config SPI Flash clock divisor. + * Please do not call this function in SDK. + * + * @param uint8_t freqdiv: clock divisor. + * + * @param uint8_t spi: 0 for SPI0, 1 for SPI1. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : config error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_config_clk(uint8_t freqdiv, uint8_t spi); + +/** + * @brief Clear all SR bits except QE bit. + * Please do not call this function in SDK. + * + * @param None. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_clear_bp(void); + +/** + * @brief Clear all SR bits except QE bit. + * Please do not call this function in SDK. + * + * @param None. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void); + +/** + * @brief Update SPI Flash parameter. + * Please do not call this function in SDK. + * + * @param uint32_t deviceId : Device ID read from SPI, the low 32 bit. + * + * @param uint32_t chip_size : The Flash size. + * + * @param uint32_t block_size : The Flash block size. + * + * @param uint32_t sector_size : The Flash sector size. + * + * @param uint32_t page_size : The Flash page size. + * + * @param uint32_t status_mask : The Mask used when read status from Flash(use single CMD). + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Update OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Update error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Update timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_config_param(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, + uint32_t sector_size, uint32_t page_size, uint32_t status_mask); + +/** + * @brief Erase whole flash chip. + * Please do not call this function in SDK. + * + * @param None + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void); + +/** + * @brief Erase a 64KB block of flash + * Uses SPI flash command D8H. + * Please do not call this function in SDK. + * + * @param uint32_t block_num : Which block to erase. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num); + +/** + * @brief Erase a sector of flash. + * Uses SPI flash command 20H. + * Please do not call this function in SDK. + * + * @param uint32_t sector_num : Which sector to erase. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num); + +/** + * @brief Erase some sectors. + * Please do not call this function in SDK. + * + * @param uint32_t start_addr : Start addr to erase, should be sector aligned. + * + * @param uint32_t area_len : Length to erase, should be sector aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len); + +/** + * @brief Write Data to Flash, you should Erase it yourself if need. + * Please do not call this function in SDK. + * + * @param uint32_t dest_addr : Address to write, should be 4 bytes aligned. + * + * @param const uint32_t *src : The pointer to data which is to write. + * + * @param uint32_t len : Length to write, should be 4 bytes aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Write OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Write timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t dest_addr, const uint32_t *src, int32_t len); + +/** + * @brief Read Data from Flash, you should Erase it yourself if need. + * Please do not call this function in SDK. + * + * @param uint32_t src_addr : Address to read, should be 4 bytes aligned. + * + * @param uint32_t *dest : The buf to read the data. + * + * @param uint32_t len : Length to read, should be 4 bytes aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t src_addr, uint32_t *dest, int32_t len); + +/** + * @brief SPI1 go into encrypto mode. + * Please do not call this function in SDK. + * + * @param None + * + * @return None + */ +void esp_rom_spiflash_write_encrypted_enable(void); + +/** + * @brief SPI1 go out of encrypto mode. + * Please do not call this function in SDK. + * + * @param None + * + * @return None + */ +void esp_rom_spiflash_write_encrypted_disable(void); + +/** + * @brief Write data to flash with transparent encryption. + * @note Sectors to be written should already be erased. + * + * @note Please do not call this function in SDK. + * + * @param uint32_t flash_addr : Address to write, should be 32 byte aligned. + * + * @param uint32_t *data : The pointer to data to write. Note, this pointer must + * be 32 bit aligned and the content of the data will be + * modified by the encryption function. + * + * @param uint32_t len : Length to write, should be 32 bytes aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Data written successfully. + * ESP_ROM_SPIFLASH_RESULT_ERR : Encryption write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Encrypto write timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len); + + +/** @brief Wait until SPI flash write operation is complete + * + * @note Please do not call this function in SDK. + * + * Reads the Write In Progress bit of the SPI flash status register, + * repeats until this bit is zero (indicating write complete). + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Write is complete + * ESP_ROM_SPIFLASH_RESULT_ERR : Error while reading status. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi); + + +/** @brief Enable Quad I/O pin functions + * + * @note Please do not call this function in SDK. + * + * Sets the HD & WP pin functions for Quad I/O modes, based on the + * efuse SPI pin configuration. + * + * @param wp_gpio_num - Number of the WP pin to reconfigure for quad I/O. + * + * @param spiconfig - Pin configuration, as returned from ets_efuse_get_spiconfig(). + * - If this parameter is 0, default SPI pins are used and wp_gpio_num parameter is ignored. + * - If this parameter is 1, default HSPI pins are used and wp_gpio_num parameter is ignored. + * - For other values, this parameter encodes the HD pin number and also the CLK pin number. CLK pin selection is used + * to determine if HSPI or SPI peripheral will be used (use HSPI if CLK pin is the HSPI clock pin, otherwise use SPI). + * Both HD & WP pins are configured via GPIO matrix to map to the selected peripheral. + */ +void esp_rom_spiflash_select_qio_pins(uint8_t wp_gpio_num, uint32_t spiconfig); + +/** + * @brief Clear WEL bit unconditionally. + * + * @return always ESP_ROM_SPIFLASH_RESULT_OK + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void); + +/** + * @brief Set WREN bit. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @return always ESP_ROM_SPIFLASH_RESULT_OK + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_enable(esp_rom_spiflash_chip_t *spi); + +/** + * @brief Fix the bug in SPI hardware communication with Flash/Ext-SRAM in High Speed. + * Please do not call this function in SDK. + * + * @param uint8_t spi: 0 for SPI0(Cache Access), 1 for SPI1(Flash read/write). + * + * @param uint8_t freqdiv: Pll is 80M, 4 for 20M, 3 for 26.7M, 2 for 40M, 1 for 80M. + * + * @return None + */ +void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); + +/** + * @brief Set SPI Flash pad drivers. + * Please do not call this function in SDK. + * + * @param uint8_t wp_gpio_num: WP gpio number. + * + * @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd + * + * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid + * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. + * Values usually read from falsh by rom code, function usually callde by rom code. + * if value with bit(3) set, the value is valid, bit[2:0] is the real value. + * + * @return None + */ +void esp_rom_spiflash_set_drvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t *drvs); + +/** + * @brief Select SPI Flash function for pads. + * Please do not call this function in SDK. + * + * @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd + * + * @return None + */ +void esp_rom_spiflash_select_padsfunc(uint32_t ishspi); + +/** + * @brief Send CommonCmd to Flash so that is can go into QIO mode, some Flash use different CMD. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_common_cmd_t *cmd : A struct to show the action of a command. + * + * @return uint16_t 0 : do not send command any more. + * 1 : go to the next command. + * n > 1 : skip (n - 1) commands. + */ +uint16_t esp_rom_spiflash_common_cmd(esp_rom_spiflash_common_cmd_t *cmd); + +extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c6/rom/tjpgd.h b/components/esp_rom/include/esp32c6/rom/tjpgd.h new file mode 100644 index 000000000000..3050f865c912 --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/tjpgd.h @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/*----------------------------------------------------------------------------/ +/ TJpgDec - Tiny JPEG Decompressor include file (C)ChaN, 2012 +/----------------------------------------------------------------------------*/ +#ifndef _TJPGDEC +#define _TJPGDEC +/*---------------------------------------------------------------------------*/ +/* System Configurations */ + +#define JD_SZBUF 512 /* Size of stream input buffer */ +#define JD_FORMAT 0 /* Output pixel format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */ +#define JD_USE_SCALE 1 /* Use descaling feature for output */ +#define JD_TBLCLIP 1 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */ + +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + + +/* Error code */ +typedef enum { + JDR_OK = 0, /* 0: Succeeded */ + JDR_INTR, /* 1: Interrupted by output function */ + JDR_INP, /* 2: Device error or wrong termination of input stream */ + JDR_MEM1, /* 3: Insufficient memory pool for the image */ + JDR_MEM2, /* 4: Insufficient stream input buffer */ + JDR_PAR, /* 5: Parameter error */ + JDR_FMT1, /* 6: Data format error (may be damaged data) */ + JDR_FMT2, /* 7: Right format but not supported */ + JDR_FMT3 /* 8: Not supported JPEG standard */ +} JRESULT; + + + +/* Rectangular structure */ +typedef struct { + WORD left, right, top, bottom; +} JRECT; + + + +/* Decompressor object structure */ +typedef struct JDEC JDEC; +struct JDEC { + UINT dctr; /* Number of bytes available in the input buffer */ + BYTE *dptr; /* Current data read ptr */ + BYTE *inbuf; /* Bit stream input buffer */ + BYTE dmsk; /* Current bit in the current read byte */ + BYTE scale; /* Output scaling ratio */ + BYTE msx, msy; /* MCU size in unit of block (width, height) */ + BYTE qtid[3]; /* Quantization table ID of each component */ + SHORT dcv[3]; /* Previous DC element of each component */ + WORD nrst; /* Restart inverval */ + UINT width, height; /* Size of the input image (pixel) */ + BYTE *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ + WORD *huffcode[2][2]; /* Huffman code word tables [id][dcac] */ + BYTE *huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */ + LONG *qttbl[4]; /* Dequaitizer tables [id] */ + void *workbuf; /* Working buffer for IDCT and RGB output */ + BYTE *mcubuf; /* Working buffer for the MCU */ + void *pool; /* Pointer to available memory pool */ + UINT sz_pool; /* Size of momory pool (bytes available) */ + UINT (*infunc)(JDEC *, BYTE *, UINT); /* Pointer to jpeg stream input function */ + void *device; /* Pointer to I/O device identifiler for the session */ +}; + + + +/* TJpgDec API functions */ +JRESULT jd_prepare (JDEC *, UINT(*)(JDEC *, BYTE *, UINT), void *, UINT, void *); +JRESULT jd_decomp (JDEC *, UINT(*)(JDEC *, void *, JRECT *), BYTE); + + +#ifdef __cplusplus +} +#endif + +#endif /* _TJPGDEC */ diff --git a/components/esp_rom/include/esp32c6/rom/uart.h b/components/esp_rom/include/esp32c6/rom/uart.h new file mode 100644 index 000000000000..9045c42f6f6e --- /dev/null +++ b/components/esp_rom/include/esp32c6/rom/uart.h @@ -0,0 +1,353 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_UART_H_ +#define _ROM_UART_H_ + +#include "esp_types.h" +#include "esp_attr.h" +#include "ets_sys.h" +#include "soc/soc.h" +#include "soc/uart_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup uart_apis, uart configuration and communication related apis + * @brief uart apis + */ + +/** @addtogroup uart_apis + * @{ + */ + +#define RX_BUFF_SIZE 0x400 +#define TX_BUFF_SIZE 100 + +//uart int enalbe register ctrl bits +#define UART_RCV_INTEN BIT0 +#define UART_TRX_INTEN BIT1 +#define UART_LINE_STATUS_INTEN BIT2 + +//uart int identification ctrl bits +#define UART_INT_FLAG_MASK 0x0E + +//uart fifo ctrl bits +#define UART_CLR_RCV_FIFO BIT1 +#define UART_CLR_TRX_FIFO BIT2 +#define UART_RCVFIFO_TRG_LVL_BITS BIT6 + +//uart line control bits +#define UART_DIV_LATCH_ACCESS_BIT BIT7 + +//uart line status bits +#define UART_RCV_DATA_RDY_FLAG BIT0 +#define UART_RCV_OVER_FLOW_FLAG BIT1 +#define UART_RCV_PARITY_ERR_FLAG BIT2 +#define UART_RCV_FRAME_ERR_FLAG BIT3 +#define UART_BRK_INT_FLAG BIT4 +#define UART_TRX_FIFO_EMPTY_FLAG BIT5 +#define UART_TRX_ALL_EMPTY_FLAG BIT6 // include fifo and shift reg +#define UART_RCV_ERR_FLAG BIT7 + +//send and receive message frame head +#define FRAME_FLAG 0x7E + +typedef enum { + UART_LINE_STATUS_INT_FLAG = 0x06, + UART_RCV_FIFO_INT_FLAG = 0x04, + UART_RCV_TMOUT_INT_FLAG = 0x0C, + UART_TXBUFF_EMPTY_INT_FLAG = 0x02 +} UartIntType; //consider bit0 for int_flag + +typedef enum { + RCV_ONE_BYTE = 0x0, + RCV_FOUR_BYTE = 0x1, + RCV_EIGHT_BYTE = 0x2, + RCV_FOURTEEN_BYTE = 0x3 +} UartRcvFifoTrgLvl; + +typedef enum { + FIVE_BITS = 0x0, + SIX_BITS = 0x1, + SEVEN_BITS = 0x2, + EIGHT_BITS = 0x3 +} UartBitsNum4Char; + +typedef enum { + ONE_STOP_BIT = 1, + ONE_HALF_STOP_BIT = 2, + TWO_STOP_BIT = 3 +} UartStopBitsNum; + +typedef enum { + NONE_BITS = 0, + ODD_BITS = 2, + EVEN_BITS = 3 + +} UartParityMode; + +typedef enum { + STICK_PARITY_DIS = 0, + STICK_PARITY_EN = 2 +} UartExistParity; + +typedef enum { + BIT_RATE_9600 = 9600, + BIT_RATE_19200 = 19200, + BIT_RATE_38400 = 38400, + BIT_RATE_57600 = 57600, + BIT_RATE_115200 = 115200, + BIT_RATE_230400 = 230400, + BIT_RATE_460800 = 460800, + BIT_RATE_921600 = 921600 +} UartBautRate; + +typedef enum { + NONE_CTRL, + HARDWARE_CTRL, + XON_XOFF_CTRL +} UartFlowCtrl; + +typedef enum { + EMPTY, + UNDER_WRITE, + WRITE_OVER +} RcvMsgBuffState; + +typedef struct { + uint8_t *pRcvMsgBuff; + uint8_t *pWritePos; + uint8_t *pReadPos; + uint8_t TrigLvl; + RcvMsgBuffState BuffState; +} RcvMsgBuff; + +typedef struct { + uint32_t TrxBuffSize; + uint8_t *pTrxBuff; +} TrxMsgBuff; + +typedef enum { + BAUD_RATE_DET, + WAIT_SYNC_FRM, + SRCH_MSG_HEAD, + RCV_MSG_BODY, + RCV_ESC_CHAR, +} RcvMsgState; + +typedef struct { + UartBautRate baut_rate; + UartBitsNum4Char data_bits; + UartExistParity exist_parity; + UartParityMode parity; // chip size in byte + UartStopBitsNum stop_bits; + UartFlowCtrl flow_ctrl; + uint8_t buff_uart_no; //indicate which uart use tx/rx buffer + RcvMsgBuff rcv_buff; +// TrxMsgBuff trx_buff; + RcvMsgState rcv_state; + int received; +} UartDevice; + +/** + * @brief Init uart device struct value and reset uart0/uart1 rx. + * Please do not call this function in SDK. + * + * @param rxBuffer, must be a pointer to RX_BUFF_SIZE bytes or NULL + * + * @return None + */ +void uartAttach(void *rxBuffer); + +/** + * @brief Init uart0 or uart1 for UART download booting mode. + * Please do not call this function in SDK. + * + * @param uint8_t uart_no : 0 for UART0, else for UART1. + * + * @param uint32_t clock : clock used by uart module, to adjust baudrate. + * + * @return None + */ +void Uart_Init(uint8_t uart_no, uint32_t clock); + +/** + * @brief Modify uart baudrate. + * This function will reset RX/TX fifo for uart. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @param uint32_t DivLatchValue : (clock << 4)/baudrate. + * + * @return None + */ +void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue); + +/** + * @brief Switch printf channel of uart_tx_one_char. + * Please do not call this function when printf. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @return None + */ +void uart_tx_switch(uint8_t uart_no); + +/** + * @brief Output a char to printf channel, wait until fifo not full. + * + * @param None + * + * @return OK. + */ +ETS_STATUS uart_tx_one_char(uint8_t TxChar); + +/** + * @brief Output a char to message exchange channel, wait until fifo not full. + * Please do not call this function in SDK. + * + * @param None + * + * @return OK. + */ +ETS_STATUS uart_tx_one_char2(uint8_t TxChar); + +/** + * @brief Wait until uart tx full empty. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @return None. + */ +void uart_tx_flush(uint8_t uart_no); + +/** + * @brief Wait until uart tx full empty and the last char send ok. + * + * @param uart_no : 0 for UART0, 1 for UART1 + * + * The function defined in ROM code has a bug, so we define the correct version + * here for compatibility. + */ +void uart_tx_wait_idle(uint8_t uart_no); + +/** + * @brief Get an input char from message channel. + * Please do not call this function in SDK. + * + * @param uint8_t *pRxChar : the pointer to store the char. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS uart_rx_one_char(uint8_t *pRxChar); + +/** + * @brief Get an input char from message channel, wait until successful. + * Please do not call this function in SDK. + * + * @param None + * + * @return char : input char value. + */ +char uart_rx_one_char_block(void); + +/** + * @brief Get an input string line from message channel. + * Please do not call this function in SDK. + * + * @param uint8_t *pString : the pointer to store the string. + * + * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * + * @return OK. + */ +ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); + +/** + * @brief Process uart recevied information in the interrupt handler. + * Please do not call this function in SDK. + * + * @param void *para : the message receive buffer. + * + * @return None + */ +void uart_rx_intr_handler(void *para); + +/** + * @brief Get an char from receive buffer. + * Please do not call this function in SDK. + * + * @param RcvMsgBuff *pRxBuff : the pointer to the struct that include receive buffer. + * + * @param uint8_t *pRxByte : the pointer to store the char. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS uart_rx_readbuff( RcvMsgBuff *pRxBuff, uint8_t *pRxByte); + +/** + * @brief Get all chars from receive buffer. + * Please do not call this function in SDK. + * + * @param uint8_t *pCmdLn : the pointer to store the string. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS UartGetCmdLn(uint8_t *pCmdLn); + +/** + * @brief Get uart configuration struct. + * Please do not call this function in SDK. + * + * @param None + * + * @return UartDevice * : uart configuration struct pointer. + */ +UartDevice *GetUartDevice(void); + +/** + * @brief Send an packet to download tool, with SLIP escaping. + * Please do not call this function in SDK. + * + * @param uint8_t *p : the pointer to output string. + * + * @param int len : the string length. + * + * @return None. + */ +void send_packet(uint8_t *p, int len); + +/** + * @brief Receive an packet from download tool, with SLIP escaping. + * Please do not call this function in SDK. + * + * @param uint8_t *p : the pointer to input string. + * + * @param int len : If string length > len, the string will be truncated. + * + * @param uint8_t is_sync : 0, only one UART module; + * 1, two UART modules. + * + * @return int : the length of the string. + */ +int recv_packet(uint8_t *p, int len, uint8_t is_sync); + +extern UartDevice UartDev; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_UART_H_ */ diff --git a/components/esp_rom/include/esp_rom_sys.h b/components/esp_rom/include/esp_rom_sys.h index 54ef25fe4757..f4beff6dbdb0 100644 --- a/components/esp_rom/include/esp_rom_sys.h +++ b/components/esp_rom/include/esp_rom_sys.h @@ -13,6 +13,9 @@ extern "C" { #endif +void esp_rom_software_reset_system(void); +void esp_rom_software_reset_cpu(int cpu_no); + /** * @brief Print formated string to console device * @note float and long long data are not supported! @@ -74,6 +77,15 @@ void esp_rom_route_intr_matrix(int cpu_core, uint32_t periph_intr_id, uint32_t c */ uint32_t esp_rom_get_cpu_ticks_per_us(void); +/** + * @brief Set the real CPU tick rate + * + * @note Call this function when CPU frequency is changed, otherwise the `esp_rom_delay_us` can be inaccurate. + * + * @param ticks_per_us CPU ticks per us + */ +void esp_rom_set_cpu_ticks_per_us(uint32_t ticks_per_us); + #ifdef __cplusplus } #endif diff --git a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c new file mode 100644 index 000000000000..f89538d21040 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c @@ -0,0 +1,188 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_rom_sys.h" +#include "esp_attr.h" +#include "soc/i2c_ana_mst_reg.h" +#include "modem/modem_lpcon_reg.h" +/** + * BB - 0x67 - BIT0 + * TXRF - 0x6B - BIT1 + * SDM - 0x63 - BIT2 + * PLL - 0x62 - BIT3 + * BIAS - 0x6A - BIT4 + * BBPLL - 0x66 - BIT5 + * ULP - 0x61 - BIT6 + * SAR - 0x69 - BIT7 + * PMU - 0x6d - BIT8 +*/ + +#define REGI2C_BIAS_MST_SEL (BIT(8)) +#define REGI2C_BBPLL_MST_SEL (BIT(9)) +#define REGI2C_ULP_CAL_MST_SEL (BIT(10)) +#define REGI2C_SAR_I2C_MST_SEL (BIT(11)) +#define REGI2C_DIG_REG_MST_SEL (BIT(12)) + +#define REGI2C_BIAS_RD_MASK (~BIT(6) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_BBPLL_RD_MASK (~BIT(7) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_ULP_CAL_RD_MASK (~BIT(8) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_SAR_I2C_RD_MASK (~BIT(9) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_DIG_REG_RD_MASK (~BIT(10) & I2C_ANA_MST_ANA_CONF1_M) + +#define I2C_ANA_MST_I2C_CTRL_REG(n) (I2C_ANA_MST_I2C0_CTRL_REG + n*4) // 0: I2C_ANA_MST_I2C0_CTRL_REG; 1: I2C_ANA_MST_I2C1_CTRL_REG + +#define REGI2C_RTC_BUSY (BIT(25)) +#define REGI2C_RTC_BUSY_M (BIT(25)) +#define REGI2C_RTC_BUSY_V 0x1 +#define REGI2C_RTC_BUSY_S 25 + +#define REGI2C_RTC_WR_CNTL (BIT(24)) +#define REGI2C_RTC_WR_CNTL_M (BIT(24)) +#define REGI2C_RTC_WR_CNTL_V 0x1 +#define REGI2C_RTC_WR_CNTL_S 24 + +#define REGI2C_RTC_DATA 0x000000FF +#define REGI2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) +#define REGI2C_RTC_DATA_V 0xFF +#define REGI2C_RTC_DATA_S 16 + +#define REGI2C_RTC_ADDR 0x000000FF +#define REGI2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) +#define REGI2C_RTC_ADDR_V 0xFF +#define REGI2C_RTC_ADDR_S 8 + +#define REGI2C_RTC_SLAVE_ID 0x000000FF +#define REGI2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) +#define REGI2C_RTC_SLAVE_ID_V 0xFF +#define REGI2C_RTC_SLAVE_ID_S 0 + +/* SLAVE */ + +#define REGI2C_BBPLL (0x66) +#define REGI2C_BBPLL_HOSTID 0 + +#define REGI2C_BIAS (0x6a) +#define REGI2C_BIAS_HOSTID 0 + +#define REGI2C_DIG_REG (0x6d) +#define REGI2C_DIG_REG_HOSTID 0 + +#define REGI2C_ULP_CAL (0x61) +#define REGI2C_ULP_CAL_HOSTID 0 + +#define REGI2C_SAR_I2C (0x69) +#define REGI2C_SAR_I2C_HOSTID 0 + +/* SLAVE END */ + +uint8_t esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) __attribute__((alias("regi2c_read_impl"))); +uint8_t esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) __attribute__((alias("regi2c_read_mask_impl"))); +void esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) __attribute__((alias("regi2c_write_impl"))); +void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) __attribute__((alias("regi2c_write_mask_impl"))); + +static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) +{ + uint32_t i2c_sel = 0; + + REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); + REG_SET_BIT(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); + + /* Before config I2C register, enable corresponding slave. */ + switch (block) { + case REGI2C_BBPLL : + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BBPLL_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK); + break; + case REGI2C_BIAS : + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BIAS_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK); + break; + case REGI2C_DIG_REG: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_DIG_REG_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK); + break; + case REGI2C_ULP_CAL: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK); + break; + case REGI2C_SAR_I2C: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK); + break; + } + + return (uint8_t)(i2c_sel ? 0: 1); +} + +uint8_t IRAM_ATTR regi2c_read_impl(uint8_t block, uint8_t host_id, uint8_t reg_add) +{ + (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint8_t ret = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + + return ret; +} + +uint8_t IRAM_ATTR regi2c_read_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) +{ + assert(msb - lsb < 8); + uint8_t i2c_sel = regi2c_enable_block(block); + + (void)host_id; + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint32_t data = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1)))); + + return ret; +} + +void IRAM_ATTR regi2c_write_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) + | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register; + | (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + +} + +void IRAM_ATTR regi2c_write_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) +{ + (void)host_id; + assert(msb - lsb < 8); + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + /*Read the i2c bus register*/ + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + temp = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + /*Write the i2c bus register*/ + temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1))); + temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp; + temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) + | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) + | ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); +} diff --git a/components/esp_rom/patches/esp_rom_regi2c.c b/components/esp_rom/patches/esp_rom_regi2c.c index 73d7d842f0b3..90827ab287b0 100644 --- a/components/esp_rom/patches/esp_rom_regi2c.c +++ b/components/esp_rom/patches/esp_rom_regi2c.c @@ -6,11 +6,11 @@ #include #include "esp_bit_defs.h" -#include "soc/syscon_reg.h" #include "esp_rom_caps.h" #include "sdkconfig.h" #if CONFIG_IDF_TARGET_ESP32S2 +#include "soc/syscon_reg.h" #define I2C_RTC_WIFI_CLK_EN (SYSCON_WIFI_CLK_EN_REG) diff --git a/components/esp_system/esp_system.c b/components/esp_system/esp_system.c index 0767a874fda5..decd4b755836 100644 --- a/components/esp_system/esp_system.c +++ b/components/esp_system/esp_system.c @@ -11,7 +11,10 @@ #include "freertos/task.h" #include "esp_cpu.h" #include "soc/rtc.h" +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/rtc_cntl_reg.h" +#endif +#include "esp_rom_sys.h" #include "esp_private/panic_internal.h" #include "esp_rom_uart.h" #if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE @@ -42,7 +45,11 @@ void IRAM_ATTR esp_restart_noos_dig(void) esp_cpu_unstall(PRO_CPU_NUM); #endif // reset the digital part +#if CONFIG_IDF_TARGET_ESP32C6 + esp_rom_software_reset_system(); +#else SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); +#endif while (true) { ; } diff --git a/components/esp_system/include/esp_system.h b/components/esp_system/include/esp_system.h index fea13af97dd8..2536d93452db 100644 --- a/components/esp_system/include/esp_system.h +++ b/components/esp_system/include/esp_system.h @@ -33,6 +33,10 @@ typedef enum { ESP_RST_DEEPSLEEP, //!< Reset after exiting deep sleep mode ESP_RST_BROWNOUT, //!< Brownout reset (software or hardware) ESP_RST_SDIO, //!< Reset over SDIO + ESP_RST_USB, //!< Reset by USB peripheral + ESP_RST_JTAG, //!< Reset by JTAG + ESP_RST_EFUSE, //!< Reset due to efuse error + ESP_RST_PWR_GLITCH, //!< Reset due to power glitch } esp_reset_reason_t; /** diff --git a/components/esp_system/ld/esp32c6/memory.ld.in b/components/esp_system/ld/esp32c6/memory.ld.in index e69de29bb2d1..a286d87d31dd 100644 --- a/components/esp_system/ld/esp32c6/memory.ld.in +++ b/components/esp_system/ld/esp32c6/memory.ld.in @@ -0,0 +1,139 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * ESP32-C6 Linker Script Memory Layout + * This file describes the memory layout (memory blocks) by virtual memory addresses. + * This linker script is passed through the C preprocessor to include configuration options. + * Please use preprocessor features sparingly! + * Restrict to simple macros with numeric values, and/or #if/#endif blocks. + */ + +#include "sdkconfig.h" +#include "ld.common" + +/** + * physical memory is mapped twice to the vritual address (IRAM and DRAM). + * `I_D_SRAM_OFFSET` is the offset between the two locations of the same physical memory + */ +#define SRAM_IRAM_START 0x40800000 +#define SRAM_DRAM_START 0x40800000 + +#define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START) +#define SRAM_DRAM_END 0x4086E610 - I_D_SRAM_OFFSET /* 2nd stage bootloader iram_loader_seg start address */ + +#define SRAM_IRAM_ORG (SRAM_IRAM_START) +#define SRAM_DRAM_ORG (SRAM_DRAM_START) + +#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +/* + * IDRAM0_2_SEG_SIZE_DEFAULT is used when page size is 64KB + */ +#define IDRAM0_2_SEG_SIZE (CONFIG_MMU_PAGE_SIZE << 8) +#endif + +#define DRAM0_0_SEG_LEN I_D_SRAM_SIZE + +MEMORY +{ + /** + * All these values assume the flash cache is on, and have the blocks this uses subtracted from the length + * of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but + * are connected to the data port of the CPU and eg allow byte-wise access. + */ + + /* IRAM for PRO CPU. */ + iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /* Flash mapped instruction data */ + irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 + + /** + * (0x20 offset above is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB).) + */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + + /** + * Shared data RAM, excluding memory reserved for ROM bss/data/stack. + * Enabling Bluetooth & Trace Memory features in menuconfig will decrease the amount of RAM available. + */ + dram0_0_seg (RW) : org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /* Flash mapped constant data */ + drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 + + /* (See irom_seg for meaning of 0x20 offset in the above.) */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + + /** + * lp ram memory (RWX). Persists over deep sleep. // TODO: IDF-5667 + */ +#if CONFIG_ULP_COPROC_ENABLED + lp_ram_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM, + len = 0x4000 - CONFIG_ULP_COPROC_RESERVE_MEM - RESERVE_RTC_MEM +#else + lp_ram_seg(RW) : org = 0x50000000, len = 0x4000 - RESERVE_RTC_MEM +#endif // CONFIG_ULP_COPROC_ENABLED + + /* We reduced the size of lp_ram_seg by RESERVE_RTC_MEM value. + It reserves the amount of LP memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ + lp_reserved_seg(RW) : org = 0x50000000 + 0x4000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM +} + +/* Heap ends at top of dram0_0_seg */ +_heap_end = 0x40000000; + +_data_seg_org = ORIGIN(rtc_data_seg); + +/** + * The lines below define location alias for .rtc.data section + * C6 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section + * Thus, the following region segments are not configurable like on other targets + */ +REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); +REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("default_code_seg", irom_seg); +#else + REGION_ALIAS("default_code_seg", iram0_0_seg); +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("default_rodata_seg", drom_seg); +#else + REGION_ALIAS("default_rodata_seg", dram0_0_seg); +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + +/** + * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must + * also be first in the segment. + */ +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), + ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") +#endif + +#if CONFIG_ESP_SYSTEM_USE_EH_FRAME + ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); + ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); +#endif diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in new file mode 100644 index 000000000000..c82c3888c54a --- /dev/null +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -0,0 +1,441 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default entry point */ +ENTRY(call_start_cpu0); + +SECTIONS +{ + /** + * RTC fast memory holds RTC wake stub code, + * including from any source file named rtc_wake_stub*.c + */ + .rtc.text : + { + . = ALIGN(4); + _rtc_fast_start = ABSOLUTE(.); + _rtc_text_start = ABSOLUTE(.); + *(.rtc.entry.text) + + mapping[rtc_text] + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + *(.rtc_text_end_test) + + /* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */ + . += _esp_memprot_prefetch_pad_size; + . = ALIGN(4); + + _rtc_text_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section located in RTC FAST Memory area. + * It holds data marked with RTC_FAST_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + + mapping[rtc_force_fast] + + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4) ; + _rtc_force_fast_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * RTC data section holds RTC wake stub + * data/rodata, including from any source file + * named rtc_wake_stub*.c and the data marked with + * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + + mapping[rtc_data] + + *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) + _rtc_data_end = ABSOLUTE(.); + } > lp_ram_seg + + /* RTC bss, from any source file named rtc_wake_stub*.c */ + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) + *rtc_wake_stub*.*(COMMON) + + mapping[rtc_bss] + + _rtc_bss_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section holds data that should not be initialized at power up + * and will be retained during deep sleep. + * User data marked with RTC_NOINIT_ATTR will be placed + * into this section. See the file "esp_attr.h" for more information. + */ + .rtc_noinit (NOLOAD): + { + . = ALIGN(4); + _rtc_noinit_start = ABSOLUTE(.); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + _rtc_noinit_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section located in RTC SLOW Memory area. + * It holds data marked with RTC_SLOW_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4) ; + _rtc_force_slow_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ + .rtc_reserved (NOLOAD): + { + . = ALIGN(4); + _rtc_reserved_start = ABSOLUTE(.); + /* New data can only be added here to ensure existing data are not moved. + Because data have adhered to the end of the segment and code is relied on it. + >> put new data here << */ + + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _rtc_reserved_end = ABSOLUTE(.); + } > rtc_reserved_seg + + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; + ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), + "RTC reserved segment data does not fit.") + + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_slow_end - _rtc_data_start) + : (_rtc_force_slow_end - _rtc_force_slow_start); + + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_fast_end - _rtc_fast_start) + : (_rtc_noinit_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), + "RTC_SLOW segment data does not fit.") + + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), + "RTC_FAST segment data does not fit.") + + .iram0.text : + { + _iram_start = ABSOLUTE(.); + /* Vectors go to start of IRAM */ + ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); + KEEP(*(.exception_vectors.text)); + . = ALIGN(4); + + _invalid_pc_placeholder = ABSOLUTE(.); + + /* Code marked as running out of IRAM */ + _iram_text_start = ABSOLUTE(.); + + mapping[iram0_text] + + } > iram0_0_seg + + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : + { + /* ESP32-C6 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */ + . += _esp_memprot_prefetch_pad_size; + . = ALIGN(_esp_memprot_align_size); + /* iram_end_test section exists for use by memprot unit tests only */ + *(.iram_end_test) + _iram_text_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.data : + { + . = ALIGN(16); + _iram_data_start = ABSOLUTE(.); + + mapping[iram0_data] + + _iram_data_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + _iram_bss_start = ABSOLUTE(.); + + mapping[iram0_bss] + + _iram_bss_end = ABSOLUTE(.); + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + /** + * This section is required to skip .iram0.text area because iram0_0_seg and + * dram0_0_seg reflect the same address space on different buses. + */ + .dram0.dummy (NOLOAD): + { + . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; + } > dram0_0_seg + + .dram0.data : + { + _data_start = ABSOLUTE(.); + *(.gnu.linkonce.d.*) + *(.data1) + __global_pointer$ = . + 0x800; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + + mapping[dram0_data] + + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } > dram0_0_seg + + /** + * This section holds data that should not be initialized at power up. + * The section located in Internal SRAM memory region. The macro _NOINIT + * can be used as attribute to place data into this section. + * See the "esp_attr.h" file for more information. + */ + .noinit (NOLOAD): + { + . = ALIGN(4); + _noinit_start = ABSOLUTE(.); + *(.noinit .noinit.*) + . = ALIGN(4) ; + _noinit_end = ABSOLUTE(.); + } > dram0_0_seg + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + + mapping[dram0_bss] + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.share.mem) + *(.gnu.linkonce.b.*) + + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } > dram0_0_seg + + ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") + + .flash.text : + { + _stext = .; + _instruction_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.text start, this can be used for mmu driver to maintain virtual address */ + _text_start = ABSOLUTE(.); + + mapping[flash_text] + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + + /** CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += _esp_flash_mmap_prefetch_pad_size; + + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ + _etext = .; + + /** + * Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + _flash_cache_start = ABSOLUTE(0); + } > default_code_seg + + /** + * This dummy section represents the .flash.text section but in default_rodata_seg. + * Thus, it must have its alignment and (at least) its size. + */ + .flash_rodata_dummy (NOLOAD): + { + _flash_rodata_dummy_start = .; + /* Start at the same alignment constraint than .flash.text */ + . = ALIGN(ALIGNOF(.flash.text)); + /* Create an empty gap as big as .flash.text section */ + . = . + SIZEOF(.flash.text); + /* Prepare the alignment of the section above. Few bytes (0x20) must be + * added for the mapping header. */ + . = ALIGN(_esp_mmu_block_size) + 0x20; + } > default_rodata_seg + + .flash.appdesc : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ + + /* Create an empty gap within this section. Thanks to this, the end of this + * section will match .flash.rodata's begin address. Thus, both sections + * will be merged when creating the final bin image. */ + . = ALIGN(ALIGNOF(.flash.rodata)); + } >default_rodata_seg + + .flash.rodata : ALIGN(0x10) + { + _flash_rodata_start = ABSOLUTE(.); + + mapping[flash_rodata] + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 7) & ~ 3; + /* + * C++ constructor and destructor tables + * Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt. + * + * RISC-V gcc is configured with --enable-initfini-array so it emits an .init_array section instead. + * But the init_priority sections will be sorted for iteration in ascending order during startup. + * The rest of the init_array sections is sorted for iteration in descending order during startup, however. + * Hence a different section is generated for the init_priority functions which is iterated in + * ascending order during startup. The corresponding code can be found in startup.c. + */ + __init_priority_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) + __init_priority_array_end = ABSOLUTE(.); + __init_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) + __init_array_end = ABSOLUTE(.); + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ + soc_reserved_memory_region_start = ABSOLUTE(.); + KEEP (*(.reserved_memory_address)) + soc_reserved_memory_region_end = ABSOLUTE(.); + /* System init functions registered via ESP_SYSTEM_INIT_FN */ + _esp_system_init_fn_array_start = ABSOLUTE(.); + KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) + _esp_system_init_fn_array_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + _thread_local_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(.eh_frame)); + } > default_rodata_seg + + /* Keep this section shall be at least aligned on 4 */ + .eh_frame : ALIGN(8) + { + __eh_frame = ABSOLUTE(.); + KEEP (*(.eh_frame)) + __eh_frame_end = ABSOLUTE(.); + /* Guarantee that this section and the next one will be merged by making + * them adjacent. */ + . = ALIGN(ALIGNOF(.eh_frame_hdr)); + } > default_rodata_seg + + /* To avoid any exception in C++ exception frame unwinding code, this section + * shall be aligned on 8. */ + .eh_frame_hdr : ALIGN(8) + { + __eh_frame_hdr = ABSOLUTE(.); + KEEP (*(.eh_frame_hdr)) + __eh_frame_hdr_end = ABSOLUTE(.); + } > default_rodata_seg + + /* + This section is a place where we dump all the rodata which aren't used at runtime, + so as to avoid binary size increase + */ + .flash.rodata_noload (NOLOAD) : + { + /* + This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address + We don't need to include the noload rodata in this section + */ + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN (4); + mapping[rodata_noload] + } > default_rodata_seg + + /* Marks the end of data, bss and possibly rodata */ + .dram0.heap_start (NOLOAD) : + { + . = ALIGN (16); + _heap_start = ABSOLUTE(.); + } > dram0_0_seg +} + +ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + +ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index 26607f92630f..867adc6f0ae5 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -23,4 +23,29 @@ _esp_memprot_align_size = CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE; _esp_memprot_align_size = 0; #endif +#if CONFIG_APP_BUILD_TYPE_RAM +_esp_mmu_block_size = 0; +#else _esp_mmu_block_size = (CONFIG_MMU_PAGE_SIZE); +#endif + +#if CONFIG_SOC_RTC_MEM_SUPPORTED + #if CONFIG_BOOTLOADER_RESERVE_RTC_MEM + #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC + #define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE) + #else + #define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE) + #endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC + #else + #define ESP_BOOTLOADER_RESERVE_RTC 0 + #endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM + + /* rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). For rtc_timer_data_in_rtc_mem section. */ + #define RTC_TIMER_RESERVE_RTC (24) + + #if CONFIG_IDF_TARGET_ESP32 + #define RESERVE_RTC_MEM (RTC_TIMER_RESERVE_RTC) + #else + #define RESERVE_RTC_MEM (ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC) + #endif +#endif // SOC_RTC_MEM_SUPPORTED diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index d060f48bfb71..63bc632fa2f3 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -61,7 +61,11 @@ bool g_panic_abort = false; static char *s_panic_abort_details = NULL; +#if CONFIG_IDF_TARGET_ESP32C6 +static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif #if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c index 3afa68ae6e9d..c14fc0f7a49c 100644 --- a/components/esp_system/port/arch/riscv/panic_arch.c +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -74,6 +74,13 @@ static inline bool test_and_print_register_bits(const uint32_t status, * Function called when a cache error occurs. It prints details such as the * explanation of why the panic occured. */ +#if CONFIG_IDF_TARGET_ESP32C6 +static inline void print_cache_err_details(const void *frame) +{ + (void) frame; + panic_print_str("Cache error\r\n"); +} +#else static inline void print_cache_err_details(const void *frame) { /* Define the array that contains the status (bits) to test on the register @@ -149,6 +156,7 @@ static inline void print_cache_err_details(const void *frame) } } } +#endif /** diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index abd5dc8f599c..f1f0f22bdc96 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -47,6 +47,9 @@ #include "esp32c3/rom/cache.h" #include "esp32c3/rom/secure_boot.h" #include "esp_memprot.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" +#include "esp32c6/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rtc.h" #include "esp32h2/rom/cache.h" diff --git a/components/esp_system/port/soc/esp32c6/CMakeLists.txt b/components/esp_system/port/soc/esp32c6/CMakeLists.txt index e69de29bb2d1..d77109f3b504 100644 --- a/components/esp_system/port/soc/esp32c6/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32c6/CMakeLists.txt @@ -0,0 +1,12 @@ +set(srcs "clk.c" + "reset_reason.c" + "system_internal.c" + "cache_err_int.c" + "../../arch/riscv/expression_with_stack.c" + "../../arch/riscv/expression_with_stack_asm.S" + "../../arch/riscv/panic_arch.c" + "../../arch/riscv/debug_stubs.c") + +add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) + +target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) diff --git a/components/esp_system/port/soc/esp32c6/Kconfig.cpu b/components/esp_system/port/soc/esp32c6/Kconfig.cpu index e69de29bb2d1..2b5a7e45b803 100644 --- a/components/esp_system/port/soc/esp32c6/Kconfig.cpu +++ b/components/esp_system/port/soc/esp32c6/Kconfig.cpu @@ -0,0 +1,24 @@ +choice ESP_DEFAULT_CPU_FREQ_MHZ + prompt "CPU frequency" + default ESP_DEFAULT_CPU_FREQ_MHZ_40 if IDF_ENV_FPGA + default ESP_DEFAULT_CPU_FREQ_MHZ_160 + help + CPU frequency to be set on application startup. + + config ESP_DEFAULT_CPU_FREQ_MHZ_40 + bool "40 MHz" + depends on IDF_ENV_FPGA + config ESP_DEFAULT_CPU_FREQ_MHZ_80 + bool "80 MHz" + config ESP_DEFAULT_CPU_FREQ_MHZ_120 + bool "120 MHz" + config ESP_DEFAULT_CPU_FREQ_MHZ_160 + bool "160 MHz" +endchoice + +config ESP_DEFAULT_CPU_FREQ_MHZ + int + default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40 + default 80 if ESP_DEFAULT_CPU_FREQ_MHZ_80 + default 120 if ESP_DEFAULT_CPU_FREQ_MHZ_120 + default 160 if ESP_DEFAULT_CPU_FREQ_MHZ_160 diff --git a/components/esp_system/port/soc/esp32c6/Kconfig.system b/components/esp_system/port/soc/esp32c6/Kconfig.system index e69de29bb2d1..1427bb2521ba 100644 --- a/components/esp_system/port/soc/esp32c6/Kconfig.system +++ b/components/esp_system/port/soc/esp32c6/Kconfig.system @@ -0,0 +1,45 @@ +menu "Brownout Detector" + config ESP_BROWNOUT_DET + bool "Hardware brownout detect & reset" + depends on !IDF_ENV_FPGA + default y + help + The ESP32-C6 has a built-in brownout detector which can detect if the voltage is lower than + a specific value. If this happens, it will reset the chip in order to prevent unintended + behaviour. + + choice ESP_BROWNOUT_DET_LVL_SEL + prompt "Brownout voltage level" + depends on ESP_BROWNOUT_DET + default ESP_BROWNOUT_DET_LVL_SEL_7 + help + The brownout detector will reset the chip when the supply voltage is approximately + below this level. Note that there may be some variation of brownout voltage level + between each chip. + + #The voltage levels here are estimates, more work needs to be done to figure out the exact voltages + #of the brownout threshold levels. + config ESP_BROWNOUT_DET_LVL_SEL_7 + bool "2.51V" + config ESP_BROWNOUT_DET_LVL_SEL_6 + bool "2.64V" + config ESP_BROWNOUT_DET_LVL_SEL_5 + bool "2.76V" + config ESP_BROWNOUT_DET_LVL_SEL_4 + bool "2.92V" + config ESP_BROWNOUT_DET_LVL_SEL_3 + bool "3.10V" + config ESP_BROWNOUT_DET_LVL_SEL_2 + bool "3.27V" + endchoice + + config ESP_BROWNOUT_DET_LVL + int + default 2 if ESP_BROWNOUT_DET_LVL_SEL_2 + default 3 if ESP_BROWNOUT_DET_LVL_SEL_3 + default 4 if ESP_BROWNOUT_DET_LVL_SEL_4 + default 5 if ESP_BROWNOUT_DET_LVL_SEL_5 + default 6 if ESP_BROWNOUT_DET_LVL_SEL_6 + default 7 if ESP_BROWNOUT_DET_LVL_SEL_7 + +endmenu diff --git a/components/esp_system/port/soc/esp32c6/cache_err_int.c b/components/esp_system/port/soc/esp32c6/cache_err_int.c new file mode 100644 index 000000000000..82cf3895e457 --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/cache_err_int.c @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + The cache has an interrupt that can be raised as soon as an access to a cached + region (flash) is done without the cache being enabled. We use that here + to panic the CPU, which from a debugging perspective is better than grabbing bad + data from the bus. +*/ +#include "esp_rom_sys.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_intr_alloc.h" +#include "soc/periph_defs.h" +#include "riscv/interrupt.h" +#include "hal/cache_ll.h" + +static const char *TAG = "CACHE_ERR"; + +void esp_cache_err_int_init(void) +{ + const uint32_t core_id = 0; + + /* Disable cache interrupts if enabled. */ + ESP_INTR_DISABLE(ETS_CACHEERR_INUM); + + /** + * Bind all cache errors to ETS_CACHEERR_INUM interrupt. we will deal with + * them in handler by different types + * + * On ESP32C6 boards, the cache is a shared one but buses are still + * distinct. So, we have an bus0 and a bus1 sharing the same cache. + * This error can occur if a bus performs a request but the cache + * is disabled. + */ + esp_rom_route_intr_matrix(core_id, ETS_CACHE_INTR_SOURCE, ETS_CACHEERR_INUM); + + /* Set the type and priority to cache error interrupts. */ + esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); + esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + + ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); + /* On the hardware side, start by clearing all the bits reponsible for cache access error */ + cache_ll_l1_clear_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + /* Then enable cache access error interrupts. */ + cache_ll_l1_enable_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + + /* Enable the interrupts for cache error. */ + ESP_INTR_ENABLE(ETS_CACHEERR_INUM); +} + +int esp_cache_err_get_cpuid(void) +{ + return 0; +} diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c new file mode 100644 index 000000000000..92487e6637af --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -0,0 +1,304 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_clk_internal.h" +#include "esp32c6/rom/ets_sys.h" +#include "esp32c6/rom/uart.h" +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/rtc_periph.h" +#include "soc/i2s_reg.h" +#include "esp_cpu.h" +#include "hal/wdt_hal.h" +#include "esp_private/esp_modem_clock.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" +#include "esp_private/esp_pmu.h" +#include "esp_rom_uart.h" +#include "esp_rom_sys.h" +#include "ocode_init.h" + +/* Number of cycles to wait from the 32k XTAL oscillator to consider it running. + * Larger values increase startup delay. Smaller values may cause false positive + * detection (i.e. oscillator runs for a few cycles and then stops). + */ +#define SLOW_CLK_CAL_CYCLES CONFIG_RTC_CLK_CAL_CYCLES + +#define MHZ (1000000) + +static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); + +static const char *TAG = "clk"; + + + __attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA + pmu_init(); + if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { + esp_ocode_calib_init(); + } + + assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); + + rtc_clk_8m_enable(true); + rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); +#endif + +#ifdef CONFIG_BOOTLOADER_WDT_ENABLE + // WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed. + // If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times. + // Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec). + // This prevents excessive delay before resetting in case the supply voltage is drawdown. + // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec). + wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT(); + uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_feed(&rtc_wdt_ctx); + //Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); +#endif + +#if defined(CONFIG_RTC_CLK_SRC_EXT_CRYS) + select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K); +#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC) + select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW); +#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K) + select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K); +#else + select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW); +#endif + +#ifdef CONFIG_BOOTLOADER_WDT_ENABLE + // After changing a frequency WDT timeout needs to be set for new frequency. + stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_feed(&rtc_wdt_ctx); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); +#endif + + rtc_cpu_freq_config_t old_config, new_config; + rtc_clk_cpu_freq_get_config(&old_config); + const uint32_t old_freq_mhz = old_config.freq_mhz; + const uint32_t new_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; + + bool res = rtc_clk_cpu_freq_mhz_to_config(new_freq_mhz, &new_config); + assert(res); + + // Wait for UART TX to finish, otherwise some UART output will be lost + // when switching APB frequency + esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); + + if (res) { + rtc_clk_cpu_freq_set_config(&new_config); + } + + // Re calculate the ccount to make time calculation correct. + esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz ); +} + +static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src) +{ + uint32_t cal_val = 0; + /* number of times to repeat 32k XTAL calibration + * before giving up and switching to the internal RC + */ + int retry_32k_xtal = 3; + + do { + if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K || rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + /* 32k XTAL oscillator needs to be enabled and running before it can + * be used. Hardware doesn't have a direct way of checking if the + * oscillator is running. Here we use rtc_clk_cal function to count + * the number of main XTAL cycles in the given number of 32k XTAL + * oscillator cycles. If the 32k XTAL has not started up, calibration + * will time out, returning 0. + */ + ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up"); + rtc_cal_sel_t cal_sel = 0; + if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + rtc_clk_32k_enable(true); + cal_sel = RTC_CAL_32K_XTAL; + } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + rtc_clk_32k_enable_external(); + cal_sel = RTC_CAL_32K_OSC_SLOW; + } + // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup. + if (SLOW_CLK_CAL_CYCLES > 0) { + cal_val = rtc_clk_cal(cal_sel, SLOW_CLK_CAL_CYCLES); + if (cal_val == 0) { + if (retry_32k_xtal-- > 0) { + continue; + } + ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator"); + rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW; + } + } + } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + rtc_clk_rc32k_enable(true); + } + rtc_clk_slow_src_set(rtc_slow_clk_src); + + if (SLOW_CLK_CAL_CYCLES > 0) { + /* TODO: 32k XTAL oscillator has some frequency drift at startup. + * Improve calibration routine to wait until the frequency is stable. + */ + cal_val = rtc_clk_cal(RTC_CAL_RTC_MUX, SLOW_CLK_CAL_CYCLES); + } else { + const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL; + cal_val = (uint32_t) (cal_dividend / rtc_clk_slow_freq_get_hz()); + } + } while (cal_val == 0); + ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val); + esp_clk_slowclk_cal_set(cal_val); +} + +void rtc_clk_select_rtc_slow_clk(void) +{ + select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K); +} + +/* This function is not exposed as an API at this point. + * All peripheral clocks are default enabled after chip is powered on. + * This function disables some peripheral clocks when cpu starts. + * These peripheral clocks are enabled when the peripherals are initialized + * and disabled when they are de-initialized. + */ +__attribute__((weak)) void esp_perip_clk_init(void) +{ + /* 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 + soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get(); + modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t) ( \ + (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW \ + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? MODEM_CLOCK_LPCLK_SRC_XTAL32K \ + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) ? MODEM_CLOCK_LPCLK_SRC_RC32K \ + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K \ + : SOC_RTC_SLOW_CLK_SRC_RC_SLOW); + modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); + + ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); +#if 0 // TODO: IDF-5658 + uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; + uint32_t common_perip_clk1 = 0; + + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); + + /* For reason that only reset CPU, do not disable the clocks + * that have been enabled before reset. + */ + if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || + rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { + common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); + hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); + wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); + } else { + common_perip_clk = SYSTEM_WDG_CLK_EN | + SYSTEM_I2S0_CLK_EN | +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 + SYSTEM_UART_CLK_EN | +#endif +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 + SYSTEM_UART1_CLK_EN | +#endif + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_LEDC_CLK_EN | + SYSTEM_TIMERGROUP1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_TWAI_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN; + + common_perip_clk1 = 0; + hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | + SYSTEM_CRYPTO_SHA_CLK_EN | + SYSTEM_CRYPTO_RSA_CLK_EN; + wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | + SYSTEM_WIFI_CLK_BT_EN_M | + SYSTEM_WIFI_CLK_UNUSED_BIT5 | + SYSTEM_WIFI_CLK_UNUSED_BIT12; + } + + //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. + common_perip_clk |= SYSTEM_I2S0_CLK_EN | +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 + SYSTEM_UART_CLK_EN | +#endif +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 + SYSTEM_UART1_CLK_EN | +#endif + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_UHCI1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_I2C_EXT1_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN; + common_perip_clk1 = 0; + + /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, + * the current is not reduced when disable I2S clock. + */ + // TOCK(check replacement) + // REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); + // REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); + + /* Disable some peripheral clocks. */ + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); + + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1); + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1); + + /* Disable hardware crypto clocks. */ + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk); + + /* Disable WiFi/BT/SDIO clocks. */ + CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); + SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); + + /* Set WiFi light sleep clock source to RTC slow clock */ + REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); + SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); + + /* Enable RNG clock. */ + periph_module_enable(PERIPH_RNG_MODULE); +#endif + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); +} diff --git a/components/esp_system/port/soc/esp32c6/reset_reason.c b/components/esp_system/port/soc/esp32c6/reset_reason.c new file mode 100644 index 000000000000..93c6812d16f7 --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/reset_reason.c @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_system.h" +#include "esp_rom_sys.h" +#include "esp_private/system_internal.h" +#include "soc/rtc_periph.h" +#include "esp32c6/rom/rtc.h" + +static void esp_reset_reason_clear_hint(void); + +static esp_reset_reason_t s_reset_reason; + +static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, esp_reset_reason_t reset_reason_hint) +{ + switch (rtc_reset_reason) { + case RESET_REASON_CHIP_POWER_ON: + return ESP_RST_POWERON; + + case RESET_REASON_CPU0_SW: + case RESET_REASON_CORE_SW: + if (reset_reason_hint == ESP_RST_PANIC || + reset_reason_hint == ESP_RST_BROWNOUT || + reset_reason_hint == ESP_RST_TASK_WDT || + reset_reason_hint == ESP_RST_INT_WDT) { + return reset_reason_hint; + } + return ESP_RST_SW; + + case RESET_REASON_CORE_DEEP_SLEEP: + return ESP_RST_DEEPSLEEP; + + case RESET_REASON_CORE_MWDT0: + return ESP_RST_TASK_WDT; + + case RESET_REASON_CORE_MWDT1: + return ESP_RST_INT_WDT; + + case RESET_REASON_CORE_RTC_WDT: + case RESET_REASON_SYS_RTC_WDT: + case RESET_REASON_SYS_SUPER_WDT: + case RESET_REASON_CPU0_RTC_WDT: + case RESET_REASON_CPU0_MWDT0: + case RESET_REASON_CPU0_MWDT1: + return ESP_RST_WDT; + + case RESET_REASON_SYS_BROWN_OUT: + return ESP_RST_BROWNOUT; + + case RESET_REASON_CORE_USB_UART: + case RESET_REASON_CORE_USB_JTAG: + return ESP_RST_USB; + + case RESET_REASON_CORE_EFUSE_CRC: + return ESP_RST_EFUSE; + + case RESET_REASON_CPU0_JTAG: + return ESP_RST_JTAG; + + case RESET_REASON_CORE_SDIO: + return ESP_RST_SDIO; + + default: + return ESP_RST_UNKNOWN; + } +} + +static void __attribute__((constructor)) esp_reset_reason_init(void) +{ + esp_reset_reason_t hint = esp_reset_reason_get_hint(); + s_reset_reason = get_reset_reason(esp_rom_get_reset_reason(PRO_CPU_NUM), hint); + if (hint != ESP_RST_UNKNOWN) { + esp_reset_reason_clear_hint(); + } +} + +esp_reset_reason_t esp_reset_reason(void) +{ + return s_reset_reason; +} + +/* Reset reason hint is stored in RTC_RESET_CAUSE_REG, a.k.a. RTC_CNTL_STORE6_REG, + * a.k.a. RTC_ENTRY_ADDR_REG. It is safe to use this register both for the + * deep sleep wake stub entry address and for reset reason hint, since wake stub + * is only used for deep sleep reset, and in this case the reason provided by + * esp_rom_get_reset_reason is unambiguous. + * + * Same layout is used as for RTC_APB_FREQ_REG (a.k.a. RTC_CNTL_STORE5_REG): + * the value is replicated in low and high half-words. In addition to that, + * MSB is set to 1, which doesn't happen when RTC_CNTL_STORE6_REG contains + * deep sleep wake stub address. + */ + +#define RST_REASON_BIT 0x80000000 +#define RST_REASON_MASK 0x7FFF +#define RST_REASON_SHIFT 16 + +/* in IRAM, can be called from panic handler */ +void IRAM_ATTR esp_reset_reason_set_hint(esp_reset_reason_t hint) +{ + assert((hint & (~RST_REASON_MASK)) == 0); + uint32_t val = hint | (hint << RST_REASON_SHIFT) | RST_REASON_BIT; + REG_WRITE(RTC_RESET_CAUSE_REG, val); +} + +/* in IRAM, can be called from panic handler */ +esp_reset_reason_t esp_reset_reason_get_hint(void) +{ + uint32_t reset_reason_hint = REG_READ(RTC_RESET_CAUSE_REG); + uint32_t high = (reset_reason_hint >> RST_REASON_SHIFT) & RST_REASON_MASK; + uint32_t low = reset_reason_hint & RST_REASON_MASK; + if ((reset_reason_hint & RST_REASON_BIT) == 0 || high != low) { + return ESP_RST_UNKNOWN; + } + return (esp_reset_reason_t) low; +} +static inline void esp_reset_reason_clear_hint(void) +{ + REG_WRITE(RTC_RESET_CAUSE_REG, 0); +} diff --git a/components/esp_system/port/soc/esp32c6/system_internal.c b/components/esp_system/port/soc/esp32c6/system_internal.c new file mode 100644 index 000000000000..75e43bf2d189 --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/system_internal.c @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_system.h" +#include "esp_private/system_internal.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_rom_sys.h" +#include "riscv/rv_utils.h" +#include "esp_rom_uart.h" +#include "soc/gpio_reg.h" +#include "esp_cpu.h" +#include "soc/rtc.h" +#include "esp_private/rtc_clk.h" +#include "soc/rtc_periph.h" +#include "soc/uart_reg.h" +#include "hal/wdt_hal.h" +#include "hal/modem_syscon_ll.h" +#include "hal/modem_lpcon_ll.h" +#include "esp_private/cache_err_int.h" + +#include "esp32c6/rom/cache.h" +#include "esp32c6/rom/rtc.h" +#include "soc/pcr_reg.h" + +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + + modem_syscon_ll_reset_all(&MODEM_SYSCON); + modem_lpcon_ll_reset_all(&MODEM_LPCON); + + // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); + SET_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + + // Clear Peripheral clk rst + CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + CLEAR_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); +} + +/* "inner" restart function for after RTOS, interrupts & anything else on this + * core are already stopped. Stalls other core, resets hardware, + * triggers restart. +*/ +void IRAM_ATTR esp_restart_noos(void) +{ + // Disable interrupts + rv_utils_intr_global_disable(); + // Enable RTC watchdog for 1 second + wdt_hal_context_t rtc_wdt_ctx; + wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); + uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + //Enable flash boot mode so that flash booting after restart is protected by the RTC WDT. + wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); + + // C6 is a single core SoC, no need to reset and stall the other CPU + + // Disable TG0/TG1 watchdogs + wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + wdt_hal_write_protect_disable(&wdt0_context); + wdt_hal_disable(&wdt0_context); + wdt_hal_write_protect_enable(&wdt0_context); + + wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1}; + wdt_hal_write_protect_disable(&wdt1_context); + wdt_hal_disable(&wdt1_context); + wdt_hal_write_protect_enable(&wdt1_context); + + // Disable cache + Cache_Disable_ICache(); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + // Moved to module internal + // SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, + // SYSTEM_SDIO_RST | // SDIO_HINF_HINF_SDIO_RST? + // SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | // TODO: IDF-5325 (ethernet) + // REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); + + esp_system_reset_modules_on_exit(); + + // Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader. +#if !CONFIG_IDF_ENV_FPGA + rtc_clk_cpu_set_to_default_config(); +#endif + + // Reset PRO CPU + esp_rom_software_reset_cpu(0); + while (true) { + ; + } +} diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index b1752d91a030..b32edc388007 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -12,6 +12,7 @@ #include "esp_system.h" #include "esp_log.h" +#include "esp_rom_sys.h" #include "sdkconfig.h" @@ -66,7 +67,6 @@ #include "esp_private/brownout.h" #include "esp_rom_caps.h" -#include "esp_rom_sys.h" #if CONFIG_SPIRAM #include "esp_psram.h" @@ -468,7 +468,11 @@ static void start_cpu0_default(void) // Now that the application is about to start, disable boot watchdog #ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE +#if CONFIG_IDF_TARGET_ESP32C6 + wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT(); +#else wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_disable(&rtc_wdt_ctx); wdt_hal_write_protect_enable(&rtc_wdt_ctx); diff --git a/components/esp_system/system_time.c b/components/esp_system/system_time.c index 075f54dfa823..f48e2d147f70 100644 --- a/components/esp_system/system_time.c +++ b/components/esp_system/system_time.c @@ -21,6 +21,8 @@ #include "esp32s3/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C2 diff --git a/components/esp_timer/src/ets_timer_legacy.c b/components/esp_timer/src/ets_timer_legacy.c index 841f8d04f141..d03aa7cbcdbc 100644 --- a/components/esp_timer/src/ets_timer_legacy.c +++ b/components/esp_timer/src/ets_timer_legacy.c @@ -34,6 +34,8 @@ #include "esp32c2/rom/ets_sys.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/ets_sys.h" #endif /* We abuse 'timer_arg' field of ETSTimer structure to hold a pointer to esp_timer */ diff --git a/components/esp_timer/src/system_time.c b/components/esp_timer/src/system_time.c index 6387422c8615..4f7f3e46d0ca 100644 --- a/components/esp_timer/src/system_time.c +++ b/components/esp_timer/src/system_time.c @@ -25,6 +25,8 @@ #include "esp32s3/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C2 diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index 48d374ff8cfc..f0fb9cd5ee88 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.c @@ -24,6 +24,8 @@ #include "esp32c2/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/cache.h" #endif /*------------------------------------------------------------------------------ diff --git a/components/hal/efuse_hal.c b/components/hal/efuse_hal.c index ae584110f7fc..bf407bb801be 100644 --- a/components/hal/efuse_hal.c +++ b/components/hal/efuse_hal.c @@ -22,3 +22,10 @@ uint32_t efuse_hal_chip_revision(void) { return efuse_hal_get_major_chip_version() * 100 + efuse_hal_get_minor_chip_version(); } + +#if CONFIG_IDF_TARGET_ESP32C6 +uint32_t efuse_hal_blk_version(void) +{ + return efuse_ll_get_blk_version_major() * 100 + efuse_ll_get_blk_version_minor(); +} +#endif diff --git a/components/hal/esp32c6/brownout_hal.c b/components/hal/esp32c6/brownout_hal.c new file mode 100644 index 000000000000..b931b0ac5258 --- /dev/null +++ b/components/hal/esp32c6/brownout_hal.c @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/brownout_ll.h" +#include "hal/brownout_hal.h" + +void brownout_hal_config(const brownout_hal_config_t *cfg) +{ + brownout_ll_ana_reset_enable(false); + brownout_ll_set_intr_wait_cycles(2); + brownout_ll_enable_flash_power_down(cfg->flash_power_down); + brownout_ll_enable_rf_power_down(cfg->rf_power_down); + brownout_ll_clear_count(); + brownout_ll_reset_config(cfg->reset_enabled, 0x3ff, 1); + brownout_ll_set_threshold(cfg->threshold); + brownout_ll_bod_enable(cfg->enabled); +} diff --git a/components/hal/esp32c6/clk_tree_hal.c b/components/hal/esp32c6/clk_tree_hal.c new file mode 100644 index 000000000000..ca6ccd1e20a1 --- /dev/null +++ b/components/hal/esp32c6/clk_tree_hal.c @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/clk_tree_hal.h" +#include "hal/clk_tree_ll.h" +#include "soc/rtc.h" +#include "hal/assert.h" +#include "hal/log.h" + +static const char *CLK_HAL_TAG = "clk_hal"; + +uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) +{ + switch (cpu_clk_src) { + case SOC_CPU_CLK_SRC_XTAL: + return clk_hal_xtal_get_freq_mhz(); + case SOC_CPU_CLK_SRC_PLL: + return clk_ll_bbpll_get_freq_mhz(); + case SOC_CPU_CLK_SRC_RC_FAST: + return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ; + default: + // Unknown CPU_CLK mux input + HAL_ASSERT(false); + return 0; + } +} + +uint32_t clk_hal_cpu_get_freq_hz(void) +{ + soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); + uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_cpu_get_hs_divider() : clk_ll_cpu_get_ls_divider(); + return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; +} + +uint32_t clk_hal_ahb_get_freq_hz(void) +{ + soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); + uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider(); + return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; +} + +uint32_t clk_hal_apb_get_freq_hz(void) +{ + return clk_hal_ahb_get_freq_hz() / clk_ll_apb_get_divider(); +} + +uint32_t clk_hal_lp_slow_get_freq_hz(void) +{ + switch (clk_ll_rtc_slow_get_src()) { + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: + return SOC_CLK_RC_SLOW_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_XTAL32K: + return SOC_CLK_XTAL32K_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: + return SOC_CLK_OSC_SLOW_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_RC32K: + return SOC_CLK_RC32K_FREQ_APPROX; + default: + // Unknown RTC_SLOW_CLK mux input + HAL_ASSERT(false); + return 0; + } +} + +uint32_t clk_hal_xtal_get_freq_mhz(void) +{ + uint32_t freq = clk_ll_xtal_load_freq_mhz(); + if (freq == 0) { + HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz"); + return (uint32_t)RTC_XTAL_FREQ_40M; + } + return freq; +} diff --git a/components/hal/esp32c6/efuse_hal.c b/components/hal/esp32c6/efuse_hal.c index e69de29bb2d1..697f581e5faf 100644 --- a/components/hal/esp32c6/efuse_hal.c +++ b/components/hal/esp32c6/efuse_hal.c @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "soc/soc_caps.h" +#include "hal/assert.h" +#include "hal/efuse_hal.h" +#include "hal/efuse_ll.h" + +#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x08 << (4 * (block)))) +#define ESP_EFUSE_BLOCK_ERROR_NUM_BITS(error_reg, block) ((error_reg) & (0x07 << (4 * (block)))) + +uint32_t efuse_hal_get_major_chip_version(void) +{ +#ifdef CONFIG_ESP_REV_NEW_CHIP_TEST + return CONFIG_ESP_REV_MIN_FULL / 100; +#else + return efuse_ll_get_chip_wafer_version_major(); +#endif +} + +uint32_t efuse_hal_get_minor_chip_version(void) +{ +#ifdef CONFIG_ESP_REV_NEW_CHIP_TEST + return CONFIG_ESP_REV_MIN_FULL % 100; +#else + return efuse_ll_get_chip_wafer_version_minor(); +#endif +} + +/******************* eFuse control functions *************************/ + +void efuse_hal_set_timing(uint32_t apb_freq_hz) +{ + (void) apb_freq_hz; + efuse_ll_set_dac_num(0xFF); + efuse_ll_set_dac_clk_div(0x28); + efuse_ll_set_pwr_on_num(0x3000); + efuse_ll_set_pwr_off_num(0x190); +} + +void efuse_hal_read(void) +{ + efuse_hal_set_timing(0); + + efuse_ll_set_conf_read_op_code(); + efuse_ll_set_read_cmd(); + + while (efuse_ll_get_read_cmd() != 0) { } + /*Due to a hardware error, we have to read READ_CMD again to make sure the efuse clock is normal*/ + while (efuse_ll_get_read_cmd() != 0) { } +} + +void efuse_hal_clear_program_registers(void) +{ + ets_efuse_clear_program_registers(); +} + +void efuse_hal_program(uint32_t block) +{ + efuse_hal_set_timing(0); + + efuse_ll_set_conf_write_op_code(); + efuse_ll_set_pgm_cmd(block); + + while (efuse_ll_get_pgm_cmd() != 0) { } + + efuse_hal_clear_program_registers(); + efuse_hal_read(); +} + +void efuse_hal_rs_calculate(const void *data, void *rs_values) +{ + ets_efuse_rs_calculate(data, rs_values); +} + +/******************* eFuse control functions *************************/ + +bool efuse_hal_is_coding_error_in_block(unsigned block) +{ + if (block == 0) { + for (unsigned i = 0; i < 5; i++) { + if (REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4)) { + return true; + } + } + } else if (block <= 10) { + // EFUSE_RD_RS_ERR0_REG: (hi) BLOCK8, BLOCK7, BLOCK6, BLOCK5, BLOCK4, BLOCK3, BLOCK2, BLOCK1 (low) + // EFUSE_RD_RS_ERR1_REG: BLOCK10, BLOCK9 + block--; + uint32_t error_reg = REG_READ(EFUSE_RD_RS_ERR0_REG + (block / 8) * 4); + return ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block % 8) != 0; + } + return false; +} diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h new file mode 100644 index 000000000000..afb3934dd1e0 --- /dev/null +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -0,0 +1,772 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_attr.h" + +#include "soc/adc_periph.h" +#include "soc/apb_saradc_struct.h" +#include "soc/apb_saradc_reg.h" +#include "soc/pmu_reg.h" +#include "soc/clk_tree_defs.h" +#include "soc/pcr_struct.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/adc_types.h" +#include "hal/adc_types_private.h" +#include "hal/regi2c_ctrl.h" +#include "hal/sar_ctrl_ll.h" + +#include "soc/regi2c_saradc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) +#define ADC_LL_EVENT_THRES0_HIGH BIT(29) +#define ADC_LL_EVENT_THRES1_HIGH BIT(28) +#define ADC_LL_EVENT_THRES0_LOW BIT(27) +#define ADC_LL_EVENT_THRES1_LOW BIT(26) + +/*--------------------------------------------------------------- + Oneshot +---------------------------------------------------------------*/ +#define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) + +/*--------------------------------------------------------------- + DMA +---------------------------------------------------------------*/ +#define ADC_LL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_FSM_RSTB_WAIT_DEFAULT (8) +#define ADC_LL_FSM_START_WAIT_DEFAULT (5) +#define ADC_LL_FSM_STANDBY_WAIT_DEFAULT (100) +#define ADC_LL_SAMPLE_CYCLE_DEFAULT (2) +#define ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT (1) + +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 + +/*--------------------------------------------------------------- + PWDET (Power Detect) +---------------------------------------------------------------*/ +#define ADC_LL_PWDET_CCT_DEFAULT (4) + +typedef enum { + ADC_LL_POWER_BY_FSM = SAR_CTRL_LL_POWER_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_LL_POWER_SW_ON = SAR_CTRL_LL_POWER_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_LL_POWER_SW_OFF = SAR_CTRL_LL_POWER_OFF, /*!< ADC XPD controlled by SW. power off. */ +} adc_ll_power_t; + +typedef enum { + ADC_LL_CTRL_DIG = 0, ///< ADC digital controller +} adc_ll_controller_t; + +/** + * @brief ADC digital controller (DMA mode) work mode. + * + * @note The conversion mode affects the sampling frequency: + * ESP32C6 only support ONLY_ADC1 mode + * SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once. + */ +typedef enum { + ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion +} adc_ll_digi_convert_mode_t; + +typedef struct { + union { + struct { + uint8_t atten: 2; + uint8_t channel: 3; + uint8_t unit: 1; + uint8_t reserved: 2; + }; + uint8_t val; + }; +} __attribute__((packed)) adc_ll_digi_pattern_table_t; + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +/** + * Set adc fsm interval parameter for digital controller. These values are fixed for same platforms. + * + * @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor. + * @param start_wait Delay time after open xpd. + * @param standby_wait Delay time to close xpd. + */ +static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait) +{ + // Internal FSM reset wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_rstb_wait, rst_wait); + // Internal FSM start wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_xpd_wait, start_wait); + // Internal FSM standby wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_standby_wait, standby_wait); +} + +/** + * Set adc sample cycle for digital controller. + * + * @note Normally, please use default value. + * @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor. + * Range: 2 ~ 0xFF. + */ +static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) +{ + /* Peripheral reg i2c has powered up in rtc_init, write directly */ + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle); +} + +/** + * Set SAR ADC module clock division factor. + * SAR ADC clock divided from digital controller clock. + * + * @param div Division factor. + */ +static inline void adc_ll_digi_set_clk_div(uint32_t div) +{ + /* ADC clock divided from digital controller clock clk */ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl, saradc_saradc_sar_clk_div, div); +} + +/** + * Set adc max conversion number for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param meas_num Max conversion number. Range: 0 ~ 255. + */ +static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl2, saradc_saradc_max_meas_num, meas_num); +} + +/** + * Enable max conversion number detection for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param enable true: enable; false: disable + */ +static inline void adc_ll_digi_convert_limit_enable(bool enable) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_meas_num_limit = enable; +} + +/** + * Set adc conversion mode for digital controller. + * + * @note ESP32C6 only support ADC1 single mode. + * + * @param mode Conversion mode select. + */ +static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode) +{ + //ESP32C6 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode +} + +/** + * Set pattern table length for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 4 items, in which channel selection, + * and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param patt_len Items range: 1 ~ 8. + */ +static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_len = patt_len - 1; +} + +/** + * Set pattern table for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 4 items, in which channel selection, + * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param pattern_index Items index. Range: 0 ~ 7. + * @param pattern Stored conversion rules. + */ +static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table) +{ + uint32_t tab; + uint8_t index = pattern_index / 4; + uint8_t offset = (pattern_index % 4) * 6; + adc_ll_digi_pattern_table_t pattern = {0}; + + pattern.val = (table.atten & 0x3) | ((table.channel & 0x7) << 2) | ((table.unit & 0x1) << 5); + if (index == 0) { + tab = APB_SARADC.saradc_sar_patt_tab1.saradc_saradc_sar_patt_tab1; // Read old register value + tab &= (~(0xFC0000 >> offset)); // Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; // Fill in the new data + APB_SARADC.saradc_sar_patt_tab1.saradc_saradc_sar_patt_tab1 = tab; // Write back + } else { + tab = APB_SARADC.saradc_sar_patt_tab2.saradc_saradc_sar_patt_tab2; // Read old register value + tab &= (~(0xFC0000 >> offset)); // Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; // Fill in the new data + APB_SARADC.saradc_sar_patt_tab2.saradc_saradc_sar_patt_tab2 = tab; // Write back + } +} + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_p_clear = 1; + APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_p_clear = 0; +} + +/** + * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize. + * + * @note Only ADC2 have arbiter function. + * @param cycle range: 0 ~ 4. + */ +static inline void adc_ll_digi_set_arbiter_stable_cycle(uint32_t cycle) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_wait_arb_cycle = cycle; +} + +/** + * ADC Digital controller output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en) +{ + if (adc_n == ADC_UNIT_1) { + APB_SARADC.saradc_ctrl2.saradc_saradc_sar1_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Set the interval clock cycle for the digital controller to trigger the measurement. + * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. + * + * @note The trigger interval should not be smaller than the sampling time of the SAR ADC. + * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095. + */ +static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_timer_target = cycle; +} + +/** + * Enable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_enable(void) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_timer_en = 1; +} + +/** + * Disable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_disable(void) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_timer_en = 0; +} + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Expression: controller_clk = (APLL or APB) / (div_num + div_a / div_b + 1). + * + * @param div_num Division factor. Range: 0 ~ 255. + * @param div_b Division factor. Range: 1 ~ 63. + * @param div_a Division factor. Range: 0 ~ 63. + */ +static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.saradc_clkm_conf, saradc_clkm_div_num, div_num); + PCR.saradc_clkm_conf.saradc_clkm_div_b = div_b; + PCR.saradc_clkm_conf.saradc_clkm_div_a = div_a; +} + +/** + * Enable clock and select clock source for ADC digital controller. + * + * @param clk_src clock source for ADC digital controller. + */ +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) +{ + switch (clk_src) { + case ADC_DIGI_CLK_SRC_XTAL: + PCR.saradc_clkm_conf.saradc_clkm_sel = 0; + break; + case ADC_DIGI_CLK_SRC_PLL_F80M: + PCR.saradc_clkm_conf.saradc_clkm_sel = 1; + break; + case ADC_DIGI_CLK_SRC_RC_FAST: + PCR.saradc_clkm_conf.saradc_clkm_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock"); + } + // Enable ADC_CTRL_CLK (i.e. digital domain clock) + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; +} + +/** + * Disable clock for ADC digital controller. + */ +static inline void adc_ll_digi_controller_clk_disable(void) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0; +} + +/** + * Reset adc digital controller filter. + * + * @param idx Filter index + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n) +{ + (void)adc_n; + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_reset = 1; + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_reset = 0; +} + +/** + * Set adc digital controller filter coeff. + * + * @param idx filter index + * @param adc_n adc unit + * @param channel adc channel + * @param coeff filter coeff + */ +static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff) +{ + uint32_t factor_reg_val = 0; + switch (coeff) { + case ADC_DIGI_IIR_FILTER_COEFF_2: + factor_reg_val = 1; + break; + case ADC_DIGI_IIR_FILTER_COEFF_4: + factor_reg_val = 2; + break; + case ADC_DIGI_IIR_FILTER_COEFF_8: + factor_reg_val = 3; + break; + case ADC_DIGI_IIR_FILTER_COEFF_16: + factor_reg_val = 4; + break; + case ADC_DIGI_IIR_FILTER_COEFF_64: + factor_reg_val = 6; + break; + default: + HAL_ASSERT(false); + } + + if (idx == ADC_DIGI_IIR_FILTER_0) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7); + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = factor_reg_val; + } else if (idx == ADC_DIGI_IIR_FILTER_1) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7); + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = factor_reg_val; + } +} + +/** + * Enable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @param idx filter index + * @param adc_n ADC unit + * @param enable Enable / Disable + */ +static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable) +{ + (void)adc_n; + if (!enable) { + if (idx == ADC_DIGI_IIR_FILTER_0) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = 0xF; + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = 0; + } else if (idx == ADC_DIGI_IIR_FILTER_1) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = 0xF; + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = 0; + } + } + //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled. +} + +/** + * Set monitor mode of adc digital controller. + * + * @note If the channel info is not supported, the monitor function will not be enabled. + * @param adc_n ADC unit. + * @param is_larger true: If ADC_OUT > threshold, Generates monitor interrupt. + * false: If ADC_OUT < threshold, Generates monitor interrupt. + */ +static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg) +{ + if (idx == ADC_DIGI_MONITOR_IDX0) { + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7); + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_high = cfg->h_threshold; + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_low = cfg->l_threshold; + } else { // ADC_DIGI_MONITOR_IDX1 + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7); + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_low = cfg->h_threshold; + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_low = cfg->l_threshold; + } +} + +/** + * Enable/disable monitor of adc digital controller. + * + * @note If the channel info is not supported, the monitor function will not be enabled. + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx) +{ + if (idx == ADC_DIGI_MONITOR_IDX0) { + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_channel = 0xF; + } else { // ADC_DIGI_MONITOR_IDX1 + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_channel = 0xF; + } +} + +/** + * Set DMA eof num of adc digital controller. + * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. + * + * @param num eof num of DMA. + */ +static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_dma_conf, saradc_apb_adc_eof_num, num); +} + +/** + * Enable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_enable(void) +{ + APB_SARADC.saradc_dma_conf.saradc_apb_adc_trans = 1; +} + +/** + * Disable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_disable(void) +{ + APB_SARADC.saradc_dma_conf.saradc_apb_adc_trans = 0; +} + +/** + * Reset adc digital controller. + */ +static inline void adc_ll_digi_reset(void) +{ + APB_SARADC.saradc_dma_conf.saradc_apb_adc_reset_fsm = 1; + APB_SARADC.saradc_dma_conf.saradc_apb_adc_reset_fsm = 0; +} + +/*--------------------------------------------------------------- + PWDET(Power detect) controller setting +---------------------------------------------------------------*/ +/** + * Set adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @param cct Range: 0 ~ 7. + */ +static inline void adc_ll_pwdet_set_cct(uint32_t cct) +{ + (void)cct; +} + +/** + * Get adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @return cct Range: 0 ~ 7. + */ +static inline uint32_t adc_ll_pwdet_get_cct(void) +{ + return 0; +} + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ +/** + * Set ADC module power management. + * + * @param manage Set ADC power status. + */ +static inline void adc_ll_set_power_manage(adc_ll_power_t manage) +{ + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; + APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 3; + } else if (manage == ADC_LL_POWER_BY_FSM) { + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; + APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 0; + } else if (manage == ADC_LL_POWER_SW_OFF) { + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0; + APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 2; + } +} + +__attribute__((always_inline)) +static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl) +{ + //Not used on ESP32C6 +} + +/* ADC calibration code. */ +/** + * @brief Set common calibration configuration. Should be shared with other parts (PWDET). + */ +__attribute__((always_inline)) +static inline void adc_ll_calibration_init(adc_unit_t adc_n) +{ + (void)adc_n; + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); +} + +/** + * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + */ +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + /* Enable/disable internal connect GND (for calibration). */ + if (internal_gnd) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1); + } else { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); + } +} + +/** + * Resume register status after calibration. + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_calibration_finish(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); +} + +/** + * Set the calibration result to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + */ +__attribute__((always_inline)) +static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + uint8_t msb = param >> 8; + uint8_t lsb = param & 0xFF; + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb); +} + +/*--------------------------------------------------------------- + Oneshot Read +---------------------------------------------------------------*/ +/** + * Set adc output data format for oneshot mode + * + * @note ESP32C6 Oneshot mode only supports 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + //ESP32C6 only supports 12bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_12 || bits == ADC_BITWIDTH_DEFAULT); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | channel); +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | 0xF); +} + +/** + * Start oneshot conversion by software + * + * @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle, + * otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow. + * This hardware limitation will be removed in future versions. + */ +static inline void adc_oneshot_ll_start(bool val) +{ + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_start = val; +} + +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) +{ + APB_SARADC.saradc_int_clr.val |= event_mask; +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event_mask) +{ + return (APB_SARADC.saradc_int_raw.val & event_mask); +} + +/** + * Get the converted value for each ADCn for controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + uint32_t ret_val = 0; + ret_val = APB_SARADC.saradc_sar1data_status.saradc_apb_saradc1_data & 0xfff; + return ret_val; +} + +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 1: The data is correct to use. + * - 0: The data is invalid. + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + return true; +} + +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)inv_en; + //For compatibility +} + +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 1; +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 0; + APB_SARADC.saradc_onetime_sample.saradc_saradc2_onetime_sample = 0; +} + +/** + * Set attenuation + * + * @note Attenuation is for all channels + * + * @param adc_n ADC unit + * @param channel ADC channel + * @param atten ADC attenuation + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)channel; + // Attenuation is for all channels, unit and channel are for compatibility + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten = atten; +} + +/** + * Get the attenuation of a particular channel on ADCn. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. + */ +__attribute__((always_inline)) +static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)channel; + return (adc_atten_t)APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/aes_ll.h b/components/hal/esp32c6/include/hal/aes_ll.h new file mode 100644 index 000000000000..792205edc077 --- /dev/null +++ b/components/hal/esp32c6/include/hal/aes_ll.h @@ -0,0 +1,225 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/hwcrypto_reg.h" +#include "hal/aes_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief State of AES accelerator, busy, idle or done + * + */ +typedef enum { + ESP_AES_STATE_IDLE = 0, /* AES accelerator is idle */ + ESP_AES_STATE_BUSY, /* Transform in progress */ + ESP_AES_STATE_DONE, /* Transform completed */ +} esp_aes_state_t; + + +/** + * @brief Write the encryption/decryption key to hardware + * + * @param key Key to be written to the AES hardware + * @param key_word_len Number of words in the key + * + * @return Number of bytes written to hardware, used for fault injection check + */ +static inline uint8_t aes_ll_write_key(const uint8_t *key, size_t key_word_len) +{ + /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */ + volatile uint8_t key_in_hardware = 0; + /* Memcpy to avoid potential unaligned access */ + uint32_t key_word; + for (int i = 0; i < key_word_len; i++) { + memcpy(&key_word, key + 4 * i, 4); + REG_WRITE(AES_KEY_0_REG + i * 4, key_word); + key_in_hardware += 4; + } + return key_in_hardware; +} + +/** + * @brief Sets the mode + * + * @param mode ESP_AES_ENCRYPT = 1, or ESP_AES_DECRYPT = 0 + * @param key_bytes Number of bytes in the key + */ +static inline void aes_ll_set_mode(int mode, uint8_t key_bytes) +{ + const uint32_t MODE_DECRYPT_BIT = 4; + unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT; + + /* See TRM for the mapping between keylength and mode bit */ + REG_WRITE(AES_MODE_REG, mode_reg_base + ((key_bytes / 8) - 2)); +} + +/** + * @brief Writes message block to AES hardware + * + * @param input Block to be written + */ +static inline void aes_ll_write_block(const void *input) +{ + uint32_t input_word; + + for (int i = 0; i < AES_BLOCK_WORDS; i++) { + memcpy(&input_word, (uint8_t*)input + 4 * i, 4); + REG_WRITE(AES_TEXT_IN_0_REG + i * 4, input_word); + } +} + +/** + * @brief Read the AES block + * + * @param output the output of the transform, length = AES_BLOCK_BYTES + */ +static inline void aes_ll_read_block(void *output) +{ + uint32_t output_word; + const size_t REG_WIDTH = sizeof(uint32_t); + + for (size_t i = 0; i < AES_BLOCK_WORDS; i++) { + output_word = REG_READ(AES_TEXT_OUT_0_REG + (i * REG_WIDTH)); + /* Memcpy to avoid potential unaligned access */ + memcpy( (uint8_t*)output + i * 4, &output_word, sizeof(output_word)); + } +} + +/** + * @brief Starts block transform + * + */ +static inline void aes_ll_start_transform(void) +{ + REG_WRITE(AES_TRIGGER_REG, 1); +} + + +/** + * @brief Read state of AES accelerator + * + * @return esp_aes_state_t + */ +static inline esp_aes_state_t aes_ll_get_state(void) +{ + return REG_READ(AES_STATE_REG); +} + + +/** + * @brief Set mode of operation + * + * @note Only used for DMA transforms + * + * @param mode + */ +static inline void aes_ll_set_block_mode(esp_aes_mode_t mode) +{ + REG_WRITE(AES_BLOCK_MODE_REG, mode); +} + +/** + * @brief Set AES-CTR counter to INC32 + * + * @note Only affects AES-CTR mode + * + */ +static inline void aes_ll_set_inc(void) +{ + REG_WRITE(AES_INC_SEL_REG, 0); +} + +/** + * @brief Release the DMA + * + */ +static inline void aes_ll_dma_exit(void) +{ + REG_WRITE(AES_DMA_EXIT_REG, 0); +} + +/** + * @brief Sets the number of blocks to be transformed + * + * @note Only used for DMA transforms + * + * @param num_blocks Number of blocks to transform + */ +static inline void aes_ll_set_num_blocks(size_t num_blocks) +{ + REG_WRITE(AES_BLOCK_NUM_REG, num_blocks); +} + +/* + * Write IV to hardware iv registers + */ +static inline void aes_ll_set_iv(const uint8_t *iv) +{ + uint32_t *reg_addr_buf = (uint32_t *)(AES_IV_MEM); + uint32_t iv_word; + + for (int i = 0; i < IV_WORDS; i++ ) { + /* Memcpy to avoid potential unaligned access */ + memcpy(&iv_word, iv + 4 * i, sizeof(iv_word)); + REG_WRITE(®_addr_buf[i], iv_word); + } +} + +/* + * Read IV from hardware iv registers + */ +static inline void aes_ll_read_iv(uint8_t *iv) +{ + uint32_t iv_word; + const size_t REG_WIDTH = sizeof(uint32_t); + + for (size_t i = 0; i < IV_WORDS; i++) { + iv_word = REG_READ(AES_IV_MEM + (i * REG_WIDTH)); + /* Memcpy to avoid potential unaligned access */ + memcpy(iv + i * 4, &iv_word, sizeof(iv_word)); + } +} + +/** + * @brief Enable or disable DMA mode + * + * @param enable true to enable, false to disable. + */ +static inline void aes_ll_dma_enable(bool enable) +{ + REG_WRITE(AES_DMA_ENABLE_REG, enable); +} + +/** + * @brief Enable or disable transform completed interrupt + * + * @param enable true to enable, false to disable. + */ +static inline void aes_ll_interrupt_enable(bool enable) +{ + REG_WRITE(AES_INT_ENA_REG, enable); +} + +/** + * @brief Clears the interrupt + * + */ +static inline void aes_ll_interrupt_clear(void) +{ + REG_WRITE(AES_INT_CLEAR_REG, 1); +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/apm_ll.h b/components/hal/esp32c6/include/hal/apm_ll.h new file mode 100644 index 000000000000..65911c263440 --- /dev/null +++ b/components/hal/esp32c6/include/hal/apm_ll.h @@ -0,0 +1,262 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "soc/pcr_reg.h" +#include "soc/tee_reg.h" +#include "soc/hp_apm_reg.h" +#include "soc/hp_apm_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) +#define APM_LL_REGION_ADDR_START_REG(regn_num) (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) +#define APM_LL_REGION_ADDR_END_REG(regn_num) (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) +#define APM_LL_REGION_ADDR_ATTR_REG(regn_num) (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) +#define APM_LL_TEE_EXCP_STATUS_REG(sec_mode) (HP_APM_M0_STATUS_REG + 0x10 * (sec_mode)) +#define APM_LL_TEE_EXCP_CLR_REG(sec_mode) (HP_APM_M0_STATUS_CLR_REG + 0x10 * (sec_mode)) +#define APM_LL_TEE_EXCP_INFO0_REG(sec_mode) (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (sec_mode)) + +#define APM_LL_HP_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) +#define APM_LL_HP_SEC_MODE_REGION_ATTR_V 0x00000003U +#define APM_LL_HP_SEC_MODE_REGION_ATTR_M(sec_mode) (APM_LL_HP_SEC_MODE_REGION_ATTR_V << (4 * (sec_mode - 1))) + +#define APM_LL_HP_MAX_REGION_NUM 15 +#define APM_LL_MASTER_MAX 32 + +/** + * @brief APM Master ID + */ +typedef enum { + APM_LL_MASTER_HPCORE = 0, + APM_LL_MASTER_LPCORE = 1, + APM_LL_MASTER_REGDMA = 2, + APM_LL_MASTER_SDIOSLV = 3, + APM_LL_MASTER_MODEM = 4, + APM_LL_MASTER_MEM_MONITOR = 5, + APM_LL_MASTER_TRACE = 6, + APM_LL_MASTER_GDMA = 16, // The beginning of GDMA master ID + APM_LL_MASTER_GDMA_SPI2 = 16, + APM_LL_MASTER_GDMA_UHCI0 = 18, + APM_LL_MASTER_GDMA_I2S0 = 19, + APM_LL_MASTER_GDMA_AES = 22, + APM_LL_MASTER_GDMA_SHA = 23, + APM_LL_MASTER_GDMA_ADC = 24, + APM_LL_MASTER_GDMA_PARLIO = 25, +} apm_ll_master_id_t; + +/** + * @brief APM Secure Mode + */ +typedef enum { + APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode */ + APM_LL_SECURE_MODE_REE0 = 1, /* Rich execution environment mode0 (need to configure APM strategy for this mode) */ + APM_LL_SECURE_MODE_REE1 = 2, /* Rich execution environment mode1 (need to configure APM strategy for this mode) */ + APM_LL_SECURE_MODE_REE2 = 3, /* Rich execution environment mode2 (need to configure APM strategy for this mode) */ +} apm_ll_secure_mode_t; + +/** + * @brief APM HP access path + */ +typedef enum { + APM_LL_HP_ACCESS_PATH_M0 = 0x0, + APM_LL_HP_ACCESS_PATH_M1 = 0x1, + APM_LL_HP_ACCESS_PATH_M2 = 0x2, + APM_LL_HP_ACCESS_PATH_M3 = 0x3, +} apm_ll_hp_access_path_t; + +/** + * @brief APM exception information + */ +typedef struct { + uint8_t excp_id; + apm_ll_secure_mode_t sec_mode; + uint8_t excp_regn; + uint8_t excp_mode; + uint32_t excp_addr; +} apm_hp_m_exception_info_t; + +/** + * @brief Set secure mode + * + * @param master_id APM master ID + * @param mode Secure mode + */ +static inline void apm_tee_ll_set_master_secure_mode(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode) +{ + REG_WRITE(TEE_LL_MODE_CTRL_REG(master_id), sec_mode); +} + +/** + * @brief TEE controller clock auto gating enable + * + * @param enable Flag for HP clock auto gating enable/disable + */ +static inline void apm_tee_ll_clk_gating_enable(bool enable) +{ + if (enable) { + REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); + } else { + REG_CLR_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); + } +} + +/** + * @brief enable/disable HP Region access permission filter + * + * @param regn_num Memory Region number + * @param enable Flag for Region access filter enable/disable + */ +static inline void apm_hp_ll_region_filter_enable(uint32_t regn_num, bool enable) +{ + if (enable) { + REG_SET_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); + } else { + REG_CLR_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); + } +} + +/** + * @brief enable/disable HP access path(M[0:3]) + * + * @param hp_m_path HP access path + * @param enable Flag for HP M path filter enable/disable + */ +static inline void apm_hp_ll_m_filter_enable(apm_ll_hp_access_path_t hp_m_path, bool enable) +{ + if (enable) { + REG_SET_BIT(HP_APM_FUNC_CTRL_REG, BIT(hp_m_path)); + } else { + REG_CLR_BIT(HP_APM_FUNC_CTRL_REG, BIT(hp_m_path)); + } +} + +/** + * @brief HP Region start address configuration + * + * @param regn_num HP Region number to be configured + * @param addr Region start address + */ +static inline void apm_hp_ll_set_region_start_address(uint32_t regn_num, uint32_t addr) +{ + REG_WRITE(APM_LL_REGION_ADDR_START_REG(regn_num), addr); +} + +/** + * @brief HP Region end address configuration + * + * @param regn_num HP Region number to be configured + * @param addr Region end address + */ +static inline void apm_hp_ll_set_region_end_address(uint32_t regn_num, uint32_t addr) +{ + REG_WRITE(APM_LL_REGION_ADDR_END_REG(regn_num), addr); +} + +/** + * @brief HP Region pms attributes configuration + * + * @param regn_num Region number to be configured + * @param sec_mode Secure mode of the Master + * @param regn_pms XWR permissions for the given secure mode and Region number + */ +static inline void apm_hp_ll_sec_mode_region_attr_config(uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) +{ + uint32_t val = 0; + val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(regn_num)); + val &= ~APM_LL_HP_SEC_MODE_REGION_ATTR_M(sec_mode); + val |= APM_LL_HP_SEC_MODE_REGION_ATTR(sec_mode, regn_pms); + REG_WRITE(APM_LL_REGION_ADDR_ATTR_REG(regn_num), val); +} + +/** + * @brief Get HP access path(M[0:3]) exception status + * + * @param hp_m_path HP access path + */ +static inline uint8_t apm_hp_ll_m_exception_status(apm_ll_hp_access_path_t hp_m_path) +{ + return REG_READ(APM_LL_TEE_EXCP_STATUS_REG(hp_m_path)); +} + +/** + * @brief Clear HP access path(M[0:3]) exception + * + * @param hp_m_path HP access path + */ +static inline void apm_hp_ll_m_exception_clear(apm_ll_hp_access_path_t hp_m_path) +{ + REG_SET_BIT(APM_LL_TEE_EXCP_CLR_REG(hp_m_path), HP_APM_M0_REGION_STATUS_CLR); +} + +/** + * @brief Get HP access path(M[0:3]) exception information + * + * @param excp_info Exception related information like addr, + * region, sec_mode and master id + */ +static inline void apm_hp_ll_get_m_exception_info(apm_hp_m_exception_info_t *excp_info) +{ + excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->sec_mode), HP_APM_M0_EXCEPTION_ID); + excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->sec_mode), HP_APM_M0_EXCEPTION_MODE); + excp_info->excp_regn = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->sec_mode), HP_APM_M0_EXCEPTION_REGION); + excp_info->excp_addr = REG_READ(HP_APM_M0_EXCEPTION_INFO1_REG); +} + +/** + * @brief Interrupt enable for access path(M[0:3]) + * + * @param hp_m_path HP access path + * @param enable Flag for access path interrupt enable/disable + */ +static inline void apm_hp_ll_m_interrupt_enable(apm_ll_hp_access_path_t hp_m_path, bool enable) +{ + if (enable) { + REG_SET_BIT(HP_APM_INT_EN_REG, BIT(hp_m_path)); + } else { + REG_CLR_BIT(HP_APM_INT_EN_REG, BIT(hp_m_path)); + } +} + +/** + * @brief HP clock auto gating enable + * + * @param enable Flag for HP clock auto gating enable/disable + */ +static inline void apm_hp_ll_clk_gating_enable(bool enable) +{ + if (enable) { + REG_SET_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); + } else { + REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); + } +} + +/** + * @brief APM/TEE/HP System Reg reset event bypass enable + * + * Disable: tee_reg/apm_reg/hp_system_reg will not only be reset by power-reset, + * but also some reset events. + * Enable: tee_reg/apm_reg/hp_system_reg will only be reset by power-reset. + * Some reset events will be bypassed. + * + * @param enable Flag for event bypass enable/disable + */ +static inline void apm_hp_ll_reset_event_enable(bool enable) +{ + if (enable) { + REG_SET_BIT(PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_APM); + } else { + REG_CLR_BIT(PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_APM); + } +} +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/brownout_ll.h b/components/hal/esp32c6/include/hal/brownout_ll.h new file mode 100644 index 000000000000..bf3edeb49a02 --- /dev/null +++ b/components/hal/esp32c6/include/hal/brownout_ll.h @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/readme.md + ******************************************************************************/ + +#pragma once +#include +#include "soc/lp_analog_peri_struct.h" +#include "hal/regi2c_ctrl.h" +#include "soc/regi2c_brownout.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief power down the flash when a brown out happens. + * + * @param enable true: power down flash. false: not power down + */ +static inline void brownout_ll_enable_flash_power_down(bool enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_close_flash_ena = enable; +} + +/** + * @brief power down the RF circuits when a brown out happens + * + * @param enable true: power down. false: not power done. + */ +static inline void brownout_ll_enable_rf_power_down(bool enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_pd_rf_ena = enable; +} + +/** + * @brief Enable this to reset brown out + * + * @note: If brown out interrupt is used, this should be disabled. + * + * @param reset_ena true: enable reset. false: disable reset. + * @param reset_wait brown out reset wait cycles + * @param select 1: chip reset, 0: system reset + */ +static inline void brownout_ll_reset_config(bool reset_ena, uint32_t reset_wait, uint8_t select) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_wait = reset_wait; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_ena = reset_ena; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_sel = select; +} + +/** + * @brief Set brown out threshold + * + * @param threshold brownout threshold + */ +static inline void brownout_ll_set_threshold(uint8_t threshold) +{ + REGI2C_WRITE_MASK(I2C_BOD, I2C_BOD_THRESHOLD, threshold); +} + +/** + * @brief Set this bit to enable the brown out detection + * + * @param bod_enable true: enable, false: disable + */ +static inline void brownout_ll_bod_enable(bool bod_enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_intr_ena = bod_enable; +} + +/** + * @brief configure the waiting cycles before sending an interrupt + * + * @param cycle waiting cycles. + */ +static inline void brownout_ll_set_intr_wait_cycles(uint8_t cycle) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_intr_wait = cycle; +} + +/** + * @brief Enable brown out interrupt + * + * @param enable true: enable, false: disable + */ +static inline void brownout_ll_intr_enable(bool enable) +{ + LP_ANA_PERI.int_ena.bod_mode0 = enable; +} + +/** + * @brief Enable brownout hardware reset + * + * @param enable + */ +static inline void brownout_ll_ana_reset_enable(bool enable) +{ + LP_ANA_PERI.bod_mode1_cntl.bod_mode1_reset_ena = enable; +} + +/** + * @brief Clear interrupt bits. + */ +__attribute__((always_inline)) +static inline void brownout_ll_intr_clear(void) +{ + LP_ANA_PERI.int_clr.bod_mode0 = 1; +} + +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 1; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/cache_ll.h b/components/hal/esp32c6/include/hal/cache_ll.h new file mode 100644 index 000000000000..82769b32d9a2 --- /dev/null +++ b/components/hal/esp32c6/include/hal/cache_ll.h @@ -0,0 +1,143 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for Cache register operations + +#pragma once + +#include "soc/extmem_reg.h" +#include "soc/ext_mem_defs.h" +#include "hal/cache_types.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define CACHE_LL_ENABLE_DISABLE_STATE_SW 1 //There's no register indicating cache enable/disable state, we need to use software way for this state. + +#define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0 +#define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0 + +#define CACHE_LL_L1_ACCESS_EVENT_MASK (1<<4) +#define CACHE_LL_L1_ACCESS_EVENT_CACHE_FAIL (1<<4) + + +/** + * @brief Get the buses of a particular cache that are mapped to a virtual address range + * + * External virtual address can only be accessed when the involved cache buses are enabled. + * This API is to get the cache buses where the memory region (from `vaddr_start` to `vaddr_start + len`) reside. + * + * @param cache_id cache ID (when l1 cache is per core) + * @param vaddr_start virtual address start + * @param len vaddr length + */ +#if !BOOTLOADER_BUILD +__attribute__((always_inline)) +#endif +static inline cache_bus_mask_t cache_ll_l1_get_bus(uint32_t cache_id, uint32_t vaddr_start, uint32_t len) +{ + HAL_ASSERT(cache_id == 0); + cache_bus_mask_t mask = 0; + + uint32_t vaddr_end = vaddr_start + len - 1; + if (vaddr_start >= IRAM0_CACHE_ADDRESS_LOW && vaddr_end < IRAM0_CACHE_ADDRESS_HIGH) { + //c6 the I/D bus memory are shared, so we always return `CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0` + mask |= CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0; + } else { + HAL_ASSERT(0); //Out of region + } + + return mask; +} + +/** + * Enable the Cache Buses + * + * @param cache_id cache ID (when l1 cache is per core) + * @param mask To know which buses should be enabled + */ +#if !BOOTLOADER_BUILD +__attribute__((always_inline)) +#endif +static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t mask) +{ + HAL_ASSERT(cache_id == 0); + //On esp32c6, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first + HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2 | CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0); + + uint32_t ibus_mask = 0; + ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_L1_CACHE_SHUT_IBUS : 0; + REG_CLR_BIT(EXTMEM_L1_CACHE_CTRL_REG, ibus_mask); + + uint32_t dbus_mask = 0; + dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_L1_CACHE_SHUT_DBUS : 0; + REG_CLR_BIT(EXTMEM_L1_CACHE_CTRL_REG, dbus_mask); +} + +/** + * Disable the Cache Buses + * + * @param cache_id cache ID (when l1 cache is per core) + * @param mask To know which buses should be disabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t mask) +{ + HAL_ASSERT(cache_id == 0); + //On esp32c6, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first + HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2 | CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0); + + uint32_t ibus_mask = 0; + ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_L1_CACHE_SHUT_IBUS : 0; + REG_SET_BIT(EXTMEM_L1_CACHE_CTRL_REG, ibus_mask); + + uint32_t dbus_mask = 0; + dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_L1_CACHE_SHUT_DBUS : 0; + REG_SET_BIT(EXTMEM_L1_CACHE_CTRL_REG, dbus_mask); +} + +/*------------------------------------------------------------------------------ + * Interrupt + *----------------------------------------------------------------------------*/ +/** + * @brief Enable Cache access error interrupt + * + * @param cache_id Cache ID, not used on C3. For compabitlity + * @param mask Interrupt mask + */ +static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask) +{ + SET_PERI_REG_MASK(EXTMEM_L1_CACHE_ACS_FAIL_INT_ENA_REG, mask); +} + +/** + * @brief Clear Cache access error interrupt status + * + * @param cache_id Cache ID, not used on C3. For compabitlity + * @param mask Interrupt mask + */ +static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask) +{ + SET_PERI_REG_MASK(EXTMEM_L1_CACHE_ACS_FAIL_INT_CLR_REG, mask); +} + +/** + * @brief Get Cache access error interrupt status + * + * @param cache_id Cache ID, not used on C3. For compabitlity + * @param mask Interrupt mask + * + * @return Status mask + */ +static inline uint32_t cache_ll_l1_get_access_error_intr_status(uint32_t cache_id, uint32_t mask) +{ + return GET_PERI_REG_MASK(EXTMEM_L1_CACHE_ACS_FAIL_INT_ST_REG, mask); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/clk_gate_ll.h b/components/hal/esp32c6/include/hal/clk_gate_ll.h new file mode 100644 index 000000000000..4e7be2030113 --- /dev/null +++ b/components/hal/esp32c6/include/hal/clk_gate_ll.h @@ -0,0 +1,338 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/periph_defs.h" +#include "soc/pcr_reg.h" +#include "soc/soc.h" +#include "soc/lpperi_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) +{ + switch (periph) { + case PERIPH_SARADC_MODULE: + return PCR_SARADC_CLK_EN; + case PERIPH_RMT_MODULE: + return PCR_RMT_CLK_EN; + case PERIPH_PCNT_MODULE: + return PCR_PCNT_CLK_EN; + case PERIPH_LEDC_MODULE: + return PCR_LEDC_CLK_EN; + case PERIPH_UART0_MODULE: + return PCR_UART0_CLK_EN; + case PERIPH_UART1_MODULE: + return PCR_UART1_CLK_EN; + case PERIPH_I2C0_MODULE: + return PCR_I2C_CLK_EN; + case PERIPH_I2S1_MODULE: + return PCR_I2S_CLK_EN; + case PERIPH_TIMG0_MODULE: + return PCR_TG0_CLK_EN; + case PERIPH_TIMG1_MODULE: + return PCR_TG1_CLK_EN; + case PERIPH_UHCI0_MODULE: + return PCR_UHCI_CLK_EN; + case PERIPH_SYSTIMER_MODULE: + return PCR_SYSTIMER_CLK_EN; + case PERIPH_SPI_MODULE: + return PCR_MSPI_CLK_EN; + case PERIPH_SPI2_MODULE: + return PCR_SPI2_CLK_EN; + case PERIPH_TWAI0_MODULE: + return PCR_TWAI0_CLK_EN; + case PERIPH_TWAI1_MODULE: + return PCR_TWAI1_CLK_EN; + case PERIPH_GDMA_MODULE: + return PCR_GDMA_CLK_EN; + case PERIPH_MCPWM0_MODULE: + return PCR_PWM_CLK_EN; + case PERIPH_ETM_MODULE: + return PCR_ETM_CLK_EN; + case PERIPH_PARLIO_MODULE: + return PCR_PARL_CLK_EN; + case PERIPH_AES_MODULE: + return PCR_AES_CLK_EN; + case PERIPH_SHA_MODULE: + return PCR_SHA_CLK_EN; + case PERIPH_ECC_MODULE: + return PCR_ECC_CLK_EN; + case PERIPH_RSA_MODULE: + return PCR_RSA_CLK_EN; + case PERIPH_HMAC_MODULE: + return PCR_HMAC_CLK_EN; + case PERIPH_DS_MODULE: + return PCR_DS_CLK_EN; + case PERIPH_TEMPSENSOR_MODULE: + return PCR_TSENS_CLK_EN; + case PERIPH_SDIO_SLAVE_MODULE: + return PCR_SDIO_SLAVE_CLK_EN; + case PERIPH_REGDMA_MODULE: + return PCR_REGDMA_CLK_EN; + //TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374). + case PERIPH_LP_I2C0_MODULE: + return LPPERI_LP_EXT_I2C_CK_EN; + default: + return 0; + } +} + +static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool enable) +{ + (void)enable; // unused + + switch (periph) { + case PERIPH_SARADC_MODULE: + return PCR_SARADC_REG_RST_EN; + case PERIPH_RMT_MODULE: + return PCR_RMT_RST_EN; + case PERIPH_PCNT_MODULE: + return PCR_PCNT_RST_EN; + case PERIPH_LEDC_MODULE: + return PCR_LEDC_RST_EN; + case PERIPH_UART0_MODULE: + return PCR_UART0_RST_EN; + case PERIPH_UART1_MODULE: + return PCR_UART1_RST_EN; + case PERIPH_I2C0_MODULE: + return PCR_I2C_RST_EN; + case PERIPH_I2S1_MODULE: + return PCR_I2S_RST_EN; + case PERIPH_TIMG0_MODULE: + return PCR_TG0_RST_EN; + case PERIPH_TIMG1_MODULE: + return PCR_TG1_RST_EN; + case PERIPH_UHCI0_MODULE: + return PCR_UHCI_RST_EN; + case PERIPH_SYSTIMER_MODULE: + return PCR_SYSTIMER_RST_EN; + case PERIPH_SPI_MODULE: + return PCR_MSPI_RST_EN; + case PERIPH_SPI2_MODULE: + return PCR_SPI2_RST_EN; + case PERIPH_TWAI0_MODULE: + return PCR_TWAI0_RST_EN; + case PERIPH_TWAI1_MODULE: + return PCR_TWAI1_RST_EN; + case PERIPH_GDMA_MODULE: + return PCR_GDMA_RST_EN; + case PERIPH_MCPWM0_MODULE: + return PCR_PWM_RST_EN; + case PERIPH_ETM_MODULE: + return PCR_ETM_RST_EN; + case PERIPH_PARLIO_MODULE: + return PCR_PARL_RST_EN; + case PERIPH_ECC_MODULE: + return PCR_ECC_RST_EN; + case PERIPH_TEMPSENSOR_MODULE: + return PCR_TSENS_RST_EN; + case PERIPH_AES_MODULE: + if (enable == true) { + // Clear reset on digital signature, otherwise AES unit is held in reset + CLEAR_PERI_REG_MASK(PCR_DS_CONF_REG, PCR_DS_RST_EN); + } + return PCR_AES_RST_EN; + case PERIPH_SHA_MODULE: + if (enable == true) { + // Clear reset on digital signature and HMAC, otherwise SHA is held in reset + CLEAR_PERI_REG_MASK(PCR_DS_CONF_REG, PCR_DS_RST_EN); + CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN); + } + return PCR_SHA_RST_EN; + case PERIPH_RSA_MODULE: + if (enable == true) { + // Clear reset on digital signature, otherwise RSA is held in reset + CLEAR_PERI_REG_MASK(PCR_DS_CONF_REG, PCR_DS_RST_EN); + } + return PCR_RSA_RST_EN; + case PERIPH_HMAC_MODULE: + return PCR_HMAC_RST_EN; + case PERIPH_DS_MODULE: + return PCR_DS_RST_EN; + case PERIPH_SDIO_SLAVE_MODULE: + return PCR_SDIO_SLAVE_RST_EN; + case PERIPH_REGDMA_MODULE: + return PCR_REGDMA_RST_EN; + //TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374). + case PERIPH_LP_I2C0_MODULE: + return LPPERI_LP_EXT_I2C_RESET_EN; + default: + return 0; + } +} + +static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) +{ + switch (periph) { + case PERIPH_SARADC_MODULE: + return PCR_SARADC_CONF_REG; + case PERIPH_RMT_MODULE: + return PCR_RMT_CONF_REG; + case PERIPH_PCNT_MODULE: + return PCR_PCNT_CONF_REG; + case PERIPH_LEDC_MODULE: + return PCR_LEDC_CONF_REG; + case PERIPH_UART0_MODULE: + return PCR_UART0_CONF_REG; + case PERIPH_UART1_MODULE: + return PCR_UART1_CONF_REG; + case PERIPH_I2C0_MODULE: + return PCR_I2C_CONF_REG; + case PERIPH_I2S1_MODULE: + return PCR_I2S_CONF_REG; + case PERIPH_TIMG0_MODULE: + return PCR_TIMERGROUP0_CONF_REG; + case PERIPH_TIMG1_MODULE: + return PCR_TIMERGROUP1_CONF_REG; + case PERIPH_UHCI0_MODULE: + return PCR_UHCI_CONF_REG; + case PERIPH_SYSTIMER_MODULE: + return PCR_SYSTIMER_CONF_REG; + case PERIPH_SPI_MODULE: + return PCR_MSPI_CONF_REG; + case PERIPH_SPI2_MODULE: + return PCR_SPI2_CONF_REG; + case PERIPH_TWAI0_MODULE: + return PCR_TWAI0_CONF_REG; + case PERIPH_TWAI1_MODULE: + return PCR_TWAI1_CONF_REG; + case PERIPH_GDMA_MODULE: + return PCR_GDMA_CONF_REG; + case PERIPH_MCPWM0_MODULE: + return PCR_PWM_CONF_REG; + case PERIPH_ETM_MODULE: + return PCR_ETM_CONF_REG; + case PERIPH_PARLIO_MODULE: + return PCR_PARL_IO_CONF_REG; + case PERIPH_AES_MODULE: + return PCR_AES_CONF_REG; + case PERIPH_SHA_MODULE: + return PCR_SHA_CONF_REG; + case PERIPH_ECC_MODULE: + return PCR_ECC_CONF_REG; + case PERIPH_RSA_MODULE: + return PCR_RSA_CONF_REG; + case PERIPH_HMAC_MODULE: + return PCR_HMAC_CONF_REG; + case PERIPH_DS_MODULE: + return PCR_DS_CONF_REG; + case PERIPH_TEMPSENSOR_MODULE: + return PCR_TSENS_CLK_CONF_REG; + case PERIPH_SDIO_SLAVE_MODULE: + return PCR_SDIO_SLAVE_CONF_REG; + case PERIPH_REGDMA_MODULE: + return PCR_REGDMA_CONF_REG; + //TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374). + case PERIPH_LP_I2C0_MODULE: + return LPPERI_CLK_EN_REG; + default: + return 0; + } +} + +static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) +{ + switch (periph) { + case PERIPH_SARADC_MODULE: + return PCR_SARADC_CONF_REG; + case PERIPH_RMT_MODULE: + return PCR_RMT_CONF_REG; + case PERIPH_PCNT_MODULE: + return PCR_PCNT_CONF_REG; + case PERIPH_LEDC_MODULE: + return PCR_LEDC_CONF_REG; + case PERIPH_UART0_MODULE: + return PCR_UART0_CONF_REG; + case PERIPH_UART1_MODULE: + return PCR_UART1_CONF_REG; + case PERIPH_I2C0_MODULE: + return PCR_I2C_CONF_REG; + case PERIPH_I2S1_MODULE: + return PCR_I2S_CONF_REG; + case PERIPH_TIMG0_MODULE: + return PCR_TIMERGROUP0_CONF_REG; + case PERIPH_TIMG1_MODULE: + return PCR_TIMERGROUP1_CONF_REG; + case PERIPH_UHCI0_MODULE: + return PCR_UHCI_CONF_REG; + case PERIPH_SYSTIMER_MODULE: + return PCR_SYSTIMER_CONF_REG; + case PERIPH_SPI_MODULE: + return PCR_MSPI_CONF_REG; + case PERIPH_SPI2_MODULE: + return PCR_SPI2_CONF_REG; + case PERIPH_TWAI0_MODULE: + return PCR_TWAI0_CONF_REG; + case PERIPH_TWAI1_MODULE: + return PCR_TWAI1_CONF_REG; + case PERIPH_GDMA_MODULE: + return PCR_GDMA_CONF_REG; + case PERIPH_MCPWM0_MODULE: + return PCR_PWM_CONF_REG; + case PERIPH_ETM_MODULE: + return PCR_ETM_CONF_REG; + case PERIPH_PARLIO_MODULE: + return PCR_PARL_IO_CONF_REG; + case PERIPH_AES_MODULE: + return PCR_AES_CONF_REG; + case PERIPH_SHA_MODULE: + return PCR_SHA_CONF_REG; + case PERIPH_ECC_MODULE: + return PCR_ECC_CONF_REG; + case PERIPH_RSA_MODULE: + return PCR_RSA_CONF_REG; + case PERIPH_HMAC_MODULE: + return PCR_HMAC_CONF_REG; + case PERIPH_DS_MODULE: + return PCR_DS_CONF_REG; + case PERIPH_TEMPSENSOR_MODULE: + return PCR_TSENS_CLK_CONF_REG; + case PERIPH_SDIO_SLAVE_MODULE: + return PCR_SDIO_SLAVE_CONF_REG; + case PERIPH_REGDMA_MODULE: + return PCR_REGDMA_CONF_REG; + //TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374). + case PERIPH_LP_I2C0_MODULE: + return LPPERI_RESET_EN_REG; + default: + return 0; + } +} + +static inline void periph_ll_enable_clk_clear_rst(periph_module_t periph) +{ + SET_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)); + CLEAR_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, true)); +} + +static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) +{ + CLEAR_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)); + SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); +} + +static inline void periph_ll_reset(periph_module_t periph) +{ + SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); + CLEAR_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); +} + +static inline bool IRAM_ATTR periph_ll_periph_enabled(periph_module_t periph) +{ + return REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 && + REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h new file mode 100644 index 000000000000..bbf162212666 --- /dev/null +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -0,0 +1,818 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/clk_tree_defs.h" +#include "soc/rtc.h" +#include "soc/pcr_struct.h" +#include "soc/lp_clkrst_struct.h" +#include "soc/pmu_reg.h" +#include "hal/regi2c_ctrl.h" +#include "soc/regi2c_bbpll.h" +#include "hal/assert.h" +#include "hal/log.h" +#include "esp32c6/rom/rtc.h" +#include "hal/misc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MHZ (1000000) + +#define CLK_LL_PLL_80M_FREQ_MHZ (80) +#define CLK_LL_PLL_120M_FREQ_MHZ (120) +#define CLK_LL_PLL_160M_FREQ_MHZ (160) +#define CLK_LL_PLL_240M_FREQ_MHZ (240) + +#define CLK_LL_PLL_480M_FREQ_MHZ (480) + +#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \ + .dac = 3, \ + .dres = 3, \ + .dgm = 3, \ + .dbuf = 1, \ +} + +/* +Set the frequency division factor of ref_tick +The FOSC of rtc calibration uses the 32 frequency division clock for ECO1, +So the frequency division factor of ref_tick must be greater than or equal to 32 +*/ +#define REG_FOSC_TICK_NUM 255 + +/** + * @brief XTAL32K_CLK enable modes + */ +typedef enum { + CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK + CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for OSC_SLOW_CLK + CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */ +} clk_ll_xtal32k_enable_mode_t; + +/** + * @brief XTAL32K_CLK configuration structure + */ +typedef struct { + uint32_t dac : 6; + uint32_t dres : 3; + uint32_t dgm : 3; + uint32_t dbuf: 1; +} clk_ll_xtal32k_config_t; + +/** + * @brief Power up BBPLL circuit + */ +static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) +{ + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C | + PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG); +} + +/** + * @brief Power down BBPLL circuit + */ +static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void) +{ + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_BBPLL_ICG) ; + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_BBPLL | PMU_TIE_LOW_XPD_BBPLL_I2C); +} + +/** + * @brief Release the root clock source locked by PMU + */ +static inline __attribute__((always_inline)) void clk_ll_cpu_clk_src_lock_release(void) +{ + SET_PERI_REG_MASK(PMU_IMM_SLEEP_SYSCLK_REG, PMU_UPDATE_DIG_SYS_CLK_SEL); +} + +/** + * @brief Enable the 32kHz crystal oscillator + * + * @param mode Used to determine the xtal32k configuration parameters + */ +static inline __attribute__((always_inline)) void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode) +{ + if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) { + // No need to configure anything for OSC_SLOW_CLK + return; + } + // Configure xtal32k + clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT(); + LP_CLKRST.xtal32k.dac_xtal32k = cfg.dac; + LP_CLKRST.xtal32k.dres_xtal32k = cfg.dres; + LP_CLKRST.xtal32k.dgm_xtal32k = cfg.dgm; + LP_CLKRST.xtal32k.dbuf_xtal32k = cfg.dbuf; + // Enable xtal32k xpd + SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K); +} + +/** + * @brief Disable the 32kHz crystal oscillator + */ +static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void) +{ + // Disable xtal32k xpd + CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K); +} + +/** + * @brief Get the state of the 32kHz crystal clock + * + * @return True if the 32kHz XTAL is enabled + */ +static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void) +{ + return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1; +} + +/** + * @brief Enable the internal oscillator output for RC32K_CLK + */ +static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void) +{ + // Enable rc32k xpd status + SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K); +} + +/** + * @brief Disable the internal oscillator output for RC32K_CLK + */ +static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void) +{ + // Disable rc32k xpd status + CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K); +} + +/** + * @brief Get the state of the internal oscillator for RC32K_CLK + * + * @return True if the oscillator is enabled + */ +static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void) +{ + return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1; +} + +/** + * @brief Enable the internal oscillator output for RC_FAST_CLK + */ +static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void) +{ + SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK); +} + +/** + * @brief Disable the internal oscillator output for RC_FAST_CLK + */ +static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void) +{ + CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK); +} + +/** + * @brief Get the state of the internal oscillator for RC_FAST_CLK + * + * @return True if the oscillator is enabled + */ +static inline __attribute__((always_inline)) bool clk_ll_rc_fast_is_enabled(void) +{ + return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK) == 1; +} + +/** + * @brief Enable the digital RC_FAST_CLK, which is used to support peripherals. + */ +static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_enable(void) +{ + LP_CLKRST.clk_to_hp.icg_hp_fosc = 1; +} + +/** + * @brief Disable the digital RC_FAST_CLK, which is used to support peripherals. + */ +static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_disable(void) +{ + LP_CLKRST.clk_to_hp.icg_hp_fosc = 0; +} + +/** + * @brief Get the state of the digital RC_FAST_CLK + * + * @return True if the digital RC_FAST_CLK is enabled + */ +static inline __attribute__((always_inline)) bool clk_ll_rc_fast_digi_is_enabled(void) +{ + return LP_CLKRST.clk_to_hp.icg_hp_fosc; +} + +/** + * @brief Enable the digital XTAL32K_CLK, which is used to support peripherals. + */ +static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_enable(void) +{ + LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 1; +} + +/** + * @brief Disable the digital XTAL32K_CLK, which is used to support peripherals. + */ +static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_disable(void) +{ + LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 0; +} + +/** + * @brief Get the state of the digital XTAL32K_CLK + * + * @return True if the digital XTAL32K_CLK is enabled + */ +static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled(void) +{ + return LP_CLKRST.clk_to_hp.icg_hp_xtal32k; +} + +/** + * @brief Enable the digital RC32K_CLK, which is used to support peripherals. + */ +static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void) +{ + LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1; +} + +/** + * @brief Disable the digital RC32K_CLK, which is used to support peripherals. + */ +static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void) +{ + LP_CLKRST.clk_to_hp.icg_hp_osc32k = 0; +} + +/** + * @brief Get the state of the digital RC32K_CLK + * + * @return True if the digital RC32K_CLK is enabled + */ +static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(void) +{ + return LP_CLKRST.clk_to_hp.icg_hp_osc32k; +} + +/** + * @brief Get PLL_CLK frequency + * + * @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid. + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void) +{ + // The target has a fixed 480MHz SPLL + return CLK_LL_PLL_480M_FREQ_MHZ; +} + +/** + * @brief Set BBPLL frequency from XTAL source (Digital part) + * + * @param pll_freq_mhz PLL frequency, in MHz + */ +static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz) +{ + // The target SPLL is fixed to 480MHz + // Do nothing + HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ); +} + +/** + * @brief Set BBPLL frequency from XTAL source (Analog part) + * + * @param pll_freq_mhz PLL frequency, in MHz + * @param xtal_freq_mhz XTAL frequency, in MHz + */ +static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz) +{ + HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ); + uint8_t div_ref; + uint8_t div7_0; + uint8_t dr1; + uint8_t dr3; + uint8_t dchgp; + uint8_t dcur; + uint8_t dbias; + + /* Configure 480M PLL */ + switch (xtal_freq_mhz) { + case RTC_XTAL_FREQ_40M: + default: + div_ref = 0; + div7_0 = 8; + dr1 = 0; + dr3 = 0; + dchgp = 5; + dcur = 3; + dbias = 2; + break; + } + uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); + uint8_t i2c_bbpll_div_7_0 = div7_0; + uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3); + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); +} + +/** + * @brief Select the clock source for CPU_CLK (SOC Clock Root) + * + * @param in_sel One of the clock sources in soc_cpu_clk_src_t + */ +static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel) +{ + switch (in_sel) { + case SOC_CPU_CLK_SRC_XTAL: + PCR.sysclk_conf.soc_clk_sel = 0; + break; + case SOC_CPU_CLK_SRC_PLL: + PCR.sysclk_conf.soc_clk_sel = 1; + break; + case SOC_CPU_CLK_SRC_RC_FAST: + PCR.sysclk_conf.soc_clk_sel = 2; + break; + default: + // Unsupported SOC_CLK mux input sel + abort(); + } +} + +/** + * @brief Get the clock source for CPU_CLK (SOC Clock Root) + * + * @return Currently selected clock source (one of soc_cpu_clk_src_t values) + */ +static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void) +{ + uint32_t clk_sel = PCR.sysclk_conf.soc_clk_sel; + switch (clk_sel) { + case 0: + return SOC_CPU_CLK_SRC_XTAL; + case 1: + return SOC_CPU_CLK_SRC_PLL; + case 2: + return SOC_CPU_CLK_SRC_RC_FAST; + default: + // Invalid SOC_CLK_SEL value + return SOC_CPU_CLK_SRC_INVALID; + } +} + +/** + * @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * + * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider. + */ +static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider) +{ + // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK + // (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) + // Fixed at 3 for HS clock source + // Corresponding register field value is PCR_HS_DIV_NUM=2 + // (2) configurable + // HS divider option: 1, 2, 4 (PCR_CPU_HS_DIV_NUM=0, 1, 3) + + HAL_ASSERT(divider == 3 || divider == 4 || divider == 6 || divider == 12); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_hs_div_num, (divider / 3) - 1); + + // 120MHz CPU freq cannot be achieved through divider, need to set force_120m + // This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL + bool force_120m = (divider == 4) ? 1 : 0; + PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m; +} + +/** + * @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) + * + * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider. + */ +static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider) +{ + // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK + // (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM) + // Fixed at 1 for LS clock source + // Corresponding register field value is PCR_LS_DIV_NUM=0 + // (2) configurable + // LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31) + HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0)); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_ls_div_num, divider - 1); +} + +/** + * @brief Get CPU_CLK's high-speed divider + * + * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void) +{ + uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force; + uint32_t cpu_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_hs_div_num); + if (cpu_hs_div == 0 && force_120m) { + return 4; + } + uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num); + return (hp_root_hs_div + 1) * (cpu_hs_div + 1); +} + +/** + * @brief Get CPU_CLK's low-speed divider + * + * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void) +{ + uint32_t cpu_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_ls_div_num); + uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num); + return (hp_root_ls_div + 1) * (cpu_ls_div + 1); +} + +/** + * @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * + * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider. + */ +static inline __attribute__((always_inline)) void clk_ll_ahb_set_hs_divider(uint32_t divider) +{ + // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK + // (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) + // Fixed at 3 for HS clock source + // Corresponding register field value is PCR_HS_DIV_NUM=2 + // (2) configurable + // HS divider option: 4, 8, 16 (PCR_AHB_HS_DIV_NUM=3, 7, 15) + HAL_ASSERT(divider == 12 || divider == 24 || divider == 48); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_hs_div_num, (divider / 3) - 1); +} + +/** + * @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) + * + * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider. + */ +static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider) +{ + // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK + // (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM) + // Fixed at 1 for LS clock source + // Corresponding register field value is PCR_LS_DIV_NUM=0 + // (2) configurable + // LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31) + HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0)); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_ls_div_num, divider - 1); +} + +/** + * @brief Get AHB_CLK's high-speed divider + * + * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void) +{ + uint32_t ahb_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_hs_div_num); + uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num); + return (hp_root_hs_div + 1) * (ahb_hs_div + 1); +} + +/** + * @brief Get AHB_CLK's low-speed divider + * + * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void) +{ + uint32_t ahb_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_ls_div_num); + uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num); + return (hp_root_ls_div + 1) * (ahb_ls_div + 1); +} + +/** + * @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider + * + * @param divider Divider. PCR_APB_DIV_NUM = divider - 1. + */ +static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider) +{ + // AHB ------> APB + // Divider option: 1, 2, 4 (PCR_APB_DIV_NUM=0, 1, 3) + HAL_ASSERT(divider == 1 || divider == 2 || divider == 4); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num, divider - 1); +} + +/** + * @brief Get APB_CLK divider + * + * @return Divider. Divider = (PCR_APB_DIV_NUM + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1; +} + +/** + * @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * + * @param divider Divider. + */ +static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider) +{ + // SOC_ROOT_CLK ------> MSPI_FAST_CLK + // HS divider option: 4, 5, 6 (PCR_MSPI_FAST_HS_DIV_NUM=3, 4, 5) + uint32_t div_num = 0; + switch (divider) { + case 4: + div_num = 3; + break; + case 5: + div_num = 4; + break; + case 6: + div_num = 5; + break; + default: + // Unsupported HS MSPI_FAST divider + abort(); + } + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_hs_div_num, div_num); +} + +/** + * @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) + * + * @param divider Divider. + */ +static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider) +{ + // SOC_ROOT_CLK ------> MSPI_FAST_CLK + // LS divider option: 1, 2, 4 (PCR_MSPI_FAST_LS_DIV_NUM=0, 1, 2) + uint32_t div_num = 0; + switch (divider) { + case 1: + div_num = 0; + break; + case 2: + div_num = 1; + break; + case 4: + div_num = 2; + break; + default: + // Unsupported LS MSPI_FAST divider + abort(); + } + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_ls_div_num, div_num); +} + +/** + * @brief Select the calibration 32kHz clock source for timergroup0 + * + * @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK) + */ +static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel) +{ + switch (in_sel) { + case SOC_RTC_SLOW_CLK_SRC_RC32K: + PCR.ctrl_32k_conf.clk_32k_sel = 0; + break; + case SOC_RTC_SLOW_CLK_SRC_XTAL32K: + PCR.ctrl_32k_conf.clk_32k_sel = 1; + break; + case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: + PCR.ctrl_32k_conf.clk_32k_sel = 2; + break; + default: + // Unsupported 32K_SEL mux input + abort(); + } +} + +/** + * @brief Get the calibration 32kHz clock source for timergroup0 + * + * @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks) + */ +static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void) +{ + uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel; + switch (clk_sel) { + case 0: + return SOC_RTC_SLOW_CLK_SRC_RC32K; + case 1: + return SOC_RTC_SLOW_CLK_SRC_XTAL32K; + case 2: + return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW; + default: + return SOC_RTC_SLOW_CLK_SRC_INVALID; + } +} + +/** + * @brief Select the clock source for RTC_SLOW_CLK + * + * @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t + */ +static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel) +{ + switch (in_sel) { + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: + LP_CLKRST.lp_clk_conf.slow_clk_sel = 0; + break; + case SOC_RTC_SLOW_CLK_SRC_XTAL32K: + LP_CLKRST.lp_clk_conf.slow_clk_sel = 1; + break; + case SOC_RTC_SLOW_CLK_SRC_RC32K: + LP_CLKRST.lp_clk_conf.slow_clk_sel = 2; + break; + case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: + LP_CLKRST.lp_clk_conf.slow_clk_sel = 3; + break; + default: + // Unsupported RTC_SLOW_CLK mux input sel + abort(); + } +} + +/** + * @brief Get the clock source for RTC_SLOW_CLK + * + * @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values) + */ +static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void) +{ + uint32_t clk_sel = LP_CLKRST.lp_clk_conf.slow_clk_sel; + switch (clk_sel) { + case 0: + return SOC_RTC_SLOW_CLK_SRC_RC_SLOW; + case 1: + return SOC_RTC_SLOW_CLK_SRC_XTAL32K; + case 2: + return SOC_RTC_SLOW_CLK_SRC_RC32K; + case 3: + return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW; + default: + return SOC_RTC_SLOW_CLK_SRC_INVALID; + } +} + +/** + * @brief Select the clock source for RTC_FAST_CLK + * + * @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t + */ +static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel) +{ + switch (in_sel) { + case SOC_RTC_FAST_CLK_SRC_RC_FAST: + LP_CLKRST.lp_clk_conf.fast_clk_sel = 0; + break; + case SOC_RTC_FAST_CLK_SRC_XTAL_D2: + LP_CLKRST.lp_clk_conf.fast_clk_sel = 1; + break; + default: + // Unsupported RTC_FAST_CLK mux input sel + abort(); + } +} + +/** + * @brief Get the clock source for RTC_FAST_CLK + * + * @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values) + */ +static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void) +{ + uint32_t clk_sel = LP_CLKRST.lp_clk_conf.fast_clk_sel; + switch (clk_sel) { + case 0: + return SOC_RTC_FAST_CLK_SRC_RC_FAST; + case 1: + return SOC_RTC_FAST_CLK_SRC_XTAL_D2; + default: + return SOC_RTC_FAST_CLK_SRC_INVALID; + } +} + +/** + * @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX. + * + * @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage. + */ +static inline __attribute__((always_inline)) void clk_ll_rc_fast_set_divider(uint32_t divider) +{ + // No divider on the target + HAL_ASSERT(divider == 1); +} + +/** + * @brief Get RC_FAST_CLK divider + * + * @return Divider. Divider = (CK8M_DIV_SEL + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider(void) +{ + // No divider on the target, always return divider = 1 + return 1; +} + +/** + * @brief Set RC_SLOW_CLK divider + * + * @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage. + */ +static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider) +{ + // No divider on the target + HAL_ASSERT(divider == 1); +} + +/************************** LP STORAGE REGISTER STORE/LOAD **************************/ +/** + * @brief Store XTAL_CLK frequency in RTC storage register + * + * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit + * halves. These are the routines to work with that representation. + * + * @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even, + * otherwise there will be a conflict with the low bit, which is used to disable logs + * in the ROM code. + */ +static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz) +{ + // Read the status of whether disabling logging from ROM code + uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG; + // If so, need to write back this setting + if (reg == RTC_DISABLE_ROM_LOG) { + xtal_freq_mhz |= 1; + } + WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16)); +} + +/** + * @brief Load XTAL_CLK frequency from RTC storage register + * + * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit + * halves. These are the routines to work with that representation. + * + * @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid. + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void) +{ + // Read from RTC storage register + uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); + if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && + xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { + return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; + } + // If the format in reg is invalid + return 0; +} + +/** + * @brief Store RTC_SLOW_CLK calibration value in RTC storage register + * + * Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds, + * in Q13.19 fixed-point format). + * + * @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format + */ +static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_cal(uint32_t cal_value) +{ + REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value); +} + +/** + * @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register + * + * This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches + * + * @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(void) +{ + return REG_READ(RTC_SLOW_CLK_CAL_REG); +} + +/* +Set the frequency division factor of ref_tick +*/ +static inline void clk_ll_rc_fast_tick_conf(void) +{ + PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/dedic_gpio_cpu_ll.h b/components/hal/esp32c6/include/hal/dedic_gpio_cpu_ll.h new file mode 100644 index 000000000000..0b0850534625 --- /dev/null +++ b/components/hal/esp32c6/include/hal/dedic_gpio_cpu_ll.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "riscv/csr.h" + +/*fast gpio*/ +#define CSR_GPIO_OEN_USER 0x803 +#define CSR_GPIO_IN_USER 0x804 +#define CSR_GPIO_OUT_USER 0x805 + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((always_inline)) +static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask) +{ + RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask); +} + +static inline void dedic_gpio_cpu_ll_write_all(uint32_t value) +{ + RV_WRITE_CSR(CSR_GPIO_OUT_USER, value); +} + +__attribute__((always_inline)) +static inline uint32_t dedic_gpio_cpu_ll_read_in(void) +{ + uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER); + return value; +} + +__attribute__((always_inline)) +static inline uint32_t dedic_gpio_cpu_ll_read_out(void) +{ + uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER); + return value; +} + +__attribute__((always_inline)) +static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value) +{ + RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value); + RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value)); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/ds_ll.h b/components/hal/esp32c6/include/hal/ds_ll.h new file mode 100644 index 000000000000..49f0630c3858 --- /dev/null +++ b/components/hal/esp32c6/include/hal/ds_ll.h @@ -0,0 +1,167 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use it in application code. + ******************************************************************************/ + +#pragma once + +#include +#include +#include + +#include "soc/hwcrypto_reg.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void ds_ll_start(void) +{ + REG_WRITE(DS_SET_START_REG, 1); +} + +/** + * @brief Wait until DS peripheral has finished any outstanding operation. + */ +static inline bool ds_ll_busy(void) +{ + return (REG_READ(DS_QUERY_BUSY_REG) > 0) ? true : false; +} + +/** + * @brief Busy wait until the hardware is ready. + */ +static inline void ds_ll_wait_busy(void) +{ + while (ds_ll_busy()); +} + +/** + * @brief In case of a key error, check what caused it. + */ +static inline ds_key_check_t ds_ll_key_error_source(void) +{ + uint32_t key_error = REG_READ(DS_QUERY_KEY_WRONG_REG); + if (key_error == 0) { + return DS_NO_KEY_INPUT; + } else { + return DS_OTHER_WRONG; + } +} + +/** + * @brief Write the initialization vector to the corresponding register field. + */ +static inline void ds_ll_configure_iv(const uint32_t *iv) +{ + for (size_t i = 0; i < (SOC_DS_KEY_PARAM_MD_IV_LENGTH / sizeof(uint32_t)); i++) { + REG_WRITE(DS_IV_MEM + (i * 4) , iv[i]); + } +} + +/** + * @brief Write the message which should be signed. + * + * @param msg Pointer to the message. + * @param size Length of msg in bytes. It is the RSA signature length in bytes. + */ +static inline void ds_ll_write_message(const uint8_t *msg, size_t size) +{ + memcpy((uint8_t*) DS_X_MEM, msg, size); + asm volatile ("fence"); +} + +/** + * @brief Write the encrypted private key parameters. + */ +static inline void ds_ll_write_private_key_params(const uint8_t *encrypted_key_params) +{ + /* Note: as the internal peripheral still has RSA 4096 structure, + but C is encrypted based on the actual max RSA length (ETS_DS_MAX_BITS), need to fragment it + when copying to hardware... + + (note if ETS_DS_MAX_BITS == 4096, this should be the same as copying data->c to hardware in one fragment) + */ + typedef struct { uint32_t addr; size_t len; } frag_t; + const frag_t frags[] = { + {DS_Y_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8}, + {DS_M_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8}, + {DS_RB_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8}, + {DS_BOX_MEM, DS_IV_MEM - DS_BOX_MEM}, + }; + const size_t NUM_FRAGS = sizeof(frags)/sizeof(frag_t); + const uint8_t *from = encrypted_key_params; + + for (int i = 0; i < NUM_FRAGS; i++) { + memcpy((uint8_t *)frags[i].addr, from, frags[i].len); + asm volatile ("fence"); + from += frags[i].len; + } +} + +/** + * @brief Begin signing procedure. + */ +static inline void ds_ll_start_sign(void) +{ + REG_WRITE(DS_SET_CONTINUE_REG, 1); +} + +/** + * @brief check the calculated signature. + * + * @return + * - DS_SIGNATURE_OK if no issue is detected with the signature. + * - DS_SIGNATURE_PADDING_FAIL if the padding of the private key parameters is wrong. + * - DS_SIGNATURE_MD_FAIL if the message digest check failed. This means that the message digest calculated using + * the private key parameters fails, i.e., the integrity of the private key parameters is not protected. + * - DS_SIGNATURE_PADDING_AND_MD_FAIL if both padding and message digest check fail. + */ +static inline ds_signature_check_t ds_ll_check_signature(void) +{ + uint32_t result = REG_READ(DS_QUERY_CHECK_REG); + switch(result) { + case 0: + return DS_SIGNATURE_OK; + case 1: + return DS_SIGNATURE_MD_FAIL; + case 2: + return DS_SIGNATURE_PADDING_FAIL; + default: + return DS_SIGNATURE_PADDING_AND_MD_FAIL; + } +} + +/** + * @brief Read the signature from the hardware. + * + * @param result The signature result. + * @param size Length of signature result in bytes. It is the RSA signature length in bytes. + */ +static inline void ds_ll_read_result(uint8_t *result, size_t size) +{ + memcpy(result, (uint8_t*) DS_Z_MEM, size); + asm volatile ("fence"); +} + +/** + * @brief Exit the signature operation. + * + * @note This does not deactivate the module. Corresponding clock/reset bits have to be triggered for deactivation. + */ +static inline void ds_ll_finish(void) +{ + REG_WRITE(DS_SET_FINISH_REG, 1); + ds_ll_wait_busy(); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/ecc_ll.h b/components/hal/esp32c6/include/hal/ecc_ll.h new file mode 100644 index 000000000000..9df9655e5da3 --- /dev/null +++ b/components/hal/esp32c6/include/hal/ecc_ll.h @@ -0,0 +1,144 @@ +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/ecc_mult_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ECC_PARAM_PX = 0x0, + ECC_PARAM_PY, + ECC_PARAM_K, +} ecc_ll_param_t; + +static inline void ecc_ll_enable_interrupt(void) +{ + REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); +} + +static inline void ecc_ll_disable_interrupt(void) +{ + REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 0); +} + +static inline void ecc_ll_clear_interrupt(void) +{ + REG_SET_FIELD(ECC_MULT_INT_CLR_REG, ECC_MULT_CALC_DONE_INT_CLR, 1); +} + +static inline void ecc_ll_set_mode(ecc_mode_t mode) +{ + switch(mode) { + case ECC_MODE_POINT_MUL: + REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0); + break; + case ECC_MODE_VERIFY: + REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2); + break; + case ECC_MODE_VERIFY_THEN_POINT_MUL: + REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 3); + break; + default: + HAL_ASSERT(false && "Unsupported mode"); + break; + } +} + +static inline void ecc_ll_set_curve(ecc_curve_t curve) +{ + switch(curve) { + case ECC_CURVE_SECP256R1: + REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH); + break; + case ECC_CURVE_SECP192R1: + REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH); + break; + default: + HAL_ASSERT(false && "Unsupported curve"); + return; + } +} + +static inline void ecc_ll_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len) +{ + uint32_t reg; + uint32_t word; + switch (param) { + case ECC_PARAM_PX: + reg = ECC_MULT_PX_MEM; + break; + case ECC_PARAM_PY: + reg = ECC_MULT_PY_MEM; + break; + case ECC_PARAM_K: + reg = ECC_MULT_K_MEM; + break; + default: + HAL_ASSERT(false && "Invalid parameter"); + return; + } + + for (int i = 0; i < len; i += 4) { + memcpy(&word, buf + i, 4); + REG_WRITE(reg + i, word); + } +} + +static inline void ecc_ll_start_calc(void) +{ + REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_START); +} + +static inline int ecc_ll_is_calc_finished(void) +{ + return REG_GET_FIELD(ECC_MULT_INT_RAW_REG, ECC_MULT_CALC_DONE_INT_RAW); +} + +static inline ecc_mode_t ecc_ll_get_mode(void) +{ + return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE); +} + +static inline int ecc_ll_get_verification_result(void) +{ + return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_VERIFICATION_RESULT); +} + +static inline ecc_curve_t ecc_ll_get_curve(void) +{ + return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH); +} + +static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len) +{ + uint32_t reg; + switch (param) { + case ECC_PARAM_PX: + reg = ECC_MULT_PX_MEM; + break; + case ECC_PARAM_PY: + reg = ECC_MULT_PY_MEM; + break; + case ECC_PARAM_K: + reg = ECC_MULT_K_MEM; + break; + default: + HAL_ASSERT(false && "Invalid parameter"); + return; + } + + memcpy(buf, (void *)reg, len); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/efuse_hal.h b/components/hal/esp32c6/include/hal/efuse_hal.h new file mode 100644 index 000000000000..b6c83d6da6d1 --- /dev/null +++ b/components/hal/esp32c6/include/hal/efuse_hal.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/soc_caps.h" +#include "hal/efuse_ll.h" +#include_next "hal/efuse_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief get chip version + */ +uint32_t efuse_hal_get_chip_revision(void); + +/** + * @brief set eFuse timings + * + * @param apb_freq_hz APB frequency in Hz + */ +void efuse_hal_set_timing(uint32_t apb_freq_hz); + +/** + * @brief trigger eFuse read operation + */ +void efuse_hal_read(void); + +/** + * @brief clear registers for programming eFuses + */ +void efuse_hal_clear_program_registers(void); + +/** + * @brief burn eFuses written in programming registers (one block at once) + * + * @param block block number + */ +void efuse_hal_program(uint32_t block); + +/** + * @brief Calculate Reed-Solomon Encoding values for a block of efuse data. + * + * @param data Pointer to data buffer (length 32 bytes) + * @param rs_values Pointer to write encoded data to (length 12 bytes) + */ +void efuse_hal_rs_calculate(const void *data, void *rs_values); + +/** + * @brief Checks coding error in a block + * + * @param block Index of efuse block + * + * @return True - block has an error. + * False - no error. + */ +bool efuse_hal_is_coding_error_in_block(unsigned block); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/efuse_ll.h b/components/hal/esp32c6/include/hal/efuse_ll.h new file mode 100644 index 000000000000..9a31621f49a3 --- /dev/null +++ b/components/hal/esp32c6/include/hal/efuse_ll.h @@ -0,0 +1,182 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/efuse_periph.h" +#include "hal/assert.h" +#include "esp32c6/rom/efuse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Always inline these functions even no gcc optimization is applied. + +/******************* eFuse fields *************************/ + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_flash_crypt_cnt(void) +{ + return EFUSE.rd_repeat_data1.spi_boot_crypt_cnt; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_wdt_delay_sel(void) +{ + return EFUSE.rd_repeat_data1.wdt_delay_sel; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_mac0(void) +{ + return EFUSE.rd_mac_spi_sys_0.mac_0; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_mac1(void) +{ + return EFUSE.rd_mac_spi_sys_1.mac_1; +} + +__attribute__((always_inline)) static inline bool efuse_ll_get_secure_boot_v2_en(void) +{ + return EFUSE.rd_repeat_data2.secure_boot_en; +} + +// use efuse_hal_get_major_chip_version() to get major chip version +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_wafer_version_major(void) +{ + return EFUSE.rd_mac_spi_sys_3.wafer_version_major; +} + +// use efuse_hal_get_minor_chip_version() to get minor chip version +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_wafer_version_minor(void) +{ + return EFUSE.rd_mac_spi_sys_3.wafer_version_minor; +} + +__attribute__((always_inline)) static inline bool efuse_ll_get_disable_wafer_version_major(void) +{ + return EFUSE.rd_repeat_data4.disable_wafer_version_major; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_active_hp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.active_hp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_active_lp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.active_lp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_lslp_dbg(void) +{ + return EFUSE.rd_mac_spi_sys_2.lslp_hp_dbg; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_lslp_hp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.lslp_hp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_dslp_dbg(void) +{ + return EFUSE.rd_mac_spi_sys_2.dslp_lp_dbg; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_dslp_lp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.dslp_lp_dbias; +} + +__attribute__((always_inline)) static inline int32_t efuse_ll_get_dbias_vol_gap(void) +{ + return EFUSE.rd_mac_spi_sys_2.dbias_vol_gap; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_major(void) +{ + return EFUSE.rd_mac_spi_sys_3.blk_version_major; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_minor(void) +{ + return EFUSE.rd_mac_spi_sys_3.blk_version_minor; +} + +__attribute__((always_inline)) static inline bool efuse_ll_get_disable_blk_version_major(void) +{ + return EFUSE.rd_repeat_data4.disable_blk_version_major; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg(void) +{ + return EFUSE.rd_mac_spi_sys_3.pkg_version; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_ocode(void) +{ + return EFUSE.rd_sys_part1_data4.ocode; +} + +/******************* eFuse control functions *************************/ + +__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void) +{ + return EFUSE.cmd.read_cmd; +} + +__attribute__((always_inline)) static inline bool efuse_ll_get_pgm_cmd(void) +{ + return EFUSE.cmd.pgm_cmd; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_read_cmd(void) +{ + EFUSE.cmd.read_cmd = 1; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_pgm_cmd(uint32_t block) +{ + HAL_ASSERT(block < ETS_EFUSE_BLOCK_MAX); + EFUSE.cmd.val = ((block << EFUSE_BLK_NUM_S) & EFUSE_BLK_NUM_M) | EFUSE_PGM_CMD; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_conf_read_op_code(void) +{ + EFUSE.conf.op_code = EFUSE_READ_OP_CODE; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_conf_write_op_code(void) +{ + EFUSE.conf.op_code = EFUSE_WRITE_OP_CODE; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_dac_num(uint8_t val) +{ + EFUSE.dac_conf.dac_num = val; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_dac_clk_div(uint8_t val) +{ + EFUSE.dac_conf.dac_clk_div = val; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_pwr_on_num(uint16_t val) +{ + EFUSE.wr_tim_conf1.pwr_on_num = val; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint16_t value) +{ + EFUSE.wr_tim_conf2.pwr_off_num = value; +} + +/******************* eFuse control functions *************************/ + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/etm_ll.h b/components/hal/esp32c6/include/hal/etm_ll.h new file mode 100644 index 000000000000..535a94eb2e8c --- /dev/null +++ b/components/hal/esp32c6/include/hal/etm_ll.h @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/lp_aon_ll.h" +#include "soc/soc_etm_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable the clock for ETM module + * + * @param hw ETM register base address + * @param enable true to enable, false to disable + */ +static inline void etm_ll_enable_clock(soc_etm_dev_t *hw, bool enable) +{ + hw->clk_en.clk_en = enable; +} + +/** + * @brief Enable ETM channel + * + * @param hw ETM register base address + * @param chan Channel ID + */ +static inline void etm_ll_enable_channel(soc_etm_dev_t *hw, uint32_t chan) +{ + if (chan < 32) { + hw->ch_ena_ad0_set.val = 1 << chan; + } else { + hw->ch_ena_ad1_set.val = 1 << (chan - 32); + } +} + +/** + * @brief Disable ETM channel + * + * @param hw ETM register base address + * @param chan Channel ID + */ +static inline void etm_ll_disable_channel(soc_etm_dev_t *hw, uint32_t chan) +{ + if (chan < 32) { + hw->ch_ena_ad0_clr.val = 1 << chan; + } else { + hw->ch_ena_ad1_clr.val = 1 << (chan - 32); + } +} + +/** + * @brief Check whether the ETM channel is enabled or not + * + * @param hw ETM register base address + * @param chan Channel ID + * @return true if the channel is enabled, false otherwise + */ +static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) +{ + if (chan < 32) { + return hw->ch_ena_ad0.val & (1 << chan); + } else { + return hw->ch_ena_ad1.val & (1 << (chan - 32)); + } +} + +/** + * @brief Set the input event for the ETM channel + * + * @param hw ETM register base address + * @param chan Channel ID + * @param event Event ID + */ +static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) +{ + hw->channel[chan].evt_id.evt_id = event; +} + +/** + * @brief Set the output task for the ETM channel + * + * @param hw ETM register base address + * @param chan Channel ID + * @param task Task ID + */ +static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) +{ + hw->channel[chan].task_id.task_id = task; +} + +#define etm_ll_is_lpcore_wakeup_triggered() lp_aon_ll_get_lpcore_etm_wakeup_flag() + +#define etm_ll_clear_lpcore_wakeup_status() lp_aon_ll_clear_lpcore_etm_wakeup_flag() + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/gdma_ll.h b/components/hal/esp32c6/include/hal/gdma_ll.h new file mode 100644 index 000000000000..57969ca513c7 --- /dev/null +++ b/components/hal/esp32c6/include/hal/gdma_ll.h @@ -0,0 +1,546 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include /* Required for NULL constant */ +#include +#include +#include "hal/gdma_types.h" +#include "soc/gdma_struct.h" +#include "soc/gdma_reg.h" +#include "soc/soc_etm_source.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) + +#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] + +#define GDMA_LL_RX_EVENT_MASK (0x7F) +#define GDMA_LL_TX_EVENT_MASK (0x3F) + +// any "dummy" peripheral ID can be used for M2M mode +#define GDMA_LL_M2M_FREE_PERIPH_ID_MASK (0xFC32) +#define GDMA_LL_INVALID_PERIPH_ID (0x3F) + +#define GDMA_LL_EVENT_TX_FIFO_UDF (1<<5) +#define GDMA_LL_EVENT_TX_FIFO_OVF (1<<4) +#define GDMA_LL_EVENT_RX_FIFO_UDF (1<<6) +#define GDMA_LL_EVENT_RX_FIFO_OVF (1<<5) +#define GDMA_LL_EVENT_TX_TOTAL_EOF (1<<3) +#define GDMA_LL_EVENT_RX_DESC_EMPTY (1<<4) +#define GDMA_LL_EVENT_TX_DESC_ERROR (1<<2) +#define GDMA_LL_EVENT_RX_DESC_ERROR (1<<3) +#define GDMA_LL_EVENT_TX_EOF (1<<1) +#define GDMA_LL_EVENT_TX_DONE (1<<0) +#define GDMA_LL_EVENT_RX_ERR_EOF (1<<2) +#define GDMA_LL_EVENT_RX_SUC_EOF (1<<1) +#define GDMA_LL_EVENT_RX_DONE (1<<0) + +#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ + (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH1, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH2, \ + }}}[group][chan][event] + +#define GDMA_LL_RX_ETM_EVENT_TABLE(group, chan, event) \ + (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH0, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH1, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH2, \ + }}}[group][chan][event] + +#define GDMA_LL_TX_ETM_TASK_TABLE(group, chan, task) \ + (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH0, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH1, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH2, \ + }}}[group][chan][task] + +#define GDMA_LL_RX_ETM_TASK_TABLE(group, chan, task) \ + (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH0, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH1, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH2, \ + }}}[group][chan][task] + +///////////////////////////////////// Common ///////////////////////////////////////// +/** + * @brief Enable DMA clock gating + */ +static inline void gdma_ll_enable_clock(gdma_dev_t *dev, bool enable) +{ + dev->misc_conf.clk_en = enable; +} + +///////////////////////////////////// RX ///////////////////////////////////////// +/** + * @brief Get DMA RX channel interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel) +{ + return dev->in_intr[channel].st.val & GDMA_LL_RX_EVENT_MASK; +} + +/** + * @brief Enable DMA RX channel interrupt + */ +static inline void gdma_ll_rx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) +{ + if (enable) { + dev->in_intr[channel].ena.val |= (mask & GDMA_LL_RX_EVENT_MASK); + } else { + dev->in_intr[channel].ena.val &= ~(mask & GDMA_LL_RX_EVENT_MASK); + } +} + +/** + * @brief Clear DMA RX channel interrupt + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask) +{ + dev->in_intr[channel].clr.val = (mask & GDMA_LL_RX_EVENT_MASK); +} + +/** + * @brief Get DMA RX channel interrupt status register address + */ +static inline volatile void *gdma_ll_rx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel) +{ + return (volatile void *)(&dev->in_intr[channel].st); +} + +/** + * @brief Enable DMA RX channel to check the owner bit in the descriptor, disabled by default + */ +static inline void gdma_ll_rx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf1.in_check_owner = enable; +} + +/** + * @brief Enable DMA RX channel burst reading data, disabled by default + */ +static inline void gdma_ll_rx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf0.in_data_burst_en = enable; +} + +/** + * @brief Enable DMA RX channel burst reading descriptor link, disabled by default + */ +static inline void gdma_ll_rx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf0.indscr_burst_en = enable; +} + +/** + * @brief Reset DMA RX channel FSM and FIFO pointer + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_reset_channel(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_conf0.in_rst = 1; + dev->channel[channel].in.in_conf0.in_rst = 0; +} + +/** + * @brief Check if DMA RX FIFO is full + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_rx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].in.infifo_status.val & 0x01; +} + +/** + * @brief Check if DMA RX FIFO is empty + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_rx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].in.infifo_status.val & 0x02; +} + +/** + * @brief Get number of bytes in RX FIFO + * @param fifo_level only supports level 1 + */ +static inline uint32_t gdma_ll_rx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].in.infifo_status.infifo_cnt; +} + +/** + * @brief Pop data from DMA RX FIFO + */ +static inline uint32_t gdma_ll_rx_pop_data(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_pop.infifo_pop = 1; + return dev->channel[channel].in.in_pop.infifo_rdata; +} + +/** + * @brief Set the descriptor link base address for RX channel + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr) +{ + dev->channel[channel].in.in_link.inlink_addr = addr; +} + +/** + * @brief Start dealing with RX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_start(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_link.inlink_start = 1; +} + +/** + * @brief Stop dealing with RX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_stop(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_link.inlink_stop = 1; +} + +/** + * @brief Restart a new inlink right after the last descriptor + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_restart(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_link.inlink_restart = 1; +} + +/** + * @brief Enable DMA RX to return the address of current descriptor when receives error + */ +static inline void gdma_ll_rx_enable_auto_return(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_link.inlink_auto_ret = enable; +} + +/** + * @brief Check if DMA RX FSM is in IDLE state + */ +static inline bool gdma_ll_rx_is_fsm_idle(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_link.inlink_park; +} + +/** + * @brief Get RX success EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_success_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_suc_eof_des_addr.val; +} + +/** + * @brief Get RX error EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_error_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_err_eof_des_addr.val; +} + +/** + * @brief Get current RX descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_current_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_dscr.val; +} + +/** + * @brief Set priority for DMA RX channel + */ +static inline void gdma_ll_rx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio) +{ + dev->channel[channel].in.in_pri.rx_pri = prio; +} + +/** + * @brief Connect DMA RX channel to a given peripheral + */ +static inline void gdma_ll_rx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) +{ + dev->channel[channel].in.in_peri_sel.peri_in_sel = periph_id; + dev->channel[channel].in.in_conf0.mem_trans_en = (periph == GDMA_TRIG_PERIPH_M2M); +} + +/** + * @brief Disconnect DMA RX channel from peripheral + */ +static inline void gdma_ll_rx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_peri_sel.peri_in_sel = GDMA_LL_INVALID_PERIPH_ID; + dev->channel[channel].in.in_conf0.mem_trans_en = false; +} + +/** + * @brief Whether to enable the ETM subsystem for RX channel + * + * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. + */ +static inline void gdma_ll_rx_enable_etm_task(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf0.in_etm_en = enable; +} + +///////////////////////////////////// TX ///////////////////////////////////////// +/** + * @brief Get DMA TX channel interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_tx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel) +{ + return dev->out_intr[channel].st.val & GDMA_LL_TX_EVENT_MASK; +} + +/** + * @brief Enable DMA TX channel interrupt + */ +static inline void gdma_ll_tx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) +{ + if (enable) { + dev->out_intr[channel].ena.val |= (mask & GDMA_LL_TX_EVENT_MASK); + } else { + dev->out_intr[channel].ena.val &= ~(mask & GDMA_LL_TX_EVENT_MASK); + } +} + +/** + * @brief Clear DMA TX channel interrupt + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask) +{ + dev->out_intr[channel].clr.val = (mask & GDMA_LL_TX_EVENT_MASK); +} + +/** + * @brief Get DMA TX channel interrupt status register address + */ +static inline volatile void *gdma_ll_tx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel) +{ + return (volatile void *)(&dev->out_intr[channel].st); +} + +/** + * @brief Enable DMA TX channel to check the owner bit in the descriptor, disabled by default + */ +static inline void gdma_ll_tx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf1.out_check_owner = enable; +} + +/** + * @brief Enable DMA TX channel burst sending data, disabled by default + */ +static inline void gdma_ll_tx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.out_data_burst_en = enable; +} + +/** + * @brief Enable DMA TX channel burst reading descriptor link, disabled by default + */ +static inline void gdma_ll_tx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.outdscr_burst_en = enable; +} + +/** + * @brief Set TX channel EOF mode + */ +static inline void gdma_ll_tx_set_eof_mode(gdma_dev_t *dev, uint32_t channel, uint32_t mode) +{ + dev->channel[channel].out.out_conf0.out_eof_mode = mode; +} + +/** + * @brief Enable DMA TX channel automatic write results back to descriptor after all data has been sent out, disabled by default + */ +static inline void gdma_ll_tx_enable_auto_write_back(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.out_auto_wrback = enable; +} + +/** + * @brief Reset DMA TX channel FSM and FIFO pointer + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_reset_channel(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_conf0.out_rst = 1; + dev->channel[channel].out.out_conf0.out_rst = 0; +} + +/** + * @brief Check if DMA TX FIFO is full + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_tx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].out.outfifo_status.val & 0x01; +} + +/** + * @brief Check if DMA TX FIFO is empty + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_tx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].out.outfifo_status.val & 0x02; +} + +/** + * @brief Get number of bytes in TX FIFO + * @param fifo_level only supports level 1 + */ +static inline uint32_t gdma_ll_tx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].out.outfifo_status.outfifo_cnt; +} + +/** + * @brief Push data into DMA TX FIFO + */ +static inline void gdma_ll_tx_push_data(gdma_dev_t *dev, uint32_t channel, uint32_t data) +{ + dev->channel[channel].out.out_push.outfifo_wdata = data; + dev->channel[channel].out.out_push.outfifo_push = 1; +} + +/** + * @brief Set the descriptor link base address for TX channel + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr) +{ + dev->channel[channel].out.out_link.outlink_addr = addr; +} + +/** + * @brief Start dealing with TX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_start(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_link.outlink_start = 1; +} + +/** + * @brief Stop dealing with TX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_stop(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_link.outlink_stop = 1; +} + +/** + * @brief Restart a new outlink right after the last descriptor + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_restart(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_link.outlink_restart = 1; +} + +/** + * @brief Check if DMA TX FSM is in IDLE state + */ +static inline bool gdma_ll_tx_is_fsm_idle(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].out.out_link.outlink_park; +} + +/** + * @brief Get TX EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_tx_get_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].out.out_eof_des_addr.val; +} + +/** + * @brief Get current TX descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_tx_get_current_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].out.out_dscr.val; +} + +/** + * @brief Set priority for DMA TX channel + */ +static inline void gdma_ll_tx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio) +{ + dev->channel[channel].out.out_pri.tx_pri = prio; +} + +/** + * @brief Connect DMA TX channel to a given peripheral + */ +static inline void gdma_ll_tx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) +{ + (void)periph; + dev->channel[channel].out.out_peri_sel.peri_out_sel = periph_id; +} + +/** + * @brief Disconnect DMA TX channel from peripheral + */ +static inline void gdma_ll_tx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_peri_sel.peri_out_sel = GDMA_LL_INVALID_PERIPH_ID; +} + +/** + * @brief Whether to enable the ETM subsystem for TX channel + * + * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. + */ +static inline void gdma_ll_tx_enable_etm_task(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.out_etm_en = enable; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/gpio_etm_ll.h b/components/hal/esp32c6/include/hal/gpio_etm_ll.h new file mode 100644 index 000000000000..6d380b27aede --- /dev/null +++ b/components/hal/esp32c6/include/hal/gpio_etm_ll.h @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "soc/gpio_ext_struct.h" +#include "soc/soc_etm_source.h" + +#define GPIO_LL_ETM_EVENT_ID_POS_EDGE(ch) (GPIO_EVT_CH0_RISE_EDGE + (ch)) +#define GPIO_LL_ETM_EVENT_ID_NEG_EDGE(ch) (GPIO_EVT_CH0_FALL_EDGE + (ch)) +#define GPIO_LL_ETM_EVENT_ID_ANY_EDGE(ch) (GPIO_EVT_CH0_ANY_EDGE + (ch)) + +#define GPIO_LL_ETM_TASK_ID_SET(ch) (GPIO_TASK_CH0_SET + (ch)) +#define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch)) +#define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch)) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set which GPIO to be bounded to the event channel + * + * @param dev Register base address + * @param chan Channel number + * @param gpio_num GPIO number + */ +static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num) +{ + dev->event_chn_cfg[chan].etm_ch0_event_sel = gpio_num; +} + +/** + * @brief Wether to enable the event channel + * + * @param dev Register base address + * @param chan Channel number + * @param enable True to enable, false to disable + */ +static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable) +{ + dev->event_chn_cfg[chan].etm_ch0_event_en = enable; +} + +/** + * @brief Set which GPIO to be bounded to the task channel + * + * @note One channel can be bounded to multiple different GPIOs + * + * @param dev Register base address + * @param chan Channel number + * @param gpio_num GPIO number + */ +static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan) +{ + int g_p = gpio_num / 4; + int g_idx = gpio_num % 4; + uint32_t reg_val = dev->etm_task_pn_cfg[g_p].val; + reg_val &= ~(0x07 << (g_idx * 8 + 1)); + reg_val |= ((chan & 0x07) << (g_idx * 8 + 1)); + dev->etm_task_pn_cfg[g_p].val = reg_val; +} + +/** + * @brief Wether to enable the GPIO to be managed by the task channel + * + * @param dev Register base address + * @param gpio_num GPIO number + * @param enable True to enable, false to disable + */ +static inline void gpio_ll_etm_enable_task_gpio(gpio_etm_dev_t *dev, uint32_t gpio_num, bool enable) +{ + int g_p = gpio_num / 4; + int g_idx = gpio_num % 4; + uint32_t reg_val = dev->etm_task_pn_cfg[g_p].val; + reg_val &= ~(0x01 << (g_idx * 8)); + reg_val |= ((enable & 0x01) << (g_idx * 8)); + dev->etm_task_pn_cfg[g_p].val = reg_val; +} + +/** + * @brief Check whether a GPIO has been enabled and managed by a task channel + * + * @param dev Register base address + * @param gpio_num GPIO number + * @return True if enabled, false otherwise + */ +static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_t gpio_num) +{ + int g_p = gpio_num / 4; + int g_idx = gpio_num % 4; + return dev->etm_task_pn_cfg[g_p].val & (0x01 << (g_idx * 8)); +} + +/** + * @brief Get the channel number that the GPIO is bounded to + * + * @param dev Register base address + * @param gpio_num GPIO number + * @return GPIO ETM Task channel number + */ +static inline uint32_t gpio_ll_etm_gpio_get_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num) +{ + int g_p = gpio_num / 4; + int g_idx = gpio_num % 4; + return (dev->etm_task_pn_cfg[g_p].val >> (g_idx * 8 + 1)) & 0x07; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/gpio_glitch_filter_ll.h b/components/hal/esp32c6/include/hal/gpio_glitch_filter_ll.h new file mode 100644 index 000000000000..86d52ba43da7 --- /dev/null +++ b/components/hal/esp32c6/include/hal/gpio_glitch_filter_ll.h @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include "hal/assert.h" +#include "soc/gpio_ext_struct.h" + +// the max window size is expected to be 64, but due to a hardware issue, we need to limit it to 63 +#define GPIO_LL_GLITCH_FILTER_MAX_WINDOW 63 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable GPIO glitch filter + * + * @param hw Glitch filter register base address + * @param filter_idx Glitch filter index + * @param enable True to enable, false to disable + */ +static inline void gpio_ll_glitch_filter_enable(gpio_glitch_filter_dev_t *hw, uint32_t filter_idx, bool enable) +{ + hw->glitch_filter_chn[filter_idx].filter_chn_en = enable; +} + +/** + * @brief Set the input GPIO for the glitch filter + * + * @param hw Glitch filter register base address + * @param filter_idx Glitch filter index + * @param gpio_num GPIO number + */ +static inline void gpio_ll_glitch_filter_set_gpio(gpio_glitch_filter_dev_t *hw, uint32_t filter_idx, uint32_t gpio_num) +{ + hw->glitch_filter_chn[filter_idx].filter_chn_input_io_num = gpio_num; +} + +/** + * @brief Set the coefficient of the glitch filter window + * + * @param hw Glitch filter register base address + * @param filter_idx Glitch filter index + * @param window_width Window width, in IOMUX clock ticks + * @param window_threshold Window threshold, in IOMUX clock ticks + */ +static inline void gpio_ll_glitch_filter_set_window_coeff(gpio_glitch_filter_dev_t *hw, uint32_t filter_idx, uint32_t window_width, uint32_t window_thres) +{ + HAL_ASSERT(window_thres <= window_width); + hw->glitch_filter_chn[filter_idx].filter_chn_window_width = window_width - 1; + hw->glitch_filter_chn[filter_idx].filter_chn_window_thres = window_thres - 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h new file mode 100644 index 000000000000..b9e71854addb --- /dev/null +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -0,0 +1,687 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for ESP32-C6 GPIO register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/gpio_periph.h" +#include "soc/gpio_struct.h" +#include "soc/lp_aon_struct.h" +#include "soc/lp_io_struct.h" +#include "soc/pmu_struct.h" +#include "soc/usb_serial_jtag_reg.h" +#include "soc/pcr_struct.h" +#include "soc/clk_tree_defs.h" +#include "hal/gpio_types.h" +#include "hal/misc.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Get GPIO hardware instance with giving gpio num +#define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) + +#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) +#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) + +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_mask = 1 << gpio_num; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (hw->enable.val & bit_mask) >> gpio_num; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + +/** + * @brief Enable pull-up on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) +{ + REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU); +} + +/** + * @brief Disable pull-up on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +__attribute__((always_inline)) +static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) +{ + REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU); +} + +/** + * @brief Enable pull-down on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) +{ + REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD); +} + +/** + * @brief Disable pull-down on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +__attribute__((always_inline)) +static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) +{ + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that esp32c6 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin + // which should be checked is USB_DM_GPIO_NUM instead. + // TODO: read the specific efuse with efuse_ll.h + if (gpio_num == USB_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + } + REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD); +} + +/** + * @brief GPIO set interrupt trigger type + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param intr_type Interrupt type, select from gpio_int_type_t + */ +static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type) +{ + hw->pin[gpio_num].int_type = intr_type; +} + +/** + * @brief Get GPIO interrupt status + * + * @param hw Peripheral GPIO hardware instance address. + * @param core_id interrupt core id + * @param status interrupt status + */ +__attribute__((always_inline)) +static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) +{ + (void)core_id; + *status = hw->pcpu_int.procpu_int; +} + +/** + * @brief Get GPIO interrupt status high + * + * @param hw Peripheral GPIO hardware instance address. + * @param core_id interrupt core id + * @param status interrupt status high + */ +__attribute__((always_inline)) +static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) +{ + *status = 0; // Less than 32 GPIOs in ESP32-C6 +} + +/** + * @brief Clear GPIO interrupt status + * + * @param hw Peripheral GPIO hardware instance address. + * @param mask interrupt status clear mask + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_intr_status(gpio_dev_t *hw, uint32_t mask) +{ + hw->status_w1tc.status_w1tc = mask; +} + +/** + * @brief Clear GPIO interrupt status high + * + * @param hw Peripheral GPIO hardware instance address. + * @param mask interrupt status high clear mask + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask) +{ + // Less than 32 GPIOs on ESP32-C6 Do nothing. +} + +/** + * @brief Enable GPIO module interrupt signal + * + * @param hw Peripheral GPIO hardware instance address. + * @param core_id Interrupt enabled CPU to corresponding ID + * @param gpio_num GPIO number. If you want to enable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); + */ +__attribute__((always_inline)) +static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, uint32_t gpio_num) +{ + HAL_ASSERT(core_id == 0 && "target SoC only has a single core"); + GPIO.pin[gpio_num].int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable pro cpu intr +} + +/** + * @brief Disable GPIO module interrupt signal + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number. If you want to disable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); + */ +__attribute__((always_inline)) +static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->pin[gpio_num].int_ena = 0; //disable GPIO intr +} + +/** + * @brief Disable input mode on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +__attribute__((always_inline)) +static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Enable input mode on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Enable GPIO pin filter + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + */ +static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable GPIO pin filter + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + */ +static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable output mode on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +__attribute__((always_inline)) +static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->enable_w1tc.enable_w1tc = (0x1 << gpio_num); + // Ensure no other output signal is routed via GPIO matrix to this pin + REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), + SIG_GPIO_OUT_IDX); +} + +/** + * @brief Enable output mode on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_output_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->enable_w1ts.enable_w1ts = (0x1 << gpio_num); +} + +/** + * @brief Disable open-drain mode on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_od_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->pin[gpio_num].pad_driver = 0; +} + +/** + * @brief Enable open-drain mode on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->pin[gpio_num].pad_driver = 1; +} + +/** + * @brief GPIO set output level + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param level Output level. 0: low ; 1: high + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level) +{ + if (level) { + hw->out_w1ts.out_w1ts = (1 << gpio_num); + } else { + hw->out_w1tc.out_w1tc = (1 << gpio_num); + } +} + +/** + * @brief GPIO get input level + * + * @warning If the pad is not configured for input (or input and output) the returned value is always 0. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number. If you want to get the logic level of e.g. pin GPIO16, gpio_num should be GPIO_NUM_16 (16); + * + * @return + * - 0 the GPIO input level is 0 + * - 1 the GPIO input level is 1 + */ +static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) +{ + return (hw->in.in_data_next >> gpio_num) & 0x1; +} + +/** + * @brief Enable GPIO wake-up function. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number. + */ +static inline void gpio_ll_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->pin[gpio_num].wakeup_enable = 0x1; +} + +/** + * @brief Disable GPIO wake-up function. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + hw->pin[gpio_num].wakeup_enable = 0; +} + +/** + * @brief Set GPIO pad drive capability + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number, only support output GPIOs + * @param strength Drive capability of the pad + */ +static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) +{ + SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, strength, FUN_DRV_S); +} + +/** + * @brief Get GPIO pad drive capability + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number, only support output GPIOs + * @param strength Pointer to accept drive capability of the pad + */ +static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) +{ + *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); +} + +/** + * @brief Enable gpio pad hold function. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number, only support output GPIOs + */ +static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 |= GPIO_HOLD_MASK[gpio_num]; +} + +/** + * @brief Disable gpio pad hold function. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number, only support output GPIOs + */ +static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num]; +} + +/** + * @brief Get digital gpio pad hold status. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number, only support output GPIOs + * + * @note caller must ensure that gpio_num is a digital io pad + * + * @return + * - true digital gpio pad is held + * - false digital gpio pad is unheld + */ +__attribute__((always_inline)) +static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) +{ + return !!(LP_AON.gpio_hold0.gpio_hold0 & GPIO_HOLD_MASK[gpio_num]); +} + +/** + * @brief Set pad input to a peripheral signal through the IOMUX. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + */ +__attribute__((always_inline)) +static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = 0; + PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); +} + +/** + * @brief Select a function for the pin in the IOMUX + * + * @param pin_name Pin name to configure + * @param func Function to assign to the pin + */ +static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) +{ + // Disable USB Serial JTAG if pins 12 or pins 13 needs to select an IOMUX function + if (pin_name == IO_MUX_GPIO12_REG || pin_name == IO_MUX_GPIO13_REG) { + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); + } + PIN_FUNC_SELECT(pin_name, func); +} + +/** + * @brief Select a function for the pin in the IOMUX + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param func Function to assign to the pin + */ +__attribute__((always_inline)) +static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func) +{ + // Disable USB Serial JTAG if pins 12 or pins 13 needs to select an IOMUX function + if (gpio_num == USB_DM_GPIO_NUM || gpio_num == USB_DP_GPIO_NUM) { + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); + } + PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func); +} + +/** + * @brief Set peripheral output to an GPIO pad through the IOMUX. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num gpio_num GPIO number of the pad. + * @param func The function number of the peripheral pin to output pin. + * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_sel = 0; + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_iomux_func_sel(IO_MUX_GPIO0_REG + (gpio_num * 4), func); +} + +/** + * @brief Set clock source of IO MUX module + * + * @param src IO MUX clock source (only a subset of soc_module_clk_t values are valid) + */ +static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) +{ + switch (src) { + case SOC_MOD_CLK_XTAL: + PCR.iomux_clk_conf.iomux_func_clk_sel = 3; + break; + case SOC_MOD_CLK_PLL_F80M: + PCR.iomux_clk_conf.iomux_func_clk_sel = 1; + break; + default: + // Unsupported IO_MUX clock source + HAL_ASSERT(false); + } +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + +/** + * @brief Force hold digital io pad. + * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. + */ +static inline void gpio_ll_force_hold_all(void) +{ + // WT flag, it gets self-cleared after the configuration is done + PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1; +} + +/** + * @brief Force unhold digital io pad. + * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode. + */ +static inline void gpio_ll_force_unhold_all(void) +{ + // WT flag, it gets self-cleared after the configuration is done + PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1; +} + +/** + * @brief Enable GPIO pin to use sleep mode pin functions during light sleep. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_SEL_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable GPIO pin to use sleep mode pin functions during light sleep. + * Pin functions remains the same in both normal execution and in light-sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_SEL_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable GPIO pull-up in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_PULLUP_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Enable GPIO pull-up in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_PULLUP_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Enable GPIO pull-down in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_PULLDOWN_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable GPIO pull-down in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_PULLDOWN_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable GPIO input in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Enable GPIO input in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Disable GPIO output in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_OUTPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/** + * @brief Enable GPIO output in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); +} + +/* Names used by the shared GPIO driver. C6 implements them as force-hold and pad wakeup. */ +static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw) +{ + (void)hw; + gpio_ll_force_hold_all(); +} + +static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) +{ + (void)hw; + gpio_ll_force_unhold_all(); +} + +static inline void gpio_ll_deepsleep_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type) +{ + (void)intr_type; + gpio_ll_wakeup_enable(hw, gpio_num); +} + +static inline void gpio_ll_deepsleep_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + gpio_ll_wakeup_disable(hw, gpio_num); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/gpspi_flash_ll.h b/components/hal/esp32c6/include/hal/gpspi_flash_ll.h new file mode 100644 index 000000000000..1cd9da5ea45a --- /dev/null +++ b/components/hal/esp32c6/include/hal/gpspi_flash_ll.h @@ -0,0 +1,395 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +// The Lowlevel layer for SPI Flash + +#pragma once + +#include +#include "soc/spi_periph.h" +#include "soc/spi_struct.h" +#include "hal/spi_types.h" +#include "hal/spi_flash_types.h" +#include // For MIN/MAX +#include +#include +#include "hal/misc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash. +#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) ) +#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 ) + +typedef typeof(GPSPI2.clock.val) gpspi_flash_ll_clock_reg_t; +#define GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (80) + +/*------------------------------------------------------------------------------ + * Control + *----------------------------------------------------------------------------*/ +/** + * Reset peripheral registers before configuration and starting control + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void gpspi_flash_ll_reset(spi_dev_t *dev) +{ + dev->user.val = 0; + dev->ctrl.val = 0; + + dev->clk_gate.clk_en = 1; + dev->clk_gate.mst_clk_active = 1; + dev->clk_gate.mst_clk_sel = 1; + + dev->dma_conf.val = 0; + dev->dma_conf.slv_tx_seg_trans_clr_en = 1; + dev->dma_conf.slv_rx_seg_trans_clr_en = 1; + dev->dma_conf.dma_slv_seg_trans_en = 0; +} + +/** + * Check whether the previous operation is done. + * + * @param dev Beginning address of the peripheral registers. + * + * @return true if last command is done, otherwise false. + */ +static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev) +{ + return (dev->cmd.usr == 0); +} + +/** + * Get the read data from the buffer after ``gpspi_flash_ll_read`` is done. + * + * @param dev Beginning address of the peripheral registers. + * @param buffer Buffer to hold the output data + * @param read_len Length to get out of the buffer + */ +static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, uint32_t read_len) +{ + if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) { + // If everything is word-aligned, do a faster memcpy + memcpy(buffer, (void *)dev->data_buf, read_len); + } else { + // Otherwise, slow(er) path copies word by word + int copy_len = read_len; + for (int i = 0; i < (read_len + 3) / 4; i++) { + int word_len = MIN(sizeof(uint32_t), copy_len); + uint32_t word = dev->data_buf[i].buf; + memcpy(buffer, &word, word_len); + buffer = (void *)((intptr_t)buffer + word_len); + copy_len -= word_len; + } + } +} + +/** + * Write a word to the data buffer. + * + * @param dev Beginning address of the peripheral registers. + * @param word Data to write at address 0. + */ +static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word) +{ + dev->data_buf[0].buf = word; +} + +/** + * Set the data to be written in the data buffer. + * + * @param dev Beginning address of the peripheral registers. + * @param buffer Buffer holding the data + * @param length Length of data in bytes. + */ +static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *buffer, uint32_t length) +{ + // Load data registers, word at a time + int num_words = (length + 3) / 4; + for (int i = 0; i < num_words; i++) { + uint32_t word = 0; + uint32_t word_len = MIN(length, sizeof(word)); + memcpy(&word, buffer, word_len); + dev->data_buf[i].buf = word; + length -= word_len; + buffer = (void *)((intptr_t)buffer + word_len); + } +} + +/** + * Trigger a user defined transaction. All phases, including command, address, dummy, and the data phases, + * should be configured before this is called. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void gpspi_flash_ll_user_start(spi_dev_t *dev) +{ + dev->cmd.update = 1; + while (dev->cmd.update); + dev->cmd.usr = 1; +} + +/** + * Set HD pin high when flash work at spi mode. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val) +{ + dev->ctrl.hold_pol = pol_val; +} + +/** + * Check whether the host is idle to perform new commands. + * + * @param dev Beginning address of the peripheral registers. + * + * @return true if the host is idle, otherwise false + */ +static inline bool gpspi_flash_ll_host_idle(const spi_dev_t *dev) +{ + return dev->cmd.usr == 0; +} + +/** + * Set phases for user-defined transaction to read + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void gpspi_flash_ll_read_phase(spi_dev_t *dev) +{ + typeof (dev->user) user = { + .usr_command = 1, + .usr_mosi = 0, + .usr_miso = 1, + .usr_addr = 1, + }; + dev->user = user; +} +/*------------------------------------------------------------------------------ + * Configs + *----------------------------------------------------------------------------*/ +/** + * Select which pin to use for the flash + * + * @param dev Beginning address of the peripheral registers. + * @param pin Pin ID to use, 0-2. Set to other values to disable all the CS pins. + */ +static inline void gpspi_flash_ll_set_cs_pin(spi_dev_t *dev, int pin) +{ + dev->misc.cs0_dis = (pin == 0) ? 0 : 1; + dev->misc.cs1_dis = (pin == 1) ? 0 : 1; +} + +/** + * Set the read io mode. + * + * @param dev Beginning address of the peripheral registers. + * @param read_mode I/O mode to use in the following transactions. + */ +static inline void gpspi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mode_t read_mode) +{ + typeof (dev->ctrl) ctrl = dev->ctrl; + typeof (dev->user) user = dev->user; + + ctrl.val &= ~(SPI_FCMD_QUAD_M | SPI_FADDR_QUAD_M | SPI_FREAD_QUAD_M | SPI_FCMD_DUAL_M | SPI_FADDR_DUAL_M | SPI_FREAD_DUAL_M); + user.val &= ~(SPI_FWRITE_QUAD_M | SPI_FWRITE_DUAL_M); + + switch (read_mode) { + case SPI_FLASH_FASTRD: + //the default option + case SPI_FLASH_SLOWRD: + break; + case SPI_FLASH_QIO: + ctrl.fread_quad = 1; + ctrl.faddr_quad = 1; + user.fwrite_quad = 1; + break; + case SPI_FLASH_QOUT: + ctrl.fread_quad = 1; + user.fwrite_quad = 1; + break; + case SPI_FLASH_DIO: + ctrl.fread_dual = 1; + ctrl.faddr_dual = 1; + user.fwrite_dual = 1; + break; + case SPI_FLASH_DOUT: + ctrl.fread_dual = 1; + user.fwrite_dual = 1; + break; + default: + abort(); + } + + dev->ctrl = ctrl; + dev->user = user; +} + +/** + * Set clock frequency to work at. + * + * @param dev Beginning address of the peripheral registers. + * @param clock_val pointer to the clock value to set + */ +static inline void gpspi_flash_ll_set_clock(spi_dev_t *dev, gpspi_flash_ll_clock_reg_t *clock_val) +{ + dev->clock.val = *clock_val; +} + +/** + * Set the input length, in bits. + * + * @param dev Beginning address of the peripheral registers. + * @param bitlen Length of input, in bits. + */ +static inline void gpspi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitlen) +{ + dev->user.usr_miso = bitlen > 0; + if (bitlen) { + dev->ms_dlen.ms_data_bitlen = bitlen - 1; + } +} + +/** + * Set the output length, in bits (not including command, address and dummy + * phases) + * + * @param dev Beginning address of the peripheral registers. + * @param bitlen Length of output, in bits. + */ +static inline void gpspi_flash_ll_set_mosi_bitlen(spi_dev_t *dev, uint32_t bitlen) +{ + dev->user.usr_mosi = bitlen > 0; + if (bitlen) { + dev->ms_dlen.ms_data_bitlen = bitlen - 1; + } +} + +/** + * Set the command. + * + * @param dev Beginning address of the peripheral registers. + * @param command Command to send + * @param bitlen Length of the command + */ +static inline void gpspi_flash_ll_set_command(spi_dev_t *dev, uint8_t command, uint32_t bitlen) +{ + dev->user.usr_command = 1; + typeof(dev->user2) user2 = { + .usr_command_value = command, + .usr_command_bitlen = (bitlen - 1), + }; + dev->user2 = user2; +} + +/** + * Get the address length that is set in register, in bits. + * + * @param dev Beginning address of the peripheral registers. + * + */ +static inline int gpspi_flash_ll_get_addr_bitlen(spi_dev_t *dev) +{ + return dev->user.usr_addr ? dev->user1.usr_addr_bitlen + 1 : 0; +} + +/** + * Set the address length to send, in bits. Should be called before commands that requires the address e.g. erase sector, read, write... + * + * @param dev Beginning address of the peripheral registers. + * @param bitlen Length of the address, in bits + */ +static inline void gpspi_flash_ll_set_addr_bitlen(spi_dev_t *dev, uint32_t bitlen) +{ + dev->user1.usr_addr_bitlen = (bitlen - 1); + dev->user.usr_addr = bitlen ? 1 : 0; +} + +/** + * Set the address to send in user mode. Should be called before commands that requires the address e.g. erase sector, read, write... + * + * @param dev Beginning address of the peripheral registers. + * @param addr Address to send + */ +static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, uint32_t bitlen) +{ + // The blank region should be all ones + uint32_t padding_ones = (bitlen == 32? 0 : UINT32_MAX >> bitlen); + dev->addr.val = (addr << (32 - bitlen)) | padding_ones; +} + +/** + * Set the address to send. Should be called before commands that requires the address e.g. erase sector, read, write... + * + * @param dev Beginning address of the peripheral registers. + * @param addr Address to send + */ +static inline void gpspi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr) +{ + dev->addr.val = addr; +} + +/** + * Set the length of dummy cycles. + * + * @param dev Beginning address of the peripheral registers. + * @param dummy_n Cycles of dummy phases + */ +static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n) +{ + dev->user.usr_dummy = dummy_n ? 1 : 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user1, usr_dummy_cyclelen, dummy_n - 1); +} + +/** + * Set extra hold time of CS after the clocks. + * + * @param dev Beginning address of the peripheral registers. + * @param hold_n Cycles of clocks before CS is inactive + */ +static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n) +{ + dev->user1.cs_hold_time = hold_n - 1; + dev->user.cs_hold = (hold_n > 0? 1: 0); +} + +static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time) +{ + dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0); + dev->user1.cs_setup_time = cs_setup_time - 1; +} + +/** + * Calculate spi_flash clock frequency division parameters for register. + * + * @param clkdiv frequency division factor + * + * @return Register setting for the given clock division factor. + */ +static inline uint32_t gpspi_flash_ll_calculate_clock_reg(uint8_t clkdiv) +{ + uint32_t div_parameter; + // See comments of `clock` in `spi_struct.h` + if (clkdiv == 1) { + div_parameter = (1 << 31); + } else { + div_parameter = ((clkdiv - 1) | (((clkdiv/2 - 1) & 0xff) << 6 ) | (((clkdiv - 1) & 0xff) << 12)); + } + return div_parameter; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/hmac_ll.h b/components/hal/esp32c6/include/hal/hmac_ll.h new file mode 100644 index 000000000000..f4f95bd8363c --- /dev/null +++ b/components/hal/esp32c6/include/hal/hmac_ll.h @@ -0,0 +1,191 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use it in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include + +#include "soc/system_reg.h" +#include "soc/hwcrypto_reg.h" +#include "hal/hmac_hal.h" + +#define SHA256_BLOCK_SZ 64 +#define SHA256_DIGEST_SZ 32 + +#define EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG 6 +#define EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 7 +#define EFUSE_KEY_PURPOSE_HMAC_UP 8 +#define EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL 5 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Makes the peripheral ready for use, after enabling it. + */ +static inline void hmac_ll_start(void) +{ + REG_WRITE(HMAC_SET_START_REG, 1); +} + +/** + * @brief Determine where the HMAC output should go. + * + * The HMAC peripheral can be configured to deliver its output to the user directly, or to deliver + * the output directly to another peripheral instead, e.g. the Digital Signature peripheral. + */ +static inline void hmac_ll_config_output(hmac_hal_output_t config) +{ + switch(config) { + case HMAC_OUTPUT_USER: + REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_UP); + break; + case HMAC_OUTPUT_DS: + REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE); + break; + case HMAC_OUTPUT_JTAG_ENABLE: + REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG); + break; + case HMAC_OUTPUT_ALL: + REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL); + break; + default: + ; // do nothing, error will be indicated by hmac_hal_config_error() + } +} + +/** + * @brief Selects which hardware key should be used. + */ +static inline void hmac_ll_config_hw_key_id(uint32_t key_id) +{ + REG_WRITE(HMAC_SET_PARA_KEY_REG, key_id); +} + +/** + * @brief Apply and check configuration. + * + * Afterwards, the configuration can be checked for errors with hmac_hal_config_error(). + */ +static inline void hmac_ll_config_finish(void) +{ + REG_WRITE(HMAC_SET_PARA_FINISH_REG, 1); +} + +/** + * + * @brief Query HMAC error state after configuration actions. + * + * @return + * - 1 or greater on error + * - 0 on success + */ +static inline uint32_t hmac_ll_config_error(void) +{ + return REG_READ(HMAC_QUERY_ERROR_REG); +} + +/** + * Wait until the HAL is ready for the next interaction. + */ +static inline void hmac_ll_wait_idle(void) +{ + uint32_t query; + do { + query = REG_READ(HMAC_QUERY_BUSY_REG); + } while(query != 0); +} + +/** + * @brief Write a message block of 512 bits to the HMAC peripheral. + */ +static inline void hmac_ll_write_block_512(const uint32_t *block) +{ + const size_t REG_WIDTH = sizeof(uint32_t); + for (size_t i = 0; i < SHA256_BLOCK_SZ / REG_WIDTH; i++) { + REG_WRITE(HMAC_WR_MESSAGE_MEM + (i * REG_WIDTH), block[i]); + } + + REG_WRITE(HMAC_SET_MESSAGE_ONE_REG, 1); +} + +/** + * @brief Read the 256 bit HMAC. + */ +static inline void hmac_ll_read_result_256(uint32_t *result) +{ + const size_t REG_WIDTH = sizeof(uint32_t); + for (size_t i = 0; i < SHA256_DIGEST_SZ / REG_WIDTH; i++) { + result[i] = REG_READ(HMAC_RD_RESULT_MEM + (i * REG_WIDTH)); + } +} + +/** + * @brief Clean the HMAC result provided to other hardware. + */ +static inline void hmac_ll_clean(void) +{ + REG_WRITE(HMAC_SET_INVALIDATE_DS_REG, 1); + REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1); +} + +/** + * @brief Signals that the following block will be the padded last block. + */ +static inline void hmac_ll_msg_padding(void) +{ + REG_WRITE(HMAC_SET_MESSAGE_PAD_REG, 1); +} + +/** + * @brief Signals that all blocks have been written and a padding block will automatically be applied by hardware. + * + * Only applies if the message length is a multiple of 512 bits. + * See the chip TRM HMAC chapter for more details. + */ +static inline void hmac_ll_msg_end(void) +{ + REG_WRITE(HMAC_SET_MESSAGE_END_REG, 1); +} + +/** + * @brief The message including padding fits into one block, so no further action needs to be taken. + * + * This is called after the one-block-message has been written. + */ +static inline void hmac_ll_msg_one_block(void) +{ + REG_WRITE(HMAC_ONE_BLOCK_REG, 1); +} + +/** + * @brief Indicate that more blocks will be written after the last block. + */ +static inline void hmac_ll_msg_continue(void) +{ + REG_WRITE(HMAC_SET_MESSAGE_ING_REG, 1); +} + +/** + * @brief Clear the HMAC result. + * + * Use this after reading the HMAC result or if aborting after any of the other steps above. + */ +static inline void hmac_ll_calc_finish(void) +{ + REG_WRITE(HMAC_SET_RESULT_FINISH_REG, 2); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h new file mode 100644 index 000000000000..76aa53949d69 --- /dev/null +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -0,0 +1,1007 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for I2C register operations + +#pragma once + +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "soc/i2c_periph.h" +#include "soc/soc_caps.h" +#include "soc/i2c_struct.h" +#include "soc/pcr_struct.h" +#include "hal/i2c_types.h" +#include "soc/clk_tree_defs.h" +#include "soc/lp_clkrst_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I2C hardware cmd register fields. + */ +typedef union { + struct { + uint32_t byte_num: 8, + ack_en: 1, + ack_exp: 1, + ack_val: 1, + op_code: 3, + reserved14: 17, + done: 1; + }; + uint32_t val; +} i2c_ll_hw_cmd_t; + +// I2C operation mode command +#define I2C_LL_CMD_RESTART 6 /*!clkm_div = clkm_div; + clk_cal->scl_low = half_cycle; + // default, scl_wait_high < scl_high + // Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency + // according to some hardware behaviors. + clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; + clk_cal->sda_hold = half_cycle / 4; + clk_cal->sda_sample = half_cycle / 2; + clk_cal->setup = half_cycle; + clk_cal->hold = half_cycle; + //default we set the timeout value to about 10 bus cycles + // log(20*half_cycle)/log(2) = log(half_cycle)/log(2) + log(20)/log(2) + clk_cal->tout = (int)(sizeof(half_cycle) * 8 - __builtin_clz(5 * half_cycle)) + 2; + + /* Verify the assumptions made by the hardware */ + HAL_ASSERT(clk_cal->scl_wait_high < clk_cal->sda_sample && + clk_cal->sda_sample < clk_cal->scl_high); +} + +/** + * @brief Update I2C configuration + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_update(i2c_dev_t *hw) +{ + hw->ctr.conf_upgate = 1; +} + +/** + * @brief Configure the I2C bus timing related register. + * + * @param hw Beginning address of the peripheral registers + * @param bus_cfg Pointer to the data structure holding the register configuration. + * + * @return None + */ +static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_num, bus_cfg->clkm_div - 1); + + /* Set div_a and div_b to 0, as it's not necessary to use them */ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_a, 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_b, 0); + /* According to the Technical Reference Manual, the following timings must be subtracted by 1. + * However, according to the practical measurement and some hardware behaviour, if wait_high_period and scl_high minus one. + * The SCL frequency would be a little higher than expected. Therefore, the solution + * here is not to minus scl_high as well as scl_wait high, and the frequency will be absolutely accurate to all frequency + * to some extent. */ + hw->scl_low_period.scl_low_period = bus_cfg->scl_low - 1; + hw->scl_high_period.scl_high_period = bus_cfg->scl_high; + hw->scl_high_period.scl_wait_high_period = bus_cfg->scl_wait_high; + //sda sample + hw->sda_hold.sda_hold_time = bus_cfg->sda_hold - 1; + hw->sda_sample.sda_sample_time = bus_cfg->sda_sample - 1; + //setup + hw->scl_rstart_setup.scl_rstart_setup_time = bus_cfg->setup - 1; + hw->scl_stop_setup.scl_stop_setup_time = bus_cfg->setup - 1; + //hold + hw->scl_start_hold.scl_start_hold_time = bus_cfg->hold - 1; + hw->scl_stop_hold.scl_stop_hold_time = bus_cfg->hold - 1; + hw->to.time_out_value = bus_cfg->tout; + hw->to.time_out_en = 1; +} + +/** + * @brief Reset I2C txFIFO + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw) +{ + hw->fifo_conf.tx_fifo_rst = 1; + hw->fifo_conf.tx_fifo_rst = 0; +} + +/** + * @brief Reset I2C rxFIFO + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_rxfifo_rst(i2c_dev_t *hw) +{ + hw->fifo_conf.rx_fifo_rst = 1; + hw->fifo_conf.rx_fifo_rst = 0; +} + +/** + * @brief Configure I2C SCL timing + * + * @param hw Beginning address of the peripheral registers + * @param hight_period The I2C SCL hight period (in core clock cycle, hight_period > 2) + * @param low_period The I2C SCL low period (in core clock cycle, low_period > 1) + * + * @return None. + */ +static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int low_period) +{ + hw->scl_low_period.scl_low_period = low_period - 1; + hw->scl_high_period.scl_high_period = hight_period - 10; + hw->scl_high_period.scl_wait_high_period = hight_period - hw->scl_high_period.scl_high_period; +} + +/** + * @brief Clear I2C interrupt status + * + * @param hw Beginning address of the peripheral registers + * @param mask Interrupt mask needs to be cleared + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask) +{ + hw->int_clr.val = mask; +} + +/** + * @brief Enable I2C interrupt + * + * @param hw Beginning address of the peripheral registers + * @param mask Interrupt mask needs to be enabled + * + * @return None + */ +static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask) +{ + hw->int_ena.val |= mask; +} + +/** + * @brief Disable I2C interrupt + * + * @param hw Beginning address of the peripheral registers + * @param mask Interrupt mask needs to be disabled + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask) +{ + hw->int_ena.val &= (~mask); +} + +/** + * @brief Get I2C interrupt status + * + * @param hw Beginning address of the peripheral registers + * + * @return I2C interrupt status + */ +__attribute__((always_inline)) +static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status) +{ + *intr_status = hw->int_status.val; +} + +/** + * @brief Configure I2C memory access mode, FIFO mode or non-FIFO mode + * + * @param hw Beginning address of the peripheral registers + * @param fifo_mode_en Set true to enable FIFO access mode, else, set it false + * + * @return None + */ +static inline void i2c_ll_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en) +{ + hw->fifo_conf.nonfifo_en = fifo_mode_en ? 0 : 1; +} + +/** + * @brief Configure I2C timeout + * + * @param hw Beginning address of the peripheral registers + * @param tout_num The I2C timeout value needs to be set (2^tout in core clock cycle) + * + * @return None + */ +static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout) +{ + hw->to.time_out_value = tout; +} + +/** + * @brief Configure I2C slave address + * + * @param hw Beginning address of the peripheral registers + * @param slave_addr I2C slave address needs to be set + * @param addr_10bit_en Set true to enable 10-bit slave address mode, set false to enable 7-bit address mode + * + * @return None + */ +static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, bool addr_10bit_en) +{ + hw->slave_addr.slave_addr = slave_addr; + hw->slave_addr.addr_10bit_en = addr_10bit_en; +} + +/** + * @brief Write I2C hardware command register + * + * @param hw Beginning address of the peripheral registers + * @param cmd I2C hardware command + * @param cmd_idx The index of the command register, should be less than 16 + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_ll_hw_cmd_t cmd, int cmd_idx) +{ + hw->command[cmd_idx].val = cmd.val; +} + +/** + * @brief Configure I2C start timing + * + * @param hw Beginning address of the peripheral registers + * @param start_setup The start condition setup period (in core clock cycle) + * @param start_hold The start condition hold period (in core clock cycle) + * + * @return None + */ +static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int start_hold) +{ + hw->scl_rstart_setup.scl_rstart_setup_time = start_setup; + hw->scl_start_hold.scl_start_hold_time = start_hold - 1; +} + +/** + * @brief Configure I2C stop timing + * + * @param hw Beginning address of the peripheral registers + * @param stop_setup The stop condition setup period (in core clock cycle) + * @param stop_hold The stop condition hold period (in core clock cycle) + * + * @return None + */ +static inline void i2c_ll_set_stop_timing(i2c_dev_t *hw, int stop_setup, int stop_hold) +{ + hw->scl_stop_setup.scl_stop_setup_time = stop_setup; + hw->scl_stop_hold.scl_stop_hold_time = stop_hold; +} + +/** + * @brief Configure I2C stop timing + * + * @param hw Beginning address of the peripheral registers + * @param sda_sample The SDA sample time (in core clock cycle) + * @param sda_hold The SDA hold time (in core clock cycle) + * + * @return None + */ +static inline void i2c_ll_set_sda_timing(i2c_dev_t *hw, int sda_sample, int sda_hold) +{ + hw->sda_hold.sda_hold_time = sda_hold; + hw->sda_sample.sda_sample_time = sda_sample; +} + +/** + * @brief Set I2C txFIFO empty threshold + * + * @param hw Beginning address of the peripheral registers + * @param empty_thr The txFIFO empty threshold + * + * @return None + */ +static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) +{ + hw->fifo_conf.txfifo_wm_thrhd = empty_thr; +} + +/** + * @brief Set I2C rxFIFO full threshold + * + * @param hw Beginning address of the peripheral registers + * @param full_thr The rxFIFO full threshold + * + * @return None + */ +static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) +{ + hw->fifo_conf.rxfifo_wm_thrhd = full_thr; +} + +/** + * @brief Set the I2C data mode, LSB or MSB + * + * @param hw Beginning address of the peripheral registers + * @param tx_mode Tx data bit mode + * @param rx_mode Rx data bit mode + * + * @return None + */ +static inline void i2c_ll_set_data_mode(i2c_dev_t *hw, i2c_trans_mode_t tx_mode, i2c_trans_mode_t rx_mode) +{ + hw->ctr.tx_lsb_first = tx_mode; + hw->ctr.rx_lsb_first = rx_mode; +} + +/** + * @brief Get the I2C data mode + * + * @param hw Beginning address of the peripheral registers + * @param tx_mode Pointer to accept the received bytes mode + * @param rx_mode Pointer to accept the sended bytes mode + * + * @return None + */ +static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode) +{ + *tx_mode = hw->ctr.tx_lsb_first; + *rx_mode = hw->ctr.rx_lsb_first; +} + +/** + * @brief Get I2C sda timing configuration + * + * @param hw Beginning address of the peripheral registers + * @param sda_sample Pointer to accept the SDA sample timing configuration + * @param sda_hold Pointer to accept the SDA hold timing configuration + * + * @return None + */ +static inline void i2c_ll_get_sda_timing(i2c_dev_t *hw, int *sda_sample, int *sda_hold) +{ + *sda_hold = hw->sda_hold.sda_hold_time; + *sda_sample = hw->sda_sample.sda_sample_time; +} + +/** + * @brief Get the I2C hardware version + * + * @param hw Beginning address of the peripheral registers + * + * @return The I2C hardware version + */ +static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw) +{ + return hw->date.date; +} + +/** + * @brief Check if the I2C bus is busy + * + * @param hw Beginning address of the peripheral registers + * + * @return True if I2C state machine is busy, else false will be returned + */ +static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw) +{ + return hw->sr.bus_busy; +} + +/** + * @brief Check if I2C is master mode + * + * @param hw Beginning address of the peripheral registers + * + * @return True if I2C is master mode, else false will be returned + */ +static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw) +{ + return hw->ctr.ms_mode; +} + +/** + * @brief Get the rxFIFO readable length + * + * @param hw Beginning address of the peripheral registers + * + * @return RxFIFO readable length + */ +__attribute__((always_inline)) +static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length) +{ + *length = hw->sr.rxfifo_cnt; +} + +/** + * @brief Get I2C txFIFO writable length + * + * @param hw Beginning address of the peripheral registers + * + * @return TxFIFO writable length + */ +__attribute__((always_inline)) +static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length) +{ + *length = SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt; +} + +/** + * @brief Get I2C timeout configuration + * + * @param hw Beginning address of the peripheral registers + * + * @return The I2C timeout value + */ +static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout) +{ + *timeout = hw->to.time_out_value; +} + +/** + * @brief Start I2C transfer + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_trans_start(i2c_dev_t *hw) +{ + hw->ctr.trans_start = 1; +} + +/** + * @brief Get I2C start timing configuration + * + * @param hw Beginning address of the peripheral registers + * @param setup_time Pointer to accept the start condition setup period + * @param hold_time Pointer to accept the start condition hold period + * + * @return None + */ +static inline void i2c_ll_get_start_timing(i2c_dev_t *hw, int *setup_time, int *hold_time) +{ + *setup_time = hw->scl_rstart_setup.scl_rstart_setup_time; + *hold_time = hw->scl_start_hold.scl_start_hold_time + 1; +} + +/** + * @brief Get I2C stop timing configuration + * + * @param hw Beginning address of the peripheral registers + * @param setup_time Pointer to accept the stop condition setup period + * @param hold_time Pointer to accept the stop condition hold period + * + * @return None + */ +static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *hold_time) +{ + *setup_time = hw->scl_stop_setup.scl_stop_setup_time; + *hold_time = hw->scl_stop_hold.scl_stop_hold_time; +} + +/** + * @brief Get I2C SCL timing configuration + * + * @param hw Beginning address of the peripheral registers + * @param high_period Pointer to accept the SCL high period + * @param low_period Pointer to accept the SCL low period + * + * @return None + */ +static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *low_period) +{ + *high_period = hw->scl_high_period.scl_high_period + hw->scl_high_period.scl_wait_high_period; + *low_period = hw->scl_low_period.scl_low_period + 1; +} + +/** + * @brief Write the I2C hardware txFIFO + * + * @param hw Beginning address of the peripheral registers + * @param ptr Pointer to data buffer + * @param len Amount of data needs to be writen + * + * @return None. + */ +__attribute__((always_inline)) +static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) +{ + for (int i = 0; i< len; i++) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); + } +} + +/** + * @brief Read the I2C hardware rxFIFO + * + * @param hw Beginning address of the peripheral registers + * @param ptr Pointer to data buffer + * @param len Amount of data needs read + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) +{ + for(int i = 0; i < len; i++) { + ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); + } +} + +/** + * @brief Configure I2C hardware filter + * + * @param hw Beginning address of the peripheral registers + * @param filter_num If the glitch period on the line is less than this value, it can be filtered out + * If `filter_num == 0`, the filter will be disabled + * + * @return None + */ +static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num) +{ + if (filter_num > 0) { + hw->filter_cfg.scl_filter_thres = filter_num; + hw->filter_cfg.sda_filter_thres = filter_num; + hw->filter_cfg.scl_filter_en = 1; + hw->filter_cfg.sda_filter_en = 1; + } else { + hw->filter_cfg.scl_filter_en = 0; + hw->filter_cfg.sda_filter_en = 0; + } +} + +/** + * @brief Get I2C hardware filter configuration + * + * @param hw Beginning address of the peripheral registers + * + * @return The hardware filter configuration + */ +static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf) +{ + *filter_conf = hw->filter_cfg.scl_filter_thres; +} + +/** + * @brief Reste I2C master FSM. When the master FSM is stuck, call this function to reset the FSM + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw) +{ + // fsm_rst is a self cleared bit. + hw->ctr.fsm_rst = 1; +} + +/** + * @brief Clear I2C bus, when the slave is stuck in a deadlock and keeps pulling the bus low, + * master can controls the SCL bus to generate 9 CLKs. + * + * Note: The master cannot detect if deadlock happens, but when the scl_st_to interrupt is generated, a deadlock may occur. + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw) +{ + hw->scl_sp_conf.scl_rst_slv_num = 9; + hw->scl_sp_conf.scl_rst_slv_en = 1; + hw->ctr.conf_upgate = 1; + // hardward will clear scl_rst_slv_en after sending SCL pulses, + // and we should set conf_upgate bit to synchronize register value. + while (hw->scl_sp_conf.scl_rst_slv_en); + hw->ctr.conf_upgate = 1; +} + +/** + * @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value. + * ack_level: 1 (NACK) + * ack_level: 0 (ACK) + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level) +{ + hw->ctr.rx_full_ack_level = ack_level; +} + +/** + * @brief Set I2C source clock + * + * @param hw Beginning address of the peripheral registers + * @param src_clk Source clock of the I2C + * + * @return None + */ +static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_clk) +{ + if (hw == &LP_I2C) { + // Do nothing + return; + } + + // src_clk : (1) for RTC_CLK, (0) for XTAL + PCR.i2c_sclk_conf.i2c_sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; +} + +#if SOC_LP_I2C_SUPPORTED +/** + * @brief Set LP I2C source clock + * + * @param hw Address offset of the LP I2C peripheral registers + * @param src_clk Source clock for the LP I2C peripheral + * + * @return None + */ +static inline void lp_i2c_ll_set_source_clk(i2c_dev_t *hw, soc_periph_lp_i2c_clk_src_t src_clk) +{ + (void)hw; + // src_clk : (0) for LP_FAST_CLK (RTC Fast), (1) for XTAL_D2_CLK + switch (src_clk) { + case LP_I2C_SCLK_LP_FAST: + LP_CLKRST.lpperi.lp_i2c_clk_sel = 0; + break; + case LP_I2C_SCLK_XTAL_D2: + LP_CLKRST.lpperi.lp_i2c_clk_sel = 1; + break; + default: + // Invalid source clock selected + abort(); + } +} +#endif /* SOC_LP_I2C_SUPPORTED */ + +/** + * @brief Enable I2C peripheral controller clock + * + * @param dev Peripheral instance address + * @param en True to enable, False to disable + */ +static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en) +{ + if (hw == &LP_I2C) { + // Do nothing + return; + } + + PCR.i2c_sclk_conf.i2c_sclk_en = en; +} + +/** + * @brief Init I2C master + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_init(i2c_dev_t *hw) +{ + typeof(hw->ctr) ctrl_reg; + ctrl_reg.val = 0; + ctrl_reg.ms_mode = 1; + ctrl_reg.sda_force_out = 1; + ctrl_reg.scl_force_out = 1; + hw->ctr.val = ctrl_reg.val; +} + +/** + * @brief Init I2C slave + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_slave_init(i2c_dev_t *hw) +{ + typeof(hw->ctr) ctrl_reg; + ctrl_reg.val = 0; + ctrl_reg.sda_force_out = 1; + ctrl_reg.scl_force_out = 1; + hw->ctr.val = ctrl_reg.val; + hw->fifo_conf.fifo_addr_cfg_en = 0; +} + +/** + * @brief Set whether slave should auto start, or only start with start signal from master + * + * @param hw Beginning address of the peripheral registers + * @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0. + */ +static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en) +{ + hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en; +} + +/** + * @brief Get I2C interrupt status register address + */ +static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev) +{ + return &dev->int_status; +} + +//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// +/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// +/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// I2C master TX interrupt bitmap +#define I2C_LL_MASTER_TX_INT (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M) +// I2C master RX interrupt bitmap +#define I2C_LL_MASTER_RX_INT (I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M) +// I2C slave TX interrupt bitmap +#define I2C_LL_SLAVE_TX_INT (I2C_TXFIFO_WM_INT_ENA_M) +// I2C slave RX interrupt bitmap +#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_WM_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M) +// I2C max timeout value +#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_VALUE + +#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */ + +/** + * @brief I2C interrupt event + */ +typedef enum { + I2C_INTR_EVENT_ERR, + I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */ + I2C_INTR_EVENT_NACK, /*!< I2C NACK event */ + I2C_INTR_EVENT_TOUT, /*!< I2C time out event */ + I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */ + I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */ + I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */ + I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */ +} i2c_intr_event_t; + +/** + * @brief Configure I2C SCL timing + * + * @param hw Beginning address of the peripheral registers + * @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2) + * @param low_period The I2C SCL low period (in core clock cycle, low_period > 1) + * @param wait_high_period The I2C SCL wait rising edge period. + * + * @return None. + */ +static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period) +{ + hw->scl_low_period.scl_low_period = low_period; + hw->scl_high_period.scl_high_period = high_period; + hw->scl_high_period.scl_wait_high_period = wait_high_period; +} + +/** + * @brief Get I2C SCL timing configuration + * + * @param hw Beginning address of the peripheral registers + * @param high_period Pointer to accept the SCL high period + * @param low_period Pointer to accept the SCL low period + * + * @return None + */ +static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, int *low_period, int *wait_high_period) +{ + *high_period = hw->scl_high_period.scl_high_period; + *wait_high_period = hw->scl_high_period.scl_wait_high_period; + *low_period = hw->scl_low_period.scl_low_period; +} + +/** + * @brief Get I2C master interrupt event + * + * @param hw Beginning address of the peripheral registers + * @param event Pointer to accept the interrupt event + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event) +{ + i2c_int_status_reg_t int_sts = hw->int_status; + if (int_sts.arbitration_lost_int_st) { + *event = I2C_INTR_EVENT_ARBIT_LOST; + } else if (int_sts.nack_int_st) { + *event = I2C_INTR_EVENT_NACK; + } else if (int_sts.time_out_int_st) { + *event = I2C_INTR_EVENT_TOUT; + } else if (int_sts.end_detect_int_st) { + *event = I2C_INTR_EVENT_END_DET; + } else if (int_sts.trans_complete_int_st) { + *event = I2C_INTR_EVENT_TRANS_DONE; + } else { + *event = I2C_INTR_EVENT_ERR; + } +} + +/** + * @brief Get I2C slave interrupt event + * + * @param hw Beginning address of the peripheral registers + * @param event Pointer to accept the interrupt event + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event) +{ + typeof(hw->int_status) int_sts = hw->int_status; + if (int_sts.txfifo_wm_int_st) { + *event = I2C_INTR_EVENT_TXFIFO_EMPTY; + } else if (int_sts.trans_complete_int_st) { + *event = I2C_INTR_EVENT_TRANS_DONE; + } else if (int_sts.rxfifo_wm_int_st) { + *event = I2C_INTR_EVENT_RXFIFO_FULL; + } else { + *event = I2C_INTR_EVENT_ERR; + } +} + +/** + * @brief Enable I2C master TX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw) +{ + hw->int_clr.val = UINT32_MAX; + hw->int_ena.val = I2C_LL_MASTER_TX_INT; +} + +/** + * @brief Enable I2C master RX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw) +{ + hw->int_clr.val = UINT32_MAX; + hw->int_ena.val = I2C_LL_MASTER_RX_INT; +} + +/** + * @brief Disable I2C master TX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw) +{ + hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT); +} + +/** + * @brief Disable I2C master RX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw) +{ + hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT); +} + +/** + * @brief + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw) +{ + hw->int_ena.val |= I2C_LL_SLAVE_TX_INT; +} + +/** + * @brief Enable I2C slave RX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_slave_enable_rx_it(i2c_dev_t *hw) +{ + hw->int_ena.val |= I2C_LL_SLAVE_RX_INT; +} + +/** + * @brief Disable I2C slave TX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw) +{ + hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT); +} + +/** + * @brief Disable I2C slave RX interrupt + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw) +{ + hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/i2s_ll.h b/components/hal/esp32c6/include/hal/i2s_ll.h new file mode 100644 index 000000000000..c36e5d7ea641 --- /dev/null +++ b/components/hal/esp32c6/include/hal/i2s_ll.h @@ -0,0 +1,1126 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for I2S register operations +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "soc/i2s_periph.h" +#include "soc/i2s_struct.h" +#include "soc/pcr_struct.h" +#include "hal/i2s_types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2S_LL_GET_HW(num) (((num) == 0)? (&I2S0) : NULL) + +#define I2S_LL_TDM_CH_MASK (0xffff) +#define I2S_LL_PDM_BCK_FACTOR (64) + +#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9) +#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) + +#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz +#define I2S_LL_DEFAULT_PLL_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT + +/** + * @brief I2S clock configuration structure + * @note Fmclk = Fsclk /(integ+numer/denom) + */ +typedef struct { + uint16_t integ; // Integer part of I2S module clock divider + uint16_t denom; // Denominator part of I2S module clock divider + uint16_t numer; // Numerator part of I2S module clock divider +} i2s_ll_mclk_div_t; + +/** + * @brief I2S module general init, enable I2S clock. + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +{ + // The clock gate enabling is moved to `periph_module_enable` + (void)hw; +} + +/** + * @brief I2S module disable I2S clock. + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_disable_clock(i2s_dev_t *hw) +{ + // The clock gate disabling is moved to `periph_module_disable` + (void)hw; +} + +/** + * @brief Enable I2S tx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_enable_clock(i2s_dev_t *hw) +{ + (void)hw; + PCR.i2s_tx_clkm_conf.i2s_tx_clkm_en = 1; +} + +/** + * @brief Enable I2S rx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_enable_clock(i2s_dev_t *hw) +{ + (void)hw; + PCR.i2s_rx_clkm_conf.i2s_rx_clkm_en = 1; +} + +/** + * @brief Disable I2S tx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw) +{ + (void)hw; + PCR.i2s_tx_clkm_conf.i2s_tx_clkm_en = 0; +} + +/** + * @brief Disable I2S rx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw) +{ + (void)hw; + PCR.i2s_rx_clkm_conf.i2s_rx_clkm_en = 0; +} + +/** + * @brief I2S mclk use tx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_mclk_bind_to_tx_clk(i2s_dev_t *hw) +{ + (void)hw; + PCR.i2s_rx_clkm_conf.i2s_mclk_sel = 0; +} + +/** + * @brief I2S mclk use rx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_mclk_bind_to_rx_clk(i2s_dev_t *hw) +{ + (void)hw; + PCR.i2s_rx_clkm_conf.i2s_mclk_sel = 1; +} + +/** + * @brief Enable I2S TX slave mode + * + * @param hw Peripheral I2S hardware instance address. + * @param slave_en Set true to enable slave mode + */ +static inline void i2s_ll_tx_set_slave_mod(i2s_dev_t *hw, bool slave_en) +{ + hw->tx_conf.tx_slave_mod = slave_en; +} + +/** + * @brief Enable I2S RX slave mode + * + * @param hw Peripheral I2S hardware instance address. + * @param slave_en Set true to enable slave mode + */ +static inline void i2s_ll_rx_set_slave_mod(i2s_dev_t *hw, bool slave_en) +{ + hw->rx_conf.rx_slave_mod = slave_en; +} + +/** + * @brief Reset I2S TX module + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_reset(i2s_dev_t *hw) +{ + hw->tx_conf.tx_reset = 1; + hw->tx_conf.tx_reset = 0; +} + +/** + * @brief Reset I2S RX module + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_reset(i2s_dev_t *hw) +{ + hw->rx_conf.rx_reset = 1; + hw->rx_conf.rx_reset = 0; +} + +/** + * @brief Reset I2S TX FIFO + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_reset_fifo(i2s_dev_t *hw) +{ + hw->tx_conf.tx_fifo_reset = 1; + hw->tx_conf.tx_fifo_reset = 0; +} + +/** + * @brief Reset I2S RX FIFO + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) +{ + hw->rx_conf.rx_fifo_reset = 1; + hw->rx_conf.rx_fifo_reset = 0; +} + +/** + * @brief Set TX source clock + * + * @param hw Peripheral I2S hardware instance address. + * @param src I2S source clock. + */ +static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) +{ + (void)hw; + switch (src) + { + case I2S_CLK_SRC_XTAL: + PCR.i2s_tx_clkm_conf.i2s_tx_clkm_sel = 0; + break; + case I2S_CLK_SRC_PLL_160M: + PCR.i2s_tx_clkm_conf.i2s_tx_clkm_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock source"); + break; + } +} + +/** + * @brief Set RX source clock + * + * @param hw Peripheral I2S hardware instance address. + * @param src I2S source clock + */ +static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) +{ + (void)hw; + switch (src) + { + case I2S_CLK_SRC_XTAL: + PCR.i2s_rx_clkm_conf.i2s_rx_clkm_sel = 0; + break; + case I2S_CLK_SRC_PLL_160M: + PCR.i2s_rx_clkm_conf.i2s_rx_clkm_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock source"); + break; + } +} + +/** + * @brief Set I2S tx bck div num + * + * @param hw Peripheral I2S hardware instance address. + * @param val value to set tx bck div num + */ +static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val) +{ + hw->tx_conf1.tx_bck_div_num = val - 1; +} + +/** + * @brief Set I2S tx raw clock division + * + * @param hw Peripheral I2S hardware instance address. + * @param div_int Integer part of division + * @param x div x + * @param y div y + * @param z div z + * @param yn1 yn1 + */ +static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1) +{ + (void)hw; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, div_int); + typeof(PCR.i2s_tx_clkm_div_conf) div = {}; + div.i2s_tx_clkm_div_x = x; + div.i2s_tx_clkm_div_y = y; + div.i2s_tx_clkm_div_z = z; + div.i2s_tx_clkm_div_yn1 = yn1; + PCR.i2s_tx_clkm_div_conf.val = div.val; +} + +/** + * @brief Set I2S rx raw clock division + * + * @param hw Peripheral I2S hardware instance address. + * @param div_int Integer part of division + * @param x div x + * @param y div y + * @param z div z + * @param yn1 yn1 + */ +static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1) +{ + (void)hw; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, div_int); + typeof(PCR.i2s_rx_clkm_div_conf) div = {}; + div.i2s_rx_clkm_div_x = x; + div.i2s_rx_clkm_div_y = y; + div.i2s_rx_clkm_div_z = z; + div.i2s_rx_clkm_div_yn1 = yn1; + PCR.i2s_rx_clkm_div_conf.val = div.val; +} + +/** + * @brief Configure I2S TX module clock divider + * + * @param hw Peripheral I2S hardware instance address. + * @param mclk_div The mclk division coefficients + */ +static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const i2s_ll_mclk_div_t *mclk_div) +{ + /* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate + * Set to particular coefficients first then update to the target coefficients, + * otherwise the clock division might be inaccurate. + * the general idea is to set a value that impossible to calculate from the regular decimal */ + i2s_ll_tx_set_raw_clk_div(hw, 7, 317, 7, 3, 0); + + uint32_t div_x = 0; + uint32_t div_y = 0; + uint32_t div_z = 0; + uint32_t div_yn1 = 0; + /* If any of denominator and numerator is 0, set all the coefficients to 0 */ + if (mclk_div->denom && mclk_div->numer) { + div_yn1 = mclk_div->numer * 2 > mclk_div->denom; + div_z = div_yn1 ? mclk_div->denom - mclk_div->numer : mclk_div->numer; + div_x = mclk_div->denom / div_z - 1; + div_y = mclk_div->denom % div_z; + } + i2s_ll_tx_set_raw_clk_div(hw, mclk_div->integ, div_x, div_y, div_z, div_yn1); +} + +/** + * @brief Set I2S rx bck div num + * + * @param hw Peripheral I2S hardware instance address. + * @param val value to set rx bck div num + */ +static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val) +{ + hw->rx_conf1.rx_bck_div_num = val - 1; +} + +/** + * @brief Configure I2S RX module clock divider + * @note mclk on ESP32 is shared by both TX and RX channel + * + * @param hw Peripheral I2S hardware instance address. + * @param mclk_div The mclk division coefficients + */ +static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const i2s_ll_mclk_div_t *mclk_div) +{ + /* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate + * Set to particular coefficients first then update to the target coefficients, + * otherwise the clock division might be inaccurate. + * the general idea is to set a value that impossible to calculate from the regular decimal */ + i2s_ll_rx_set_raw_clk_div(hw, 7, 317, 7, 3, 0); + + uint32_t div_x = 0; + uint32_t div_y = 0; + uint32_t div_z = 0; + uint32_t div_yn1 = 0; + /* If any of denominator and numerator is 0, set all the coefficients to 0 */ + if (mclk_div->denom && mclk_div->numer) { + div_yn1 = mclk_div->numer * 2 > mclk_div->denom; + div_z = div_yn1 ? mclk_div->denom - mclk_div->numer : mclk_div->numer; + div_x = mclk_div->denom / div_z - 1; + div_y = mclk_div->denom % div_z; + } + i2s_ll_rx_set_raw_clk_div(hw, mclk_div->integ, div_x, div_y, div_z, div_yn1); +} + +/** + * @brief Start I2S TX + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_start(i2s_dev_t *hw) +{ + // Have to update registers before start + hw->tx_conf.tx_update = 1; + while (hw->tx_conf.tx_update); + hw->tx_conf.tx_start = 1; +} + +/** + * @brief Start I2S RX + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_start(i2s_dev_t *hw) +{ + // Have to update registers before start + hw->rx_conf.rx_update = 1; + while (hw->rx_conf.rx_update); + hw->rx_conf.rx_start = 1; +} + +/** + * @brief Stop I2S TX + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_stop(i2s_dev_t *hw) +{ + hw->tx_conf.tx_start = 0; +} + +/** + * @brief Stop I2S RX + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_stop(i2s_dev_t *hw) +{ + hw->rx_conf.rx_start = 0; +} + +/** + * @brief Configure TX WS signal width + * + * @param hw Peripheral I2S hardware instance address. + * @param width WS width in BCK cycle + */ +static inline void i2s_ll_tx_set_ws_width(i2s_dev_t *hw, int width) +{ + hw->tx_conf1.tx_tdm_ws_width = width - 1; +} + +/** + * @brief Configure RX WS signal width + * + * @param hw Peripheral I2S hardware instance address. + * @param width WS width in BCK cycle + */ +static inline void i2s_ll_rx_set_ws_width(i2s_dev_t *hw, int width) +{ + hw->rx_conf1.rx_tdm_ws_width = width - 1; +} + +/** + * @brief Configure the received length to trigger in_suc_eof interrupt + * + * @param hw Peripheral I2S hardware instance address. + * @param eof_num the byte length to trigger in_suc_eof interrupt + */ +static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num) +{ + hw->rx_eof_num.rx_eof_num = eof_num; +} + +/** + * @brief Congfigure TX chan bit and audio data bit + * + * @param hw Peripheral I2S hardware instance address. + * @param chan_bit The chan bit width + * @param data_bit The audio data bit width + */ +static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int data_bit) +{ + hw->tx_conf1.tx_bits_mod = data_bit - 1; + hw->tx_conf1.tx_tdm_chan_bits = chan_bit - 1; +} + +/** + * @brief Congfigure RX chan bit and audio data bit + * + * @param hw Peripheral I2S hardware instance address. + * @param chan_bit The chan bit width + * @param data_bit The audio data bit width + */ +static inline void i2s_ll_rx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int data_bit) +{ + hw->rx_conf1.rx_bits_mod = data_bit - 1; + hw->rx_conf1.rx_tdm_chan_bits = chan_bit - 1; +} + +/** + * @brief Configure RX half_sample_bit + * + * @param hw Peripheral I2S hardware instance address. + * @param half_sample_bits half sample bit width + */ +static inline void i2s_ll_tx_set_half_sample_bit(i2s_dev_t *hw, int half_sample_bits) +{ + hw->tx_conf1.tx_half_sample_bits = half_sample_bits - 1; +} + +/** + * @brief Configure RX half_sample_bit + * + * @param hw Peripheral I2S hardware instance address. + * @param half_sample_bits half sample bit width + */ +static inline void i2s_ll_rx_set_half_sample_bit(i2s_dev_t *hw, int half_sample_bits) +{ + hw->rx_conf1.rx_half_sample_bits = half_sample_bits - 1; +} + +/** + * @brief Enable TX MSB shift, the data will be launch at the first BCK clock + * + * @param hw Peripheral I2S hardware instance address. + * @param msb_shift_enable Set true to enable MSB shift + */ +static inline void i2s_ll_tx_enable_msb_shift(i2s_dev_t *hw, bool msb_shift_enable) +{ + hw->tx_conf1.tx_msb_shift = msb_shift_enable; +} + +/** + * @brief Enable RX MSB shift, the data will be launch at the first BCK clock + * + * @param hw Peripheral I2S hardware instance address. + * @param msb_shift_enable Set true to enable MSB shift + */ +static inline void i2s_ll_rx_enable_msb_shift(i2s_dev_t *hw, bool msb_shift_enable) +{ + hw->rx_conf1.rx_msb_shift = msb_shift_enable; +} + +/** + * @brief Configure TX total chan number + * + * @param hw Peripheral I2S hardware instance address. + * @param total_num Total chan number + */ +static inline void i2s_ll_tx_set_chan_num(i2s_dev_t *hw, int total_num) +{ + hw->tx_tdm_ctrl.tx_tdm_tot_chan_num = total_num - 1; +} + +/** + * @brief Configure RX total chan number + * + * @param hw Peripheral I2S hardware instance address. + * @param total_num Total chan number + */ +static inline void i2s_ll_rx_set_chan_num(i2s_dev_t *hw, int total_num) +{ + hw->rx_tdm_ctrl.rx_tdm_tot_chan_num = total_num - 1; +} + +/** + * @brief Set the bimap of the active TX chan, only the active chan can launch audio data. + * + * @param hw Peripheral I2S hardware instance address. + * @param chan_mask mask of tx active chan + */ +static inline void i2s_ll_tx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_mask) +{ + uint32_t tdm_ctrl = hw->tx_tdm_ctrl.val; + tdm_ctrl &= 0xFFFF0000; + tdm_ctrl |= chan_mask; + hw->tx_tdm_ctrl.val = tdm_ctrl; +} + +/** + * @brief Set the bimap of the active RX chan, only the active chan can receive audio data. + * + * @param hw Peripheral I2S hardware instance address. + * @param chan_mask mask of rx active chan + */ +static inline void i2s_ll_rx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_mask) +{ + uint32_t tdm_ctrl = hw->rx_tdm_ctrl.val; + tdm_ctrl &= 0xFFFF0000; + tdm_ctrl |= chan_mask; + hw->rx_tdm_ctrl.val = tdm_ctrl; +} + +/** + * @brief Set I2S tx chan mode + * + * @param hw Peripheral I2S hardware instance address. + * @param slot_mask select slot to send data + */ +static inline void i2s_ll_tx_select_std_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) +{ + /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot + * Otherwise always enable the first two slots */ + hw->tx_tdm_ctrl.tx_tdm_tot_chan_num = 1; // tx_tdm_tot_chan_num = 2 slots - 1 = 1 + uint32_t chan_mask = 0; + switch (slot_mask) + { + case I2S_STD_SLOT_LEFT: + chan_mask |= 0x01; + break; + case I2S_STD_SLOT_RIGHT: + chan_mask |= 0x02; + break; + case I2S_STD_SLOT_BOTH: + chan_mask |= 0x03; + break; + default: + break; + } + i2s_ll_tx_set_active_chan_mask(hw, chan_mask); +} + +/** + * @brief Set I2S rx chan mode + * + * @param hw Peripheral I2S hardware instance address. + * @param slot_mask select slot to receive data + */ +static inline void i2s_ll_rx_select_std_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) +{ + /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot + * Otherwise always enable the first two slots */ + hw->rx_tdm_ctrl.rx_tdm_tot_chan_num = 1; // rx_tdm_tot_chan_num = 2 slots - 1 = 1 + uint32_t chan_mask = 0; + switch (slot_mask) + { + case I2S_STD_SLOT_LEFT: + chan_mask |= 0x01; + break; + case I2S_STD_SLOT_RIGHT: + chan_mask |= 0x02; + break; + case I2S_STD_SLOT_BOTH: + chan_mask |= 0x03; + break; + default: + break; + } + i2s_ll_rx_set_active_chan_mask(hw, chan_mask); +} + +/** + * @brief PDM slot mode + * + * @param hw Peripheral I2S hardware instance address. + * @param mod Channel mode + * while tx_ws_idle_pol = 0: + * 0: stereo + * 1: Both slots transmit left + * 2: Both slots transmit right + * 3: Left transmits `conf_single_data` right transmits data + * 4: Right transmits `conf_single_data` left transmits data + * while tx_ws_idle_pol = 1: + 0: stereo + * 1: Both slots transmit right + * 2: Both slots transmit left + * 3: Right transmits `conf_single_data` left transmits data + * 4: Left transmits `conf_single_data` right transmits data + */ +static inline void i2s_ll_tx_set_pdm_chan_mod(i2s_dev_t *hw, uint32_t mod) +{ + hw->tx_conf.tx_chan_mod = mod; +} + +/** + * @brief Set TX WS signal pol level + * + * @param hw Peripheral I2S hardware instance address. + * @param ws_pol_level pin level of WS(output) when receiving left channel data + */ +static inline void i2s_ll_tx_set_ws_idle_pol(i2s_dev_t *hw, bool ws_pol_level) +{ + hw->tx_conf.tx_ws_idle_pol = ws_pol_level; +} + +/** + * @brief Set RX WS signal pol level + * + * @param hw Peripheral I2S hardware instance address. + * @param ws_pol_level pin level of WS(input) when receiving left channel data + */ +static inline void i2s_ll_rx_set_ws_idle_pol(i2s_dev_t *hw, bool ws_pol_level) +{ + hw->rx_conf.rx_ws_idle_pol = ws_pol_level; +} + +/** + * @brief Enable I2S TX TDM mode + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_enable_tdm(i2s_dev_t *hw) +{ + hw->tx_conf.tx_pdm_en = false; + hw->tx_conf.tx_tdm_en = true; + hw->tx_pcm2pdm_conf.pcm2pdm_conv_en = false; +} + +/** + * @brief Enable I2S RX TDM mode + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_enable_tdm(i2s_dev_t *hw) +{ + hw->rx_conf.rx_pdm_en = false; + hw->rx_conf.rx_tdm_en = true; +} + +/** + * @brief Enable I2S TX STD mode + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_enable_std(i2s_dev_t *hw) +{ + i2s_ll_tx_enable_tdm(hw); +} + +/** + * @brief Enable I2S RX STD mode + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_enable_std(i2s_dev_t *hw) +{ + i2s_ll_rx_enable_tdm(hw); +} + +/** + * @brief Enable TX PDM mode. + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_enable_pdm(i2s_dev_t *hw) +{ + hw->tx_conf.tx_pdm_en = true; + hw->tx_conf.tx_tdm_en = false; + hw->tx_pcm2pdm_conf.pcm2pdm_conv_en = true; +} + +/** + * @brief Set I2S TX PDM prescale + * + * @param hw Peripheral I2S hardware instance address. + * @param prescale I2S TX PDM prescale + */ +static inline void i2s_ll_tx_set_pdm_prescale(i2s_dev_t *hw, bool prescale) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_pcm2pdm_conf, tx_pdm_prescale, prescale); +} + +/** + * @brief Set I2S TX PDM high pass filter scaling + * + * @param hw Peripheral I2S hardware instance address. + * @param sig_scale I2S TX PDM signal scaling before transmit to the filter + */ +static inline void i2s_ll_tx_set_pdm_hp_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale) +{ + hw->tx_pcm2pdm_conf.tx_pdm_hp_in_shift = sig_scale; +} + +/** + * @brief Set I2S TX PDM low pass filter scaling + * + * @param hw Peripheral I2S hardware instance address. + * @param sig_scale I2S TX PDM signal scaling before transmit to the filter + */ +static inline void i2s_ll_tx_set_pdm_lp_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale) +{ + hw->tx_pcm2pdm_conf.tx_pdm_lp_in_shift = sig_scale; +} + +/** + * @brief Set I2S TX PDM sinc filter scaling + * + * @param hw Peripheral I2S hardware instance address. + * @param sig_scale I2S TX PDM signal scaling before transmit to the filter + */ +static inline void i2s_ll_tx_set_pdm_sinc_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sinc_in_shift = sig_scale; +} + +/** + * @brief Set I2S TX PDM sigma-delta filter scaling + * + * @param hw Peripheral I2S hardware instance address. + * @param sig_scale I2S TX PDM signal scaling before transmit to the filter + */ +static inline void i2s_ll_tx_set_pdm_sd_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_in_shift = sig_scale; +} + +/** + * @brief Set I2S TX PDM high pass filter param0 + * + * @param hw Peripheral I2S hardware instance address. + * @param param The fourth parameter of PDM TX IIR_HP filter stage 1 is (504 + I2S_TX_IIR_HP_MULT12_0[2:0]) + */ +static inline void i2s_ll_tx_set_pdm_hp_filter_param0(i2s_dev_t *hw, uint32_t param) +{ + hw->tx_pcm2pdm_conf1.tx_iir_hp_mult12_0 = param; +} + +/** + * @brief Set I2S TX PDM high pass filter param5 + * + * @param hw Peripheral I2S hardware instance address. + * @param param The fourth parameter of PDM TX IIR_HP filter stage 2 is (504 + I2S_TX_IIR_HP_MULT12_5[2:0]) + */ +static inline void i2s_ll_tx_set_pdm_hp_filter_param5(i2s_dev_t *hw, uint32_t param) +{ + hw->tx_pcm2pdm_conf1.tx_iir_hp_mult12_5 = param; +} + +/** + * @brief Enable I2S TX PDM high pass filter + * + * @param hw Peripheral I2S hardware instance address. + * @param enable Set true to enable I2S TX PDM high pass filter, set false to bypass it + */ +static inline void i2s_ll_tx_enable_pdm_hp_filter(i2s_dev_t *hw, bool enable) +{ + hw->tx_pcm2pdm_conf.tx_pdm_hp_bypass = !enable; +} + +/** + * @brief Set I2S TX PDM sigma-delta codec dither + * + * @param hw Peripheral I2S hardware instance address. + * @param dither I2S TX PDM sigmadelta dither value + */ +static inline void i2s_ll_tx_set_pdm_sd_dither(i2s_dev_t *hw, uint32_t dither) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_dither = dither; +} + +/** + * @brief Set I2S TX PDM sigma-delta codec dither + * + * @param hw Peripheral I2S hardware instance address. + * @param dither2 I2S TX PDM sigmadelta dither2 value + */ +static inline void i2s_ll_tx_set_pdm_sd_dither2(i2s_dev_t *hw, uint32_t dither2) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_dither2 = dither2; +} + +/** + * @brief Set the PDM TX over sampling ratio + * + * @param hw Peripheral I2S hardware instance address. + * @param ovr Over sampling ratio + */ +static inline void i2s_ll_tx_set_pdm_over_sample_ratio(i2s_dev_t *hw, uint32_t ovr) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sinc_osr2 = ovr; +} + +/** + * @brief Configure I2S TX PDM sample rate + * Fpdm = 64*Fpcm*fp/fs + * + * @param hw Peripheral I2S hardware instance address. + * @param fp The fp value of TX PDM filter module group0. + * @param fs The fs value of TX PDM filter module group0. + */ +static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t fs) +{ + hw->tx_pcm2pdm_conf1.tx_pdm_fp = fp; + hw->tx_pcm2pdm_conf1.tx_pdm_fs = fs; +} + +/** + * @brief Get I2S TX PDM fp configuration paramater + * + * @param hw Peripheral I2S hardware instance address. + * @return + * - fp configuration paramater + */ +static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw) +{ + return hw->tx_pcm2pdm_conf1.tx_pdm_fp; +} + +/** + * @brief Get I2S TX PDM fs configuration paramater + * + * @param hw Peripheral I2S hardware instance address. + * @return + * - fs configuration paramater + */ +static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw) +{ + return hw->tx_pcm2pdm_conf1.tx_pdm_fs; +} + +/** + * @brief Enable RX PDM mode. + * @note ESP32-C6 doesn't support pdm in rx mode, disable anyway + * + * @param hw Peripheral I2S hardware instance address. + * @param pdm_enable Set true to RX enable PDM mode (ignored) + */ +static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw, bool pdm_enable) +{ + // Due to the lack of `PDM to PCM` module on ESP32-C6, PDM RX is not available + HAL_ASSERT(!pdm_enable); + hw->rx_conf.rx_pdm_en = 0; + hw->rx_conf.rx_tdm_en = 1; +} + +/** + * @brief Configura TX a/u-law decompress or compress + * + * @param hw Peripheral I2S hardware instance address. + * @param pcm_cfg PCM configuration paramater + */ +static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg) +{ + hw->tx_conf.tx_pcm_conf = pcm_cfg; + hw->tx_conf.tx_pcm_bypass = !pcm_cfg; +} + +/** + * @brief Configure RX a/u-law decompress or compress + * + * @param hw Peripheral I2S hardware instance address. + * @param pcm_cfg PCM configuration paramater + */ +static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg) +{ + hw->rx_conf.rx_pcm_conf = pcm_cfg; + hw->rx_conf.rx_pcm_bypass = !pcm_cfg; +} + +/** + * @brief Enable TX audio data left alignment + * + * @param hw Peripheral I2S hardware instance address. + * @param ena Set true to enable left alignment + */ +static inline void i2s_ll_tx_enable_left_align(i2s_dev_t *hw, bool ena) +{ + hw->tx_conf.tx_left_align = ena; +} + +/** + * @brief Enable RX audio data left alignment + * + * @param hw Peripheral I2S hardware instance address. + * @param ena Set true to enable left alignment + */ +static inline void i2s_ll_rx_enable_left_align(i2s_dev_t *hw, bool ena) +{ + hw->rx_conf.rx_left_align = ena; +} + +/** + * @brief Enable TX big endian mode + * + * @param hw Peripheral I2S hardware instance address. + * @param ena Set true to enable big endian mode + */ +static inline void i2s_ll_rx_enable_big_endian(i2s_dev_t *hw, bool ena) +{ + hw->rx_conf.rx_big_endian = ena; +} + +/** + * @brief Enable RX big endian mode + * + * @param hw Peripheral I2S hardware instance address. + * @param ena Set true to enable big endian mode + */ +static inline void i2s_ll_tx_enable_big_endian(i2s_dev_t *hw, bool ena) +{ + hw->tx_conf.tx_big_endian = ena; +} + +/** + * @brief Configure TX bit order + * + * @param hw Peripheral I2S hardware instance address. + * @param lsb_order_ena Set true to enable LSB bit order + */ +static inline void i2s_ll_tx_set_bit_order(i2s_dev_t *hw, bool lsb_order_ena) +{ + hw->tx_conf.tx_bit_order = lsb_order_ena; +} + +/** + * @brief Configure RX bit order + * + * @param hw Peripheral I2S hardware instance address. + * @param lsb_order_ena Set true to enable LSB bit order + */ +static inline void i2s_ll_rx_set_bit_order(i2s_dev_t *hw, bool lsb_order_ena) +{ + hw->rx_conf.rx_bit_order = lsb_order_ena; +} + +/** + * @brief Configure TX skip mask enable + * + * @param hw Peripheral I2S hardware instance address. + * @param skip_mask_ena Set true to skip inactive channels. + */ +static inline void i2s_ll_tx_set_skip_mask(i2s_dev_t *hw, bool skip_mask_ena) +{ + hw->tx_tdm_ctrl.tx_tdm_skip_msk_en = skip_mask_ena; +} + + +/** + * @brief Configure single data + * + * @param hw Peripheral I2S hardware instance address. + * @param data Single data to be set + */ +static inline void i2s_ll_set_single_data(i2s_dev_t *hw, uint32_t data) +{ + hw->conf_single_data.val = data; +} + +/** + * @brief Enable TX mono mode + * @note MONO in hardware means only one channel got data, but another doesn't + * MONO in software means two channel share same data + * This function aims to use MONO in software meaning + * so 'tx_mono' and 'tx_chan_equal' should be enabled at the same time + * + * @param hw Peripheral I2S hardware instance address. + * @param mono_ena Set true to enable mono mde. + */ +static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena) +{ + hw->tx_conf.tx_mono = mono_ena; + hw->tx_conf.tx_chan_equal = mono_ena; +} + +/** + * @brief Enable RX mono mode + * + * @param hw Peripheral I2S hardware instance address. + * @param mono_ena Set true to enable mono mde. + */ +static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena) +{ + hw->rx_conf.rx_mono = mono_ena; + hw->rx_conf.rx_mono_fst_vld = mono_ena; +} + +/** + * @brief Enable loopback mode + * + * @param hw Peripheral I2S hardware instance address. + * @param ena Set true to share BCK and WS signal for tx module and rx module. + */ +static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool ena) +{ + hw->tx_conf.sig_loopback = ena; +} + +/** + * @brief PDM TX DMA data take mode + * + * @param hw Peripheral I2S hardware instance address. + * @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo) + * @param is_fst_valid Whether take the DMA data at the first half period + * Only take effet when 'is_mono' is true + */ +static inline void i2s_ll_tx_pdm_dma_take_mode(i2s_dev_t *hw, bool is_mono, bool is_fst_valid) +{ + hw->tx_conf.tx_mono = is_mono; + hw->tx_conf.tx_mono_fst_vld = is_fst_valid; +} + +/** + * @brief PDM TX slot mode + * @note Mode Left Slot Right Slot Chan Mode WS Pol + * ----------------------------------------------------------------- + * Stereo Left Right 0 x + * ----------------------------------------------------------------- + * Mono Left Left 1 0 + * Mono Right Right 2 0 + * Mono Single Right 3 0 + * Mono Left Single 4 0 + * ----------------------------------------------------------------- + * Mono Right Right 1 1 + * Mono Left Left 2 1 + * Mono Left Single 3 1 + * Mono Single Right 4 1 + * @note The 'Single' above means always sending the value of `conf_single_data` reg + * The default value of `conf_single_data` reg is '0', it is not public for now + * + * @param hw Peripheral I2S hardware instance address. + * @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo) + * @param is_copy Whether the un-selected slot copies the data from the selected one + * If not, the un-selected slot will transmit the data from 'conf_single_data' + * @param mask The slot mask to selet the slot + */ +static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask) +{ + if (is_mono) { + /* The default tx_ws_idle_pol is false */ + if (is_copy) { + hw->tx_conf.tx_chan_mod = mask == I2S_PDM_SLOT_LEFT ? 1 : 2; + } else { + hw->tx_conf.tx_chan_mod = mask == I2S_PDM_SLOT_LEFT ? 4 : 3; + } + } else { + hw->tx_conf.tx_chan_mod = 0; + } +} + +/** + * @brief PDM TX line mode + * @note Mode DAC Mode 2 lines output + * ------------------------------------------- + * PDM codec 0 1 + * DAC 1-line 1 0 + * DAC 2-line 1 1 + * + * @param hw Peripheral I2S hardware instance address. + * @param line_mode PDM TX line mode + */ +static inline void i2s_ll_tx_pdm_line_mode(i2s_dev_t *hw, i2s_pdm_tx_line_mode_t line_mode) +{ + hw->tx_pcm2pdm_conf.tx_pdm_dac_mode_en = line_mode > I2S_PDM_TX_ONE_LINE_CODEC; + hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = line_mode != I2S_PDM_TX_ONE_LINE_DAC; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/ieee802154_ll.h b/components/hal/esp32c6/include/hal/ieee802154_ll.h new file mode 100644 index 000000000000..14e548a1d3c0 --- /dev/null +++ b/components/hal/esp32c6/include/hal/ieee802154_ll.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/ieee802154_common_ll.h" + +#define IEEE802154_TXPOWER_VALUE_MAX 20 +#define IEEE802154_TXPOWER_VALUE_MIN -15 +#define IEEE802154_TXPOWER_INDEX_MIN 3 + +#define IEEE802154_RSSI_COMPENSATION_VALUE 0 diff --git a/components/hal/esp32c6/include/hal/ledc_ll.h b/components/hal/esp32c6/include/hal/ledc_ll.h new file mode 100644 index 000000000000..49eaa0a09837 --- /dev/null +++ b/components/hal/esp32c6/include/hal/ledc_ll.h @@ -0,0 +1,607 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for LEDC register operations. +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#include "hal/ledc_types.h" +#include "soc/ledc_struct.h" +#include "soc/ledc_reg.h" +#include "soc/pcr_struct.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LEDC_LL_GET_HW() &LEDC + +#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_DUTY_NUM_V) +#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_DUTY_CYCLE_V) +#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_SCALE_V) +#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V) +#define LEDC_LL_FRACTIONAL_BITS (8) +#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1) + +#define LEDC_LL_GLOBAL_CLOCKS { \ + LEDC_SLOW_CLK_PLL_DIV, \ + LEDC_SLOW_CLK_XTAL, \ + LEDC_SLOW_CLK_RC_FAST, \ + } + +#define LEDC_LL_GLOBAL_CLK_DEFAULT LEDC_SLOW_CLK_RC_FAST + + +/** + * @brief Enable LEDC function clock + * + * @param hw Beginning address of the peripheral registers + * @param en True to enable, false to disable + * + * @return None + */ +static inline void ledc_ll_enable_clock(ledc_dev_t *hw, bool en) +{ + (void)hw; + PCR.ledc_sclk_conf.ledc_sclk_en = en; +} + +/** + * @brief Set LEDC low speed timer clock + * + * @param hw Beginning address of the peripheral registers + * @param slow_clk_sel LEDC low speed timer clock source + * + * @return None + */ +static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel) +{ + (void)hw; + uint32_t clk_sel_val = 0; + if (slow_clk_sel == LEDC_SLOW_CLK_PLL_DIV) { + clk_sel_val = 1; + } else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) { + clk_sel_val = 2; + } else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) { + clk_sel_val = 3; + } + PCR.ledc_sclk_conf.ledc_sclk_sel = clk_sel_val; +} + +/** + * @brief Get LEDC low speed timer clock + * + * @param hw Beginning address of the peripheral registers + * @param slow_clk_sel LEDC low speed timer clock source + * + * @return None + */ +static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel) +{ + (void)hw; + uint32_t clk_sel_val = PCR.ledc_sclk_conf.ledc_sclk_sel; + if (clk_sel_val == 1) { + *slow_clk_sel = LEDC_SLOW_CLK_PLL_DIV; + } else if (clk_sel_val == 2) { + *slow_clk_sel = LEDC_SLOW_CLK_RC_FAST; + } else if (clk_sel_val == 3) { + *slow_clk_sel = LEDC_SLOW_CLK_XTAL; + } else { + abort(); + } +} + +/** + * @brief Update LEDC low speed timer + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * + * @return None + */ +static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel) +{ + hw->timer_group[speed_mode].timer[timer_sel].conf.para_up = 1; + // Here, we don't wait for the bit gets cleared since it can take quite long depends on the pwm frequency +} + +/** + * @brief Reset LEDC timer + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * + * @return None + */ +static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel) +{ + hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1; + hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0; +} + +/** + * @brief Pause LEDC timer + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * + * @return None + */ +static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel) +{ + hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1; +} + +/** + * @brief Resume LEDC timer + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * + * @return None + */ +static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel) +{ + hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0; +} + +/** + * @brief Set LEDC timer clock divider + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source + * + * @return None + */ +static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider) +{ + hw->timer_group[speed_mode].timer[timer_sel].conf.clk_div = clock_divider; +} + +/** + * @brief Get LEDC timer clock divider + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source + * + * @return None + */ +static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider) +{ + *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clk_div; +} + +/** + * @brief Get LEDC timer clock source + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * @param clk_src Pointer to accept the timer clock source + * + * @return None + */ +static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src) +{ + // The target has no timer-specific clock source option + HAL_ASSERT(hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 0); + *clk_src = LEDC_SCLK; +} + +/** + * @brief Set LEDC duty resolution + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)] + * + * @return None + */ +static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution) +{ + hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res = duty_resolution; +} + +/** + * @brief Get LEDC duty resolution + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * @param duty_resolution Pointer to accept the resolution of duty setting in number of bits. + * + * @return None + */ +static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution) +{ + *duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res; +} + +/** + * @brief Update channel configure when select low speed mode + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * + * @return None + */ +static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num) +{ + hw->channel_group[speed_mode].channel[channel_num].conf0.para_up = 1; +} + +/** + * @brief Get LEDC max duty + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param max_duty Pointer to accept the max duty + * + * @return None + */ +static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty) +{ + uint32_t timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel; + *max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_res)); +} + +/** + * @brief Set LEDC hpoint value + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param hpoint_val LEDC hpoint value(max: 0xfffff) + * + * @return None + */ +static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val) +{ + hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val; +} + +/** + * @brief Get LEDC hpoint value + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff) + * + * @return None + */ +static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val) +{ + *hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint; +} + +/** + * @brief Set LEDC the integer part of duty value + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)] + * + * @return None + */ +static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val) +{ + hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4; +} + +/** + * @brief Get LEDC duty value + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_val Pointer to accept the LEDC duty value + * + * @return None + */ +static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val) +{ + *duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_r >> 4); +} + +/** + * @brief Set LEDC duty change direction + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_direction LEDC duty change direction, increase or decrease + * + * @return None + */ +static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction) +{ + hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_inc = duty_direction; +} + +/** + * @brief Get LEDC duty change direction + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_direction Pointer to accept the LEDC duty change direction, increase or decrease + * + * @return None + */ +static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction) +{ + *duty_direction = (ledc_duty_direction_t)(hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_inc); +} + +/** + * @brief Set the number of increased or decreased times + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_num The number of increased or decreased times + * + * @return None + */ +static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num) +{ + hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_num = duty_num; +} + +/** + * @brief Set the duty cycles of increase or decrease + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_cycle The duty cycles + * + * @return None + */ +static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle) +{ + hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_cycle = duty_cycle; +} + +/** + * @brief Set the step scale of increase or decrease + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_scale The step scale + * + * @return None + */ +static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale) +{ + hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_scale = duty_scale; +} + +/** + * @brief Set the range number of the specified duty configurations to be written from gamma_wr register to gamma ram + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_range Range index (0 - (SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX-1)), it specifies to which range in gamma ram to write + * + * @return None + */ +static inline void ledc_ll_set_duty_range_wr_addr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_range) +{ + hw->channel_gamma_group[speed_mode].channel[channel_num].wr_addr.gamma_wr_addr = duty_range; +} + +/** + * @brief Set the total number of ranges in one fading + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param range_num Total number of ranges (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX) of the fading configured + * + * @return None + */ +static inline void ledc_ll_set_range_number(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t range_num) +{ + hw->channel_gamma_conf_group[speed_mode].gamma_conf[channel_num].gamma_entry_num = range_num; +} + +/** + * @brief Get the total number of ranges in one fading + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param range_num Pointer to accept fade range number + * + * @return None + */ +static inline void ledc_ll_get_range_number(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *range_num) +{ + *range_num = hw->channel_gamma_conf_group[speed_mode].gamma_conf[channel_num].gamma_entry_num; +} + +/** + * @brief Set the range number of the specified duty configurations to be read from gamma ram to gamma_rd register + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_range Range index (0 - (SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX-1)), it specifies to which range in gamma ram to read + * + * @return None + */ +static inline void ledc_ll_set_duty_range_rd_addr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_range) +{ + hw->channel_gamma_group[speed_mode].channel[channel_num].rd_addr.gamma_rd_addr = duty_range; +} + +/** + * @brief Get fade configurations in gamma_rd register + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param dir Pointer to accept fade direction value + * @param cycle Pointer to accept fade cycle value + * @param scale Pointer to accept fade scale value + * @param step Pointer to accept fade step value + * + * @return None + */ +static inline void ledc_ll_get_duty_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step) +{ + uint32_t val = hw->channel_gamma_group[speed_mode].channel[channel_num].rd_data.gamma_rd_data; + *dir = (val & LEDC_CH0_GAMMA_DUTY_INC_M) >> LEDC_CH0_GAMMA_DUTY_INC_S; + *cycle = (val & LEDC_CH0_GAMMA_DUTY_CYCLE_M) >> LEDC_CH0_GAMMA_DUTY_CYCLE_S; + *scale = (val & LEDC_CH0_GAMMA_SCALE_M) >> LEDC_CH0_GAMMA_SCALE_S; + *step = (val & LEDC_CH0_GAMMA_DUTY_NUM_M) >> LEDC_CH0_GAMMA_DUTY_NUM_S; +} + +/** + * @brief Set the output enable + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param sig_out_en The output enable status + * + * @return None + */ +static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en) +{ + hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en; +} + +/** + * @brief Set the duty start + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param duty_start The duty start + * + * @return None + */ +static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start) +{ + hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start; +} + +/** + * @brief Set output idle level + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param idle_level The output idle level + * + * @return None + */ +static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level) +{ + hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1; +} + +/** + * @brief Set fade end interrupt enable + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param fade_end_intr_en The fade end interrupt enable status + * + * @return None + */ +static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en) +{ + uint32_t value = hw->int_ena.val; + uint32_t int_en_base = LEDC_DUTY_CHNG_END_CH0_INT_ENA_S; + hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num)))); +} + +/** + * @brief Get fade end interrupt status + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param intr_status The fade end interrupt status + * + * @return None + */ +static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status) +{ + uint32_t value = hw->int_st.val; + uint32_t int_en_base = LEDC_DUTY_CHNG_END_CH0_INT_ENA_S; + *intr_status = (value >> int_en_base) & 0xff; +} + +/** + * @brief Clear fade end interrupt status + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * + * @return None + */ +static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num) +{ + uint32_t int_en_base = LEDC_DUTY_CHNG_END_CH0_INT_ENA_S; + hw->int_clr.val = BIT(int_en_base + channel_num); +} + +/** + * @brief Set timer index of the specified channel + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t + * + * @return None + */ +static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel) +{ + hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel; +} + +/** + * @brief Get timer index of the specified channel + * + * @param hw Beginning address of the peripheral registers + * @param speed_mode LEDC speed_mode, low-speed mode only + * @param channel_num LEDC channel index (0-5), select from ledc_channel_t + * @param timer_sel Pointer to accept the LEDC timer index + * + * @return None + */ +static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel) +{ + *timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/lp_aon_hal.h b/components/hal/esp32c6/include/hal/lp_aon_hal.h new file mode 100644 index 000000000000..c38f6da831fb --- /dev/null +++ b/components/hal/esp32c6/include/hal/lp_aon_hal.h @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "hal/lp_aon_ll.h" + +#define rtc_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() +#define rtc_hal_ext1_set_wakeup_pins(io_mask, mode_mask) lp_aon_ll_ext1_set_wakeup_pins(io_mask, mode_mask) +#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() + +#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) diff --git a/components/hal/esp32c6/include/hal/lp_aon_ll.h b/components/hal/esp32c6/include/hal/lp_aon_ll.h new file mode 100644 index 000000000000..c212d33b9aef --- /dev/null +++ b/components/hal/esp32c6/include/hal/lp_aon_ll.h @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 LP_AON register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/lp_aon_struct.h" +#include "hal/misc.h" +#include "esp32c6/rom/rtc.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get ext1 wakeup source status + * @return The lower 8 bits of the returned value are the bitmap of + * the wakeup source status, bit 0~7 corresponds to LP_IO 0~7 + */ +static inline uint32_t lp_aon_ll_ext1_get_wakeup_status(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status); +} + +/** + * @brief Clear the ext1 wakeup source status + */ +static inline void lp_aon_ll_ext1_clear_wakeup_status(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status_clr, 1); +} + +/** + * @brief Set the wake-up LP_IO of the ext1 wake-up source + * @param io_mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 + * @param level_mask LP_IO wakeup level bitmap, bit 0~7 corresponds to LP_IO 0~7 wakeup level + * each bit's corresponding position is set to 0, the wakeup level will be low + * on the contrary, each bit's corresponding position is set to 1, the wakeup + * level will be high + */ +static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t level_mask) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, io_mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, level_mask); +} + +/** + * @brief Clear all ext1 wakup-source setting + */ +static inline void lp_aon_ll_ext1_clear_wakeup_pins(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, 0); +} + +/** + * @brief Get ext1 wakeup source setting + * @return The lower 8 bits of the returned value are the bitmap of + * the wakeup source status, bit 0~7 corresponds to LP_IO 0~7 + */ +static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel); +} + + +/** + * @brief ROM obtains the wake-up type through LP_AON_STORE9_REG[0]. + * Set the flag to inform + * @param true: deepsleep false: lightsleep + */ +static inline void lp_aon_ll_inform_wakeup_type(bool dslp) +{ + if (dslp) { + REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */ + + } else { + REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */ + } +} + +/** + * @brief Get the flag that marks whether LP CPU is awakened by ETM + * + * @return Return true if lpcore is woken up by soc_etm + */ +static inline bool lp_aon_ll_get_lpcore_etm_wakeup_flag(void) +{ + return REG_GET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG); +} + +/** + * @brief Clear the flag that marks whether LP CPU is awakened by soc_etm + */ +static inline void lp_aon_ll_clear_lpcore_etm_wakeup_flag(void) +{ + REG_SET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG_CLR); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/lp_timer_ll.h b/components/hal/esp32c6/include/hal/lp_timer_ll.h new file mode 100644 index 000000000000..d04bccb55906 --- /dev/null +++ b/components/hal/esp32c6/include/hal/lp_timer_ll.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 LP_Timer register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/lp_timer_struct.h" +#include "soc/lp_timer_reg.h" +#include "soc/lp_aon_reg.h" +#include "hal/lp_timer_types.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) +{ + dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; + dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; +} + +FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) +{ + dev->target[timer_id].hi.enable = en; +} + +FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t buffer_id) +{ + return dev->counter[buffer_id].lo.counter_lo; +} + +FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t buffer_id) +{ + return dev->counter[buffer_id].hi.counter_hi; +} + +FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) +{ + dev->update.update = 1; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_alarm_intr_status(lp_timer_dev_t *dev) +{ + dev->int_clr.alarm = 1; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_overflow_intr_status(lp_timer_dev_t *dev) +{ + dev->int_clr.overflow = 1; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_alarm_intr_status(lp_timer_dev_t *dev) +{ + dev->lp_int_clr.alarm = 1; +} + +FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_lp_intr_raw(lp_timer_dev_t *dev) +{ + return dev->lp_int_raw.val; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_intsts_mask(lp_timer_dev_t *dev, uint32_t mask) +{ + dev->lp_int_clr.val = mask; +} + +FORCE_INLINE_ATTR uint64_t lp_timer_ll_time_to_count(uint64_t time_in_us) +{ + uint32_t slow_clk_value = REG_READ(LP_AON_STORE1_REG); + return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/lpwdt_ll.h b/components/hal/esp32c6/include/hal/lpwdt_ll.h new file mode 100644 index 000000000000..caa3cfb12d8b --- /dev/null +++ b/components/hal/esp32c6/include/hal/lpwdt_ll.h @@ -0,0 +1,328 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for Timer Group register operations. +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "hal/misc.h" +#include "hal/wdt_types.h" +#include "soc/rtc_cntl_periph.h" +#include "soc/efuse_reg.h" +#include "esp_attr.h" +#include "esp_assert.h" + +#include "esp32c6/rom/ets_sys.h" + +/* The value that needs to be written to LP_WDT_WPROTECT_REG to write-enable the wdt registers */ +#define LP_WDT_WKEY_VALUE 0x50D83AA1 +/* The value that needs to be written to LP_WDT_SWD_WPROTECT_REG to write-enable the swd registers */ +#define LP_WDT_SWD_WKEY_VALUE 0x50D83AA1 + +/* Possible values for RTC_CNTL_WDT_CPU_RESET_LENGTH and RTC_CNTL_WDT_SYS_RESET_LENGTH */ +#define LP_WDT_RESET_LENGTH_100_NS 0 +#define LP_WDT_RESET_LENGTH_200_NS 1 +#define LP_WDT_RESET_LENGTH_300_NS 2 +#define LP_WDT_RESET_LENGTH_400_NS 3 +#define LP_WDT_RESET_LENGTH_500_NS 4 +#define LP_WDT_RESET_LENGTH_800_NS 5 +#define LP_WDT_RESET_LENGTH_1600_NS 6 +#define LP_WDT_RESET_LENGTH_3200_NS 7 + +#define LP_WDT_STG_SEL_OFF 0 +#define LP_WDT_STG_SEL_INT 1 +#define LP_WDT_STG_SEL_RESET_CPU 2 +#define LP_WDT_STG_SEL_RESET_SYSTEM 3 +#define LP_WDT_STG_SEL_RESET_RTC 4 + +//Type check wdt_stage_action_t +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == LP_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == LP_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == LP_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == LP_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_RTC == LP_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +//Type check wdt_reset_sig_length_t +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == LP_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == LP_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == LP_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == LP_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == LP_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == LP_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == LP_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == LP_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); + +/** + * @brief Enable the RWDT + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void lpwdt_ll_enable(lp_wdt_dev_t *hw) +{ + hw->config0.wdt_en = 1; +} + +/** + * @brief Disable the RWDT + * + * @param hw Start address of the peripheral registers. + * @note This function does not disable the flashboot mode. Therefore, given that + * the MWDT is disabled using this function, a timeout can still occur + * if the flashboot mode is simultaneously enabled. + */ +FORCE_INLINE_ATTR void lpwdt_ll_disable(lp_wdt_dev_t *hw) +{ + hw->config0.wdt_en = 0; +} + +/** + * @brief Check if the RWDT is enabled + * + * @param hw Start address of the peripheral registers. + * @return True if RTC WDT is enabled + */ +FORCE_INLINE_ATTR bool lpwdt_ll_check_if_enabled(lp_wdt_dev_t *hw) +{ + return (hw->config0.wdt_en) ? true : false; +} + +/** + * @brief Configure a particular stage of the RWDT + * + * @param hw Start address of the peripheral registers. + * @param stage Which stage to configure + * @param timeout Number of timer ticks for the stage to timeout (see note). + * @param behavior What action to take when the stage times out + * + * @note The value of of RWDT stage 0 timeout register is special, in + * that an implicit multiplier is applied to that value to produce + * and effective timeout tick value. The multiplier is dependent + * on an EFuse value. Therefore, when configuring stage 0, the valid + * values for the timeout argument are: + * - If Efuse value is 0, any even number between [2,2*UINT32_MAX] + * - If Efuse value is 1, any multiple of 4 between [4,4*UINT32_MAX] + * - If Efuse value is 2, any multiple of 8 between [8,8*UINT32_MAX] + * - If Efuse value is 3, any multiple of 16 between [16,16*UINT32_MAX] + */ +FORCE_INLINE_ATTR void lpwdt_ll_config_stage(lp_wdt_dev_t *hw, wdt_stage_t stage, uint32_t timeout_ticks, wdt_stage_action_t behavior) +{ + switch (stage) { + case WDT_STAGE0: + hw->config0.wdt_stg0 = behavior; + //Account of implicty multiplier applied to stage 0 timeout tick config value + hw->config1.val = timeout_ticks >> (1 + REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_WDT_DELAY_SEL)); + break; + case WDT_STAGE1: + hw->config0.wdt_stg1 = behavior; + hw->config2.val = timeout_ticks; + break; + case WDT_STAGE2: + hw->config0.wdt_stg2 = behavior; + hw->config3.val = timeout_ticks; + break; + case WDT_STAGE3: + hw->config0.wdt_stg3 = behavior; + hw->config4.val = timeout_ticks; + break; + default: + abort(); + } +} + +/** + * @brief Disable a particular stage of the RWDT + * + * @param hw Start address of the peripheral registers. + * @param stage Which stage to disable + */ +FORCE_INLINE_ATTR void lpwdt_ll_disable_stage(lp_wdt_dev_t *hw, wdt_stage_t stage) +{ + switch (stage) { + case WDT_STAGE0: + hw->config0.wdt_stg0 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE1: + hw->config0.wdt_stg1 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE2: + hw->config0.wdt_stg2 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE3: + hw->config0.wdt_stg3 = WDT_STAGE_ACTION_OFF; + break; + default: + abort(); + } +} + +/** + * @brief Set the length of the CPU reset action + * + * @param hw Start address of the peripheral registers. + * @param length Length of CPU reset signal + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_cpu_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length) +{ + hw->config0.wdt_cpu_reset_length = length; +} + +/** + * @brief Set the length of the system reset action + * + * @param hw Start address of the peripheral registers. + * @param length Length of system reset signal + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_sys_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length) +{ + hw->config0.wdt_sys_reset_length = length; +} + +/** + * @brief Enable/Disable the RWDT flashboot mode. + * + * @param hw Start address of the peripheral registers. + * @param enable True to enable RWDT flashboot mode, false to disable RWDT flashboot mode. + * + * @note Flashboot mode is independent and can trigger a WDT timeout event if the + * WDT's enable bit is set to 0. Flashboot mode for RWDT is automatically enabled + * on flashboot, and should be disabled by software when flashbooting completes. + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_flashboot_en(lp_wdt_dev_t *hw, bool enable) +{ + hw->config0.wdt_flashboot_mod_en = (enable) ? 1 : 0; +} + +/** + * @brief Enable/Disable the CPU0 to be reset on WDT_STAGE_ACTION_RESET_CPU + * + * @param hw Start address of the peripheral registers. + * @param enable True to enable CPU0 to be reset, false to disable. + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_procpu_reset_en(lp_wdt_dev_t *hw, bool enable) +{ + hw->config0.wdt_procpu_reset_en = (enable) ? 1 : 0; +} + +/** + * @brief Enable/Disable the CPU1 to be reset on WDT_STAGE_ACTION_RESET_CPU + * + * @param hw Start address of the peripheral registers. + * @param enable True to enable CPU1 to be reset, false to disable. + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_appcpu_reset_en(lp_wdt_dev_t *hw, bool enable) +{ + hw->config0.wdt_appcpu_reset_en = (enable) ? 1 : 0; +} + +/** + * @brief Enable/Disable the RWDT pause during sleep functionality + * + * @param hw Start address of the peripheral registers. + * @param enable True to enable, false to disable. + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_pause_in_sleep_en(lp_wdt_dev_t *hw, bool enable) +{ + hw->config0.wdt_pause_in_slp = (enable) ? 1 : 0; +} + +/** + * @brief Enable/Disable chip reset on RWDT timeout. + * + * A chip reset also resets the analog portion of the chip. It will appear as a + * POWERON reset rather than an RTC reset. + * + * @param hw Start address of the peripheral registers. + * @param enable True to enable, false to disable. + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_en(lp_wdt_dev_t *hw, bool enable) +{ + hw->config0.wdt_chip_reset_en = (enable) ? 1 : 0; +} + +/** + * @brief Set width of chip reset signal + * + * @param hw Start address of the peripheral registers. + * @param width Width of chip reset signal in terms of number of RTC_SLOW_CLK cycles + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_width(lp_wdt_dev_t *hw, uint32_t width) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->config0, wdt_chip_reset_width, width); +} + +/** + * @brief Feed the RWDT + * + * Resets the current timer count and current stage. + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void lpwdt_ll_feed(lp_wdt_dev_t *hw) +{ + hw->feed.rtc_wdt_feed = 1; +} + +/** + * @brief Enable write protection of the RWDT registers + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw) +{ + hw->wprotect.val = 0; +} + +/** + * @brief Disable write protection of the RWDT registers + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw) +{ + hw->wprotect.val = LP_WDT_WKEY_VALUE; +} + +/** + * @brief Enable the RWDT interrupt. + * + * @param hw Start address of the peripheral registers. + * @param enable True to enable RWDT interrupt, false to disable. + */ +FORCE_INLINE_ATTR void lpwdt_ll_set_intr_enable(lp_wdt_dev_t *hw, bool enable) +{ + hw->int_ena.lp_wdt_int_ena = (enable) ? 1 : 0; +} + +/** + * @brief Check if the RWDT interrupt has been triggered + * + * @param hw Start address of the peripheral registers. + * @return True if the RWDT interrupt was triggered + */ +FORCE_INLINE_ATTR bool lpwdt_ll_check_intr_status(lp_wdt_dev_t *hw) +{ + return (hw->int_st.lp_wdt_int_st) ? true : false; +} + +/** + * @brief Clear the RWDT interrupt status. + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void lpwdt_ll_clear_intr_status(lp_wdt_dev_t *hw) +{ + hw->int_clr.lp_wdt_int_clr = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/mcpwm_ll.h b/components/hal/esp32c6/include/hal/mcpwm_ll.h new file mode 100644 index 000000000000..a928a928e4e8 --- /dev/null +++ b/components/hal/esp32c6/include/hal/mcpwm_ll.h @@ -0,0 +1,1653 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for ESP32-C6 MCPWM register operations + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/mcpwm_struct.h" +#include "soc/clk_tree_defs.h" +#include "soc/pcr_struct.h" +#include "hal/mcpwm_types.h" +#include "hal/misc.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Get MCPWM group register base address +#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : NULL) + +// MCPWM interrupt event mask +#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer)) +#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3)) +#define MCPWM_LL_EVENT_TIMER_FULL(timer) (1 << ((timer) + 6)) +#define MCPWM_LL_EVENT_TIMER_MASK(timer) (MCPWM_LL_EVENT_TIMER_STOP(timer) | MCPWM_LL_EVENT_TIMER_EMPTY(timer) | MCPWM_LL_EVENT_TIMER_FULL(timer)) +#define MCPWM_LL_EVENT_FAULT_ENTER(fault) (1 << ((fault) + 9)) +#define MCPWM_LL_EVENT_FAULT_EXIT(fault) (1 << ((fault) + 12)) +#define MCPWM_LL_EVENT_FAULT_MASK(fault) (MCPWM_LL_EVENT_FAULT_ENTER(fault) | MCPWM_LL_EVENT_FAULT_EXIT(fault)) +#define MCPWM_LL_EVENT_CMP_EQUAL(oper, cmp) (1 << ((oper) + (cmp) * 3 + 15)) +#define MCPWM_LL_EVENT_OPER_BRAKE_CBC(oper) (1 << ((oper) + 21)) +#define MCPWM_LL_EVENT_OPER_BRAKE_OST(oper) (1 << ((oper) + 24)) +#define MCPWM_LL_EVENT_OPER_MASK(oper) (MCPWM_LL_EVENT_OPER_BRAKE_CBC(oper) | MCPWM_LL_EVENT_OPER_BRAKE_OST(oper)) +#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27)) + +// Maximum values due to limited register bit width +#define MCPWM_LL_MAX_GROUP_PRESCALE 256 +#define MCPWM_LL_MAX_TIMER_PRESCALE 256 +#define MCPWM_LL_MAX_CARRIER_PRESCALE 16 +#define MCPWM_LL_MAX_CARRIER_ONESHOT 16 +#define MCPWM_LL_MAX_CAPTURE_PRESCALE 256 +#define MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE 1 +#define MCPWM_LL_MAX_DEAD_DELAY 65536 +#define MCPWM_LL_MAX_COUNT_VALUE 65536 + +// translate the HAL types into register values +#define MCPWM_LL_TIMER_EVENT_TO_REG_VAL(event) ((uint8_t[]) {0, 1}[(event)]) +#define MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) ((uint8_t[]) {0, 1, 2, 3}[(action)]) +#define MCPWM_LL_BRAKE_MODE_TO_REG_VAL(mode) ((uint8_t[]) {0, 1}[(mode)]) + +/** + * @brief The dead time module's clock source + */ +typedef enum { + MCPWM_LL_DEADTIME_CLK_SRC_GROUP, + MCPWM_LL_DEADTIME_CLK_SRC_TIMER, +} mcpwm_ll_deadtime_clock_src_t; + +////////////////////////////////////////MCPWM Group Specific//////////////////////////////////////////////////////////// + +/** + * @brief Set the clock source for MCPWM + * + * @param mcpwm Peripheral instance address + * @param clk_src Clock source for the MCPWM peripheral + */ +static inline void mcpwm_ll_group_set_clock_source(mcpwm_dev_t *mcpwm, soc_module_clk_t clk_src) +{ + (void)mcpwm; // only one MCPWM instance + switch (clk_src) { + case SOC_MOD_CLK_PLL_F160M: + PCR.pwm_clk_conf.pwm_clkm_sel = 1; + break; + case SOC_MOD_CLK_XTAL: + PCR.pwm_clk_conf.pwm_clkm_sel = 2; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @brief Enable MCPWM module clock + * + * @param mcpwm Peripheral instance address + * @param en true to enable, false to disable + */ +static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en) +{ + (void)mcpwm; // only one MCPWM instance + PCR.pwm_clk_conf.pwm_clkm_en = en; +} + +/** + * @brief Set the MCPWM group clock prescale + * + * @param mcpwm Peripheral instance address + * @param prescale Prescale value + */ +static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale) +{ + (void)mcpwm; // only one MCPWM instance + // group clock: PWM_clk = source_clock / (prescale) + HAL_ASSERT(prescale <= 256 && prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, prescale - 1); +} + +/** + * @brief Enable update MCPWM active registers from shadow registers + * + * @param mcpwm Peripheral instance address + */ +static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm) +{ + mcpwm->update_cfg.global_up_en = 1; + mcpwm->update_cfg.op0_up_en = 1; + mcpwm->update_cfg.op1_up_en = 1; + mcpwm->update_cfg.op2_up_en = 1; +} + +/** + * @brief Flush shadow registers to active registers + * + * @param mcpwm Peripheral instance address + */ +static inline void mcpwm_ll_group_flush_shadow(mcpwm_dev_t *mcpwm) +{ + // a toggle can trigger a forced update of all active registers in MCPWM, i.e. shadow->active + mcpwm->update_cfg.global_force_up = 1; + mcpwm->update_cfg.global_force_up = 0; +} + +//////////////////////////////////////////Interrupt Specific//////////////////////////////////////////////////////////// + +/** + * @brief Get interrupt status register address + * + * @param mcpwm Peripheral instance address + * @return Register address + */ +static inline volatile void *mcpwm_ll_intr_get_status_reg(mcpwm_dev_t *mcpwm) +{ + return &mcpwm->int_st; +} + +/** + * @brief Enable MCPWM interrupt for specific event mask + * + * @param mcpwm Peripheral instance address + * @param mask Event mask + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_intr_enable(mcpwm_dev_t *mcpwm, uint32_t mask, bool enable) +{ + if (enable) { + mcpwm->int_ena.val |= mask; + } else { + mcpwm->int_ena.val &= ~mask; + } +} + +/** + * @brief Get MCPWM interrupt status + * + * @param mcpwm Peripheral instance address + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t mcpwm_ll_intr_get_status(mcpwm_dev_t *mcpwm) +{ + return mcpwm->int_st.val; +} + +/** + * @brief Clear MCPWM interrupt status by mask + * + * @param mcpwm Peripheral instance address + * @param mask Interupt status mask + */ +__attribute__((always_inline)) +static inline void mcpwm_ll_intr_clear_status(mcpwm_dev_t *mcpwm, uint32_t mask) +{ + mcpwm->int_clr.val = mask; +} + +////////////////////////////////////////MCPWM Timer Specific//////////////////////////////////////////////////////////// + +/** + * @brief Set MCPWM timer prescale + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param prescale Prescale value + */ +static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int timer_id, uint32_t prescale) +{ + HAL_ASSERT(prescale <= 256 && prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_prescale, prescale - 1); +} + +/** + * @brief Set peak value for MCPWM timer + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param peak Peak value + * @param symmetric True to set symmetric peak value, False to set asymmetric peak value + */ +__attribute__((always_inline)) +static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) +{ + if (!symmetric) { // in asymmetric mode, period = [0,peak-1] + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak - 1); + } else { // in symmetric mode, period = [0,peak-1] + [peak,1] + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak); + } +} + +/** + * @brief Update MCPWM period immediately + * @note When period value is updated in the shadow register, it will be flushed to active register immediately. + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_update_period_at_once(mcpwm_dev_t *mcpwm, int timer_id) +{ + mcpwm->timer[timer_id].timer_cfg0.timer_period_upmethod = 0; +} + +/** + * @brief Enable to update MCPWM period upon TEZ event + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_timer_enable_update_period_on_tez(mcpwm_dev_t *mcpwm, int timer_id, bool enable) +{ + if (enable) { + mcpwm->timer[timer_id].timer_cfg0.timer_period_upmethod |= 0x01; + } else { + mcpwm->timer[timer_id].timer_cfg0.timer_period_upmethod &= ~0x01; + } +} + +/** + * @brief Enable to update MCPWM period upon sync event + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_timer_enable_update_period_on_sync(mcpwm_dev_t *mcpwm, int timer_id, bool enable) +{ + if (enable) { + mcpwm->timer[timer_id].timer_cfg0.timer_period_upmethod |= 0x02; + } else { + mcpwm->timer[timer_id].timer_cfg0.timer_period_upmethod &= ~0x02; + } +} + +/** + * @brief Set MCPWM timer count mode + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param mode Timer count mode + */ +static inline void mcpwm_ll_timer_set_count_mode(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_count_mode_t mode) +{ + switch (mode) { + case MCPWM_TIMER_COUNT_MODE_PAUSE: + mcpwm->timer[timer_id].timer_cfg1.timer_mod = 0; + break; + case MCPWM_TIMER_COUNT_MODE_UP: + mcpwm->timer[timer_id].timer_cfg1.timer_mod = 1; + break; + case MCPWM_TIMER_COUNT_MODE_DOWN: + mcpwm->timer[timer_id].timer_cfg1.timer_mod = 2; + break; + case MCPWM_TIMER_COUNT_MODE_UP_DOWN: + mcpwm->timer[timer_id].timer_cfg1.timer_mod = 3; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @brief Execute MCPWM timer start/stop command + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param cmd Timer start/stop command + */ +static inline void mcpwm_ll_timer_set_start_stop_command(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_start_stop_cmd_t cmd) +{ + switch (cmd) { + case MCPWM_TIMER_STOP_EMPTY: + mcpwm->timer[timer_id].timer_cfg1.timer_start = 0; + break; + case MCPWM_TIMER_STOP_FULL: + mcpwm->timer[timer_id].timer_cfg1.timer_start = 1; + break; + case MCPWM_TIMER_START_NO_STOP: + mcpwm->timer[timer_id].timer_cfg1.timer_start = 2; + break; + case MCPWM_TIMER_START_STOP_EMPTY: + mcpwm->timer[timer_id].timer_cfg1.timer_start = 3; + break; + case MCPWM_TIMER_START_STOP_FULL: + mcpwm->timer[timer_id].timer_cfg1.timer_start = 4; + break; + default: + HAL_ASSERT(false); + break;; + } +} + +/** + * @brief Get timer count value + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @return Timer count value + */ +__attribute__((always_inline)) +static inline uint32_t mcpwm_ll_timer_get_count_value(mcpwm_dev_t *mcpwm, int timer_id) +{ + // status.value saves the "next count value", so need an extra round up here to get the current count value according to count mode + // timer is paused + if (mcpwm->timer[timer_id].timer_cfg1.timer_mod == 0) { + return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_status, timer_value); + } + if (mcpwm->timer[timer_id].timer_status.timer_direction) { // down direction + return (HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_status, timer_value) + 1) % + (HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + 1); + } + // up direction + return (HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_status, timer_value) + + HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period)) % + (HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + 1); +} + +/** + * @brief Get timer count direction + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @return Timer count direction + */ +__attribute__((always_inline)) +static inline mcpwm_timer_direction_t mcpwm_ll_timer_get_count_direction(mcpwm_dev_t *mcpwm, int timer_id) +{ + return mcpwm->timer[timer_id].timer_status.timer_direction ? MCPWM_TIMER_DIRECTION_DOWN : MCPWM_TIMER_DIRECTION_UP; +} + +/** + * @brief Enable sync input for timer + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int timer_id, bool enable) +{ + mcpwm->timer[timer_id].timer_sync.timer_synci_en = enable; +} + +/** + * @brief Use the input sync signal as the output sync signal (i.e. propagate the input sync signal) + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_propagate_input_sync(mcpwm_dev_t *mcpwm, int timer_id) +{ + // sync_out is selected to sync_in + mcpwm->timer[timer_id].timer_sync.timer_synco_sel = 0; +} + +/** + * @brief Set the sync output signal to one of the timer event + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param event Timer event + */ +static inline void mcpwm_ll_timer_sync_out_on_timer_event(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_event_t event) +{ + switch (event) { + case MCPWM_TIMER_EVENT_EMPTY: + mcpwm->timer[timer_id].timer_sync.timer_synco_sel = 1; + break; + case MCPWM_TIMER_EVENT_FULL: + mcpwm->timer[timer_id].timer_sync.timer_synco_sel = 2; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @brief Disable sync output for MCPWM timer + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_disable_sync_out(mcpwm_dev_t *mcpwm, int timer_id) +{ + // sync_out will always be zero + mcpwm->timer[timer_id].timer_sync.timer_synco_sel = 3; +} + +/** + * @brief Trigger MCPWM timer software sync event + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_trigger_soft_sync(mcpwm_dev_t *mcpwm, int timer_id) +{ + mcpwm->timer[timer_id].timer_sync.timer_sync_sw = ~mcpwm->timer[timer_id].timer_sync.timer_sync_sw; +} + +/** + * @brief Set sync count value for MCPWM timer + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param phase_value Sync phase value + */ +static inline void mcpwm_ll_timer_set_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t phase_value) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_sync, timer_phase, phase_value); +} + +/** + * @brief Set sync phase direction for MCPWM timer + * + * @param mcpwm Peripheral instance address + * @param timer_id Timer ID, index from 0 to 2 + * @param direction Sync phase direction + */ +static inline void mcpwm_ll_timer_set_sync_phase_direction(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_direction_t direction) +{ + mcpwm->timer[timer_id].timer_sync.timer_phase_direction = direction; +} + +/** + * @brief Select which GPIO sync input to use + * + * @param mcpwm Peripheral instance address + * @param timer Timer ID, index from 0 to 2 + * @param gpio_sync_id GPIO sync ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_set_gpio_sync_input(mcpwm_dev_t *mcpwm, int timer, int gpio_sync_id) +{ + mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3)); + mcpwm->timer_synci_cfg.val |= (gpio_sync_id + 4) << (timer * 3); +} + +/** + * @brief Select which timer sync input to use + * + * @param mcpwm Peripheral instance address + * @param timer Timer ID, index from 0 to 2 + * @param timer_sync_id Timer sync ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_set_timer_sync_input(mcpwm_dev_t *mcpwm, int timer, int timer_sync_id) +{ + mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3)); + mcpwm->timer_synci_cfg.val |= (timer_sync_id + 1) << (timer * 3); +} + +/** + * @brief Clear timer sync input selection + * + * @param mcpwm Peripheral instance address + * @param timer Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_timer_clear_sync_input(mcpwm_dev_t *mcpwm, int timer) +{ + // no sync input is selected, but software sync can still work + mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3)); +} + +/** + * @brief Invert the GPIO sync input signal + * + * @param mcpwm Peripheral instance address + * @param sync_id GPIO sync ID, index from 0 to 2 + * @param invert True to invert, False to not invert + */ +static inline void mcpwm_ll_invert_gpio_sync_input(mcpwm_dev_t *mcpwm, int sync_id, bool invert) +{ + if (invert) { + mcpwm->timer_synci_cfg.val |= 1 << (sync_id + 9); + } else { + mcpwm->timer_synci_cfg.val &= ~(1 << (sync_id + 9)); + } +} + +////////////////////////////////////////MCPWM Operator Specific///////////////////////////////////////////////////////// + +/** + * @brief Flush operator shadow registers to active registers + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + */ +static inline void mcpwm_ll_operator_flush_shadow(mcpwm_dev_t *mcpwm, int operator_id) +{ + mcpwm->update_cfg.val ^= (1 << (2 * operator_id + 3)); +} + +/** + * @brief Connect operator and timer by ID + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param timer_id Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_operator_connect_timer(mcpwm_dev_t *mcpwm, int operator_id, int timer_id) +{ + mcpwm->operator_timersel.val &= ~(0x03 << (2 * operator_id)); + mcpwm->operator_timersel.val |= (timer_id << (2 * operator_id)); +} + +/** + * @brief Update the compare value immediately + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param compare_id Compare ID, index from 0 to 1 + */ +static inline void mcpwm_ll_operator_update_compare_at_once(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) +{ + mcpwm->operators[operator_id].gen_stmp_cfg.val &= ~(0x0F << (4 * compare_id)); +} + +/** + * @brief Enable to update the compare value upon TEZ event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param compare_id Compare ID, index from 0 to 1 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_operator_enable_update_compare_on_tez(mcpwm_dev_t *mcpwm, int operator_id, int compare_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].gen_stmp_cfg.val |= (1 << 0) << (4 * compare_id); + } else { + mcpwm->operators[operator_id].gen_stmp_cfg.val &= ~((1 << 0) << (4 * compare_id)); + } +} + +/** + * @brief Enable to update the compare value upon TEP event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param compare_id Compare ID, index from 0 to 1 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_operator_enable_update_compare_on_tep(mcpwm_dev_t *mcpwm, int operator_id, int compare_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].gen_stmp_cfg.val |= (1 << 1) << (4 * compare_id); + } else { + mcpwm->operators[operator_id].gen_stmp_cfg.val &= ~((1 << 1) << (4 * compare_id)); + } +} + +/** + * @brief Enable to update the compare value upon sync event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param compare_id Compare ID, index from 0 to 1 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_operator_enable_update_compare_on_sync(mcpwm_dev_t *mcpwm, int operator_id, int compare_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].gen_stmp_cfg.val |= (1 << 2) << (4 * compare_id); + } else { + mcpwm->operators[operator_id].gen_stmp_cfg.val &= ~((1 << 2) << (4 * compare_id)); + } +} + +/** + * @brief Stop updating the compare value + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param compare_id Compare ID, index from 0 to 1 + * @param stop_or_not True to stop, False to not stop + */ +static inline void mcpwm_ll_operator_stop_update_compare(mcpwm_dev_t *mcpwm, int operator_id, int compare_id, bool stop_or_not) +{ + if (stop_or_not) { + mcpwm->operators[operator_id].gen_stmp_cfg.val |= (1 << 3) << (4 * compare_id); + } else { + mcpwm->operators[operator_id].gen_stmp_cfg.val &= ~((1 << 3) << (4 * compare_id)); + } +} + +/** + * @brief Set compare value for comparator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param compare_id Compare ID, index from 0 to 1 + * @param compare_value Compare value + */ +__attribute__((always_inline)) +static inline void mcpwm_ll_operator_set_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id, uint32_t compare_value) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], cmpr, compare_value); +} + +/** + * @brief Update operator actions immediately + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + */ +static inline void mcpwm_ll_operator_update_action_at_once(mcpwm_dev_t *mcpwm, int operator_id) +{ + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod = 0; +} + +/** + * @brief Enable update actions on TEZ event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_operator_enable_update_action_on_tez(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod |= 1 << 0; + } else { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod &= ~(1 << 0); + } +} + +/** + * @brief Enable update actions on TEP event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_operator_enable_update_action_on_tep(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod |= 1 << 1; + } else { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod &= ~(1 << 1); + } +} + +/** + * @brief Enable update actions on sync event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_operator_enable_update_action_on_sync(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod |= 1 << 2; + } else { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod &= ~(1 << 2); + } +} + +/** + * @brief Stop updating actions + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param stop_or_not True to stop, False to not stop + */ +static inline void mcpwm_ll_operator_stop_update_action(mcpwm_dev_t *mcpwm, int operator_id, bool stop_or_not) +{ + if (stop_or_not) { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod |= 1 << 3; + } else { + mcpwm->operators[operator_id].gen_cfg0.gen_cfg_upmethod &= ~(1 << 3); + } +} + +/** + * @brief Set trigger from GPIO (reuse the fault GPIO) + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param trig_id Trigger ID, index from 0 to 1 + * @param fault_gpio_id Fault GPIO ID, index from 0 to 3 + */ +static inline void mcpwm_ll_operator_set_trigger_from_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) +{ + mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); + mcpwm->operators[operator_id].gen_cfg0.val |= (fault_gpio_id << (4 + 3 * trig_id)); +} + +/** + * @brief Set trigger from sync event (when the timer/gpio/soft taken the sync signal) + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param trig_id Trigger ID, index from 0 to 1 + */ +static inline void mcpwm_ll_operator_set_trigger_from_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) +{ + // the timer here is not selectable, must be the one connected with the operator + mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); + mcpwm->operators[operator_id].gen_cfg0.val |= (3 << (4 + 3 * trig_id)); +} + +////////////////////////////////////////MCPWM Generator Specific//////////////////////////////////////////////////////// + +/** + * @brief Reset actions for the generator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + */ +static inline void mcpwm_ll_generator_reset_actions(mcpwm_dev_t *mcpwm, int operator_id, int generator_id) +{ + mcpwm->operators[operator_id].generator[generator_id].val = 0; +} + +/** + * @brief Set generator action on timer event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + * @param direction Timer direction + * @param event Timer event + * @param action Action to set + */ +static inline void mcpwm_ll_generator_set_action_on_timer_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, + mcpwm_timer_direction_t direction, mcpwm_timer_event_t event, mcpwm_generator_action_t action) +{ + // empty: 0, full: 1 + if (direction == MCPWM_TIMER_DIRECTION_UP) { // utez, utep + mcpwm->operators[operator_id].generator[generator_id].val &= ~(0x03 << (MCPWM_LL_TIMER_EVENT_TO_REG_VAL(event) * 2)); + mcpwm->operators[operator_id].generator[generator_id].val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (MCPWM_LL_TIMER_EVENT_TO_REG_VAL(event) * 2); + } else if (direction == MCPWM_TIMER_DIRECTION_DOWN) { // dtez, dtep + mcpwm->operators[operator_id].generator[generator_id].val &= ~(0x03 << (MCPWM_LL_TIMER_EVENT_TO_REG_VAL(event) * 2 + 12)); + mcpwm->operators[operator_id].generator[generator_id].val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (MCPWM_LL_TIMER_EVENT_TO_REG_VAL(event) * 2 + 12); + } +} + +/** + * @brief Set generator action on compare event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + * @param direction Timer direction + * @param comp_id Compare ID, index from 0 to 1 + * @param action Action to set + */ +static inline void mcpwm_ll_generator_set_action_on_compare_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, + mcpwm_timer_direction_t direction, int cmp_id, int action) +{ + if (direction == MCPWM_TIMER_DIRECTION_UP) { // utea, uteb + mcpwm->operators[operator_id].generator[generator_id].val &= ~(0x03 << (cmp_id * 2 + 4)); + mcpwm->operators[operator_id].generator[generator_id].val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (cmp_id * 2 + 4); + } else if (direction == MCPWM_TIMER_DIRECTION_DOWN) { // dtea, dteb + mcpwm->operators[operator_id].generator[generator_id].val &= ~(0x03 << (cmp_id * 2 + 16)); + mcpwm->operators[operator_id].generator[generator_id].val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (cmp_id * 2 + 16); + } +} + +/** + * @brief Set generator action on trigger event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + * @param direction Timer direction + * @param trig_id Trigger ID, index from 0 to 1 + * @param action Action to set + */ +static inline void mcpwm_ll_generator_set_action_on_trigger_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, + mcpwm_timer_direction_t direction, int trig_id, int action) +{ + if (direction == MCPWM_TIMER_DIRECTION_UP) { // ut0, ut1 + mcpwm->operators[operator_id].generator[generator_id].val &= ~(0x03 << (trig_id * 2 + 8)); + mcpwm->operators[operator_id].generator[generator_id].val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (trig_id * 2 + 8); + } else if (direction == MCPWM_TIMER_DIRECTION_DOWN) { // dt0, dt1 + mcpwm->operators[operator_id].generator[generator_id].val &= ~(0x03 << (trig_id * 2 + 20)); + mcpwm->operators[operator_id].generator[generator_id].val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (trig_id * 2 + 20); + } +} + +/** + * @brief Set generator action on brake event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + * @param direction Timer direction + * @param brake_mode Brake mode + * @param action Action to set + */ +static inline void mcpwm_ll_generator_set_action_on_brake_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, + mcpwm_timer_direction_t direction, mcpwm_operator_brake_mode_t brake_mode, int action) +{ + // the following bit operation is highly depend on the register bit layout. + // the priority comes: generator ID > brake mode > direction + if (direction == MCPWM_TIMER_DIRECTION_UP) { + mcpwm->operators[operator_id].fh_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * MCPWM_LL_BRAKE_MODE_TO_REG_VAL(brake_mode) + 2)); + mcpwm->operators[operator_id].fh_cfg0.val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (8 + 8 * generator_id + 4 * MCPWM_LL_BRAKE_MODE_TO_REG_VAL(brake_mode) + 2); + } else if (direction == MCPWM_TIMER_DIRECTION_DOWN) { + mcpwm->operators[operator_id].fh_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * MCPWM_LL_BRAKE_MODE_TO_REG_VAL(brake_mode))); + mcpwm->operators[operator_id].fh_cfg0.val |= MCPWM_LL_GEN_ACTION_TO_REG_CAL(action) << (8 + 8 * generator_id + 4 * MCPWM_LL_BRAKE_MODE_TO_REG_VAL(brake_mode)); + } +} + +/** + * @brief Trigger non-continue forced action for generator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + */ +static inline void mcpwm_ll_gen_trigger_noncontinue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id) +{ + if (generator_id == 0) { + mcpwm->operators[operator_id].gen_force.gen_a_nciforce = ~mcpwm->operators[operator_id].gen_force.gen_a_nciforce; + } else { + mcpwm->operators[operator_id].gen_force.gen_b_nciforce = ~mcpwm->operators[operator_id].gen_force.gen_b_nciforce; + } +} + +/** + * @brief Disable continue forced action for generator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + */ +static inline void mcpwm_ll_gen_disable_continue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id) +{ + mcpwm->operators[operator_id].gen_force.gen_cntuforce_upmethod = 0; // update force method immediately + if (generator_id == 0) { + mcpwm->operators[operator_id].gen_force.gen_a_cntuforce_mode = 0; + } else { + mcpwm->operators[operator_id].gen_force.gen_b_cntuforce_mode = 0; + } +} + +/** + * @brief Disable non-continue forced action for generator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + */ +static inline void mcpwm_ll_gen_disable_noncontinue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id) +{ + if (generator_id == 0) { + mcpwm->operators[operator_id].gen_force.gen_a_nciforce_mode = 0; + } else { + mcpwm->operators[operator_id].gen_force.gen_b_nciforce_mode = 0; + } +} + +/** + * @brief Set continue force level for generator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + * @param level Force level to set + */ +static inline void mcpwm_ll_gen_set_continue_force_level(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int level) +{ + mcpwm->operators[operator_id].gen_force.gen_cntuforce_upmethod = 0; // update force method immediately + if (generator_id == 0) { + mcpwm->operators[operator_id].gen_force.gen_a_cntuforce_mode = level + 1; + } else { + mcpwm->operators[operator_id].gen_force.gen_b_cntuforce_mode = level + 1; + } +} + +/** + * @brief Set non-continue force level for generator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator_id Generator ID, index from 0 to 1 + * @param level Force level to set + */ +static inline void mcpwm_ll_gen_set_noncontinue_force_level(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int level) +{ + if (generator_id == 0) { + mcpwm->operators[operator_id].gen_force.gen_a_nciforce_mode = level + 1; + } else { + mcpwm->operators[operator_id].gen_force.gen_b_nciforce_mode = level + 1; + } +} + +////////////////////////////////////////MCPWM Dead Time Specific//////////////////////////////////////////////////////// + +/** + * @brief Set clock source for dead time submodule + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param src Clock source for dead time submodule + */ +static inline void mcpwm_ll_operator_set_deadtime_clock_src(mcpwm_dev_t *mcpwm, int operator_id, mcpwm_ll_deadtime_clock_src_t src) +{ + switch (src) { + case MCPWM_LL_DEADTIME_CLK_SRC_GROUP: + mcpwm->operators[operator_id].dt_cfg.db_clk_sel = 0; + break; + case MCPWM_LL_DEADTIME_CLK_SRC_TIMER: + mcpwm->operators[operator_id].dt_cfg.db_clk_sel = 1; + break;; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Select the generator for RED block + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator Generator ID, index from 0 to 1 + */ +static inline void mcpwm_ll_deadtime_red_select_generator(mcpwm_dev_t *mcpwm, int operator_id, int generator) +{ + mcpwm->operators[operator_id].dt_cfg.db_red_insel = generator; +} + +/** + * @brief Select the generator for FED block + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param generator Generator ID, index from 0 to 1 + */ +static inline void mcpwm_ll_deadtime_fed_select_generator(mcpwm_dev_t *mcpwm, int operator_id, int generator) +{ + mcpwm->operators[operator_id].dt_cfg.db_fed_insel = generator; +} + +/** + * @brief Set which path to bypass in the deadtime submodule + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param path Path to bypass, index from 0 to 1 + * @param bypass True to bypass, False to not bypass + */ +static inline void mcpwm_ll_deadtime_bypass_path(mcpwm_dev_t *mcpwm, int operator_id, int path, bool bypass) +{ + if (bypass) { + mcpwm->operators[operator_id].dt_cfg.val |= 1 << (path + 15); + } else { + mcpwm->operators[operator_id].dt_cfg.val &= ~(1 << (path + 15)); + } +} + +/** + * @brief Invert the output path + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param path Path to invert, index from 0 to 1 + * @param invert True to invert, False to not invert + */ +static inline void mcpwm_ll_deadtime_invert_outpath(mcpwm_dev_t *mcpwm, int operator_id, int path, bool invert) +{ + if (invert) { + mcpwm->operators[operator_id].dt_cfg.val |= 1 << (path + 13); + } else { + mcpwm->operators[operator_id].dt_cfg.val &= ~(1 << (path + 13)); + } +} + +/** + * @brief Swap the output path + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param path Path to swap, index from 0 to 1 + * @param swap True to swap, False to not swap + */ +static inline void mcpwm_ll_deadtime_swap_out_path(mcpwm_dev_t *mcpwm, int operator_id, int path, bool swap) +{ + if (swap) { + mcpwm->operators[operator_id].dt_cfg.val |= 1 << (path + 9); + } else { + mcpwm->operators[operator_id].dt_cfg.val &= ~(1 << (path + 9)); + } +} + +/** + * @brief Enable the DEB block + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_deadtime_enable_deb(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + mcpwm->operators[operator_id].dt_cfg.db_deb_mode = enable; +} + +/** + * @brief Get the deadtime switch topology + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @return Dead time submodule's switch topology, each bit represents one switch on/off status + */ +static inline uint32_t mcpwm_ll_deadtime_get_switch_topology(mcpwm_dev_t *mcpwm, int operator_id) +{ + return (mcpwm->operators[operator_id].dt_cfg.db_deb_mode << 8) | (mcpwm->operators[operator_id].dt_cfg.db_b_outswap << 7) | + (mcpwm->operators[operator_id].dt_cfg.db_a_outswap << 6) | (mcpwm->operators[operator_id].dt_cfg.db_fed_insel << 5) | + (mcpwm->operators[operator_id].dt_cfg.db_red_insel << 4) | (mcpwm->operators[operator_id].dt_cfg.db_fed_outinvert << 3) | + (mcpwm->operators[operator_id].dt_cfg.db_red_outinvert << 2) | (mcpwm->operators[operator_id].dt_cfg.db_a_outbypass << 1) | + (mcpwm->operators[operator_id].dt_cfg.db_b_outbypass << 0); +} + +/** + * @brief Set falling edge delay duration + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param fed Delay duration, in deadtime submodule's clock cycles + */ +static inline void mcpwm_ll_deadtime_set_falling_delay(mcpwm_dev_t *mcpwm, int operator_id, uint32_t fed) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->operators[operator_id].dt_fed_cfg, db_fed, fed - 1); +} + +/** + * @brief Set rising edge delay duration + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param red Delay duration, in deadtime submodule's clock cycles + */ +static inline void mcpwm_ll_deadtime_set_rising_delay(mcpwm_dev_t *mcpwm, int operator_id, uint32_t red) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->operators[operator_id].dt_red_cfg, db_red, red - 1); +} + +/** + * @brief Update deadtime immediately + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + */ +static inline void mcpwm_ll_deadtime_update_delay_at_once(mcpwm_dev_t *mcpwm, int operator_id) +{ + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod = 0; + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod = 0; +} + +/** + * @brief Enable to update deadtime on TEZ event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_deadtime_enable_update_delay_on_tez(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod |= 1 << 0; + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod |= 1 << 0; + } else { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod &= ~(1 << 0); + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod &= ~(1 << 0); + } +} + +/** + * @brief Enable to update deadtime on TEP event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_deadtime_enable_update_delay_on_tep(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod |= 1 << 1; + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod |= 1 << 1; + } else { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod &= ~(1 << 1); + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod &= ~(1 << 1); + } +} + +/** + * @brief Enable to update deadtime on sync event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_deadtime_enable_update_delay_on_sync(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod |= 1 << 2; + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod |= 1 << 2; + } else { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod &= ~(1 << 2); + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod &= ~(1 << 2); + } +} + +/** + * @brief Stop updating deadtime + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param stop_or_not True to stop, False to continue + */ +static inline void mcpwm_ll_deadtime_stop_update_delay(mcpwm_dev_t *mcpwm, int operator_id, bool stop_or_not) +{ + if (stop_or_not) { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod |= 1 << 3; + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod |= 1 << 3; + } else { + mcpwm->operators[operator_id].dt_cfg.db_fed_upmethod &= ~(1 << 3); + mcpwm->operators[operator_id].dt_cfg.db_red_upmethod &= ~(1 << 3); + } +} + +////////////////////////////////////////MCPWM Carrier Specific////////////////////////////////////////////////////////// + +/** + * @brief Enable carrier for MCPWM operator + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_carrier_enable(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + mcpwm->operators[operator_id].carrier_cfg.chopper_en = enable; +} + +/** + * @brief Set prescale for MCPWM carrier source clock + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param prescale Prescale value + */ +static inline void mcpwm_ll_carrier_set_prescale(mcpwm_dev_t *mcpwm, int operator_id, uint8_t prescale) +{ + HAL_ASSERT(prescale > 0 && prescale <= 16); + mcpwm->operators[operator_id].carrier_cfg.chopper_prescale = prescale - 1; +} + +/** + * @brief Set duty cycle of MCPWM carrier + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param carrier_duty Duty cycle value + */ +static inline void mcpwm_ll_carrier_set_duty(mcpwm_dev_t *mcpwm, int operator_id, uint8_t carrier_duty) +{ + mcpwm->operators[operator_id].carrier_cfg.chopper_duty = carrier_duty; +} + +/** + * @brief Invert the signal after the carrier is applied + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param invert True to invert, False to not invert + */ +static inline void mcpwm_ll_carrier_out_invert(mcpwm_dev_t *mcpwm, int operator_id, bool invert) +{ + mcpwm->operators[operator_id].carrier_cfg.chopper_out_invert = invert; +} + +/** + * @brief Invert the signal before applying the carrier + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param invert True to invert, False to not invert + */ +static inline void mcpwm_ll_carrier_in_invert(mcpwm_dev_t *mcpwm, int operator_id, bool invert) +{ + mcpwm->operators[operator_id].carrier_cfg.chopper_in_invert = invert; +} + +/** + * @brief Set the first pulse width of the carrier + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param pulse_width Pulse width + */ +static inline void mcpwm_ll_carrier_set_first_pulse_width(mcpwm_dev_t *mcpwm, int operator_id, uint8_t pulse_width) +{ + HAL_ASSERT(pulse_width >= 1); + mcpwm->operators[operator_id].carrier_cfg.chopper_oshtwth = pulse_width - 1; +} + +////////////////////////////////////////MCPWM Fault Specific//////////////////////////////////////////////////////////// + +/** + * @brief Enable GPIO fault detection + * + * @param mcpwm Peripheral instance address + * @param fault_sig GPIO fault ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_fault_enable_detection(mcpwm_dev_t *mcpwm, int fault_sig, bool enable) +{ + if (enable) { + mcpwm->fault_detect.val |= 1 << fault_sig; + } else { + mcpwm->fault_detect.val &= ~(1 << fault_sig); + } +} + +/** + * @brief Set fault polarity (i.e. which level is treated as an active fault) + * + * @param mcpwm Peripheral instance address + * @param fault_sig GPIO fault ID, index from 0 to 2 + * @param level Active level, 0 for low, 1 for high + */ +static inline void mcpwm_ll_fault_set_active_level(mcpwm_dev_t *mcpwm, int fault_sig, bool level) +{ + if (level) { + mcpwm->fault_detect.val |= 1 << (fault_sig + 3); + } else { + mcpwm->fault_detect.val &= ~(1 << (fault_sig + 3)); + } +} + +/** + * @brief Clear the OST brake + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + */ +static inline void mcpwm_ll_brake_clear_ost(mcpwm_dev_t *mcpwm, int operator_id) +{ + // a posedge can clear the ost fault status + mcpwm->operators[operator_id].fh_cfg1.tz_clr_ost = 0; + mcpwm->operators[operator_id].fh_cfg1.tz_clr_ost = 1; +} + +/** + * @brief Enable the OST brake + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param fault_sig GPIO fault ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_brake_enable_oneshot_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].fh_cfg0.val |= (1 << (7 - fault_sig)); + } else { + mcpwm->operators[operator_id].fh_cfg0.val &= ~(1 << (7 - fault_sig)); + } +} + +/** + * @brief Enable the CBC brake + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param fault_sig GPIO fault ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_brake_enable_cbc_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].fh_cfg0.val |= (enable << (3 - fault_sig)); + } else { + mcpwm->operators[operator_id].fh_cfg0.val &= ~(1 << (3 - fault_sig)); + } +} + +/** + * @brief Enable refresh the CBC brake on TEZ event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_brake_enable_cbc_refresh_on_tez(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].fh_cfg1.val |= 1 << 1; + } else { + mcpwm->operators[operator_id].fh_cfg1.val &= ~(1 << 1); + } +} + +/** + * @brief Enable refresh the CBC brake on TEP event + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_fault_enable_cbc_refresh_on_tep(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + if (enable) { + mcpwm->operators[operator_id].fh_cfg1.val |= 1 << 2; + } else { + mcpwm->operators[operator_id].fh_cfg1.val &= ~(1 << 2); + } +} + +/** + * @brief Enable software CBC brake + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_brake_enable_soft_cbc(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + mcpwm->operators[operator_id].fh_cfg0.tz_sw_cbc = enable; +} + +/** + * @brief Enable software OST brake + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_brake_enable_soft_ost(mcpwm_dev_t *mcpwm, int operator_id, bool enable) +{ + mcpwm->operators[operator_id].fh_cfg0.tz_sw_ost = enable; +} + +/** + * @brief Trigger software CBC brake for once + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + */ +static inline void mcpwm_ll_brake_trigger_soft_cbc(mcpwm_dev_t *mcpwm, int operator_id) +{ + mcpwm->operators[operator_id].fh_cfg1.tz_force_cbc = ~mcpwm->operators[operator_id].fh_cfg1.tz_force_cbc; +} + +/** + * @brief Trigger software OST brake for once + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + */ +static inline void mcpwm_ll_brake_trigger_soft_ost(mcpwm_dev_t *mcpwm, int operator_id) +{ + mcpwm->operators[operator_id].fh_cfg1.tz_force_ost = ~mcpwm->operators[operator_id].fh_cfg1.tz_force_ost; +} + +/** + * @brief Whether the OST brake is still active + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @return True if active, False if not + */ +static inline bool mcpwm_ll_ost_brake_active(mcpwm_dev_t *mcpwm, int operator_id) +{ + return mcpwm->operators[operator_id].fh_status.tz_ost_on; +} + +/** + * @brief Whether the CBC brake is still active + * + * @param mcpwm Peripheral instance address + * @param operator_id Operator ID, index from 0 to 2 + * @return True if active, False if not + */ +static inline bool mcpwm_ll_cbc_brake_active(mcpwm_dev_t *mcpwm, int operator_id) +{ + return mcpwm->operators[operator_id].fh_status.tz_cbc_on; +} + +////////////////////////////////////////MCPWM Capture Specific////////////////////////////////////////////////////////// + +/** + * @brief Enable capture timer + * + * @param mcpwm Peripheral instance address + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_capture_enable_timer(mcpwm_dev_t *mcpwm, bool enable) +{ + mcpwm->cap_timer_cfg.cap_timer_en = enable; +} + +/** + * @brief Enable capture channel + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_capture_enable_channel(mcpwm_dev_t *mcpwm, int channel, bool enable) +{ + mcpwm->cap_chn_cfg[channel].capn_en = enable; +} + +/** + * @brief Set sync phase for capture timer + * + * @param mcpwm Peripheral instance address + * @param phase_value Phase value + */ +static inline void mcpwm_ll_capture_set_sync_phase_value(mcpwm_dev_t *mcpwm, uint32_t phase_value) +{ + mcpwm->cap_timer_phase.cap_phase = phase_value; +} + +/** + * @brief Enable sync for capture timer + * + * @param mcpwm Peripheral instance address + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_capture_enable_timer_sync(mcpwm_dev_t *mcpwm, bool enable) +{ + mcpwm->cap_timer_cfg.cap_synci_en = enable; +} + +/** + * @brief Set the timer sync source for MCPWM capture timer + * + * @param mcpwm Peripheral instance address + * @param sync_out_timer MCPWM Timer ID, index from 0 to 2 + */ +static inline void mcpwm_ll_capture_set_timer_sync(mcpwm_dev_t *mcpwm, int sync_out_timer) +{ + mcpwm->cap_timer_cfg.cap_synci_sel = sync_out_timer + 1; +} + +/** + * @brief Set the GPIO sync source for MCPWM capture timer + * + * @param mcpwm Peripheral instance address + * @param gpio_sync GPIO sync ID, index from 0 to 2 + */ +static inline void mcpwm_ll_capture_set_gpio_sync(mcpwm_dev_t *mcpwm, int gpio_sync) +{ + mcpwm->cap_timer_cfg.cap_synci_sel = gpio_sync + 4; +} + +/** + * @brief Trigger a software sync for capture timer + * + * @param mcpwm Peripheral instance address + */ +static inline void mcpwm_ll_capture_trigger_sw_sync(mcpwm_dev_t *mcpwm) +{ + mcpwm->cap_timer_cfg.cap_sync_sw = 1; // auto clear +} + +/** + * @brief Enable capture on positive edge + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_capture_enable_posedge(mcpwm_dev_t *mcpwm, int channel, bool enable) +{ + if (enable) { + mcpwm->cap_chn_cfg[channel].val |= 1 << 2; + } else { + mcpwm->cap_chn_cfg[channel].val &= ~(1 << 2); + } +} + +/** + * @brief Enable capture on negative edge + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @param enable True to enable, False to disable + */ +static inline void mcpwm_ll_capture_enable_negedge(mcpwm_dev_t *mcpwm, int channel, bool enable) +{ + if (enable) { + mcpwm->cap_chn_cfg[channel].val |= 1 << 1; + } else { + mcpwm->cap_chn_cfg[channel].val &= ~(1 << 1); + } +} + +/** + * @brief Invert the capture input signal + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @param invert True to invert, False to not invert + */ +static inline void mcpwm_ll_invert_input(mcpwm_dev_t *mcpwm, int channel, bool invert) +{ + mcpwm->cap_chn_cfg[channel].capn_in_invert = invert; +} + +/** + * @brief Trigger the software capture for once + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + */ +static inline void mcpwm_ll_trigger_soft_capture(mcpwm_dev_t *mcpwm, int channel) +{ + mcpwm->cap_chn_cfg[channel].capn_sw = 1; // auto clear +} + +/** + * @brief Get the captured value + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @return Captured value + */ +__attribute__((always_inline)) +static inline uint32_t mcpwm_ll_capture_get_value(mcpwm_dev_t *mcpwm, int channel) +{ + return mcpwm->cap_chn[channel].capn_value; +} + +/** + * @brief Get the captured edge + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @return Captured edge + */ +__attribute__((always_inline)) +static inline mcpwm_capture_edge_t mcpwm_ll_capture_get_edge(mcpwm_dev_t *mcpwm, int channel) +{ + return mcpwm->cap_status.val & (1 << channel) ? MCPWM_CAP_EDGE_NEG : MCPWM_CAP_EDGE_POS; +} + +/** + * @brief Set the prescale of the input capture signal + * + * @param mcpwm Peripheral instance address + * @param channel Channel ID, index from 0 to 2 + * @param prescale Prescale value + */ +static inline void mcpwm_ll_capture_set_prescale(mcpwm_dev_t *mcpwm, int channel, uint32_t prescale) +{ + HAL_ASSERT(prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->cap_chn_cfg[channel], capn_prescale, prescale - 1); +} + +//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// +/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// +/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static inline uint32_t mcpwm_ll_group_get_clock_prescale(mcpwm_dev_t *mcpwm) +{ + (void)mcpwm; // only one MCPWM instance + return HAL_FORCE_READ_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num) + 1; +} + +static inline uint32_t mcpwm_ll_timer_get_clock_prescale(mcpwm_dev_t *mcpwm, int timer_id) +{ + mcpwm_timer_cfg0_reg_t cfg0 = mcpwm->timer[timer_id].timer_cfg0; + return cfg0.timer_prescale + 1; +} + +static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) +{ + return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + (symmetric ? 0 : 1); +} + +static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) +{ + switch (mcpwm->timer[timer_id].timer_cfg1.timer_mod) { + case 1: + return MCPWM_TIMER_COUNT_MODE_UP; + case 2: + return MCPWM_TIMER_COUNT_MODE_DOWN; + case 3: + return MCPWM_TIMER_COUNT_MODE_UP_DOWN; + case 0: + default: + return MCPWM_TIMER_COUNT_MODE_PAUSE; + } +} + +static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) +{ + return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], cmpr); +} + +__attribute__((always_inline)) +static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) +{ + return (mcpwm->int_st.val >> 27) & 0x07; +} + +__attribute__((always_inline)) +static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) +{ + mcpwm->int_clr.val = (capture_mask & 0x07) << 27; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/mmu_ll.h b/components/hal/esp32c6/include/hal/mmu_ll.h new file mode 100644 index 000000000000..69641daffbd9 --- /dev/null +++ b/components/hal/esp32c6/include/hal/mmu_ll.h @@ -0,0 +1,412 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for MMU register operations + +#pragma once + +#include "soc/spi_mem_reg.h" +#include "soc/ext_mem_defs.h" +#include "hal/assert.h" +#include "hal/mmu_types.h" +#include "hal/efuse_ll.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Convert MMU virtual address to linear address + * + * @param vaddr virtual address + * + * @return linear address + */ +static inline uint32_t mmu_ll_vaddr_to_laddr(uint32_t vaddr) +{ + return vaddr & SOC_MMU_LINEAR_ADDR_MASK; +} + +/** + * Convert MMU linear address to virtual address + * + * @param laddr linear address + * @param vaddr_type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` + * + * @return virtual address + */ +static inline uint32_t mmu_ll_laddr_to_vaddr(uint32_t laddr, mmu_vaddr_t vaddr_type) +{ + //On ESP32C6, I/D share the same vaddr range + return SOC_MMU_IBUS_VADDR_BASE | laddr; +} + +__attribute__((always_inline)) static inline bool mmu_ll_cache_encryption_enabled(void) +{ + unsigned cnt = efuse_ll_get_flash_crypt_cnt(); + // 3 bits wide, any odd number - 1 or 3 - bits set means encryption is on + cnt = ((cnt >> 2) ^ (cnt >> 1) ^ cnt) & 0x1; + return (cnt == 1); +} + +/** + * Get MMU page size + * + * @param mmu_id MMU ID + * + * @return MMU page size code + */ +__attribute__((always_inline)) +static inline mmu_page_size_t mmu_ll_get_page_size(uint32_t mmu_id) +{ + (void)mmu_id; + uint32_t page_size_code = REG_GET_FIELD(SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_PAGE_SIZE); + return (page_size_code == 0) ? MMU_PAGE_64KB : \ + (page_size_code == 1) ? MMU_PAGE_32KB : \ + (page_size_code == 2) ? MMU_PAGE_16KB : \ + MMU_PAGE_8KB; +} + +/** + * Set MMU page size + * + * @param size MMU page size + */ +__attribute__((always_inline)) +static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) +{ + uint8_t reg_val = (size == MMU_PAGE_64KB) ? 0 : \ + (size == MMU_PAGE_32KB) ? 1 : \ + (size == MMU_PAGE_16KB) ? 2 : \ + (size == MMU_PAGE_8KB) ? 3 : 0; + REG_SET_FIELD(SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_PAGE_SIZE, reg_val); +} + +/** + * Check if the external memory vaddr region is valid + * + * @param mmu_id MMU ID + * @param vaddr_start start of the virtual address + * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` + * + * @return + * True for valid + */ +__attribute__((always_inline)) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) +{ + (void)mmu_id; + (void)type; + uint32_t vaddr_end = vaddr_start + len - 1; + return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); +} + +/** + * Check if the paddr region is valid + * + * @param mmu_id MMU ID + * @param paddr_start start of the physical address + * @param len length, in bytes + * + * @return + * True for valid + */ +static inline bool mmu_ll_check_valid_paddr_region(uint32_t mmu_id, uint32_t paddr_start, uint32_t len) +{ + (void)mmu_id; + return (paddr_start < (mmu_ll_get_page_size(mmu_id) * MMU_MAX_PADDR_PAGE_NUM)) && + (len < (mmu_ll_get_page_size(mmu_id) * MMU_MAX_PADDR_PAGE_NUM)) && + ((paddr_start + len - 1) < (mmu_ll_get_page_size(mmu_id) * MMU_MAX_PADDR_PAGE_NUM)); +} + +/** + * To get the MMU table entry id to be mapped + * + * @param mmu_id MMU ID + * @param vaddr virtual address to be mapped + * + * @return + * MMU table entry id + */ +__attribute__((always_inline)) +static inline uint32_t mmu_ll_get_entry_id(uint32_t mmu_id, uint32_t vaddr) +{ + (void)mmu_id; + mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id); + uint32_t shift_code = 0; + switch (page_size) { + case MMU_PAGE_64KB: + shift_code = 16; + break; + case MMU_PAGE_32KB: + shift_code = 15; + break; + case MMU_PAGE_16KB: + shift_code = 14; + break; + case MMU_PAGE_8KB: + shift_code = 13; + break; + default: + HAL_ASSERT(shift_code); + } + return ((vaddr & MMU_VADDR_MASK) >> shift_code); +} + +/** + * Format the paddr to be mappable + * + * @param mmu_id MMU ID + * @param paddr physical address to be mapped + * @param target paddr memory target, not used + * + * @return + * mmu_val - paddr in MMU table supported format + */ +__attribute__((always_inline)) +static inline uint32_t mmu_ll_format_paddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target) +{ + (void)mmu_id; + (void)target; + mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id); + uint32_t shift_code = 0; + switch (page_size) { + case MMU_PAGE_64KB: + shift_code = 16; + break; + case MMU_PAGE_32KB: + shift_code = 15; + break; + case MMU_PAGE_16KB: + shift_code = 14; + break; + case MMU_PAGE_8KB: + shift_code = 13; + break; + default: + HAL_ASSERT(shift_code); + } + return paddr >> shift_code; +} + +/** + * Write to the MMU table to map the virtual memory and the physical memory + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * @param mmu_val Value to be set into an MMU entry, for physical address + * @param target MMU target physical memory. + */ +__attribute__((always_inline)) static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32_t mmu_val, mmu_target_t target) +{ + (void)mmu_id; + (void)target; + uint32_t mmu_raw_value; + if (mmu_ll_cache_encryption_enabled()) { + mmu_val |= MMU_SENSITIVE; + } + + mmu_raw_value = mmu_val | MMU_VALID; + REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id); + REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0), mmu_raw_value); +} + +/** + * Read the raw value from MMU table + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * @param mmu_val Value to be read from MMU table + */ +__attribute__((always_inline)) static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id) +{ + (void)mmu_id; + uint32_t mmu_raw_value; + uint32_t ret; + REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id); + mmu_raw_value = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0)); + if (mmu_ll_cache_encryption_enabled()) { + mmu_raw_value &= ~MMU_SENSITIVE; + } + if (!(mmu_raw_value & MMU_VALID)) { + return 0; + } + ret = mmu_raw_value & MMU_VALID_VAL_MASK; + return ret; +} + +/** + * Set MMU table entry as invalid + * + * @param mmu_id MMU ID + * @param entry_id MMU entry + */ +__attribute__((always_inline)) static inline void mmu_ll_set_entry_invalid(uint32_t mmu_id, uint32_t entry_id) +{ + (void)mmu_id; + REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id); + REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0), MMU_INVALID); +} + +/** + * Unmap all the items in the MMU table + * + * @param mmu_id MMU ID + */ +__attribute__((always_inline)) +static inline void mmu_ll_unmap_all(uint32_t mmu_id) +{ + for (int i = 0; i < MMU_ENTRY_NUM; i++) { + mmu_ll_set_entry_invalid(mmu_id, i); + } +} + +/** + * Check MMU table entry value is valid + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * + * @return Ture for MMU entry is valid; False for invalid + */ +static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) +{ + (void)mmu_id; + HAL_ASSERT(entry_id < MMU_ENTRY_NUM); + + REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id); + return (REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0)) & MMU_VALID) ? true : false; +} + +/** + * Get MMU table entry is invalid + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * return true for MMU entry is invalid, false for valid + */ +__attribute__((always_inline)) +static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id) +{ + return !mmu_ll_check_entry_valid(mmu_id, entry_id); +} + +/** + * Get the MMU table entry target + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * + * @return Target, see `mmu_target_t` + */ +static inline mmu_target_t mmu_ll_get_entry_target(uint32_t mmu_id, uint32_t entry_id) +{ + (void)mmu_id; + return MMU_TARGET_FLASH0; +} + +/** + * Convert MMU entry ID to paddr base + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * + * @return paddr base + */ +static inline uint32_t mmu_ll_entry_id_to_paddr_base(uint32_t mmu_id, uint32_t entry_id) +{ + (void)mmu_id; + HAL_ASSERT(entry_id < MMU_ENTRY_NUM); + + mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id); + uint32_t shift_code = 0; + switch (page_size) { + case MMU_PAGE_64KB: + shift_code = 16; + break; + case MMU_PAGE_32KB: + shift_code = 15; + break; + case MMU_PAGE_16KB: + shift_code = 14; + break; + case MMU_PAGE_8KB: + shift_code = 13; + break; + default: + HAL_ASSERT(shift_code); + } + + REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id); + return (REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0)) & MMU_VALID_VAL_MASK) << shift_code; +} + +/** + * Find the MMU table entry ID based on table map value + * @note This function can only find the first match entry ID. However it is possible that a physical address + * is mapped to multiple virtual addresses + * + * @param mmu_id MMU ID + * @param mmu_val map value to be read from MMU table standing for paddr + * @param target physical memory target, see `mmu_target_t` + * + * @return MMU entry ID, -1 for invalid + */ +static inline int mmu_ll_find_entry_id_based_on_map_value(uint32_t mmu_id, uint32_t mmu_val, mmu_target_t target) +{ + (void)mmu_id; + for (int i = 0; i < MMU_ENTRY_NUM; i++) { + if (mmu_ll_check_entry_valid(mmu_id, i)) { + if (mmu_ll_get_entry_target(mmu_id, i) == target) { + REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), i); + if ((REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0)) & MMU_VALID_VAL_MASK) == mmu_val) { + return i; + } + } + } + } + + return -1; +} + +/** + * Convert MMU entry ID to vaddr base + * + * @param mmu_id MMU ID + * @param entry_id MMU entry ID + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` + */ +static inline uint32_t mmu_ll_entry_id_to_vaddr_base(uint32_t mmu_id, uint32_t entry_id, mmu_vaddr_t type) +{ + (void)mmu_id; + mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id); + uint32_t shift_code = 0; + + switch (page_size) { + case MMU_PAGE_64KB: + shift_code = 16; + break; + case MMU_PAGE_32KB: + shift_code = 15; + break; + case MMU_PAGE_16KB: + shift_code = 14; + break; + case MMU_PAGE_8KB: + shift_code = 13; + break; + default: + HAL_ASSERT(shift_code); + } + uint32_t laddr = entry_id << shift_code; + return mmu_ll_laddr_to_vaddr(laddr, type); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/modem_lpcon_ll.h b/components/hal/esp32c6/include/hal/modem_lpcon_ll.h new file mode 100644 index 000000000000..aa4288f51930 --- /dev/null +++ b/components/hal/esp32c6/include/hal/modem_lpcon_ll.h @@ -0,0 +1,286 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 MODEM LPCON register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "hal/assert.h" +#include "modem/modem_lpcon_struct.h" +#include "hal/modem_clock_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_test_clk(modem_lpcon_dev_t *hw, bool en) +{ + hw->test_conf.clk_en = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_ble_rtc_timer_slow_osc(modem_lpcon_dev_t *hw, bool en) +{ + hw->lp_timer_conf.clk_lp_timer_sel_osc_slow = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_ble_rtc_timer_fast_osc(modem_lpcon_dev_t *hw, bool en) +{ + hw->lp_timer_conf.clk_lp_timer_sel_osc_fast = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_ble_rtc_timer_main_xtal(modem_lpcon_dev_t *hw, bool en) +{ + hw->lp_timer_conf.clk_lp_timer_sel_xtal = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_ble_rtc_timer_32k_xtal(modem_lpcon_dev_t *hw, bool en) +{ + hw->lp_timer_conf.clk_lp_timer_sel_xtal32k = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_ble_rtc_timer_divisor_value(modem_lpcon_dev_t *hw, uint32_t value) +{ + hw->lp_timer_conf.clk_lp_timer_div_num = value; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_ble_rtc_timer_divisor_value(modem_lpcon_dev_t *hw) +{ + return hw->lp_timer_conf.clk_lp_timer_div_num; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_coex_lpclk_slow_osc(modem_lpcon_dev_t *hw, bool en) +{ + hw->coex_lp_clk_conf.clk_coex_lp_sel_osc_slow = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_coex_lpclk_fast_osc(modem_lpcon_dev_t *hw, bool en) +{ + hw->coex_lp_clk_conf.clk_coex_lp_sel_osc_fast = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_coex_lpclk_main_xtal(modem_lpcon_dev_t *hw, bool en) +{ + hw->coex_lp_clk_conf.clk_coex_lp_sel_xtal = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_coex_lpclk_32k_xtal(modem_lpcon_dev_t *hw, bool en) +{ + hw->coex_lp_clk_conf.clk_coex_lp_sel_xtal32k = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_coex_lpclk_divisor_value(modem_lpcon_dev_t *hw, uint32_t value) +{ + hw->coex_lp_clk_conf.clk_coex_lp_div_num = value; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_coex_lpclk_divisor_value(modem_lpcon_dev_t *hw) +{ + return hw->coex_lp_clk_conf.clk_coex_lp_div_num; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_wifi_lpclk_slow_osc(modem_lpcon_dev_t *hw, bool en) +{ + hw->wifi_lp_clk_conf.clk_wifipwr_lp_sel_osc_slow = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_wifi_lpclk_fast_osc(modem_lpcon_dev_t *hw, bool en) +{ + hw->wifi_lp_clk_conf.clk_wifipwr_lp_sel_osc_fast = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_wifi_lpclk_main_xtal(modem_lpcon_dev_t *hw, bool en) +{ + hw->wifi_lp_clk_conf.clk_wifipwr_lp_sel_xtal = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_wifi_lpclk_32k_xtal(modem_lpcon_dev_t *hw, bool en) +{ + hw->wifi_lp_clk_conf.clk_wifipwr_lp_sel_xtal32k = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_wifi_lpclk_divisor_value(modem_lpcon_dev_t *hw, uint32_t value) +{ + hw->wifi_lp_clk_conf.clk_wifipwr_lp_div_num = value; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_wifi_lpclk_divisor_value(modem_lpcon_dev_t *hw) +{ + return hw->wifi_lp_clk_conf.clk_wifipwr_lp_div_num; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_i2c_master_160m_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->i2c_mst_clk_conf.clk_i2c_mst_sel_160m = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_select_modem_32k_clock_source(modem_lpcon_dev_t *hw, uint32_t src) +{ + hw->modem_32k_clk_conf.clk_modem_32k_sel = src; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_wifipwr_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_wifipwr_en = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_coex_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_coex_en = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_i2c_master_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_i2c_mst_en = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_ble_rtc_timer_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_lp_timer_en = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_wifipwr_force_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf_force_on.clk_wifipwr_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_coex_force_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf_force_on.clk_coex_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_i2c_master_force_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf_force_on.clk_i2c_mst_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_enable_ble_rtc_timer_force_clock(modem_lpcon_dev_t *hw, bool en) +{ + hw->clk_conf_force_on.clk_lp_timer_fo = en; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_wifipwr_icg_bitmap(modem_lpcon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_wifipwr_st_map; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_wifipwr_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_wifipwr_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_coex_icg_bitmap(modem_lpcon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_coex_st_map; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_coex_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_coex_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_i2c_master_icg_bitmap(modem_lpcon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_i2c_mst_st_map; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_i2c_master_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_i2c_mst_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_lp_apb_icg_bitmap(modem_lpcon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_lp_apb_st_map; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_set_lp_apb_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_lp_apb_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_reset_wifipwr(modem_lpcon_dev_t *hw) +{ + hw->rst_conf.rst_wifipwr = 1; + hw->rst_conf.rst_wifipwr = 0; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_reset_coex(modem_lpcon_dev_t *hw) +{ + hw->rst_conf.rst_coex = 1; + hw->rst_conf.rst_coex = 0; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_reset_i2c_master(modem_lpcon_dev_t *hw) +{ + hw->rst_conf.rst_i2c_mst = 1; + hw->rst_conf.rst_i2c_mst = 0; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_reset_ble_rtc_timer(modem_lpcon_dev_t *hw) +{ + hw->rst_conf.rst_lp_timer = 1; + hw->rst_conf.rst_lp_timer = 0; +} + +__attribute__((always_inline)) +static inline void modem_lpcon_ll_reset_all(modem_lpcon_dev_t *hw) +{ + hw->rst_conf.val = 0xf; + hw->rst_conf.val = 0; +} + +__attribute__((always_inline)) +static inline uint32_t modem_lpcon_ll_get_date(modem_lpcon_dev_t *hw) +{ + return hw->date.val; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/modem_syscon_ll.h b/components/hal/esp32c6/include/hal/modem_syscon_ll.h new file mode 100644 index 000000000000..1b9a6a90567f --- /dev/null +++ b/components/hal/esp32c6/include/hal/modem_syscon_ll.h @@ -0,0 +1,596 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 MODEM SYSCON register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "hal/assert.h" +#include "modem/modem_syscon_struct.h" +#include "hal/modem_clock_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_test_clk(modem_syscon_dev_t *hw, bool en) +{ + hw->test_conf.clk_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_data_dump_mux_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_data_dump_mux = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_etm_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_etm_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_ieee802154_apb_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_zb_apb_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_ieee802154_mac_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_zb_mac_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_modem_sec_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_modem_sec_en = en; + hw->clk_conf.clk_modem_sec_ecb_en = en; + hw->clk_conf.clk_modem_sec_ccm_en = en; + hw->clk_conf.clk_modem_sec_bah_en = en; + hw->clk_conf.clk_modem_sec_apb_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_ble_timer_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_ble_timer_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_data_dump_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf.clk_data_dump_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_etm_force_clock(modem_syscon_dev_t *hw) +{ + hw->clk_conf_force_on.clk_etm_fo = 1; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_ieee802154_apb_clock_force(modem_syscon_dev_t *hw) +{ + hw->clk_conf_force_on.clk_zb_apb_fo = 1; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_ieee802154_mac_clock_force(modem_syscon_dev_t *hw) +{ + hw->clk_conf_force_on.clk_zb_mac_fo = 1; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_modem_sec_force_clock(modem_syscon_dev_t *hw) +{ + hw->clk_conf_force_on.clk_modem_sec_fo = 1; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_ble_timer_force_clock(modem_syscon_dev_t *hw) +{ + hw->clk_conf_force_on.clk_ble_timer_fo = 1; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_data_dump_force_clock(modem_syscon_dev_t *hw) +{ + hw->clk_conf_force_on.clk_data_dump_fo = 1; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_ieee802154_icg_bitmap(modem_syscon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_zb_st_map; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_set_ieee802154_icg_bitmap(modem_syscon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_zb_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_fe_icg_bitmap(modem_syscon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_fe_st_map; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_set_fe_icg_bitmap(modem_syscon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_fe_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_bt_icg_bitmap(modem_syscon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_bt_st_map; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_set_bt_icg_bitmap(modem_syscon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_bt_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_wifi_icg_bitmap(modem_syscon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_wifi_st_map; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_set_wifi_icg_bitmap(modem_syscon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_wifi_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_modem_periph_icg_bitmap(modem_syscon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_modem_peri_st_map; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_set_modem_periph_icg_bitmap(modem_syscon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_modem_peri_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_modem_apb_icg_bitmap(modem_syscon_dev_t *hw) +{ + return hw->clk_conf_power_st.clk_modem_apb_st_map; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_set_modem_apb_icg_bitmap(modem_syscon_dev_t *hw, uint32_t bitmap) +{ + hw->clk_conf_power_st.clk_modem_apb_st_map = bitmap; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_wifibb(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_wifibb = 1; + hw->modem_rst_conf.rst_wifibb = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_wifimac(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_wifimac = 1; + hw->modem_rst_conf.rst_wifimac = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_fe(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_fe = 1; + hw->modem_rst_conf.rst_fe = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_btmac_apb(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_btmac_apb = 1; + hw->modem_rst_conf.rst_btmac_apb = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_btmac(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_btmac = 1; + hw->modem_rst_conf.rst_btmac = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_btbb_apb(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_btbb_apb = 1; + hw->modem_rst_conf.rst_btbb_apb = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_btbb(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_btbb = 1; + hw->modem_rst_conf.rst_btbb = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_etm(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_etm = 1; + hw->modem_rst_conf.rst_etm = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_zbmac(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_zbmac = 1; + hw->modem_rst_conf.rst_zbmac = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_modem_sec(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_modem_ecb = 1; + hw->modem_rst_conf.rst_modem_ccm = 1; + hw->modem_rst_conf.rst_modem_bah = 1; + hw->modem_rst_conf.rst_modem_sec = 1; + hw->modem_rst_conf.rst_modem_ecb = 0; + hw->modem_rst_conf.rst_modem_ccm = 0; + hw->modem_rst_conf.rst_modem_bah = 0; + hw->modem_rst_conf.rst_modem_sec = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_ble_timer(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_ble_timer = 1; + hw->modem_rst_conf.rst_ble_timer = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_data_dump(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.rst_data_dump = 1; + hw->modem_rst_conf.rst_data_dump = 0; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_reset_all(modem_syscon_dev_t *hw) +{ + hw->modem_rst_conf.val = 0xffffffff; + hw->modem_rst_conf.val = 0; +} + + +__attribute__((always_inline)) +static inline void modem_syscon_ll_clk_conf1_configure(modem_syscon_dev_t *hw, bool en, uint32_t mask) +{ + if(en){ + hw->clk_conf1.val = hw->clk_conf1.val | mask; + } else { + hw->clk_conf1.val = hw->clk_conf1.val & ~mask; + } +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_clk_wifibb_configure(modem_syscon_dev_t *hw, bool en) +{ + /* Configure + clk_wifibb_22m / clk_wifibb_40m / clk_wifibb_44m / clk_wifibb_80m + clk_wifibb_40x / clk_wifibb_80x / clk_wifibb_40x1 / clk_wifibb_80x1 + clk_wifibb_160x1 + */ + modem_syscon_ll_clk_conf1_configure(hw, en, 0x1ff); +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_22m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_22m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_40m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_40m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_44m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_44m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_80m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_80m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_40x_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_40x_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_80x_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_80x_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_40x1_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_40x1_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_80x1_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_80x1_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_160x1_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_160x1_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_480m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifibb_480m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifi_mac_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifimac_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifi_apb_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_wifi_apb_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_20m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_20m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_40m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_40m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_80m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_80m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_160m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_160m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_cal_160m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_cal_160m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_apb_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_apb_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_bt_apb_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_bt_apb_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_bt_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_bt_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_480m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_480m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_anamode_40m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_anamode_40m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_anamode_80m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_anamode_80m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_anamode_160m_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1.clk_fe_anamode_160m_en = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_22m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_22m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_40m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_40m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_44m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_44m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_80m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_80m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_40x_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_40x_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_80x_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_80x_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_40x1_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_40x1_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_80x1_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_80x1_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_160x1_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_160x1_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifibb_480m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifibb_480m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifi_mac_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifimac_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_wifi_apb_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_wifi_apb_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_20m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_20m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_40m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_40m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_80m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_80m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_160m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_160m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_cal_160m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_cal_160m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_apb_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_apb_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_bt_apb_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_bt_apb_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_bt_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_bt_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_480m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_480m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_anamode_40m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_anamode_40m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_anamode_80m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_anamode_80m_fo = en; +} + +__attribute__((always_inline)) +static inline void modem_syscon_ll_enable_fe_anamode_160m_force_clock(modem_syscon_dev_t *hw, bool en) +{ + hw->clk_conf1_force_on.clk_fe_anamode_160m_fo = en; +} + +__attribute__((always_inline)) +static inline uint32_t modem_syscon_ll_get_date(modem_syscon_dev_t *hw) +{ + return hw->date.val; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/mpu_ll.h b/components/hal/esp32c6/include/hal/mpu_ll.h new file mode 100644 index 000000000000..d90dc0136875 --- /dev/null +++ b/components/hal/esp32c6/include/hal/mpu_ll.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Copied from C3, and this LL is currently unused for ESP32-C3 */ + +static inline uint32_t mpu_ll_id_to_addr(unsigned id) +{ + abort(); +} + +static inline void mpu_ll_set_region_rw(uint32_t addr) +{ + abort(); +} + +static inline void mpu_ll_set_region_rwx(uint32_t addr) +{ + abort(); +} + +static inline void mpu_ll_set_region_x(uint32_t addr) +{ + abort(); +} + + +static inline void mpu_ll_set_region_illegal(uint32_t addr) +{ + abort(); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/mwdt_ll.h b/components/hal/esp32c6/include/hal/mwdt_ll.h new file mode 100644 index 000000000000..c77ee9ee3d7b --- /dev/null +++ b/components/hal/esp32c6/include/hal/mwdt_ll.h @@ -0,0 +1,307 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for Timer Group register operations. +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "soc/timer_periph.h" +#include "soc/timer_group_struct.h" +#include "soc/pcr_struct.h" +#include "hal/wdt_types.h" +#include "hal/assert.h" +#include "esp_attr.h" +#include "esp_assert.h" +#include "hal/misc.h" + +/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ +#define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 + +//Type check wdt_stage_action_t +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == TIMG_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == TIMG_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +//Type check wdt_reset_sig_length_t +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == TIMG_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == TIMG_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == TIMG_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == TIMG_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == TIMG_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == TIMG_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == TIMG_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); + +/** + * @brief Enable the MWDT + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw) +{ + hw->wdtconfig0.wdt_en = 1; +} + +/** + * @brief Disable the MWDT + * + * @param hw Start address of the peripheral registers. + * @note This function does not disable the flashboot mode. Therefore, given that + * the MWDT is disabled using this function, a timeout can still occur + * if the flashboot mode is simultaneously enabled. + */ +FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw) +{ + hw->wdtconfig0.wdt_en = 0; +} + +/** + * Check if the MWDT is enabled + * + * @param hw Start address of the peripheral registers. + * @return True if the MWDT is enabled, false otherwise + */ +FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw) +{ + return (hw->wdtconfig0.wdt_en) ? true : false; +} + +/** + * @brief Configure a particular stage of the MWDT + * + * @param hw Start address of the peripheral registers. + * @param stage Which stage to configure + * @param timeout Number of timer ticks for the stage to timeout + * @param behavior What action to take when the stage times out + */ +FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior) +{ + switch (stage) { + case WDT_STAGE0: + hw->wdtconfig0.wdt_stg0 = behavior; + hw->wdtconfig2.wdt_stg0_hold = timeout; + break; + case WDT_STAGE1: + hw->wdtconfig0.wdt_stg1 = behavior; + hw->wdtconfig3.wdt_stg1_hold = timeout; + break; + case WDT_STAGE2: + hw->wdtconfig0.wdt_stg2 = behavior; + hw->wdtconfig4.wdt_stg2_hold = timeout; + break; + case WDT_STAGE3: + hw->wdtconfig0.wdt_stg3 = behavior; + hw->wdtconfig5.wdt_stg3_hold = timeout; + break; + default: + HAL_ASSERT(false && "unsupported WDT stage"); + break; + } + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; +} + +/** + * @brief Disable a particular stage of the MWDT + * + * @param hw Start address of the peripheral registers. + * @param stage Which stage to disable + */ +FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage) +{ + switch (stage) { + case WDT_STAGE0: + hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE1: + hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE2: + hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE3: + hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; + break; + default: + HAL_ASSERT(false && "unsupported WDT stage"); + break; + } + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; +} + +/** + * @brief Set the length of the CPU reset action + * + * @param hw Start address of the peripheral registers. + * @param length Length of CPU reset signal + */ +FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) +{ + hw->wdtconfig0.wdt_cpu_reset_length = length; + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; +} + +/** + * @brief Set the length of the system reset action + * + * @param hw Start address of the peripheral registers. + * @param length Length of system reset signal + */ +FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) +{ + hw->wdtconfig0.wdt_sys_reset_length = length; + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; +} + +/** + * @brief Enable/Disable the MWDT flashboot mode. + * + * @param hw Beginning address of the peripheral registers. + * @param enable True to enable WDT flashboot mode, false to disable WDT flashboot mode. + * + * @note Flashboot mode is independent and can trigger a WDT timeout event if the + * WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled + * on flashboot, and should be disabled by software when flashbooting completes. + */ +FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable) +{ + hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0; + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; +} + +/** + * @brief Set the clock prescaler of the MWDT + * + * @param hw Start address of the peripheral registers. + * @param prescaler Prescaler value between 1 to 65535 + */ +FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler) +{ + // In case the compiler optimise a 32bit instruction (e.g. s32i) into 8/16bit instruction (e.g. s8i, which is not allowed to access a register) + // We take care of the "read-modify-write" procedure by ourselves. + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdtconfig1, wdt_clk_prescale, prescaler); + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; +} + +/** + * @brief Feed the MWDT + * + * Resets the current timer count and current stage. + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw) +{ + hw->wdtfeed.wdt_feed = 1; +} + +/** + * @brief Enable write protection of the MWDT registers + * + * Locking the MWDT will prevent any of the MWDT's registers from being modified + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw) +{ + hw->wdtwprotect.wdt_wkey = 0; +} + +/** + * @brief Disable write protection of the MWDT registers + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw) +{ + hw->wdtwprotect.wdt_wkey = TIMG_WDT_WKEY_VALUE; +} + +/** + * @brief Clear the MWDT interrupt status. + * + * @param hw Start address of the peripheral registers. + */ +FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw) +{ + hw->int_clr_timers.wdt_int_clr = 1; +} + +/** + * @brief Set the interrupt enable bit for the MWDT interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param enable Whether to enable the MWDT interrupt + */ +FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable) +{ + hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0; +} + +/** + * @brief Set the clock source for the MWDT. + * + * @param hw Beginning address of the peripheral registers. + * @param clk_src Clock source + */ +FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src) +{ + uint8_t clk_id = 0; + switch (clk_src) { + case MWDT_CLK_SRC_XTAL: + clk_id = 0; + break; + case MWDT_CLK_SRC_PLL_F80M: + clk_id = 1; + break; + case MWDT_CLK_SRC_RC_FAST: + clk_id = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + if (hw == &TIMERG0) { + PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_sel = clk_id; + } else { + PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_sel = clk_id; + } +} + +/** + * @brief Enable MWDT module clock + * + * @param hw Beginning address of the peripheral registers. + * @param en true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en) +{ + if (hw == &TIMERG0) { + PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_en = en; + } else { + PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_en = en; + } +} + + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/parlio_ll.h b/components/hal/esp32c6/include/hal/parlio_ll.h new file mode 100644 index 000000000000..55c1226702c8 --- /dev/null +++ b/components/hal/esp32c6/include/hal/parlio_ll.h @@ -0,0 +1,612 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "soc/pcr_struct.h" +#include "soc/parl_io_struct.h" +#include "hal/parlio_types.h" + +#define PARLIO_LL_RX_MAX_BYTES_PER_FRAME 0xFFFF +#define PARLIO_LL_RX_MAX_CLOCK_DIV 0x10000 +#define PARLIO_LL_RX_MAX_TIMEOUT 0xFFFF + +#define PARLIO_LL_TX_MAX_BYTES_PER_FRAME 0xFFFF +#define PARLIO_LL_TX_MAX_BITS_PER_FRAME (PARLIO_LL_TX_MAX_BYTES_PER_FRAME * 8) +#define PARLIO_LL_TX_MAX_CLOCK_DIV 0x10000 + +#define PARLIO_LL_EVENT_TX_FIFO_EMPTY (1 << 0) +#define PARLIO_LL_EVENT_RX_FIFO_FULL (1 << 1) +#define PARLIO_LL_EVENT_TX_EOF (1 << 2) +#define PARLIO_LL_EVENT_TX_MASK (PARLIO_LL_EVENT_TX_FIFO_EMPTY | PARLIO_LL_EVENT_TX_EOF) +#define PARLIO_LL_EVENT_RX_MASK (PARLIO_LL_EVENT_RX_FIFO_FULL) + +#define PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG 15 // TXD[15] can be used a valid signal + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PARLIO_LL_CLK_SRC_XTAL = PARLIO_CLK_SRC_XTAL, + PARLIO_LL_CLK_SRC_PLL_F240M = PARLIO_CLK_SRC_PLL_F240M, + PARLIO_LL_CLK_SRC_PAD, // clock source from GPIO pad +} parlio_ll_clock_source_t; + +typedef enum { + PARLIO_LL_RX_EOF_COND_RX_FULL, /*!< RX unit generates EOF event when it receives enough data */ + PARLIO_LL_RX_EOF_COND_EN_INACTIVE, /*!< RX unit generates EOF event when the external enable signal becomes inactive */ +} parlio_ll_rx_eof_cond_t; + +///////////////////////////////////////RX Unit/////////////////////////////////////// + +/** + * @brief Set the clock source for the RX unit + * + * @param dev Parallel IO register base address + * @param src Clock source + */ +static inline void parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_ll_clock_source_t src) +{ + (void)dev; + uint32_t clk_sel = 0; + switch (src) { + case PARLIO_LL_CLK_SRC_XTAL: + clk_sel = 0; + break; + case PARLIO_LL_CLK_SRC_PLL_F240M: + clk_sel = 1; + break; + case PARLIO_LL_CLK_SRC_PAD: + clk_sel = 3; + break; + + default: // unsupported clock source + HAL_ASSERT(false); + break; + } + PCR.parl_clk_rx_conf.parl_clk_rx_sel = clk_sel; +} + +/** + * @brief Set the clock divider for the RX unit + * + * @param dev Parallel IO register base address + * @param div Clock divider + */ +static inline void parlio_ll_rx_set_clock_div(parl_io_dev_t *dev, uint32_t div) +{ + (void)dev; + HAL_ASSERT(div > 0 && div <= PARLIO_LL_RX_MAX_CLOCK_DIV); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_rx_conf, parl_clk_rx_div_num, div - 1); +} + +/** + * @brief Reset the RX unit Core clock domain + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_reset_clock(parl_io_dev_t *dev) +{ + (void)dev; + PCR.parl_clk_rx_conf.parl_rx_rst_en = 1; + PCR.parl_clk_rx_conf.parl_rx_rst_en = 0; +} + +/** + * @brief Enable the RX unit Core clock domain + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_enable_clock(parl_io_dev_t *dev, bool en) +{ + (void)dev; + PCR.parl_clk_rx_conf.parl_clk_rx_en = en; +} + +/** + * @brief Set the condition to generate the RX EOF event + * + * @param dev Parallel IO register base address + * @param cond RX EOF condition + */ +static inline void parlio_ll_rx_set_eof_condition(parl_io_dev_t *dev, parlio_ll_rx_eof_cond_t cond) +{ + dev->rx_cfg0.rx_eof_gen_sel = cond; +} + +/** + * @brief Start RX unit to sample the input data + * + * @param dev Parallel IO register base address + * @param en True to start, False to stop + */ +static inline void parlio_ll_rx_start(parl_io_dev_t *dev, bool en) +{ + dev->rx_cfg0.rx_start = en; +} + +/** + * @brief Set the receive length + * + * @note The receive length can be used to generate DMA EOF signal, or to work as a frame end delimiter + * + * @param dev Parallel IO register base address + * @param bitlen Number of bits to receive in the next transaction, bitlen must be a multiple of 8 + */ +static inline void parlio_ll_rx_set_recv_bit_len(parl_io_dev_t *dev, uint32_t bitlen) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_cfg0, rx_data_bytelen, bitlen / 8); +} + +/** + * @brief Set the sub mode of the level controlled receive mode + * + * @param dev Parallel IO register base address + * @param active_level Level of the external enable signal, true for active high, false for active low + */ +static inline void parlio_ll_rx_set_level_recv_mode(parl_io_dev_t *dev, bool active_level) +{ + dev->rx_cfg0.rx_smp_mode_sel = 0; + dev->rx_cfg0.rx_level_submode_sel = !active_level; // 0: active low, 1: active high +} + +/** + * @brief Set the sub mode of the pulse controlled receive mode + * + * @param dev Parallel IO register base address + * @param start_inc Whether the start pulse is counted + * @param end_inc Whether the end pulse is counted + * @param end_by_len Whether to use the frame length to determine the end of the frame + * @param pulse_inv Whether the pulse is inverted + */ +static inline void parlio_ll_rx_set_pulse_recv_mode(parl_io_dev_t *dev, bool start_inc, bool end_inc, bool end_by_len, bool pulse_inv) +{ + uint32_t submode = 0; + uint32_t step = 1; + if (end_by_len) { + submode += 4; + } else { + step = 2; + if (!end_inc) { + submode += 1; + } + } + if (!start_inc) { + submode += step; + } + if (pulse_inv) { + submode += 6; + } + dev->rx_cfg0.rx_smp_mode_sel = 1; + dev->rx_cfg0.rx_pulse_submode_sel = submode; +} + +/** + * @brief Set the receive mode to software controlled receive mode + * + * @param dev Parallel IO register base address + */ +static inline void parlio_ll_rx_set_soft_recv_mode(parl_io_dev_t *dev) +{ + dev->rx_cfg0.rx_smp_mode_sel = 2; +} + +/** + * @brief Whether to start the software controlled receive mode + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_rx_start_soft_recv(parl_io_dev_t *dev, bool en) +{ + dev->rx_cfg0.rx_sw_en = en; +} + +/** + * @brief Set the sample clock edge + * + * @param dev Parallel IO register base address + * @param edge Sample clock edge + */ +static inline void parlio_ll_rx_set_sample_clock_edge(parl_io_dev_t *dev, parlio_sample_edge_t edge) +{ + dev->rx_cfg0.rx_clk_edge_sel = edge; +} + +/** + * @brief Set the order to pack bits into one byte + * + * @param dev Parallel IO register base address + * @param order Packing order + */ +static inline void parlio_ll_rx_set_bit_pack_order(parl_io_dev_t *dev, parlio_bit_pack_order_t order) +{ + dev->rx_cfg0.rx_bit_pack_order = order; +} + +/** + * @brief Set the bus width of the RX unit + * + * @param dev Parallel IO register base address + * @param width Bus width + */ +static inline void parlio_ll_rx_set_bus_width(parl_io_dev_t *dev, uint32_t width) +{ + uint32_t width_sel = 0; + switch (width) { + case 16: + width_sel = 0; + break; + case 8: + width_sel = 1; + break; + case 4: + width_sel = 2; + break; + case 2: + width_sel = 3; + break; + case 1: + width_sel = 4; + break; + default: + HAL_ASSERT(false); + } + dev->rx_cfg0.rx_bus_wid_sel = width_sel; +} + +/** + * @brief Reset RX Async FIFO + * + * @note During the reset of the asynchronous FIFO, it takes two clock cycles to synchronize within AHB clock domain (GDMA) and Core clock domain. + * The reset synchronization must be performed two clock cycles in advance. + * @note If the next frame transfer needs to be reset, you need to first switch to the internal free-running clock, + * and then switch to the actual clock after the reset is completed. + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_reset_fifo(parl_io_dev_t *dev) +{ + dev->rx_cfg0.rx_fifo_srst = 1; + dev->rx_cfg0.rx_fifo_srst = 0; +} + +/** + * @brief Set which data line as the enable signal + * + * @param dev Parallel IO register base address + * @param line_num Data line number (0-15) + */ +static inline void parlio_ll_rx_treat_data_line_as_en(parl_io_dev_t *dev, uint32_t line_num) +{ + dev->rx_cfg1.rx_ext_en_sel = line_num; +} + +/** + * @brief Enable RX timeout feature + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_rx_enable_timeout(parl_io_dev_t *dev, bool en) +{ + dev->rx_cfg1.rx_timeout_en = en; +} + +/** + * @brief Set the threshold of RX timeout + * + * @param dev Parallel IO register base address + * @param thres Threshold of RX timeout + */ +static inline void parlio_ll_rx_set_timeout_thres(parl_io_dev_t *dev, uint32_t thres) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_cfg1, rx_timeout_threshold, thres); +} + +/** + * @brief Update the RX configuration, to make the new configuration take effect + * + * @param dev Parallel IO register base address + */ +static inline void parlio_ll_rx_update_config(parl_io_dev_t *dev) +{ + dev->rx_cfg1.rx_reg_update = 1; + while (dev->rx_cfg1.rx_reg_update); +} + +///////////////////////////////////TX Unit/////////////////////////////////////// + +/** + * @brief Set the clock source for the TX unit + * + * @param dev Parallel IO register base address + * @param src Clock source + */ +static inline void parlio_ll_tx_set_clock_source(parl_io_dev_t *dev, parlio_ll_clock_source_t src) +{ + (void)dev; + uint32_t clk_sel = 0; + switch (src) { + case PARLIO_LL_CLK_SRC_XTAL: + clk_sel = 0; + break; + case PARLIO_LL_CLK_SRC_PLL_F240M: + clk_sel = 1; + break; + case PARLIO_LL_CLK_SRC_PAD: + clk_sel = 3; + break; + + default: // unsupported clock source + HAL_ASSERT(false); + break; + } + PCR.parl_clk_tx_conf.parl_clk_tx_sel = clk_sel; +} + +/** + * @brief Set the clock divider for the TX unit + * + * @param dev Parallel IO register base address + * @param div Clock divider + */ +static inline void parlio_ll_tx_set_clock_div(parl_io_dev_t *dev, uint32_t div) +{ + (void)dev; + HAL_ASSERT(div > 0 && div <= PARLIO_LL_TX_MAX_CLOCK_DIV); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_tx_conf, parl_clk_tx_div_num, div - 1); +} + +/** + * @brief Reset the TX unit Core clock domain + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_reset_clock(parl_io_dev_t *dev) +{ + (void)dev; + PCR.parl_clk_tx_conf.parl_tx_rst_en = 1; + PCR.parl_clk_tx_conf.parl_tx_rst_en = 0; +} + +/** + * @brief Enable the TX unit Core clock domain + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_enable_clock(parl_io_dev_t *dev, bool en) +{ + (void)dev; + PCR.parl_clk_tx_conf.parl_clk_tx_en = en; +} + +/** + * @brief Set the data length to be transmitted + * + * @param dev Parallel IO register base address + * @param bitlen Data length in bits, must be a multiple of 8 + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_set_trans_bit_len(parl_io_dev_t *dev, uint32_t bitlen) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_cfg0, tx_bytelen, bitlen / 8); +} + +/** + * @brief Wether to enable the TX clock gating + * + * @note The TXD[7] will be taken as the gating enable signal + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_tx_enable_clock_gating(parl_io_dev_t *dev, bool en) +{ + dev->tx_cfg0.tx_gating_en = en; +} + +/** + * @brief Start TX unit to transmit data + * + * @param dev Parallel IO register base address + * @param en True to start, False to stop + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_start(parl_io_dev_t *dev, bool en) +{ + dev->tx_cfg0.tx_start = en; +} + +/** + * @brief Whether to treat the MSB of TXD as the valid signal + * + * @note If enabled, TXD[15] will work as valid signal, which stay high during data transmission. + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_tx_treat_msb_as_valid(parl_io_dev_t *dev, bool en) +{ + dev->tx_cfg0.tx_hw_valid_en = en; +} + +/** + * @brief Set the sample clock edge + * + * @param dev Parallel IO register base address + * @param edge Sample clock edge + */ +static inline void parlio_ll_tx_set_sample_clock_edge(parl_io_dev_t *dev, parlio_sample_edge_t edge) +{ + dev->tx_cfg0.tx_smp_edge_sel = edge; +} + +/** + * @brief Set the order to unpack bits from a byte + * + * @param dev Parallel IO register base address + * @param order Packing order + */ +static inline void parlio_ll_tx_set_bit_pack_order(parl_io_dev_t *dev, parlio_bit_pack_order_t order) +{ + dev->tx_cfg0.tx_bit_unpack_order = order; +} + +/** + * @brief Set the bus width of the TX unit + * + * @param dev Parallel IO register base address + * @param width Bus width + */ +static inline void parlio_ll_tx_set_bus_width(parl_io_dev_t *dev, uint32_t width) +{ + uint32_t width_sel = 0; + switch (width) { + case 16: + width_sel = 0; + break; + case 8: + width_sel = 1; + break; + case 4: + width_sel = 2; + break; + case 2: + width_sel = 3; + break; + case 1: + width_sel = 4; + break; + default: + HAL_ASSERT(false); + } + dev->tx_cfg0.tx_bus_wid_sel = width_sel; +} + +/** + * @brief Reset TX Async FIFO + * + * @note During the reset of the asynchronous FIFO, it takes two clock cycles to synchronize within AHB clock domain (GDMA) and Core clock domain. + * The reset synchronization must be performed two clock cycles in advance. + * @note If the next frame transfer needs to be reset, you need to first switch to the internal free-running clock, + * and then switch to the actual clock after the reset is completed. + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_reset_fifo(parl_io_dev_t *dev) +{ + dev->tx_cfg0.tx_fifo_srst = 1; + dev->tx_cfg0.tx_fifo_srst = 0; +} + +/** + * @brief Set the value to output on the TXD when the TX unit is in IDLE state + * + * @param dev Parallel IO register base address + * @param value Value to output + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_set_idle_data_value(parl_io_dev_t *dev, uint32_t value) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_cfg1, tx_idle_value, value); +} + +/** + * @brief Check whether the TX unit is ready + * + * @param dev Parallel IO register base address + * @return true: ready, false: busy + */ +__attribute__((always_inline)) +static inline bool parlio_ll_tx_is_ready(parl_io_dev_t *dev) +{ + return dev->st.tx_ready; +} + +////////////////////////////////////Interrupt//////////////////////////////////////////////// + +/** + * @brief Enable Parallel IO interrupt for specific event mask + * + * @param dev Parallel IO register base address + * @param mask Event mask + * @param enable True to enable, False to disable + */ +static inline void parlio_ll_enable_interrupt(parl_io_dev_t *dev, uint32_t mask, bool enable) +{ + if (enable) { + dev->int_ena.val |= mask; + } else { + dev->int_ena.val &= ~mask; + } +} + +/** + * @brief Get interrupt status for TX unit + * + * @param dev Parallel IO register base address + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t parlio_ll_tx_get_interrupt_status(parl_io_dev_t *dev) +{ + return dev->int_st.val & PARLIO_LL_EVENT_TX_MASK; +} + +/** + * @brief Get interrupt status for RX unit + * + * @param dev Parallel IO register base address + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t parlio_ll_rx_get_interrupt_status(parl_io_dev_t *dev) +{ + return dev->int_st.val & PARLIO_LL_EVENT_RX_MASK; +} + +/** + * @brief Clear Parallel IO interrupt status by mask + * + * @param dev Parallel IO register base address + * @param mask Interrupt status mask + */ +__attribute__((always_inline)) +static inline void parlio_ll_clear_interrupt_status(parl_io_dev_t *dev, uint32_t mask) +{ + dev->int_clr.val = mask; +} + +/** + * @brief Get interrupt status register address + * + * @param dev Parallel IO register base address + * @return Register address + */ +static inline volatile void *parlio_ll_get_interrupt_status_reg(parl_io_dev_t *dev) +{ + return &dev->int_st; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/pau_ll.h b/components/hal/esp32c6/include/hal/pau_ll.h new file mode 100644 index 000000000000..8fb18d7146c3 --- /dev/null +++ b/components/hal/esp32c6/include/hal/pau_ll.h @@ -0,0 +1,155 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 PAU(Power Assist Unit) register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/pau_reg.h" +#include "soc/pau_struct.h" +#include "hal/pau_types.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev) +{ + return dev->regdma_conf.flow_err; +} + +static inline void pau_ll_select_regdma_entry_link(pau_dev_t *dev, int link) +{ + dev->regdma_conf.link_sel = link; +} + +static inline void pau_ll_set_regdma_entry_link_backup_direction(pau_dev_t *dev, bool to_mem) +{ + dev->regdma_conf.to_mem = to_mem ? 1 : 0; +} + +static inline void pau_ll_set_regdma_entry_link_backup_start_enable(pau_dev_t *dev) +{ + dev->regdma_conf.start = 1; +} + +static inline void pau_ll_set_regdma_entry_link_backup_start_disable(pau_dev_t *dev) +{ + dev->regdma_conf.start = 0; +} + +static inline void pau_ll_set_regdma_select_wifimac_link(pau_dev_t *dev) +{ + dev->regdma_conf.sel_mac = 1; +} + +static inline void pau_ll_set_regdma_deselect_wifimac_link(pau_dev_t *dev) +{ + dev->regdma_conf.sel_mac = 0; +} + +static inline void pau_ll_set_regdma_wifimac_link_backup_direction(pau_dev_t *dev, bool to_mem) +{ + dev->regdma_conf.to_mem_mac = to_mem ? 1 : 0; +} + +static inline void pau_ll_set_regdma_wifimac_link_backup_start_enable(pau_dev_t *dev) +{ + dev->regdma_conf.start_mac = 1; +} + +static inline void pau_ll_set_regdma_wifimac_link_backup_start_disable(pau_dev_t *dev) +{ + dev->regdma_conf.start_mac = 0; +} + +static inline void pau_ll_set_regdma_link0_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_0_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_link1_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_1_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_link2_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_2_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_link3_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_3_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_wifimac_link_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_mac_addr.val = (uint32_t)link_addr; +} + +static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev) +{ + return dev->regdma_current_link_addr.val; +} + +static inline uint32_t pau_ll_get_regdma_backup_addr(pau_dev_t *dev) +{ + return dev->regdma_backup_addr.val; +} + +static inline uint32_t pau_ll_get_regdma_memory_addr(pau_dev_t *dev) +{ + return dev->regdma_mem_addr.val; +} + +static inline uint32_t pau_ll_get_regdma_intr_raw_signal(pau_dev_t *dev) +{ + return dev->int_raw.val; +} + +static inline uint32_t pau_ll_get_regdma_intr_status(pau_dev_t *dev) +{ + return dev->int_st.val; +} + +static inline void pau_ll_set_regdma_backup_done_intr_enable(pau_dev_t *dev) +{ + dev->int_ena.done_int_ena = 1; +} + +static inline void pau_ll_set_regdma_backup_done_intr_disable(pau_dev_t *dev) +{ + dev->int_ena.done_int_ena = 0; +} + +static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev) +{ + dev->int_ena.error_int_ena = 1; +} + +static inline void pau_ll_set_regdma_backup_error_intr_disable(pau_dev_t *dev) +{ + dev->int_ena.error_int_ena = 0; +} + +static inline void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev) +{ + dev->int_clr.done_int_clr = 1; +} + +static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev) +{ + dev->int_clr.error_int_clr = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/pcnt_ll.h b/components/hal/esp32c6/include/hal/pcnt_ll.h new file mode 100644 index 000000000000..963fbf7c73db --- /dev/null +++ b/components/hal/esp32c6/include/hal/pcnt_ll.h @@ -0,0 +1,426 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for ESP32-C6 PCNT register operations + +#pragma once + +#include +#include +#include +#include "soc/pcnt_struct.h" +#include "hal/pcnt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL) +#define PCNT_LL_MAX_GLITCH_WIDTH 1023 +#define PCNT_LL_MAX_LIM SHRT_MAX +#define PCNT_LL_MIN_LIN SHRT_MIN + +typedef enum { + PCNT_LL_WATCH_EVENT_INVALID = -1, + PCNT_LL_WATCH_EVENT_THRES1, + PCNT_LL_WATCH_EVENT_THRES0, + PCNT_LL_WATCH_EVENT_LOW_LIMIT, + PCNT_LL_WATCH_EVENT_HIGH_LIMIT, + PCNT_LL_WATCH_EVENT_ZERO_CROSS, + PCNT_LL_WATCH_EVENT_MAX +} pcnt_ll_watch_event_id_t; + +#define PCNT_LL_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1) +#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id)) + +/** + * @brief Set PCNT channel edge action + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param pos_act Counter action when detecting positive edge + * @param neg_act Counter action when detecting negative edge + */ +static inline void pcnt_ll_set_edge_action(pcnt_dev_t *hw, uint32_t unit, uint32_t channel, pcnt_channel_edge_action_t pos_act, pcnt_channel_edge_action_t neg_act) +{ + if (channel == 0) { + hw->conf_unit[unit].conf0.ch0_pos_mode = pos_act; + hw->conf_unit[unit].conf0.ch0_neg_mode = neg_act; + } else { + hw->conf_unit[unit].conf0.ch1_pos_mode = pos_act; + hw->conf_unit[unit].conf0.ch1_neg_mode = neg_act; + } +} + +/** + * @brief Set PCNT channel level action + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param high_act Counter action when control signal is high level + * @param low_act Counter action when control signal is low level + */ +static inline void pcnt_ll_set_level_action(pcnt_dev_t *hw, uint32_t unit, uint32_t channel, pcnt_channel_level_action_t high_act, pcnt_channel_level_action_t low_act) +{ + if (channel == 0) { + hw->conf_unit[unit].conf0.ch0_hctrl_mode = high_act; + hw->conf_unit[unit].conf0.ch0_lctrl_mode = low_act; + } else { + hw->conf_unit[unit].conf0.ch1_hctrl_mode = high_act; + hw->conf_unit[unit].conf0.ch1_lctrl_mode = low_act; + } +} + +/** + * @brief Get pulse counter value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit Pulse Counter unit number + * @return PCNT count value (a signed integer) + */ +__attribute__((always_inline)) +static inline int pcnt_ll_get_count(pcnt_dev_t *hw, uint32_t unit) +{ + pcnt_un_cnt_reg_t cnt_reg = hw->cnt_unit[unit]; + int16_t value = cnt_reg.pulse_cnt; + return value; +} + +/** + * @brief Pause PCNT counter of PCNT unit + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + */ +__attribute__((always_inline)) +static inline void pcnt_ll_stop_count(pcnt_dev_t *hw, uint32_t unit) +{ + hw->ctrl.val |= 1 << (2 * unit + 1); +} + +/** + * @brief Resume counting for PCNT counter + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number, select from uint32_t + */ +__attribute__((always_inline)) +static inline void pcnt_ll_start_count(pcnt_dev_t *hw, uint32_t unit) +{ + hw->ctrl.val &= ~(1 << (2 * unit + 1)); +} + +/** + * @brief Clear PCNT counter value to zero + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number, select from uint32_t + */ +__attribute__((always_inline)) +static inline void pcnt_ll_clear_count(pcnt_dev_t *hw, uint32_t unit) +{ + hw->ctrl.val |= 1 << (2 * unit); + hw->ctrl.val &= ~(1 << (2 * unit)); +} + +/** + * @brief Enable PCNT interrupt for PCNT unit + * @note Each PCNT unit has five watch point events that share the same interrupt bit. + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit_mask PCNT units mask + * @param enable True to enable interrupt, False to disable interrupt + */ +static inline void pcnt_ll_enable_intr(pcnt_dev_t *hw, uint32_t unit_mask, bool enable) +{ + if (enable) { + hw->int_ena.val |= unit_mask; + } else { + hw->int_ena.val &= ~unit_mask; + } +} + +/** + * @brief Get PCNT interrupt status + * + * @param hw Peripheral PCNT hardware instance address. + * @return Interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t pcnt_ll_get_intr_status(pcnt_dev_t *hw) +{ + return hw->int_st.val; +} + +/** + * @brief Clear PCNT interrupt status + * + * @param hw Peripheral PCNT hardware instance address. + * @param status value to clear interrupt status + */ +__attribute__((always_inline)) +static inline void pcnt_ll_clear_intr_status(pcnt_dev_t *hw, uint32_t status) +{ + hw->int_clr.val = status; +} + +/** + * @brief Enable PCNT high limit event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_high_limit_event(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.thr_h_lim_en = enable; +} + +/** + * @brief Enable PCNT low limit event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_low_limit_event(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.thr_l_lim_en = enable; +} + +/** + * @brief Enable PCNT zero cross event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_zero_cross_event(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.thr_zero_en = enable; +} + +/** + * @brief Enable PCNT threshold event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param thres Threshold ID + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_thres_event(pcnt_dev_t *hw, uint32_t unit, uint32_t thres, bool enable) +{ + if (thres == 0) { + hw->conf_unit[unit].conf0.thr_thres0_en = enable; + } else { + hw->conf_unit[unit].conf0.thr_thres1_en = enable; + } +} + +/** + * @brief Disable all PCNT threshold events + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit unit number + */ +static inline void pcnt_ll_disable_all_events(pcnt_dev_t *hw, uint32_t unit) +{ + hw->conf_unit[unit].conf0.val &= ~(PCNT_LL_WATCH_EVENT_MASK << 11); +} + +/** + * @brief Set PCNT high limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param value PCNT high limit value + */ +static inline void pcnt_ll_set_high_limit_value(pcnt_dev_t *hw, uint32_t unit, int value) +{ + pcnt_un_conf2_reg_t conf2_reg = hw->conf_unit[unit].conf2; + conf2_reg.cnt_h_lim = value; + hw->conf_unit[unit].conf2 = conf2_reg; +} + +/** + * @brief Set PCNT low limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param value PCNT low limit value + */ +static inline void pcnt_ll_set_low_limit_value(pcnt_dev_t *hw, uint32_t unit, int value) +{ + pcnt_un_conf2_reg_t conf2_reg = hw->conf_unit[unit].conf2; + conf2_reg.cnt_l_lim = value; + hw->conf_unit[unit].conf2 = conf2_reg; +} + +/** + * @brief Set PCNT threshold value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param thres Threshold ID + * @param value PCNT threshold value + */ +static inline void pcnt_ll_set_thres_value(pcnt_dev_t *hw, uint32_t unit, uint32_t thres, int value) +{ + pcnt_un_conf1_reg_t conf1_reg = hw->conf_unit[unit].conf1; + if (thres == 0) { + conf1_reg.cnt_thres0 = value; + } else { + conf1_reg.cnt_thres1 = value; + } + hw->conf_unit[unit].conf1 = conf1_reg; +} + +/** + * @brief Get PCNT high limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return PCNT high limit value + */ +static inline int pcnt_ll_get_high_limit_value(pcnt_dev_t *hw, uint32_t unit) +{ + pcnt_un_conf2_reg_t conf2_reg = hw->conf_unit[unit].conf2; + int16_t value = conf2_reg.cnt_h_lim ; + return value; +} + +/** + * @brief Get PCNT low limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return PCNT high limit value + */ +static inline int pcnt_ll_get_low_limit_value(pcnt_dev_t *hw, uint32_t unit) +{ + pcnt_un_conf2_reg_t conf2_reg = hw->conf_unit[unit].conf2; + int16_t value = conf2_reg.cnt_l_lim ; + return value; +} + +/** + * @brief Get PCNT threshold value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param thres Threshold ID + * @return PCNT threshold value + */ +static inline int pcnt_ll_get_thres_value(pcnt_dev_t *hw, uint32_t unit, uint32_t thres) +{ + int16_t value; + pcnt_un_conf1_reg_t conf1_reg = hw->conf_unit[unit].conf1; + if (thres == 0) { + value = conf1_reg.cnt_thres0 ; + } else { + value = conf1_reg.cnt_thres1 ; + } + return value; +} + +/** + * @brief Get PCNT unit runtime status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return PCNT unit runtime status + */ +static inline uint32_t pcnt_ll_get_unit_status(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->status_unit[unit].val; +} + +/** + * @brief Get PCNT zero cross mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return Zero cross mode + */ +__attribute__((always_inline)) +static inline pcnt_unit_zero_cross_mode_t pcnt_ll_get_zero_cross_mode(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->status_unit[unit].val & 0x03; +} + +/** + * @brief Get PCNT event status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return Event status word + */ +__attribute__((always_inline)) +static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->status_unit[unit].val >> 2; +} + +/** + * @brief Set PCNT glitch filter threshold + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param filter_val PCNT signal filter value, counter in APB_CLK cycles. + * Any pulses lasting shorter than this will be ignored when the filter is enabled. + */ +static inline void pcnt_ll_set_glitch_filter_thres(pcnt_dev_t *hw, uint32_t unit, uint32_t filter_val) +{ + hw->conf_unit[unit].conf0.filter_thres = filter_val; +} + +/** + * @brief Get PCNT glitch filter threshold + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return glitch filter threshold + */ +static inline uint32_t pcnt_ll_get_glitch_filter_thres(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->conf_unit[unit].conf0.filter_thres ; +} + +/** + * @brief Enable PCNT glitch filter + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable True to enable the filter, False to disable the filter + */ +static inline void pcnt_ll_enable_glitch_filter(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.filter_en = enable; +} + +/** + * @brief Get interrupt status register address. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Interrupt status register address + */ +static inline volatile void *pcnt_ll_get_intr_status_reg(pcnt_dev_t *hw) +{ + return &hw->int_st.val; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/pmu_hal.h b/components/hal/esp32c6/include/hal/pmu_hal.h new file mode 100644 index 000000000000..f4ca27e9e897 --- /dev/null +++ b/components/hal/esp32c6/include/hal/pmu_hal.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PMU + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/soc_caps.h" +#include "hal/pmu_ll.h" +#include "hal/pmu_types.h" + +typedef struct { + pmu_dev_t *dev; +} pmu_hal_context_t; + +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle); + +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal); + +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle); + +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_modem_backup_enable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_modem_backup_disable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_modem_active_backup_enable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_modem_active_backup_disable(pmu_hal_context_t *hal); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/pmu_ll.h b/components/hal/esp32c6/include/hal/pmu_ll.h new file mode 100644 index 000000000000..2470f73247cf --- /dev/null +++ b/components/hal/esp32c6/include/hal/pmu_ll.h @@ -0,0 +1,686 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 PMU register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "esp_attr.h" +#include "hal/assert.h" +#include "soc/pmu_struct.h" +#include "hal/pmu_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the power domain that needs to be powered down in the digital power + * + * @param hw Beginning address of the peripheral registers. + * @param mode The pmu mode + * @param flag Digital power domain flag + * + * @return None + */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t flag) +{ + hw->hp_sys[mode].dig_power.val = flag; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func) +{ + hw->hp_sys[mode].icg_func = icg_func; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_apb(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t bitmap) +{ + hw->hp_sys[mode].icg_apb = bitmap; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_modem(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t code) +{ + hw->hp_sys[mode].icg_modem.code = code; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_uart_wakeup_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool wakeup_en) +{ + hw->hp_sys[mode].syscntl.uart_wakeup_en = wakeup_en; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_hold_all_lp_pad(pmu_dev_t *hw, pmu_hp_mode_t mode, bool hold_all) +{ + hw->hp_sys[mode].syscntl.lp_pad_hold_all = hold_all; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_hold_all_hp_pad(pmu_dev_t *hw, pmu_hp_mode_t mode, bool hold_all) +{ + hw->hp_sys[mode].syscntl.hp_pad_hold_all = hold_all; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_pad_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel) +{ + hw->hp_sys[mode].syscntl.dig_pad_slp_sel = slp_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_pause_watchdog(pmu_dev_t *hw, pmu_hp_mode_t mode, bool pause_wdt) +{ + hw->hp_sys[mode].syscntl.dig_pause_wdt = pause_wdt; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_cpu_stall(pmu_dev_t *hw, pmu_hp_mode_t mode, bool cpu_stall) +{ + hw->hp_sys[mode].syscntl.dig_cpu_stall = cpu_stall; +} + +/** + * @brief Set the power domain that needs to be powered down in the clock power + * + * @param hw Beginning address of the peripheral registers. + * @param mode The pmu mode + * @param flag Clock power domain flag + * + * @return None + */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_clk_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t xpd_flag) +{ + hw->hp_sys[mode].clk_power.val = xpd_flag; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_xtal) +{ + hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_bias_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_bias) +{ + hw->hp_sys[mode].bias.xpd_bias = xpd_bias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_dbg_atten(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t value) +{ + hw->hp_sys[mode].bias.dbg_atten = value; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_current_power_off(pmu_dev_t *hw, pmu_hp_mode_t mode, bool off) +{ + hw->hp_sys[mode].bias.pd_cur = off; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool en) +{ + hw->hp_sys[mode].bias.bias_sleep = en; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_retention_param(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t param) +{ + hw->hp_sys[mode].backup.val = param; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_modem_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_MODEM].backup.hp_sleep2modem_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_modem_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_MODEM].backup.hp_sleep2modem_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_backup_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func) +{ + hw->hp_sys[mode].backup_clk = icg_func; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sysclk_nodiv(pmu_dev_t *hw, pmu_hp_mode_t mode, bool sysclk_nodiv) +{ + hw->hp_sys[mode].sysclk.dig_sysclk_nodiv = sysclk_nodiv; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_sysclk_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool icg_sysclk_en) +{ + hw->hp_sys[mode].sysclk.icg_sysclk_en = icg_sysclk_en; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sysclk_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel) +{ + hw->hp_sys[mode].sysclk.sysclk_slp_sel = slp_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_sysclk_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel) +{ + hw->hp_sys[mode].sysclk.icg_slp_sel = slp_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_sysclk(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t sysclk_sel) +{ + hw->hp_sys[mode].sysclk.dig_sysclk_sel = sysclk_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_xpd) +{ + hw->hp_sys[mode].regulator0.slp_logic_xpd = slp_xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_xpd) +{ + hw->hp_sys[mode].regulator0.slp_mem_xpd = slp_xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd) +{ + hw->hp_sys[mode].regulator0.xpd = xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias) +{ + hw->hp_sys[mode].regulator0.slp_logic_dbias = slp_dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias) +{ + hw->hp_sys[mode].regulator0.slp_mem_dbias = slp_dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t dbias) +{ + hw->hp_sys[mode].regulator0.dbias = dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_driver_bar(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t drv_b) +{ + hw->hp_sys[mode].regulator1.drv_b = drv_b; +} + + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_slp_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool slp_xpd) +{ + hw->lp_sys[mode].regulator0.slp_xpd = slp_xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd) +{ + hw->lp_sys[mode].regulator0.xpd = xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_sleep_dbias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t slp_dbias) +{ + hw->lp_sys[mode].regulator0.slp_dbias = slp_dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_dbias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t dbias) +{ + hw->lp_sys[mode].regulator0.dbias = dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_driver_bar(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t drv_b) +{ + hw->lp_sys[mode].regulator1.drv_b = drv_b; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_xtal_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_xtal) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].xtal.xpd_xtal = xpd_xtal; +} + + +FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t flag) +{ + hw->lp_sys[mode].dig_power.val = flag; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_clk_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t xpd_flag) +{ + hw->lp_sys[mode].clk_power.val = xpd_flag; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_clk_power(pmu_dev_t *hw, pmu_lp_mode_t mode) +{ + return hw->lp_sys[mode].clk_power.val; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_bias) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.xpd_bias = xpd_bias; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_dbg_atten(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t value) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.dbg_atten = value; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_current_power_off(pmu_dev_t *hw, pmu_lp_mode_t mode, bool off) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.pd_cur = off; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_lp_mode_t mode, bool en) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.bias_sleep = en; +} + + +/****/ +FORCE_INLINE_ATTR void pmu_ll_imm_set_clk_power(pmu_dev_t *hw, uint32_t flag) +{ + hw->imm.clk_power.val = flag; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_icg_slp_sel(pmu_dev_t *hw, bool slp_sel) +{ + if (slp_sel) { + hw->imm.sleep_sysclk.tie_high_icg_slp_sel = 1; + } else { + hw->imm.sleep_sysclk.tie_low_icg_slp_sel = 1; + } +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_sysclk_sel(pmu_dev_t *hw, bool update) +{ + hw->imm.sleep_sysclk.update_dig_sysclk_sel = update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_switch(pmu_dev_t *hw, bool update) +{ + hw->imm.sleep_sysclk.update_dig_icg_switch = update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_func(pmu_dev_t *hw, bool icg_func_update) +{ + hw->imm.hp_func_icg.update_dig_icg_func_en = icg_func_update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_apb(pmu_dev_t *hw, bool icg_apb_update) +{ + hw->imm.hp_apb_icg.update_dig_icg_apb_en = icg_apb_update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_modem_code(pmu_dev_t *hw, bool icg_modem_update) +{ + hw->imm.modem_icg.update_dig_icg_modem_en = icg_modem_update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_rootclk_sel(pmu_dev_t *hw, bool rootclk_sel) +{ + if (rootclk_sel) { + hw->imm.lp_icg.tie_high_lp_rootclk_sel = 1; + } else { + hw->imm.lp_icg.tie_low_lp_rootclk_sel = 1; + } +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_hp_pad_hold_all(pmu_dev_t *hw, bool hold_all) +{ + if (hold_all) { + hw->imm.pad_hold_all.tie_high_hp_pad_hold_all = 1; + } else { + hw->imm.pad_hold_all.tie_low_hp_pad_hold_all = 1; + } +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_pad_hold_all(pmu_dev_t *hw, bool hold_all) +{ + if (hold_all) { + hw->imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; + } else { + hw->imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; + } +} + +/*** */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool rst) +{ + hw->power.hp_pd[domain].force_reset = rst; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_isolate(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool iso) +{ + hw->power.hp_pd[domain].force_iso = iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_power_up(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool fpu) +{ + hw->power.hp_pd[domain].force_pu = fpu; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_no_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool no_rst) +{ + hw->power.hp_pd[domain].force_no_reset = no_rst; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_no_isolate(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool no_iso) +{ + hw->power.hp_pd[domain].force_no_iso = no_iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_power_down(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool fpd) +{ + hw->power.hp_pd[domain].force_pd = fpd; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_reset(pmu_dev_t *hw, bool rst) +{ + hw->power.lp_peri.force_reset = rst; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_isolate(pmu_dev_t *hw, bool iso) +{ + hw->power.lp_peri.force_iso = iso; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_power_up(pmu_dev_t *hw, bool fpu) +{ + hw->power.lp_peri.force_pu = fpu; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_no_reset(pmu_dev_t *hw, bool no_rst) +{ + hw->power.lp_peri.force_no_reset = no_rst; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_no_isolate(pmu_dev_t *hw, bool no_iso) +{ + hw->power.lp_peri.force_no_iso = no_iso; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_power_down(pmu_dev_t *hw, bool fpd) +{ + hw->power.lp_peri.force_pd = fpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_isolate(pmu_dev_t *hw, uint32_t iso) +{ + hw->power.mem_cntl.force_hp_mem_iso = iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_down(pmu_dev_t *hw, uint32_t fpd) +{ + hw->power.mem_cntl.force_hp_mem_pd = fpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_no_isolate(pmu_dev_t *hw, uint32_t no_iso) +{ + hw->power.mem_cntl.force_hp_mem_no_iso = no_iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_up(pmu_dev_t *hw, uint32_t fpu) +{ + hw->power.mem_cntl.force_hp_mem_pu = fpu; +} + +/*** */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_enable(pmu_dev_t *hw) +{ + hw->wakeup.cntl0.sleep_req = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_reject_enable(pmu_dev_t *hw, uint32_t reject) +{ + hw->wakeup.cntl1.sleep_reject_ena = reject; + hw->wakeup.cntl1.slp_reject_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_reject_disable(pmu_dev_t *hw) +{ + hw->wakeup.cntl1.slp_reject_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_wakeup_enable(pmu_dev_t *hw, uint32_t wakeup) +{ + hw->wakeup.cntl2 = wakeup; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) +{ + hw->wakeup.cntl3.sleep_prt_sel = mode; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) +{ + hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) +{ + hw->wakeup.cntl4.slp_reject_cause_clr = 1; +} + +FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_wakeup(pmu_dev_t *hw) +{ + return (hw->hp_ext.int_raw.wakeup == 1); +} + +FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_reject(pmu_dev_t *hw) +{ + return (hw->hp_ext.int_raw.reject == 1); +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_sw_intr_status(pmu_dev_t *hw) +{ + hw->hp_ext.int_clr.sw = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_wakeup_intr_status(pmu_dev_t *hw) +{ + hw->hp_ext.int_clr.wakeup = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw) +{ + hw->hp_ext.int_clr.reject = 1; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_wakeup_cause(pmu_dev_t *hw) +{ + return hw->wakeup.status0; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw) +{ + return hw->wakeup.status1; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_interrupt_raw(pmu_dev_t *hw) +{ + return hw->lp_ext.int_raw.val; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask) +{ + hw->lp_ext.int_clr.val = mask; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) +{ + hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) +{ + return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) +{ + return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer0.powerdown_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_down_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer0.powerdown_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer1.powerdown_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer1.powerdown_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) +{ + hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) +{ + return hw->wakeup.cntl5.lp_ana_wait_target; +} + +FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->wakeup.cntl5.modem_wait_target = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw) +{ + return hw->wakeup.cntl5.modem_wait_target; +} + +FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.clk_wait.wait_xtal_stable = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.clk_wait.wait_xtal_stable; +} + +FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.clk_wait.wait_pll_stable = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.clk_wait.wait_pll_stable; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer1.wait_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer1.wait_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer1.powerup_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer1.powerup_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->wakeup.cntl7.ana_wait_target = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) +{ + return hw->wakeup.cntl7.ana_wait_target; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer0.wait_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer0.wait_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer0.powerup_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer0.powerup_timer; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_sysclk_sleep_select_state(pmu_dev_t *hw) +{ + return hw->clk_state0.sysclk_slp_sel; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h new file mode 100644 index 000000000000..597cbdf36856 --- /dev/null +++ b/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/regi2c_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Start BBPLL self-calibration + */ +static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void) +{ + REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH); + REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW); +} + +/** + * @brief Stop BBPLL self-calibration + */ +static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void) +{ + REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW); + REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH); +} + +/** + * @brief Check whether BBPLL calibration is done + * + * @return True if calibration is done; otherwise false + */ +static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void) +{ + return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE); +} + +/** + * @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU); +} + +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PU); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PD); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/rmt_ll.h b/components/hal/esp32c6/include/hal/rmt_ll.h new file mode 100644 index 000000000000..06075b330f8f --- /dev/null +++ b/components/hal/esp32c6/include/hal/rmt_ll.h @@ -0,0 +1,861 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @note TX and RX channels are index from 0 in the LL driver, i.e. tx_channel = [0,1], rx_channel = [0,1] + */ + +#pragma once + +#include +#include +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/rmt_types.h" +#include "soc/rmt_struct.h" +#include "soc/pcr_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RMT_LL_EVENT_TX_DONE(channel) (1 << (channel)) +#define RMT_LL_EVENT_TX_THRES(channel) (1 << ((channel) + 8)) +#define RMT_LL_EVENT_TX_LOOP_END(channel) (1 << ((channel) + 12)) +#define RMT_LL_EVENT_TX_ERROR(channel) (1 << ((channel) + 4)) +#define RMT_LL_EVENT_RX_DONE(channel) (1 << ((channel) + 2)) +#define RMT_LL_EVENT_RX_THRES(channel) (1 << ((channel) + 10)) +#define RMT_LL_EVENT_RX_ERROR(channel) (1 << ((channel) + 6)) +#define RMT_LL_EVENT_TX_MASK(channel) (RMT_LL_EVENT_TX_DONE(channel) | RMT_LL_EVENT_TX_THRES(channel) | RMT_LL_EVENT_TX_LOOP_END(channel)) +#define RMT_LL_EVENT_RX_MASK(channel) (RMT_LL_EVENT_RX_DONE(channel) | RMT_LL_EVENT_RX_THRES(channel)) + +#define RMT_LL_MAX_LOOP_COUNT_PER_BATCH 1023 +#define RMT_LL_MAX_FILTER_VALUE 255 +#define RMT_LL_MAX_IDLE_VALUE 32767 + +typedef enum { + RMT_LL_MEM_OWNER_SW = 0, + RMT_LL_MEM_OWNER_HW = 1, +} rmt_ll_mem_owner_t; + +/** + * @brief Enable clock gate for register and memory + * + * @param dev Peripheral instance address + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) +{ + dev->sys_conf.clk_en = enable; // register clock gating + dev->sys_conf.mem_clk_force_on = enable; // memory clock gating +} + +/** + * @brief Power down memory + * + * @param dev Peripheral instance address + * @param enable True to power down, False to power up + */ +static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +{ + dev->sys_conf.mem_force_pu = !enable; + dev->sys_conf.mem_force_pd = enable; +} + +/** + * @brief Enable APB accessing RMT memory in nonfifo mode + * + * @param dev Peripheral instance address + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) +{ + dev->sys_conf.apb_fifo_mask = enable; +} + +/** + * @brief Set clock source and divider for RMT channel group + * + * @param dev Peripheral instance address + * @param channel not used as clock source is set for all channels + * @param src Clock source + * @param divider_integral Integral part of the divider + * @param divider_denominator Denominator part of the divider + * @param divider_numerator Numerator part of the divider + */ +static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) +{ + // Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b) + (void)channel; // the source clock is set for all channels + HAL_ASSERT(divider_integral >= 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.rmt_sclk_conf, rmt_sclk_div_num, divider_integral - 1); + PCR.rmt_sclk_conf.rmt_sclk_div_a = divider_numerator; + PCR.rmt_sclk_conf.rmt_sclk_div_b = divider_denominator; + switch (src) { + case RMT_CLK_SRC_PLL_F80M: + PCR.rmt_sclk_conf.rmt_sclk_sel = 1; + break; + case RMT_CLK_SRC_RC_FAST: + PCR.rmt_sclk_conf.rmt_sclk_sel = 2; + break; + case RMT_CLK_SRC_XTAL: + PCR.rmt_sclk_conf.rmt_sclk_sel = 3; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @brief Enable RMT peripheral source clock + * + * @param dev Peripheral instance address + * @param en True to enable, False to disable + */ +static inline void rmt_ll_enable_group_clock(rmt_dev_t *dev, bool en) +{ + (void)dev; + PCR.rmt_sclk_conf.rmt_sclk_en = en; +} + +////////////////////////////////////////TX Channel Specific///////////////////////////////////////////////////////////// + +/** + * @brief Reset clock divider for TX channels by mask + * + * @param dev Peripheral instance address + * @param channel_mask Mask of TX channels + */ +static inline void rmt_ll_tx_reset_channels_clock_div(rmt_dev_t *dev, uint32_t channel_mask) +{ + // write 1 to reset + dev->ref_cnt_rst.val |= channel_mask & 0x03; +} + +/** + * @brief Set TX channel clock divider + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param div Division value + */ +static inline void rmt_ll_tx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div) +{ + HAL_ASSERT(div >= 1 && div <= 256 && "divider out of range"); + // limit the maximum divider to 256 + if (div >= 256) { + div = 0; // 0 means 256 division + } + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn, div); +} + +/** + * @brief Reset RMT reading pointer for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_reset_pointer(rmt_dev_t *dev, uint32_t channel) +{ + dev->chnconf0[channel].mem_rd_rst_chn = 1; + dev->chnconf0[channel].mem_rd_rst_chn = 0; + dev->chnconf0[channel].apb_mem_rst_chn = 1; + dev->chnconf0[channel].apb_mem_rst_chn = 0; +} + +/** + * @brief Start transmitting for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_start(rmt_dev_t *dev, uint32_t channel) +{ + // update other configuration registers before start transmitting + dev->chnconf0[channel].conf_update_chn = 1; + dev->chnconf0[channel].tx_start_chn = 1; +} + +/** + * @brief Stop transmitting for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_stop(rmt_dev_t *dev, uint32_t channel) +{ + dev->chnconf0[channel].tx_stop_chn = 1; + // stop won't take place until configurations updated + dev->chnconf0[channel].conf_update_chn = 1; +} + +/** + * @brief Set memory block number for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param block_num memory block number + */ +static inline void rmt_ll_tx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num) +{ + dev->chnconf0[channel].mem_size_chn = block_num; +} + +/** + * @brief Enable TX wrap + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_tx_enable_wrap(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chnconf0[channel].mem_tx_wrap_en_chn = enable; +} + +/** + * @brief Enable transmitting in a loop + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param enable True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_enable_loop(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chnconf0[channel].tx_conti_mode_chn = enable; +} + +/** + * @brief Set loop count for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param count TX loop count + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_set_loop_count(rmt_dev_t *dev, uint32_t channel, uint32_t count) +{ + HAL_ASSERT(count <= RMT_LL_MAX_LOOP_COUNT_PER_BATCH && "loop count out of range"); + dev->chn_tx_lim[channel].tx_loop_num_chn = count; +} + +/** + * @brief Reset loop count for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_reset_loop_count(rmt_dev_t *dev, uint32_t channel) +{ + dev->chn_tx_lim[channel].loop_count_reset_chn = 1; + dev->chn_tx_lim[channel].loop_count_reset_chn = 0; +} + +/** + * @brief Enable loop count for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param enable True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_enable_loop_count(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chn_tx_lim[channel].tx_loop_cnt_en_chn = enable; +} + +/** + * @brief Enable loop stop at count value automatically + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param enable True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_enable_loop_autostop(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chn_tx_lim[channel].loop_stop_en_chn = enable; +} + +/** + * @brief Enable transmit multiple channels synchronously + * + * @param dev Peripheral instance address + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_tx_enable_sync(rmt_dev_t *dev, bool enable) +{ + dev->tx_sim.tx_sim_en = enable; +} + +/** + * @brief Clear the TX channels synchronous group + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_tx_clear_sync_group(rmt_dev_t *dev) +{ + dev->tx_sim.val &= ~(0x03); +} + +/** + * @brief Add TX channels to the synchronous group + * + * @param dev Peripheral instance address + * @param channel_mask Mask of TX channels to be added to the synchronous group + */ +static inline void rmt_ll_tx_sync_group_add_channels(rmt_dev_t *dev, uint32_t channel_mask) +{ + dev->tx_sim.val |= (channel_mask & 0x03); +} + +/** + * @brief Remove TX channels from the synchronous group + * + * @param dev Peripheral instance address + * @param channel_mask Mask of TX channels to be removed from the synchronous group + */ +static inline void rmt_ll_tx_sync_group_remove_channels(rmt_dev_t *dev, uint32_t channel_mask) +{ + dev->tx_sim.val &= ~channel_mask; +} + +/** + * @brief Fix the output level when TX channel is in IDLE state + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param level IDLE level (1 => high, 0 => low) + * @param enable True to fix the IDLE level, otherwise the IDLE level is determined by EOF encoder + */ +__attribute__((always_inline)) +static inline void rmt_ll_tx_fix_idle_level(rmt_dev_t *dev, uint32_t channel, uint8_t level, bool enable) +{ + dev->chnconf0[channel].idle_out_en_chn = enable; + dev->chnconf0[channel].idle_out_lv_chn = level; +} + +/** + * @brief Set the amount of RMT symbols that can trigger the limitation interrupt + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param limit Specify the number of symbols + */ +static inline void rmt_ll_tx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit) +{ + dev->chn_tx_lim[channel].tx_lim_chn = limit; +} + +/** + * @brief Set high and low duration of carrier signal + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param high_ticks Duration of high level + * @param low_ticks Duration of low level + */ +static inline void rmt_ll_tx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks) +{ + HAL_ASSERT(high_ticks >= 1 && high_ticks <= 65536 && low_ticks >= 1 && low_ticks <= 65536 && "out of range high/low ticks"); + // ticks=0 means 65536 in hardware + if (high_ticks >= 65536) { + high_ticks = 0; + } + if (low_ticks >= 65536) { + low_ticks = 0; + } + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chncarrier_duty[channel], carrier_high_chn, high_ticks); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chncarrier_duty[channel], carrier_low_chn, low_ticks); +} + +/** + * @brief Enable modulating carrier signal to TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_tx_enable_carrier_modulation(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chnconf0[channel].carrier_en_chn = enable; +} + +/** + * @brief Set on high or low to modulate the carrier signal + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param level Which level to modulate on (0=>low level, 1=>high level) + */ +static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level) +{ + dev->chnconf0[channel].carrier_out_lv_chn = level; +} + +/** + * @brief Enable to always output carrier signal, regardless of a valid data transmission + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + */ +static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chnconf0[channel].carrier_eff_en_chn = !enable; +} + +////////////////////////////////////////RX Channel Specific///////////////////////////////////////////////////////////// + +/** + * @brief Reset clock divider for RX channels by mask + * + * @param dev Peripheral instance address + * @param channel_mask Mask of RX channels + */ +static inline void rmt_ll_rx_reset_channels_clock_div(rmt_dev_t *dev, uint32_t channel_mask) +{ + // write 1 to reset + dev->ref_cnt_rst.val |= ((channel_mask & 0x03) << 2); +} + +/** + * @brief Set RX channel clock divider + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param div Division value + */ +static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div) +{ + HAL_ASSERT(div >= 1 && div <= 256 && "divider out of range"); + // limit the maximum divider to 256 + if (div >= 256) { + div = 0; // 0 means 256 division + } + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm, div); +} + +/** + * @brief Reset RMT writing pointer for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + */ +__attribute__((always_inline)) +static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel) +{ + dev->chmconf[channel].conf1.mem_wr_rst_chm = 1; + dev->chmconf[channel].conf1.mem_wr_rst_chm = 0; + dev->chmconf[channel].conf1.apb_mem_rst_chm = 1; + dev->chmconf[channel].conf1.apb_mem_rst_chm = 0; +} + +/** + * @brief Enable receiving for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param enable True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void rmt_ll_rx_enable(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chmconf[channel].conf1.rx_en_chm = enable; + // rx won't be enabled until configurations updated + dev->chmconf[channel].conf1.conf_update_chm = 1; +} + +/** + * @brief Set memory block number for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param block_num memory block number + */ +static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num) +{ + dev->chmconf[channel].conf0.mem_size_chm = block_num; +} + +/** + * @brief Set the time length for RX channel before going into IDLE state + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param thres Time length threshold + */ +__attribute__((always_inline)) +static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) +{ + dev->chmconf[channel].conf0.idle_thres_chm = thres; +} + +/** + * @brief Set RMT memory owner for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param owner Memory owner + */ +__attribute__((always_inline)) +static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt_ll_mem_owner_t owner) +{ + dev->chmconf[channel].conf1.mem_owner_chm = owner; +} + +/** + * @brief Enable filter for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX chanenl number + * @param enable True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chmconf[channel].conf1.rx_filter_en_chm = enable; +} + +/** + * @brief Set RX channel filter threshold (i.e. the maximum width of one pulse signal that would be treated as a noise) + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param thres Filter threshold + */ +__attribute__((always_inline)) +static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf1, rx_filter_thres_chm, thres); +} + +/** + * @brief Get RMT memory write cursor offset + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @return writer offset + */ +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_memory_writer_offset(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chmstatus[channel].mem_waddr_ex_chm - (channel + 2) * 48; +} + +/** + * @brief Set the amount of RMT symbols that can trigger the limitation interrupt + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param limit Specify the number of symbols + */ +static inline void rmt_ll_rx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit) +{ + dev->chm_rx_lim[channel].rmt_rx_lim_chm = limit; +} + +/** + * @brief Set high and low duration of carrier signal + * + * @param dev dev Peripheral instance address + * @param channel RMT TX channel number + * @param high_ticks Duration of high level + * @param low_ticks Duration of low level + */ +static inline void rmt_ll_rx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks) +{ + HAL_ASSERT(high_ticks >= 1 && high_ticks <= 65536 && low_ticks >= 1 && low_ticks <= 65536 && "out of range high/low ticks"); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chm_rx_carrier_rm[channel], carrier_high_thres_chm, high_ticks - 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chm_rx_carrier_rm[channel], carrier_low_thres_chm, low_ticks - 1); +} + +/** + * @brief Enable demodulating the carrier on RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_rx_enable_carrier_demodulation(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chmconf[channel].conf0.carrier_en_chm = enable; +} + +/** + * @brief Set on high or low to demodulate the carrier signal + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param level Which level to demodulate (0=>low level, 1=>high level) + */ +static inline void rmt_ll_rx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level) +{ + dev->chmconf[channel].conf0.carrier_out_lv_chm = level; +} + +/** + * @brief Enable RX wrap + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @param enable True to enable, False to disable + */ +static inline void rmt_ll_rx_enable_wrap(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chmconf[channel].conf1.mem_rx_wrap_en_chm = enable; +} + +//////////////////////////////////////////Interrupt Specific//////////////////////////////////////////////////////////// + +/** + * @brief Enable RMT interrupt for specific event mask + * + * @param dev Peripheral instance address + * @param mask Event mask + * @param enable True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool enable) +{ + if (enable) { + dev->int_ena.val |= mask; + } else { + dev->int_ena.val &= ~mask; + } +} + +/** + * @brief Clear RMT interrupt status by mask + * + * @param dev Peripheral instance address + * @param mask Interupt status mask + */ +__attribute__((always_inline)) +static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) +{ + dev->int_clr.val = mask; +} + +/** + * @brief Get interrupt status register address + * + * @param dev Peripheral instance address + * @return Register address + */ +static inline volatile void *rmt_ll_get_interrupt_status_reg(rmt_dev_t *dev) +{ + return &dev->int_st; +} + +/** + * @brief Get interrupt status for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t rmt_ll_tx_get_interrupt_status(rmt_dev_t *dev, uint32_t channel) +{ + return dev->int_st.val & RMT_LL_EVENT_TX_MASK(channel); +} + +/** + * @brief Get interrupt raw status for TX channel + * + * @param dev Peripheral instance address + * @param channel RMT TX channel number + * @return Interrupt raw status + */ +static inline uint32_t rmt_ll_tx_get_interrupt_status_raw(rmt_dev_t *dev, uint32_t channel) +{ + return dev->int_raw.val & (RMT_LL_EVENT_TX_MASK(channel) | RMT_LL_EVENT_TX_ERROR(channel)); +} + +/** + * @brief Get interrupt raw status for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @return Interrupt raw status + */ +static inline uint32_t rmt_ll_rx_get_interrupt_status_raw(rmt_dev_t *dev, uint32_t channel) +{ + return dev->int_raw.val & (RMT_LL_EVENT_RX_MASK(channel) | RMT_LL_EVENT_RX_ERROR(channel)); +} + +/** + * @brief Get interrupt status for RX channel + * + * @param dev Peripheral instance address + * @param channel RMT RX channel number + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t channel) +{ + return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel); +} + +//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// +/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// +/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chnstatus[channel].val; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chmstatus[channel].val; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel) +{ + uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn); + return div == 0 ? 256 : div; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel) +{ + uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm); + return div == 0 ? 256 : div; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chmconf[channel].conf0.idle_thres_chm; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chnconf0[channel].mem_size_chn; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chmconf[channel].conf0.mem_size_chm; +} + +__attribute__((always_inline)) +static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chnconf0[channel].tx_conti_mode_chn; +} + +__attribute__((always_inline)) +static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel) +{ + rmt_clock_source_t clk_src = RMT_CLK_SRC_PLL_F80M; + switch (PCR.rmt_sclk_conf.rmt_sclk_sel) { + case 1: + clk_src = RMT_CLK_SRC_PLL_F80M; + break; + case 2: + clk_src = RMT_CLK_SRC_RC_FAST; + break; + case 3: + clk_src = RMT_CLK_SRC_XTAL; + break; + } + return clk_src; +} + +__attribute__((always_inline)) +static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chnconf0[channel].idle_out_en_chn; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chnconf0[channel].idle_out_lv_chn; +} + +static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +{ + // the RTC domain can also power down RMT memory + // so it's probably not enough to detect whether it's powered down or not + // mem_force_pd has higher priority than mem_force_pu + return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chmconf[channel].conf1.mem_owner_chm; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel) +{ + return dev->chm_rx_lim[channel].rmt_rx_lim_chm; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev) +{ + return dev->int_st.val & 0x03; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev) +{ + return (dev->int_st.val >> 2) & 0x03; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev) +{ + return (dev->int_st.val >> 4) & 0x03; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev) +{ + return (dev->int_st.val >> 6) & 0x03; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev) +{ + return (dev->int_st.val >> 8) & 0x03; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev) +{ + return (dev->int_st.val >> 10) & 0x03; +} + +__attribute__((always_inline)) +static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev) +{ + return (dev->int_st.val >> 12) & 0x03; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/rtc_io_ll.h b/components/hal/esp32c6/include/hal/rtc_io_ll.h new file mode 100644 index 000000000000..38cb8bb9eddc --- /dev/null +++ b/components/hal/esp32c6/include/hal/rtc_io_ll.h @@ -0,0 +1,405 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "soc/rtc_periph.h" +#include "soc/pcr_struct.h" +#include "soc/rtc_io_struct.h" +#include "soc/lp_aon_struct.h" +#include "soc/pmu_struct.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/gpio_types.h" +#include "soc/io_mux_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTCIO_LL_PIN_FUNC 0 + +typedef enum { + RTCIO_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ + RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ +} rtcio_ll_func_t; + +typedef enum { + RTCIO_WAKEUP_DISABLE = 0, /*!< Disable GPIO interrupt */ + RTCIO_WAKEUP_LOW_LEVEL = 0x4, /*!< GPIO interrupt type : input low level trigger */ + RTCIO_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */ +} rtcio_ll_wake_type_t; + +typedef enum { + RTCIO_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ + RTCIO_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ +} rtcio_ll_out_mode_t; + +/** + * @brief Select the rtcio function. + * + * @note The RTC function must be selected before the pad analog function is enabled. + * @note The clock gating 'PCR.iomux_conf.iomux_clk_en' is the gate of both 'lp_io' and 'etm_gpio' + * And it's default to be turned on, so we don't need to operate this clock gate here additionally + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param func Select pin function. + */ +static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) +{ + if (func == RTCIO_FUNC_RTC) { + // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask |= BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + //0:RTC FUNCTION 1,2,3:Reserved + LP_IO.gpio[rtcio_num].mcu_sel = RTCIO_LL_PIN_FUNC; + } else if (func == RTCIO_FUNC_DIGITAL) { + // Clear the bit to use digital GPIO module + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask &= ~BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + } +} + +/** + * Enable rtcio output. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_output_enable(int rtcio_num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1ts, enable_w1ts, BIT(rtcio_num)); +} + +/** + * Disable rtcio output. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_output_disable(int rtcio_num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1tc, enable_w1tc, BIT(rtcio_num)); +} + +/** + * Set RTCIO output level. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param level 0: output low; ~0: output high. + */ +static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) +{ + if (level) { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1ts, out_data_w1ts, BIT(rtcio_num)); + } else { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1tc, out_data_w1tc, BIT(rtcio_num)); + } +} + +/** + * Enable rtcio input. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_input_enable(int rtcio_num) +{ + LP_IO.gpio[rtcio_num].fun_ie = 1; +} + +/** + * Disable rtcio input. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_input_disable(int rtcio_num) +{ + LP_IO.gpio[rtcio_num].fun_ie = 0; +} + +/** + * Get RTCIO input level. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return 0: input low; ~0: input high. + */ +static inline uint32_t rtcio_ll_get_level(int rtcio_num) +{ + return (uint32_t)(LP_IO.in.in_data_next >> rtcio_num) & 0x1; +} + +/** + * @brief Set RTC GPIO pad drive capability + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param strength Drive capability of the pad. Range: 0 ~ 3. + */ +static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength) +{ + LP_IO.gpio[rtcio_num].fun_drv = strength; +} + +/** + * @brief Get RTC GPIO pad drive capability. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Drive capability of the pad. Range: 0 ~ 3. + */ +static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) +{ + return LP_IO.gpio[rtcio_num].fun_drv; +} + +/** + * @brief Set RTC GPIO pad output mode. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return mode Output mode. + */ +static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode) +{ + LP_IO.pin[rtcio_num].pad_driver = mode; +} + +/** + * RTC GPIO pullup enable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pullup_enable(int rtcio_num) +{ + /* Enable internal weak pull-up */ + LP_IO.gpio[rtcio_num].fun_wpu = 1; +} + +/** + * RTC GPIO pullup disable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pullup_disable(int rtcio_num) +{ + /* Disable internal weak pull-up */ + LP_IO.gpio[rtcio_num].fun_wpu = 0; +} + +/** + * RTC GPIO pulldown enable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pulldown_enable(int rtcio_num) +{ + /* Enable internal weak pull-down */ + LP_IO.gpio[rtcio_num].fun_wpd = 1; +} + +/** + * RTC GPIO pulldown disable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pulldown_disable(int rtcio_num) +{ + /* Enable internal weak pull-down */ + LP_IO.gpio[rtcio_num].fun_wpd = 0; +} + +/** + * Enable force hold function for an RTC IO pad. + * + * Enabling HOLD function will cause the pad to lock current status, such as, + * input/output enable, input/output value, function, drive strength values. + * This function is useful when going into light or deep sleep mode to prevent + * the pin configuration from changing. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_force_hold_enable(int rtcio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 |= BIT(rtcio_num); +} + +/** + * Disable hold function on an RTC IO pad + * + * @note If disable the pad hold, the status of pad maybe changed in sleep mode. + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_force_hold_disable(int rtcio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num); +} + +/** + * Enable force hold function for all RTC IO pads + * + * Enabling HOLD function will cause the pad to lock current status, such as, + * input/output enable, input/output value, function, drive strength values. + * This function is useful when going into light or deep sleep mode to prevent + * the pin configuration from changing. + */ +static inline void rtcio_ll_force_hold_all(void) +{ + PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; +} + +/** + * Disable hold function fon all RTC IO pads + * + * @note If disable the pad hold, the status of pad maybe changed in sleep mode. + */ +static inline void rtcio_ll_force_unhold_all(void) +{ + PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; +} + +/** + * Enable wakeup function and set wakeup type from light sleep or deep sleep for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Wakeup on high level or low level. + */ +static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type) +{ + LP_IO.pin[rtcio_num].wakeup_enable = 0x1; + LP_IO.pin[rtcio_num].int_type = type; +} + +/** + * Disable wakeup function from light sleep or deep sleep for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_wakeup_disable(int rtcio_num) +{ + LP_IO.pin[rtcio_num].wakeup_enable = 0; + LP_IO.pin[rtcio_num].int_type = RTCIO_WAKEUP_DISABLE; +} + +/** + * Enable rtc io output in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_output_in_sleep(gpio_num_t gpio_num) +{ + LP_IO.gpio[gpio_num].mcu_oe = 1; +} + +/** + * Disable rtc io output in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_output_in_sleep(gpio_num_t gpio_num) +{ + LP_IO.gpio[gpio_num].mcu_oe = 0; +} + +/** + * Enable rtc io input in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_input_in_sleep(gpio_num_t gpio_num) +{ + LP_IO.gpio[gpio_num].mcu_ie = 1; +} + +/** + * Disable rtc io input in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_input_in_sleep(gpio_num_t gpio_num) +{ + LP_IO.gpio[gpio_num].mcu_ie = 0; +} + +/** + * Enable rtc io keep another setting in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_sleep_setting(gpio_num_t gpio_num) +{ + LP_IO.gpio[gpio_num].slp_sel = 1; +} + +/** + * Disable rtc io keep another setting in deep sleep. (Default) + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num) +{ + LP_IO.gpio[gpio_num].slp_sel = 0; +} + +/** + * @brief Get the status of whether an IO is used for sleep wake-up. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @return True if the pin is enabled to wake up from deep-sleep + */ +static inline bool rtcio_ll_wakeup_is_enabled(gpio_num_t gpio_num) +{ + HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function"); + // On ESP32-C6, (lp_io pin number) == (gpio pin number) + return LP_IO.pin[gpio_num].wakeup_enable; +} + +/** + * @brief Get the rtc io interrupt status + * + * @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT. + */ +static inline uint32_t rtcio_ll_get_interrupt_status(void) +{ + return (uint32_t)(LP_IO.status.status_interrupt); +} + +/** + * @brief Clear all LP IO pads status + */ +static inline void rtcio_ll_clear_interrupt_status(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_w1tc, 0xff); +} + +static inline void rtcio_ll_in_sleep_enable_input(gpio_num_t gpio_num) +{ + rtcio_ll_enable_input_in_sleep(gpio_num); +} + +static inline void rtcio_ll_in_sleep_disable_input(gpio_num_t gpio_num) +{ + rtcio_ll_disable_input_in_sleep(gpio_num); +} + +static inline void rtcio_ll_in_sleep_enable_output(gpio_num_t gpio_num) +{ + rtcio_ll_enable_output_in_sleep(gpio_num); +} + +static inline void rtcio_ll_in_sleep_disable_output(gpio_num_t gpio_num) +{ + rtcio_ll_disable_output_in_sleep(gpio_num); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/rwdt_ll.h b/components/hal/esp32c6/include/hal/rwdt_ll.h new file mode 100644 index 000000000000..f4f059934261 --- /dev/null +++ b/components/hal/esp32c6/include/hal/rwdt_ll.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +// The LL layer for RTC(LP) watchdog register operations. +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal/lpwdt_ll.h" + +typedef lp_wdt_dev_t rwdt_dev_t; + +#define RWDT_DEV_GET() &LP_WDT + +#define rwdt_ll_enable(hw) \ + lpwdt_ll_enable(hw) + +#define rwdt_ll_disable(hw) \ + lpwdt_ll_disable(hw) + +#define rwdt_ll_check_if_enabled(hw) \ + lpwdt_ll_check_if_enabled(hw) + +#define rwdt_ll_config_stage(hw, stage, timeout_ticks, behavior) \ + lpwdt_ll_config_stage(hw, stage, timeout_ticks, behavior) + +#define rwdt_ll_disable_stage(hw, stage) \ + lpwdt_ll_disable_stage(hw, stage) + +#define rwdt_ll_set_cpu_reset_length(hw, length) \ + lpwdt_ll_set_cpu_reset_length(hw, length) + +#define rwdt_ll_set_sys_reset_length(hw, length) \ + lpwdt_ll_set_sys_reset_length(hw, length) + +#define rwdt_ll_set_flashboot_en(hw, enable) \ + lpwdt_ll_set_flashboot_en(hw, enable) + +#define rwdt_ll_set_procpu_reset_en(hw, enable) \ + lpwdt_ll_set_procpu_reset_en(hw, enable) + +#define rwdt_ll_set_appcpu_reset_en(hw, enable) \ + lpwdt_ll_set_appcpu_reset_en(hw, enable) + +#define rwdt_ll_set_pause_in_sleep_en(hw, enable) \ + lpwdt_ll_set_pause_in_sleep_en(hw, enable) + +#define rwdt_ll_set_chip_reset_en(hw, enable) \ + lpwdt_ll_set_chip_reset_en(hw, enable) + +#define rwdt_ll_set_chip_reset_width(hw, width) \ + lpwdt_ll_set_chip_reset_width(hw, width) + +#define rwdt_ll_feed(hw) \ + lpwdt_ll_feed(hw) + +#define rwdt_ll_write_protect_enable(hw) \ + lpwdt_ll_write_protect_enable(hw) + +#define rwdt_ll_write_protect_disable(hw) \ + lpwdt_ll_write_protect_disable(hw) + +#define rwdt_ll_set_intr_enable(hw, enable) \ + lpwdt_ll_set_intr_enable(hw, enable) + +#define rwdt_ll_check_intr_status(hw) \ + lpwdt_ll_check_intr_status(hw) + +#define rwdt_ll_clear_intr_status(hw) \ + lpwdt_ll_clear_intr_status(hw) + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/sar_ctrl_ll.h b/components/hal/esp32c6/include/hal/sar_ctrl_ll.h new file mode 100644 index 000000000000..2a3ec6ca6325 --- /dev/null +++ b/components/hal/esp32c6/include/hal/sar_ctrl_ll.h @@ -0,0 +1,73 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. + * Related peripherals are: + * - ADC + * - PWDET + * + * All of above peripherals require SAR to work correctly. + * As SAR has some registers that will influence above mentioned peripherals. + * This file gives an abstraction for such registers + */ + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/apb_saradc_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PWDET_LL_SAR_POWER_FORCE_BIT BIT(24) +#define PWDET_LL_SAR_POWER_CNTL_BIT BIT(23) + + +typedef enum { + SAR_CTRL_LL_POWER_FSM, //SAR power controlled by FSM + SAR_CTRL_LL_POWER_ON, //SAR power on + SAR_CTRL_LL_POWER_OFF, //SAR power off +} sar_ctrl_ll_power_t; + +/*--------------------------------------------------------------- + SAR power control +---------------------------------------------------------------*/ +/** + * @brief Set SAR power mode when controlled by PWDET + * + * @param[in] mode See `sar_ctrl_ll_power_t` + */ +__attribute__((always_inline)) +static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode) +{ + if (mode == SAR_CTRL_LL_POWER_FSM) { + REG_CLR_BIT(PWDET_CONF_REG, PWDET_LL_SAR_POWER_FORCE_BIT); + } else if (mode == SAR_CTRL_LL_POWER_ON) { + REG_SET_BIT(PWDET_CONF_REG, PWDET_LL_SAR_POWER_FORCE_BIT); + REG_SET_BIT(PWDET_CONF_REG, PWDET_LL_SAR_POWER_CNTL_BIT); + } else if (mode == SAR_CTRL_LL_POWER_OFF) { + REG_SET_BIT(PWDET_CONF_REG, PWDET_LL_SAR_POWER_FORCE_BIT); + REG_CLR_BIT(PWDET_CONF_REG, PWDET_LL_SAR_POWER_CNTL_BIT); + } +} + +/** + * @brief Set SAR power ctrl source + * + * @param[in] force set PWDET as SAR power ctrl source when force is true + */ +static inline void sar_ctrl_ll_force_power_ctrl_from_pwdet(bool force) +{ + APB_SARADC.saradc_ctrl.saradc_saradc2_pwdet_drv = force; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/sdio_slave_ll.h b/components/hal/esp32c6/include/hal/sdio_slave_ll.h new file mode 100644 index 000000000000..29031b9475d4 --- /dev/null +++ b/components/hal/esp32c6/include/hal/sdio_slave_ll.h @@ -0,0 +1,509 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for SDIO slave register operations +// It's strange but `tx_*` regs for host->slave transfers while `rx_*` regs for slave->host transfers +// To reduce ambiguity, we call (host->slave, tx) transfers receiving and (slave->host, rx) transfers receiving + +#pragma once + +#include "hal/sdio_slave_hal.h" +#include "soc/slc_struct.h" +#include "soc/slc_reg.h" +#include "soc/host_struct.h" +#include "soc/host_reg.h" +#include "soc/hinf_struct.h" +#include "soc/lldesc.h" + +/// Get address of the only SLC registers +#define sdio_slave_ll_get_slc(ID) (&SLC) +/// Get address of the only HOST registers +#define sdio_slave_ll_get_host(ID) (&HOST) +/// Get address of the only HINF registers +#define sdio_slave_ll_get_hinf(ID) (&HINF) + + +/* + * SLC2 DMA Desc struct, aka sdio_slave_ll_desc_t + * + * -------------------------------------------------------------- + * | own | EoF | sub_sof | 1'b0 | length [13:0] | size [13:0] | + * -------------------------------------------------------------- + * | buf_ptr [31:0] | + * -------------------------------------------------------------- + * | next_desc_ptr [31:0] | + * -------------------------------------------------------------- + */ + +/* this bitfield is start from the LSB!!! */ +typedef struct sdio_slave_ll_desc_s { + volatile uint32_t size : 14, + length: 14, + offset: 1, /* starting from bit28, h/w reserved 1bit, s/w use it as offset in buffer */ + sosf : 1, /* start of sub-frame */ + eof : 1, /* end of frame */ + owner : 1; /* hw or sw */ + volatile const uint8_t *buf; /* point to buffer data */ + union { + volatile uint32_t empty; + STAILQ_ENTRY(sdio_slave_ll_desc_s) qe; /* pointing to the next desc */ + }; +} sdio_slave_ll_desc_t; + +/// Mask of general purpose interrupts sending from the host. +typedef enum { + SDIO_SLAVE_LL_SLVINT_0 = BIT(0), ///< General purpose interrupt bit 0. + SDIO_SLAVE_LL_SLVINT_1 = BIT(1), + SDIO_SLAVE_LL_SLVINT_2 = BIT(2), + SDIO_SLAVE_LL_SLVINT_3 = BIT(3), + SDIO_SLAVE_LL_SLVINT_4 = BIT(4), + SDIO_SLAVE_LL_SLVINT_5 = BIT(5), + SDIO_SLAVE_LL_SLVINT_6 = BIT(6), + SDIO_SLAVE_LL_SLVINT_7 = BIT(7), +} sdio_slave_ll_slvint_t; + +/** + * Initialize the hardware. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_init(slc_dev_t *slc) +{ + slc->slc0int_ena.val = 0; + + slc->slcconf0.slc0_rx_auto_wrback = 1; + slc->slcconf0.slc0_token_auto_clr = 0; + slc->slcconf0.slc0_rx_loop_test = 0; + slc->slcconf0.slc0_tx_loop_test = 0; + + slc->slcconf1.slc0_rx_stitch_en = 0; + slc->slcconf1.slc0_tx_stitch_en = 0; + slc->slcconf1.slc0_len_auto_clr = 0; + + slc->slc_rx_dscr_conf.slc0_token_no_replace = 1; +} + +/** + * Set the timing for the communication + * + * @param host Address of the host registers + * @param timing Timing configuration to set + */ +static inline void sdio_slave_ll_set_timing(host_dev_t *host, sdio_slave_timing_t timing) +{ + switch(timing) { + case SDIO_SLAVE_TIMING_PSEND_PSAMPLE: + host->conf.frc_sdio20 = 0x1f; + host->conf.frc_sdio11 = 0; + host->conf.frc_pos_samp = 0x1f; + host->conf.frc_neg_samp = 0; + break; + case SDIO_SLAVE_TIMING_PSEND_NSAMPLE: + host->conf.frc_sdio20 = 0x1f; + host->conf.frc_sdio11 = 0; + host->conf.frc_pos_samp = 0; + host->conf.frc_neg_samp = 0x1f; + break; + case SDIO_SLAVE_TIMING_NSEND_PSAMPLE: + host->conf.frc_sdio20 = 0; + host->conf.frc_sdio11 = 0x1f; + host->conf.frc_pos_samp = 0x1f; + host->conf.frc_neg_samp = 0; + break; + case SDIO_SLAVE_TIMING_NSEND_NSAMPLE: + host->conf.frc_sdio20 = 0; + host->conf.frc_sdio11 = 0x1f; + host->conf.frc_pos_samp = 0; + host->conf.frc_neg_samp = 0x1f; + break; + } +} + +/** + * Set the CCCR, SDIO and Physical Layer version + */ +static inline void sdio_slave_ll_init_version(hinf_dev_t *hinf) +{ + hinf->cfg_data1.sdio_ver = 0x232; +} + +/** + * Set the HS supported bit to be read by the host. + * + * @param hinf Address of the hinf registers + * @param hs true if supported, otherwise false. + */ +static inline void sdio_slave_ll_enable_hs(hinf_dev_t *hinf, bool hs) +{ + if (hs) { + hinf->cfg_data1.highspeed_enable = 1; + } else { + hinf->cfg_data1.highspeed_enable = 0; + } +} + +/** + * Set the IO Ready bit to be read by the host. + * + * @param hinf Address of the hinf registers + * @param ready true if ready, otherwise false. + */ +static inline void sdio_slave_ll_set_ioready(hinf_dev_t *hinf, bool ready) +{ + hinf->cfg_data1.sdio_ioready1 = (ready ? 1 : 0); //set IO ready to 1 to stop host from using +} + +/*--------------------------------------------------------------------------- + * Send + *--------------------------------------------------------------------------*/ +/** + * Reset the sending DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_reset(slc_dev_t *slc) +{ + //reset to flush previous packets + slc->slcconf0.slc0_rx_rst = 1; + slc->slcconf0.slc0_rx_rst = 0; +} + +/** + * Start the sending DMA with the given descriptor. + * + * @param slc Address of the SLC registers + * @param desc Descriptor to send + */ +static inline void sdio_slave_ll_send_start(slc_dev_t *slc, const sdio_slave_ll_desc_t *desc) +{ + slc->slc0rx_link_addr.slc0_rxlink_addr = (uint32_t)desc; + slc->slc0rx_link.slc0_rxlink_start = 1; +} + +/** + * Write the PKT_LEN register to be written by the host to a certain value. + * + * @param slc Address of the SLC registers + * @param len Length to write + */ +static inline void sdio_slave_ll_send_write_len(slc_dev_t *slc, uint32_t len) +{ + slc->slc0_len_conf.val = FIELD_TO_VALUE2(SDIO_SLC0_LEN_WDATA, len) | FIELD_TO_VALUE2(SDIO_SLC0_LEN_WR, 1); +} + +/** + * Read the value of PKT_LEN register. The register may keep the same until read + * by the host. + * + * @param host Address of the host registers + * @return The value of PKT_LEN register. + */ +static inline uint32_t sdio_slave_ll_send_read_len(host_dev_t *host) +{ + return host->pkt_len.hostslchost_slc0_len; +} + +/** + * Enable the rx_done interrupt. (sending) + * + * @param slc Address of the SLC registers + * @param ena true if enable, otherwise false. + */ +static inline void sdio_slave_ll_send_part_done_intr_ena(slc_dev_t *slc, bool ena) +{ + slc->slc0int_ena.slc0_rx_done_int_ena = (ena ? 1 : 0); +} + +/** + * Clear the rx_done interrupt. (sending) + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_part_done_clear(slc_dev_t *slc) +{ + slc->slc0int_clr.slc0_rx_done_int_clr = 1; +} + +/** + * Check whether the hardware is ready for the SW to use rx_done to invoke + * the ISR. + * + * @param slc Address of the SLC registers + * @return true if ready, otherwise false. + */ +static inline bool sdio_slave_ll_send_invoker_ready(slc_dev_t *slc) +{ + return slc->slc0int_raw.slc0_rx_done_int_raw; +} + +/** + * Stop the sending DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_stop(slc_dev_t *slc) +{ + slc->slc0rx_link.slc0_rxlink_stop = 1; +} + +/** + * Enable the sending interrupt (rx_eof). + * + * @param slc Address of the SLC registers + * @param ena true to enable, false to disable + */ +static inline void sdio_slave_ll_send_intr_ena(slc_dev_t *slc, bool ena) +{ + slc->slc0int_ena.slc0_rx_eof_int_ena = (ena? 1: 0); +} + +/** + * Clear the sending interrupt (rx_eof). + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_intr_clr(slc_dev_t *slc) +{ + slc->slc0int_clr.slc0_rx_eof_int_clr = 1; +} + +/** + * Check whether the sending is done. + * + * @param slc Address of the SLC registers + * @return true if done, otherwise false + */ +static inline bool sdio_slave_ll_send_done(slc_dev_t *slc) +{ + return slc->slc0int_st.slc0_rx_eof_int_st != 0; +} + +/** + * Clear the host interrupt indicating the slave having packet to be read. + * + * @param host Address of the host registers + */ +static inline void sdio_slave_ll_send_hostint_clr(host_dev_t *host) +{ + host->slc0host_int_clr.slc0_rx_new_packet_int_clr = 1; +} + +/*--------------------------------------------------------------------------- + * Receive + *--------------------------------------------------------------------------*/ +/** + * Enable the receiving interrupt. + * + * @param slc Address of the SLC registers + * @param ena + */ +static inline void sdio_slave_ll_recv_intr_ena(slc_dev_t *slc, bool ena) +{ + slc->slc0int_ena.slc0_tx_done_int_ena = (ena ? 1 : 0); +} + +/** + * Start receiving DMA with the given descriptor. + * + * @param slc Address of the SLC registers + * @param desc Descriptor of the receiving buffer. + */ +static inline void sdio_slave_ll_recv_start(slc_dev_t *slc, sdio_slave_ll_desc_t *desc) +{ + slc->slc0tx_link_addr.slc0_txlink_addr = (uint32_t)desc; + slc->slc0tx_link.slc0_txlink_start = 1; +} + +/** + * Increase the receiving buffer counter by 1. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_size_inc(slc_dev_t *slc) +{ + // fields wdata and inc_more should be written by the same instruction. + slc->slc0token1.val = FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WDATA, 1) | FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_INC_MORE, 1); +} + +/** + * Reset the receiving buffer. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_size_reset(slc_dev_t *slc) +{ + slc->slc0token1.val = FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WDATA, 0) | FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WR, 1); +} + +/** + * Check whether there is a receiving finished event. + * + * @param slc Address of the SLC registers + * @return + */ +static inline bool sdio_slave_ll_recv_done(slc_dev_t *slc) +{ + return slc->slc0int_raw.slc0_tx_done_int_raw != 0; +} + +/** + * Clear the receiving finished interrupt. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_done_clear(slc_dev_t *slc) +{ + slc->slc0int_clr.slc0_tx_done_int_clr = 1; +} + +/** + * Restart the DMA. Call after you modified the next pointer of the tail descriptor to the appended + * descriptor. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_restart(slc_dev_t *slc) +{ + slc->slc0tx_link.slc0_txlink_restart = 1; +} + +/** + * Reset the receiving DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_reset(slc_dev_t *slc) +{ + slc->slcconf0.slc0_tx_rst = 1; + slc->slcconf0.slc0_tx_rst = 0; +} + +/** + * Stop the receiving DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_stop(slc_dev_t *slc) +{ + slc->slc0tx_link.slc0_txlink_stop = 1; +} + +/*--------------------------------------------------------------------------- + * Host + *--------------------------------------------------------------------------*/ +/** + * Get the address of the shared general purpose register. Internal. + * + * @param host Address of the host registers + * @param pos Position of the register, 0-63 except 24-27. + * @return address of the register. + */ +static inline intptr_t sdio_slave_ll_host_get_w_reg(host_dev_t* host, int pos) +{ + return (intptr_t )&(host->conf_w0) + pos + (pos>23?4:0) + (pos>31?12:0); +} + +/** + * Get the value of the shared general purpose register. + * + * @param host Address of the host registers + * @param pos Position of the register, 0-63, except 24-27. + * @return value of the register. + */ +static inline uint8_t sdio_slave_ll_host_get_reg(host_dev_t *host, int pos) +{ + return *(uint8_t*)sdio_slave_ll_host_get_w_reg(host, pos); +} + +/** + * Set the value of the shared general purpose register. + * + * @param host Address of the host registers + * @param pos Position of the register, 0-63, except 24-27. + * @param reg Value to set. + */ +static inline void sdio_slave_ll_host_set_reg(host_dev_t* host, int pos, uint8_t reg) +{ + uint32_t* addr = (uint32_t*)(sdio_slave_ll_host_get_w_reg(host, pos) & (~3)); + uint32_t shift = (pos % 4) * 8; + *addr &= ~(0xff << shift); + *addr |= ((uint32_t)reg << shift); +} + +/** + * Get the interrupt enable bits for the host. + * + * @param host Address of the host registers + * @return Enabled interrupts + */ +static inline sdio_slave_hostint_t sdio_slave_ll_host_get_intena(host_dev_t* host) +{ + return host->slc0host_func1_int_ena.val; +} + +/** + * Set the interrupt enable bits for the host. + * + * @param host Address of the host registers + * @param mask Mask of interrupts to enable + */ +static inline void sdio_slave_ll_host_set_intena(host_dev_t *host, const sdio_slave_hostint_t *mask) +{ + host->slc0host_func1_int_ena.val = (*mask); +} + +/** + * Clear the interrupt bits for the host. + * @param host Address of the host registers + * @param mask Mask of interrupts to clear. + */ +static inline void sdio_slave_ll_host_intr_clear(host_dev_t* host, const sdio_slave_hostint_t *mask) +{ + host->slc0host_int_clr.val = (*mask); +} + +/** + * Send general purpose interrupts to the host. + * @param slc Address of the SLC registers + * @param mask Mask of interrupts to seend to host + */ +static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_hostint_t *mask) +{ + //use registers in SLC to trigger, rather than write HOST registers directly + //other interrupts than tohost interrupts are not supported yet + slc->slcintvec_tohost.slc0_tohost_intvec = (*mask); +} + +/** + * Enable some of the slave interrups (send from host) + * + * @param slc Address of the SLC registers + * @param mask Mask of interrupts to enable, all those set to 0 will be disabled. + */ +static inline void sdio_slave_ll_slvint_set_ena(slc_dev_t *slc, const sdio_slave_ll_slvint_t *mask) +{ + //other interrupts are not enabled + slc->slc0int_ena.val = (slc->slc0int_ena.val & (~0xff)) | ((*mask) & 0xff); +} + +/** + * Fetch the slave interrupts (send from host) and clear them. + * + * @param slc Address of the SLC registers + * @param out_slv_int Output of the slave interrupts fetched and cleared. + */ +static inline void sdio_slave_ll_slvint_fetch_clear(slc_dev_t *slc, sdio_slave_ll_slvint_t *out_slv_int) +{ + sdio_slave_ll_slvint_t slv_int = slc->slc0int_st.val & 0xff; + *out_slv_int = slv_int; + slc->slc0int_clr.val = slv_int; +} diff --git a/components/hal/esp32c6/include/hal/sdm_ll.h b/components/hal/esp32c6/include/hal/sdm_ll.h new file mode 100644 index 000000000000..7bdad37119de --- /dev/null +++ b/components/hal/esp32c6/include/hal/sdm_ll.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "soc/gpio_ext_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set Sigma-delta enable + * + * @param hw Peripheral SIGMADELTA hardware instance address. + * @param en Sigma-delta enable value + */ +static inline void sdm_ll_enable_clock(gpio_sd_dev_t *hw, bool en) +{ + hw->misc.function_clk_en = en; +} + +/** + * @brief Set Sigma-delta channel duty. + * + * @param hw Peripheral SIGMADELTA hardware instance address. + * @param channel Sigma-delta channel number + * @param density Sigma-delta quantized density of one channel, the value ranges from -128 to 127, recommended range is -90 ~ 90. + * The waveform is more like a random one in this range. + */ +__attribute__((always_inline)) +static inline void sdm_ll_set_pulse_density(gpio_sd_dev_t *hw, int channel, int8_t density) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[channel], duty, (uint32_t)density); +} + +/** + * @brief Set Sigma-delta channel's clock pre-scale value. + * + * @param hw Peripheral SIGMADELTA hardware instance address. + * @param channel Sigma-delta channel number + * @param prescale The divider of source clock, ranges from 1 to 256 + */ +static inline void sdm_ll_set_prescale(gpio_sd_dev_t *hw, int channel, uint32_t prescale) +{ + HAL_ASSERT(prescale && prescale <= 256); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[channel], prescale, prescale - 1); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/sha_ll.h b/components/hal/esp32c6/include/hal/sha_ll.h new file mode 100644 index 000000000000..1191bfafcaed --- /dev/null +++ b/components/hal/esp32c6/include/hal/sha_ll.h @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "soc/hwcrypto_reg.h" +#include "hal/sha_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Start a new SHA block conversions (no initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_start_block(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_START_REG, 1); +} + +/** + * @brief Continue a SHA block conversion (initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_continue_block(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_CONTINUE_REG, 1); +} + +/** + * @brief Start a new SHA message conversion using DMA (no initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_start_dma(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_DMA_START_REG, 1); +} + +/** + * @brief Continue a SHA message conversion using DMA (initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_continue_dma(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_DMA_CONTINUE_REG, 1); +} + +/** + * @brief Load the current hash digest to digest register + * + * @note Happens automatically on ESP32C6 + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_load(esp_sha_type sha_type) +{ +} + +/** + * @brief Sets the number of message blocks to be hashed + * + * @note DMA operation only + * + * @param num_blocks Number of message blocks to process + */ +static inline void sha_ll_set_block_num(size_t num_blocks) +{ + REG_WRITE(SHA_DMA_BLOCK_NUM_REG, num_blocks); +} + +/** + * @brief Checks if the SHA engine is currently busy hashing a block + * + * @return true SHA engine busy + * @return false SHA engine idle + */ +static inline bool sha_ll_busy(void) +{ + return REG_READ(SHA_BUSY_REG); +} + +/** + * @brief Write a text (message) block to the SHA engine + * + * @param input_text Input buffer to be written to the SHA engine + * @param block_word_len Number of words in block + */ +static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len) +{ + uint32_t *data_words = (uint32_t *)input_text; + uint32_t *reg_addr_buf = (uint32_t *)(SHA_M_MEM); + + for (int i = 0; i < block_word_len; i++) { + REG_WRITE(®_addr_buf[i], data_words[i]); + } +} + +/** + * @brief Read the message digest from the SHA engine + * + * @param sha_type The SHA algorithm type + * @param digest_state Buffer that message digest will be written to + * @param digest_word_len Length of the message digest + */ +static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len) +{ + uint32_t *digest_state_words = (uint32_t *)digest_state; + const size_t REG_WIDTH = sizeof(uint32_t); + + for (size_t i = 0; i < digest_word_len; i++) { + digest_state_words[i] = REG_READ(SHA_H_MEM + (i * REG_WIDTH)); + } + +} + +/** + * @brief Write the message digest to the SHA engine + * + * @param sha_type The SHA algorithm type + * @param digest_state Message digest to be written to SHA engine + * @param digest_word_len Length of the message digest + */ +static inline void sha_ll_write_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len) +{ + uint32_t *digest_state_words = (uint32_t *)digest_state; + uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_MEM); + + for (int i = 0; i < digest_word_len; i++) { + REG_WRITE(®_addr_buf[i], digest_state_words[i]); + } +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h new file mode 100644 index 000000000000..5e05cd6aba0f --- /dev/null +++ b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The Lowlevel layer for SPI Flash Encryption. + +#include +#include +#include "soc/hp_system_reg.h" +#include "soc/xts_aes_reg.h" +#include "soc/soc.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// Choose type of chip you want to encrypt manully +typedef enum +{ + FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. + PSRAM_ENCRYPTION_MANU = 1 ///!< Manually encrypt the psram chip. +} flash_encrypt_ll_type_t; + +/** + * Enable the flash encryption function under spi boot mode and download boot mode. + */ +static inline void spi_flash_encrypt_ll_enable(void) +{ + REG_SET_BIT(HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG, + HP_SYSTEM_ENABLE_DOWNLOAD_MANUAL_ENCRYPT | + HP_SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT); +} + +/* + * Disable the flash encryption mode. + */ +static inline void spi_flash_encrypt_ll_disable(void) +{ + REG_CLR_BIT(HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG, + HP_SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT); +} + +/** + * Choose type of chip you want to encrypt manully + * + * @param type The type of chip to be encrypted + * + * @note The hardware currently support flash encryption. + */ +static inline void spi_flash_encrypt_ll_type(flash_encrypt_ll_type_t type) +{ + // Our hardware only support flash encryption + HAL_ASSERT(type == FLASH_ENCRYPTION_MANU); + REG_SET_FIELD(XTS_AES_DESTINATION_REG(0), XTS_AES_DESTINATION, type); +} + +/** + * Configure the data size of a single encryption. + * + * @param block_size Size of the desired block. + */ +static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) +{ + // Desired block should not be larger than the block size. + REG_SET_FIELD(XTS_AES_LINESIZE_REG(0), XTS_AES_LINESIZE, size >> 5); +} + +/** + * Save 32-bit piece of plaintext. + * + * @param address the address of written flash partition. + * @param buffer Buffer to store the input data. + * @param size Buffer size. + * + */ +static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) +{ + uint32_t plaintext_offs = (address % 64); + memcpy((void *)(XTS_AES_PLAIN_MEM(0) + plaintext_offs), buffer, size); +} + +/** + * Copy the flash address to XTS_AES physical address + * + * @param flash_addr flash address to write. + */ +static inline void spi_flash_encrypt_ll_address_save(uint32_t flash_addr) +{ + REG_SET_FIELD(XTS_AES_PHYSICAL_ADDRESS_REG(0), XTS_AES_PHYSICAL_ADDRESS, flash_addr); +} + +/** + * Start flash encryption + */ +static inline void spi_flash_encrypt_ll_calculate_start(void) +{ + REG_SET_FIELD(XTS_AES_TRIGGER_REG(0), XTS_AES_TRIGGER, 1); +} + +/** + * Wait for flash encryption termination + */ +static inline void spi_flash_encrypt_ll_calculate_wait_idle(void) +{ + while(REG_GET_FIELD(XTS_AES_STATE_REG(0), XTS_AES_STATE) == 0x1) { + } +} + +/** + * Finish the flash encryption and make encrypted result accessible to SPI. + */ +static inline void spi_flash_encrypt_ll_done(void) +{ + REG_SET_BIT(XTS_AES_RELEASE_REG(0), XTS_AES_RELEASE); + while(REG_GET_FIELD(XTS_AES_STATE_REG(0), XTS_AES_STATE) != 0x3) { + } +} + +/** + * Set to destroy encrypted result + */ +static inline void spi_flash_encrypt_ll_destroy(void) +{ + REG_SET_BIT(XTS_AES_DESTROY_REG(0), XTS_AES_DESTROY); +} + +/** + * Check if is qualified to encrypt the buffer + * + * @param address the address of written flash partition. + * @param length Buffer size. + */ +static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length) +{ + return ((address % length) == 0) ? true : false; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/spi_flash_ll.h b/components/hal/esp32c6/include/hal/spi_flash_ll.h new file mode 100644 index 000000000000..522b862cb08d --- /dev/null +++ b/components/hal/esp32c6/include/hal/spi_flash_ll.h @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +// The Lowlevel layer for SPI Flash + +#pragma once + +#include "gpspi_flash_ll.h" +#include "spimem_flash_ll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define spi_flash_ll_calculate_clock_reg(host_id, clock_div) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_calculate_clock_reg(clock_div) \ + : gpspi_flash_ll_calculate_clock_reg(clock_div)) + +#define spi_flash_ll_get_source_clock_freq_mhz(host_id) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_get_source_freq_mhz() : GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ) + +#define spi_flash_ll_get_hw(host_id) (((host_id)<=SPI1_HOST ? (spi_dev_t*) spimem_flash_ll_get_hw(host_id) \ + : gpspi_flash_ll_get_hw(host_id))) + +#define spi_flash_ll_hw_get_id(dev) ({int dev_id = spimem_flash_ll_hw_get_id(dev); \ + if (dev_id < 0) {\ + dev_id = gpspi_flash_ll_hw_get_id(dev);\ + }\ + dev_id; \ + }) +// Since ESP32-C6, WB_mode is available, we extend 8 bits to occupy `Continuous Read Mode` bits. +#define SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS (8) + +typedef union { + gpspi_flash_ll_clock_reg_t gpspi; + spimem_flash_ll_clock_reg_t spimem; +} spi_flash_ll_clock_reg_t; + +#ifdef GPSPI_BUILD +#define spi_flash_ll_reset(dev) gpspi_flash_ll_reset((spi_dev_t*)dev) +#define spi_flash_ll_cmd_is_done(dev) gpspi_flash_ll_cmd_is_done((spi_dev_t*)dev) +#define spi_flash_ll_get_buffer_data(dev, buffer, read_len) gpspi_flash_ll_get_buffer_data((spi_dev_t*)dev, buffer, read_len) +#define spi_flash_ll_set_buffer_data(dev, buffer, len) gpspi_flash_ll_set_buffer_data((spi_dev_t*)dev, buffer, len) +#define spi_flash_ll_user_start(dev) gpspi_flash_ll_user_start((spi_dev_t*)dev) +#define spi_flash_ll_host_idle(dev) gpspi_flash_ll_host_idle((spi_dev_t*)dev) +#define spi_flash_ll_read_phase(dev) gpspi_flash_ll_read_phase((spi_dev_t*)dev) +#define spi_flash_ll_set_cs_pin(dev, pin) gpspi_flash_ll_set_cs_pin((spi_dev_t*)dev, pin) +#define spi_flash_ll_set_read_mode(dev, read_mode) gpspi_flash_ll_set_read_mode((spi_dev_t*)dev, read_mode) +#define spi_flash_ll_set_clock(dev, clk) gpspi_flash_ll_set_clock((spi_dev_t*)dev, (gpspi_flash_ll_clock_reg_t*)clk) +#define spi_flash_ll_set_miso_bitlen(dev, bitlen) gpspi_flash_ll_set_miso_bitlen((spi_dev_t*)dev, bitlen) +#define spi_flash_ll_set_mosi_bitlen(dev, bitlen) gpspi_flash_ll_set_mosi_bitlen((spi_dev_t*)dev, bitlen) +#define spi_flash_ll_set_command(dev, cmd, bitlen) gpspi_flash_ll_set_command((spi_dev_t*)dev, cmd, bitlen) +#define spi_flash_ll_set_addr_bitlen(dev, bitlen) gpspi_flash_ll_set_addr_bitlen((spi_dev_t*)dev, bitlen) +#define spi_flash_ll_get_addr_bitlen(dev) gpspi_flash_ll_get_addr_bitlen((spi_dev_t*)dev) +#define spi_flash_ll_set_address(dev, addr) gpspi_flash_ll_set_address((spi_dev_t*)dev, addr) +#define spi_flash_ll_set_usr_address(dev, addr, bitlen) gpspi_flash_ll_set_usr_address((spi_dev_t*)dev, addr, bitlen) +#define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy) +#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n) +#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time) +#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C6*/ } +#else +#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev) +#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev) +#define spi_flash_ll_erase_chip(dev) spimem_flash_ll_erase_chip((spi_mem_dev_t*)dev) +#define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) +#define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) +#define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) +#define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) +#define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) +#define spi_flash_ll_user_start(dev) spimem_flash_ll_user_start((spi_mem_dev_t*)dev) +#define spi_flash_ll_host_idle(dev) spimem_flash_ll_host_idle((spi_mem_dev_t*)dev) +#define spi_flash_ll_read_phase(dev) spimem_flash_ll_read_phase((spi_mem_dev_t*)dev) +#define spi_flash_ll_set_cs_pin(dev, pin) spimem_flash_ll_set_cs_pin((spi_mem_dev_t*)dev, pin) +#define spi_flash_ll_set_read_mode(dev, read_mode) spimem_flash_ll_set_read_mode((spi_mem_dev_t*)dev, read_mode) +#define spi_flash_ll_set_clock(dev, clk) spimem_flash_ll_set_clock((spi_mem_dev_t*)dev, (spimem_flash_ll_clock_reg_t*)clk) +#define spi_flash_ll_set_miso_bitlen(dev, bitlen) spimem_flash_ll_set_miso_bitlen((spi_mem_dev_t*)dev, bitlen) +#define spi_flash_ll_set_mosi_bitlen(dev, bitlen) spimem_flash_ll_set_mosi_bitlen((spi_mem_dev_t*)dev, bitlen) +#define spi_flash_ll_set_command(dev, cmd, bitlen) spimem_flash_ll_set_command((spi_mem_dev_t*)dev, cmd, bitlen) +#define spi_flash_ll_set_addr_bitlen(dev, bitlen) spimem_flash_ll_set_addr_bitlen((spi_mem_dev_t*)dev, bitlen) +#define spi_flash_ll_get_addr_bitlen(dev) spimem_flash_ll_get_addr_bitlen((spi_mem_dev_t*) dev) +#define spi_flash_ll_set_address(dev, addr) spimem_flash_ll_set_address((spi_mem_dev_t*)dev, addr) +#define spi_flash_ll_set_usr_address(dev, addr, bitlen) spimem_flash_ll_set_usr_address((spi_mem_dev_t*)dev, addr, bitlen) +#define spi_flash_ll_set_dummy(dev, dummy) spimem_flash_ll_set_dummy((spi_mem_dev_t*)dev, dummy) +#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n) +#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time) +#define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr) + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/spi_ll.h b/components/hal/esp32c6/include/hal/spi_ll.h new file mode 100644 index 000000000000..a7886ea8dc84 --- /dev/null +++ b/components/hal/esp32c6/include/hal/spi_ll.h @@ -0,0 +1,1214 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for SPI register operations + +#pragma once + +#include //for abs() +#include +#include "esp_attr.h" +#include "esp_types.h" +#include "soc/spi_periph.h" +#include "soc/spi_struct.h" +#include "soc/lldesc.h" +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/spi_types.h" +#include "soc/pcr_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// Interrupt not used. Don't use in app. +#define SPI_LL_UNUSED_INT_MASK (SPI_TRANS_DONE_INT_ENA | SPI_SLV_WR_DMA_DONE_INT_ENA | SPI_SLV_RD_DMA_DONE_INT_ENA | SPI_SLV_WR_BUF_DONE_INT_ENA | SPI_SLV_RD_BUF_DONE_INT_ENA) +/// These 2 masks together will set SPI transaction to one line mode +#define SPI_LL_ONE_LINE_CTRL_MASK (SPI_FREAD_QUAD | SPI_FREAD_DUAL | SPI_FCMD_QUAD | SPI_FCMD_DUAL | SPI_FADDR_QUAD | SPI_FADDR_DUAL) +#define SPI_LL_ONE_LINE_USER_MASK (SPI_FWRITE_QUAD | SPI_FWRITE_DUAL) +/// Swap the bit order to its correct place to send +#define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)(data) << (32 - len)) +#define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):&GPSPI2) + +#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits +#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized + +/** + * The data structure holding calculated clock configuration. Since the + * calculation needs long time, it should be calculated during initialization and + * stored somewhere to be quickly used. + */ +typedef uint32_t spi_ll_clock_val_t; +typedef spi_dev_t spi_dma_dev_t; + +// Type definition of all supported interrupts +typedef enum { + SPI_LL_INTR_TRANS_DONE = BIT(0), ///< A transaction has done + SPI_LL_INTR_RDBUF = BIT(6), ///< Has received RDBUF command. Only available in slave HD. + SPI_LL_INTR_WRBUF = BIT(7), ///< Has received WRBUF command. Only available in slave HD. + SPI_LL_INTR_RDDMA = BIT(8), ///< Has received RDDMA command. Only available in slave HD. + SPI_LL_INTR_WRDMA = BIT(9), ///< Has received WRDMA command. Only available in slave HD. + SPI_LL_INTR_CMD7 = BIT(10), ///< Has received CMD7 command. Only available in slave HD. + SPI_LL_INTR_CMD8 = BIT(11), ///< Has received CMD8 command. Only available in slave HD. + SPI_LL_INTR_CMD9 = BIT(12), ///< Has received CMD9 command. Only available in slave HD. + SPI_LL_INTR_CMDA = BIT(13), ///< Has received CMDA command. Only available in slave HD. + SPI_LL_INTR_SEG_DONE = BIT(14), +} spi_ll_intr_t; +FLAG_ATTR(spi_ll_intr_t) + +// Flags for conditions under which the transaction length should be recorded +typedef enum { + SPI_LL_TRANS_LEN_COND_WRBUF = BIT(0), ///< WRBUF length will be recorded + SPI_LL_TRANS_LEN_COND_RDBUF = BIT(1), ///< RDBUF length will be recorded + SPI_LL_TRANS_LEN_COND_WRDMA = BIT(2), ///< WRDMA length will be recorded + SPI_LL_TRANS_LEN_COND_RDDMA = BIT(3), ///< RDDMA length will be recorded +} spi_ll_trans_len_cond_t; +FLAG_ATTR(spi_ll_trans_len_cond_t) + +// SPI base command +typedef enum { + /* Slave HD Only */ + SPI_LL_BASE_CMD_HD_WRBUF = 0x01, + SPI_LL_BASE_CMD_HD_RDBUF = 0x02, + SPI_LL_BASE_CMD_HD_WRDMA = 0x03, + SPI_LL_BASE_CMD_HD_RDDMA = 0x04, + SPI_LL_BASE_CMD_HD_SEG_END = 0x05, + SPI_LL_BASE_CMD_HD_EN_QPI = 0x06, + SPI_LL_BASE_CMD_HD_WR_END = 0x07, + SPI_LL_BASE_CMD_HD_INT0 = 0x08, + SPI_LL_BASE_CMD_HD_INT1 = 0x09, + SPI_LL_BASE_CMD_HD_INT2 = 0x0A, +} spi_ll_base_command_t; + +/*------------------------------------------------------------------------------ + * Control + *----------------------------------------------------------------------------*/ + +/** + * Select SPI peripheral clock source (master). + * + * @param hw Beginning address of the peripheral registers. + * @param clk_source clock source to select, see valid sources in type `spi_clock_source_t` + */ +static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source) +{ + switch (clk_source) + { + case SPI_CLK_SRC_RC_FAST: + PCR.spi2_clkm_conf.spi2_clkm_sel = 2; + break; + case SPI_CLK_SRC_XTAL: + PCR.spi2_clkm_conf.spi2_clkm_sel = 0; + break; + default: + PCR.spi2_clkm_conf.spi2_clkm_sel = 1; + break; + } +} + +/** + * Initialize SPI peripheral (master). + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_master_init(spi_dev_t *hw) +{ + //Reset timing + hw->user1.cs_setup_time = 0; + hw->user1.cs_hold_time = 0; + + //use all 64 bytes of the buffer + hw->user.usr_miso_highpart = 0; + hw->user.usr_mosi_highpart = 0; + + //Disable unneeded ints + hw->slave.val = 0; + hw->user.val = 0; + + PCR.spi2_clkm_conf.spi2_clkm_en = 1; + PCR.spi2_clkm_conf.spi2_clkm_sel = 1; + + hw->dma_conf.val = 0; + hw->dma_conf.slv_tx_seg_trans_clr_en = 1; + hw->dma_conf.slv_rx_seg_trans_clr_en = 1; + hw->dma_conf.dma_slv_seg_trans_en = 0; +} + +/** + * Initialize SPI peripheral (slave). + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_slave_init(spi_dev_t *hw) +{ + //Configure slave + hw->clock.val = 0; + hw->user.val = 0; + hw->ctrl.val = 0; + hw->user.doutdin = 1; //we only support full duplex + hw->user.sio = 0; + hw->slave.slave_mode = 1; + hw->slave.soft_reset = 1; + hw->slave.soft_reset = 0; + //use all 64 bytes of the buffer + hw->user.usr_miso_highpart = 0; + hw->user.usr_mosi_highpart = 0; + + // Configure DMA In-Link to not be terminated when transaction bit counter exceeds + hw->dma_conf.rx_eof_en = 0; + hw->dma_conf.dma_slv_seg_trans_en = 0; + + //Disable unneeded ints + hw->dma_int_ena.val &= ~SPI_LL_UNUSED_INT_MASK; +} + +/** + * Initialize SPI peripheral (slave half duplex mode) + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_slave_hd_init(spi_dev_t *hw) +{ + hw->clock.val = 0; + hw->user.val = 0; + hw->ctrl.val = 0; + hw->user.doutdin = 0; + hw->user.sio = 0; + + hw->slave.soft_reset = 1; + hw->slave.soft_reset = 0; + hw->slave.slave_mode = 1; +} + +/** + * Determine and unify the default level of mosi line when bus free + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) +{ + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state +} + +/** + * Apply the register configurations and wait until it's done + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_apply_config(spi_dev_t *hw) +{ + hw->cmd.update = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done; +} + +/** + * Trigger start of user-defined transaction. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_user_start(spi_dev_t *hw) +{ + hw->cmd.usr = 1; +} + +/** + * Get current running command bit-mask. (Preview) + * + * @param hw Beginning address of the peripheral registers. + * + * @return Bitmask of running command, see ``SPI_CMD_REG``. 0 if no in-flight command. + */ +static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw) +{ + return hw->cmd.val; +} + +/** + * Reset the slave peripheral before next transaction. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_slave_reset(spi_dev_t *hw) +{ + hw->slave.soft_reset = 1; + hw->slave.soft_reset = 0; +} + +/** + * Reset SPI CPU TX FIFO + * + * On ESP32C3, this function is not seperated + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.buf_afifo_rst = 1; + hw->dma_conf.buf_afifo_rst = 0; +} + +/** + * Reset SPI CPU RX FIFO + * + * On ESP32C3, this function is not seperated + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_cpu_rx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.rx_afifo_rst = 1; + hw->dma_conf.rx_afifo_rst = 0; +} + +/** + * Reset SPI DMA TX FIFO + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_dma_tx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.dma_afifo_rst = 1; + hw->dma_conf.dma_afifo_rst = 0; +} + +/** + * Reset SPI DMA RX FIFO + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_dma_rx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.rx_afifo_rst = 1; + hw->dma_conf.rx_afifo_rst = 0; +} + +/** + * Clear in fifo full error + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_infifo_full_clr(spi_dev_t *hw) +{ + hw->dma_int_clr.dma_infifo_full_err = 1; +} + +/** + * Clear out fifo empty error + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_outfifo_empty_clr(spi_dev_t *hw) +{ + hw->dma_int_clr.dma_outfifo_empty_err = 1; +} + +/*------------------------------------------------------------------------------ + * DMA + *----------------------------------------------------------------------------*/ +/** + * Enable/Disable RX DMA (Peripherals->DMA->RAM) + * + * @param hw Beginning address of the peripheral registers. + * @param enable 1: enable; 2: disable + */ +static inline void spi_ll_dma_rx_enable(spi_dev_t *hw, bool enable) +{ + hw->dma_conf.dma_rx_ena = enable; +} + +/** + * Enable/Disable TX DMA (RAM->DMA->Peripherals) + * + * @param hw Beginning address of the peripheral registers. + * @param enable 1: enable; 2: disable + */ +static inline void spi_ll_dma_tx_enable(spi_dev_t *hw, bool enable) +{ + hw->dma_conf.dma_tx_ena = enable; +} + +/** + * Configuration of RX DMA EOF interrupt generation way + * + * @param hw Beginning address of the peripheral registers. + * @param enable 1: spi_dma_inlink_eof is set when the number of dma pushed data bytes is equal to the value of spi_slv/mst_dma_rd_bytelen[19:0] in spi dma transition. 0: spi_dma_inlink_eof is set by spi_trans_done in non-seg-trans or spi_dma_seg_trans_done in seg-trans. + */ +static inline void spi_ll_dma_set_rx_eof_generation(spi_dev_t *hw, bool enable) +{ + hw->dma_conf.rx_eof_en = enable; +} + +/*------------------------------------------------------------------------------ + * Buffer + *----------------------------------------------------------------------------*/ +/** + * Write to SPI hardware data buffer. + * + * @param hw Beginning address of the peripheral registers. + * @param buffer_to_send Address of the data to be written to the hardware data buffer. + * @param bitlen Length to write, in bits. + */ +static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_send, size_t bitlen) +{ + for (int x = 0; x < bitlen; x += 32) { + //Use memcpy to get around alignment issues for txdata + uint32_t word; + memcpy(&word, &buffer_to_send[x / 8], 4); + hw->data_buf[(x / 32)].buf = word; + } +} + +/** + * Write to SPI hardware data buffer by buffer ID (address) + * + * @param hw Beginning address of the peripheral registers + * @param byte_id Start ID (address) of the hardware buffer to be written + * @param data Address of the data to be written to the hardware data buffer. + * @param len Length to write, in bytes. + */ +static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len) +{ + HAL_ASSERT(byte_id + len <= 64); + HAL_ASSERT(len > 0); + HAL_ASSERT(byte_id >= 0); + + while (len > 0) { + uint32_t word; + int offset = byte_id % 4; + int copy_len = 4 - offset; + if (copy_len > len) { + copy_len = len; + } + + //read-modify-write + if (copy_len != 4) { + word = hw->data_buf[byte_id / 4].buf; //read + } + memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify + hw->data_buf[byte_id / 4].buf = word; //write + + data += copy_len; + byte_id += copy_len; + len -= copy_len; + } +} + +/** + * Read from SPI hardware data buffer. + * + * @param hw Beginning address of the peripheral registers. + * @param buffer_to_rcv Address of a buffer to read data from hardware data buffer + * @param bitlen Length to read, in bits. + */ +static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, size_t bitlen) +{ + for (int x = 0; x < bitlen; x += 32) { + //Do a memcpy to get around possible alignment issues in rx_buffer + uint32_t word = hw->data_buf[x / 32].buf; + int len = bitlen - x; + if (len > 32) { + len = 32; + } + memcpy(&buffer_to_rcv[x / 8], &word, (len + 7) / 8); + } +} + +/** + * Read from SPI hardware data buffer by buffer ID (address) + * + * @param hw Beginning address of the peripheral registers + * @param byte_id Start ID (address) of the hardware buffer to be read + * @param data Address of a buffer to read data from hardware data buffer + * @param len Length to read, in bytes. + */ +static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *out_data, int len) +{ + while (len > 0) { + uint32_t word = hw->data_buf[byte_id / 4].buf; + int offset = byte_id % 4; + int copy_len = 4 - offset; + if (copy_len > len) { + copy_len = len; + } + + memcpy(out_data, ((uint8_t *)&word) + offset, copy_len); + byte_id += copy_len; + out_data += copy_len; + len -= copy_len; + } +} + +/*------------------------------------------------------------------------------ + * Configs: mode + *----------------------------------------------------------------------------*/ +/** + * Enable/disable the postive-cs feature. + * + * @param hw Beginning address of the peripheral registers. + * @param cs One of the CS (0-2) to enable/disable the feature. + * @param pos_cs True to enable the feature, otherwise disable (default). + */ +static inline void spi_ll_master_set_pos_cs(spi_dev_t *hw, int cs, uint32_t pos_cs) +{ + if (pos_cs) { + hw->misc.master_cs_pol |= (1 << cs); + } else { + hw->misc.master_cs_pol &= ~(1 << cs); + } +} + +/** + * Enable/disable the LSBFIRST feature for TX data. + * + * @param hw Beginning address of the peripheral registers. + * @param lsbfirst True if LSB of TX data to be sent first, otherwise MSB is sent first (default). + */ +static inline void spi_ll_set_tx_lsbfirst(spi_dev_t *hw, bool lsbfirst) +{ + hw->ctrl.wr_bit_order = lsbfirst; +} + +/** + * Enable/disable the LSBFIRST feature for RX data. + * + * @param hw Beginning address of the peripheral registers. + * @param lsbfirst True if first bit received as LSB, otherwise as MSB (default). + */ +static inline void spi_ll_set_rx_lsbfirst(spi_dev_t *hw, bool lsbfirst) +{ + hw->ctrl.rd_bit_order = lsbfirst; +} + +/** + * Set SPI mode for the peripheral as master. + * + * @param hw Beginning address of the peripheral registers. + * @param mode SPI mode to work at, 0-3. + */ +static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode) +{ + //Configure polarity + if (mode == 0) { + hw->misc.ck_idle_edge = 0; + hw->user.ck_out_edge = 0; + } else if (mode == 1) { + hw->misc.ck_idle_edge = 0; + hw->user.ck_out_edge = 1; + } else if (mode == 2) { + hw->misc.ck_idle_edge = 1; + hw->user.ck_out_edge = 1; + } else if (mode == 3) { + hw->misc.ck_idle_edge = 1; + hw->user.ck_out_edge = 0; + } +} + +/** + * Set SPI mode for the peripheral as slave. + * + * @param hw Beginning address of the peripheral registers. + * @param mode SPI mode to work at, 0-3. + */ +static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma_used) +{ + if (mode == 0) { + hw->misc.ck_idle_edge = 0; + hw->user.rsck_i_edge = 0; + hw->user.tsck_i_edge = 0; + hw->slave.clk_mode_13 = 0; + } else if (mode == 1) { + hw->misc.ck_idle_edge = 0; + hw->user.rsck_i_edge = 1; + hw->user.tsck_i_edge = 1; + hw->slave.clk_mode_13 = 1; + } else if (mode == 2) { + hw->misc.ck_idle_edge = 1; + hw->user.rsck_i_edge = 1; + hw->user.tsck_i_edge = 1; + hw->slave.clk_mode_13 = 0; + } else if (mode == 3) { + hw->misc.ck_idle_edge = 1; + hw->user.rsck_i_edge = 0; + hw->user.tsck_i_edge = 0; + hw->slave.clk_mode_13 = 1; + } + hw->slave.rsck_data_out = 0; +} + +/** + * Set SPI to work in full duplex or half duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * @param half_duplex True to work in half duplex mode, otherwise in full duplex mode. + */ +static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex) +{ + hw->user.doutdin = !half_duplex; +} + +/** + * Set SPI to work in SIO mode or not. + * + * SIO is a mode which MOSI and MISO share a line. The device MUST work in half-duplexmode. + * + * @param hw Beginning address of the peripheral registers. + * @param sio_mode True to work in SIO mode, otherwise false. + */ +static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode) +{ + hw->user.sio = sio_mode; +} + +/** + * Configure the SPI transaction line mode for the master to use. + * + * @param hw Beginning address of the peripheral registers. + * @param line_mode SPI transaction line mode to use, see ``spi_line_mode_t``. + */ +static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t line_mode) +{ + hw->ctrl.val &= ~SPI_LL_ONE_LINE_CTRL_MASK; + hw->user.val &= ~SPI_LL_ONE_LINE_USER_MASK; + hw->ctrl.fcmd_dual = (line_mode.cmd_lines == 2); + hw->ctrl.fcmd_quad = (line_mode.cmd_lines == 4); + hw->ctrl.faddr_dual = (line_mode.addr_lines == 2); + hw->ctrl.faddr_quad = (line_mode.addr_lines == 4); + hw->ctrl.fread_dual = (line_mode.data_lines == 2); + hw->user.fwrite_dual = (line_mode.data_lines == 2); + hw->ctrl.fread_quad = (line_mode.data_lines == 4); + hw->user.fwrite_quad = (line_mode.data_lines == 4); +} + +/** + * Set the SPI slave to work in segment transaction mode + * + * @param hw Beginning address of the peripheral registers. + * @param seg_trans True to work in seg mode, otherwise false. + */ +static inline void spi_ll_slave_set_seg_mode(spi_dev_t *hw, bool seg_trans) +{ + hw->dma_conf.dma_slv_seg_trans_en = seg_trans; +} + +/** + * Select one of the CS to use in current transaction. + * + * @param hw Beginning address of the peripheral registers. + * @param cs_id The cs to use, 0-2, otherwise none of them is used. + */ +static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id) +{ + hw->misc.cs0_dis = (cs_id == 0) ? 0 : 1; + hw->misc.cs1_dis = (cs_id == 1) ? 0 : 1; + hw->misc.cs2_dis = (cs_id == 2) ? 0 : 1; + hw->misc.cs3_dis = (cs_id == 3) ? 0 : 1; + hw->misc.cs4_dis = (cs_id == 4) ? 0 : 1; + hw->misc.cs5_dis = (cs_id == 5) ? 0 : 1; +} + +/** + * Keep Chip Select activated after the current transaction. + * + * @param hw Beginning address of the peripheral registers. + * @param keep_active if 0 don't keep CS activated, else keep CS activated + */ +static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) +{ + hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0; +} + +/*------------------------------------------------------------------------------ + * Configs: parameters + *----------------------------------------------------------------------------*/ +/** + * Set the clock for master by stored value. + * + * @param hw Beginning address of the peripheral registers. + * @param val Stored clock configuration calculated before (by ``spi_ll_cal_clock``). + */ +static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_clock_val_t *val) +{ + hw->clock.val = *(uint32_t *)val; +} + +/** + * Get the frequency of given dividers. Don't use in app. + * + * @param fapb APB clock of the system. + * @param pre Pre devider. + * @param n Main divider. + * + * @return Frequency of given dividers. + */ +static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n) +{ + return (fapb / (pre * n)); +} + +/** + * Calculate the nearest frequency avaliable for master. + * + * @param fapb APB clock of the system. + * @param hz Frequncy desired. + * @param duty_cycle Duty cycle desired. + * @param out_reg Output address to store the calculated clock configurations for the return frequency. + * + * @return Actual (nearest) frequency. + */ +static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg) +{ + typeof(GPSPI2.clock) reg; + int eff_clk; + + //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value. + if (hz > ((fapb / 4) * 3)) { + //Using Fapb directly will give us the best result here. + reg.clkcnt_l = 0; + reg.clkcnt_h = 0; + reg.clkcnt_n = 0; + reg.clkdiv_pre = 0; + reg.clk_equ_sysclk = 1; + eff_clk = fapb; + } else { + //For best duty cycle resolution, we want n to be as close to 32 as possible, but + //we also need a pre/n combo that gets us as close as possible to the intended freq. + //To do this, we bruteforce n and calculate the best pre to go along with that. + //If there's a choice between pre/n combos that give the same result, use the one + //with the higher n. + int pre, n, h, l; + int bestn = -1; + int bestpre = -1; + int besterr = 0; + int errval; + for (n = 2; n <= 64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse. + //Effectively, this does pre=round((fapb/n)/hz). + pre = ((fapb / n) + (hz / 2)) / hz; + if (pre <= 0) { + pre = 1; + } + if (pre > 16) { + pre = 16; + } + errval = abs(spi_ll_freq_for_pre_n(fapb, pre, n) - hz); + if (bestn == -1 || errval <= besterr) { + besterr = errval; + bestn = n; + bestpre = pre; + } + } + + n = bestn; + pre = bestpre; + l = n; + //This effectively does round((duty_cycle*n)/256) + h = (duty_cycle * n + 127) / 256; + if (h <= 0) { + h = 1; + } + + reg.clk_equ_sysclk = 0; + reg.clkcnt_n = n - 1; + reg.clkdiv_pre = pre - 1; + reg.clkcnt_h = h - 1; + reg.clkcnt_l = l - 1; + eff_clk = spi_ll_freq_for_pre_n(fapb, pre, n); + } + if (out_reg != NULL) { + *(uint32_t *)out_reg = reg.val; + } + return eff_clk; +} + +/** + * Calculate and set clock for SPI master according to desired parameters. + * + * This takes long, suggest to calculate the configuration during + * initialization by ``spi_ll_master_cal_clock`` and store the result, then + * configure the clock by stored value when used by + * ``spi_ll_msater_set_clock_by_reg``. + * + * @param hw Beginning address of the peripheral registers. + * @param fapb APB clock of the system. + * @param hz Frequncy desired. + * @param duty_cycle Duty cycle desired. + * + * @return Actual frequency that is used. + */ +static inline int spi_ll_master_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle) +{ + spi_ll_clock_val_t reg_val; + int freq = spi_ll_master_cal_clock(fapb, hz, duty_cycle, ®_val); + spi_ll_master_set_clock_by_reg(hw, ®_val); + return freq; +} + +/** + * Set the mosi delay after the output edge to the signal. (Preview) + * + * The delay mode/num is a Espressif conception, may change in the new chips. + * + * @param hw Beginning address of the peripheral registers. + * @param delay_mode Delay mode, see TRM. + * @param delay_num APB clocks to delay. + */ +static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int delay_num) +{ +} + +/** + * Set the miso delay applied to the input signal before the internal peripheral. (Preview) + * + * The delay mode/num is a Espressif conception, may change in the new chips. + * + * @param hw Beginning address of the peripheral registers. + * @param delay_mode Delay mode, see TRM. + * @param delay_num APB clocks to delay. + */ +static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int delay_num) +{ +} + +/** + * Set the delay of SPI clocks before the CS inactive edge after the last SPI clock. + * + * @param hw Beginning address of the peripheral registers. + * @param hold Delay of SPI clocks after the last clock, 0 to disable the hold phase. + */ +static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold) +{ + hw->user1.cs_hold_time = hold; + hw->user.cs_hold = hold ? 1 : 0; +} + +/** + * Set the delay of SPI clocks before the first SPI clock after the CS active edge. + * + * Note ESP32 doesn't support to use this feature when command/address phases + * are used in full duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * @param setup Delay of SPI clocks after the CS active edge, 0 to disable the setup phase. + */ +static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup) +{ + hw->user1.cs_setup_time = setup - 1; + hw->user.cs_setup = setup ? 1 : 0; +} + +/*------------------------------------------------------------------------------ + * Configs: data + *----------------------------------------------------------------------------*/ +/** + * Set the output length (master). + * This should be called before master setting MISO(input) length + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen output length, in bits. + */ +static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen) +{ + if (bitlen > 0) { + hw->ms_dlen.ms_data_bitlen = bitlen - 1; + } +} + +/** + * Set the input length (master). + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen input length, in bits. + */ +static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen) +{ + if (bitlen > 0) { + hw->ms_dlen.ms_data_bitlen = bitlen - 1; + } +} + +/** + * Set the maximum input length (slave). + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Input length, in bits. + */ +static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen) +{ + //This is not used in esp32c3 +} + +/** + * Set the maximum output length (slave). + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Output length, in bits. + */ +static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen) +{ + //This is not used in esp32c3 +} + +/** + * Set the length of command phase. + * + * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit + * command phases takes 4 cycles in 4-bit mode. + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Length of command phase, in bits. 0 to disable the command phase. + */ +static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen) +{ + hw->user2.usr_command_bitlen = bitlen - 1; + hw->user.usr_command = bitlen ? 1 : 0; +} + +/** + * Set the length of address phase. + * + * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit + * address phases takes 4 cycles in 4-bit mode. + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Length of address phase, in bits. 0 to disable the address phase. + */ +static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen) +{ + hw->user1.usr_addr_bitlen = bitlen - 1; + hw->user.usr_addr = bitlen ? 1 : 0; +} + +/** + * Set the address value in an intuitive way. + * + * The length and lsbfirst is required to shift and swap the address to the right place. + * + * @param hw Beginning address of the peripheral registers. + * @param address Address to set + * @param addrlen Length of the address phase + * @param lsbfirst Whether the LSB first feature is enabled. + */ +static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen, uint32_t lsbfirst) +{ + if (lsbfirst) { + /* The output address start from the LSB of the highest byte, i.e. + * addr[24] -> addr[31] + * ... + * addr[0] -> addr[7] + * So swap the byte order to let the LSB sent first. + */ + addr = HAL_SWAP32(addr); + //otherwise only addr register is sent + hw->addr.val = addr; + } else { + // shift the address to MSB of addr register. + // output address will be sent from MSB to LSB of addr register + hw->addr.val = addr << (32 - addrlen); + } +} + +/** + * Set the command value in an intuitive way. + * + * The length and lsbfirst is required to shift and swap the command to the right place. + * + * @param hw Beginning command of the peripheral registers. + * @param command Command to set + * @param addrlen Length of the command phase + * @param lsbfirst Whether the LSB first feature is enabled. + */ +static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst) +{ + if (lsbfirst) { + // The output command start from bit0 to bit 15, kept as is. + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, cmd); + } else { + /* Output command will be sent from bit 7 to 0 of command_value, and + * then bit 15 to 8 of the same register field. Shift and swap to send + * more straightly. + */ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, HAL_SPI_SWAP_DATA_TX(cmd, cmdlen)); + } +} + +/** + * Set dummy clocks to output before RX phase (master), or clocks to skip + * before the data phase and after the address phase (slave). + * + * Note this phase is also used to compensate RX timing in half duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * @param dummy_n Dummy cycles used. 0 to disable the dummy phase. + */ +static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n) +{ + hw->user.usr_dummy = dummy_n ? 1 : 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user1, usr_dummy_cyclelen, dummy_n - 1); +} + +/** + * Enable/disable the RX data phase. + * + * @param hw Beginning address of the peripheral registers. + * @param enable True if RX phase exist, otherwise false. + */ +static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable) +{ + hw->user.usr_miso = enable; +} + +/** + * Enable/disable the TX data phase. + * + * @param hw Beginning address of the peripheral registers. + * @param enable True if TX phase exist, otherwise false. + */ +static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable) +{ + hw->user.usr_mosi = enable; +} + +/** + * Get the received bit length of the slave. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Received bits of the slave. + */ +static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw) +{ + return hw->slave1.slv_data_bitlen; +} + +/*------------------------------------------------------------------------------ + * Interrupts + *----------------------------------------------------------------------------*/ +//helper macros to generate code for each interrupts +#define FOR_EACH_ITEM(op, list) do { list(op) } while(0) +#define INTR_LIST(item) \ + item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done, dma_int_raw.trans_done, dma_int_clr.trans_done, dma_int_set.trans_done_int_set) \ + item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done, dma_int_raw.slv_rd_buf_done, dma_int_clr.slv_rd_buf_done, dma_int_set.slv_rd_buf_done_int_set) \ + item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done, dma_int_raw.slv_wr_buf_done, dma_int_clr.slv_wr_buf_done, dma_int_set.slv_wr_buf_done_int_set) \ + item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done, dma_int_raw.slv_rd_dma_done, dma_int_clr.slv_rd_dma_done, dma_int_set.slv_rd_dma_done_int_set) \ + item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done, dma_int_raw.slv_wr_dma_done, dma_int_clr.slv_wr_dma_done, dma_int_set.slv_wr_dma_done_int_set) \ + item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done, dma_int_raw.dma_seg_trans_done, dma_int_clr.dma_seg_trans_done, dma_int_set.dma_seg_trans_done_int_set) \ + item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7, dma_int_raw.slv_cmd7, dma_int_clr.slv_cmd7, dma_int_set.slv_cmd7_int_set) \ + item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8, dma_int_raw.slv_cmd8, dma_int_clr.slv_cmd8, dma_int_set.slv_cmd8_int_set) \ + item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9, dma_int_raw.slv_cmd9, dma_int_clr.slv_cmd9, dma_int_set.slv_cmd9_int_set) \ + item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda, dma_int_raw.slv_cmda, dma_int_clr.slv_cmda, dma_int_set.slv_cmda_int_set) + + +static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1; + FOR_EACH_ITEM(ENA_INTR, INTR_LIST); +#undef ENA_INTR +} + +static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0; + FOR_EACH_ITEM(DIS_INTR, INTR_LIST); +#undef DIS_INTR +} + +static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define SET_INTR(intr_bit, _, __, ___, set_reg) if (intr_mask & (intr_bit)) hw->set_reg = 1; + FOR_EACH_ITEM(SET_INTR, INTR_LIST); +#undef SET_INTR +} + +static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define CLR_INTR(intr_bit, _, __, clr_reg, ...) if (intr_mask & (intr_bit)) hw->clr_reg = 1; + FOR_EACH_ITEM(CLR_INTR, INTR_LIST); +#undef CLR_INTR +} + +static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true; + FOR_EACH_ITEM(GET_INTR, INTR_LIST); + return false; +#undef GET_INTR +} + +#undef FOR_EACH_ITEM +#undef INTR_LIST + +/** + * Disable the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_disable_int(spi_dev_t *hw) +{ + hw->dma_int_ena.trans_done = 0; +} + +/** + * Clear the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_clear_int_stat(spi_dev_t *hw) +{ + hw->dma_int_clr.trans_done = 1; +} + +/** + * Set the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_int_stat(spi_dev_t *hw) +{ + hw->dma_int_set.trans_done_int_set = 1; +} + +/** + * Enable the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_enable_int(spi_dev_t *hw) +{ + hw->dma_int_ena.trans_done = 1; +} + +/*------------------------------------------------------------------------------ + * Slave HD + *----------------------------------------------------------------------------*/ +static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask) +{ + hw->slave.slv_rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0; + hw->slave.slv_wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0; + hw->slave.slv_rddma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDDMA) ? 1 : 0; + hw->slave.slv_wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0; +} + +static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw) +{ + return hw->slave1.slv_data_bitlen / 8; +} + +static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw) +{ + return hw->slave1.slv_last_addr; +} + +#undef SPI_LL_RST_MASK +#undef SPI_LL_UNUSED_INT_MASK + +/** + * Get the base spi command + * + * @param cmd_t Command value + */ +static inline uint8_t spi_ll_get_slave_hd_base_command(spi_command_t cmd_t) +{ + uint8_t cmd_base = 0x00; + switch (cmd_t) + { + case SPI_CMD_HD_WRBUF: + cmd_base = SPI_LL_BASE_CMD_HD_WRBUF; + break; + case SPI_CMD_HD_RDBUF: + cmd_base = SPI_LL_BASE_CMD_HD_RDBUF; + break; + case SPI_CMD_HD_WRDMA: + cmd_base = SPI_LL_BASE_CMD_HD_WRDMA; + break; + case SPI_CMD_HD_RDDMA: + cmd_base = SPI_LL_BASE_CMD_HD_RDDMA; + break; + case SPI_CMD_HD_SEG_END: + cmd_base = SPI_LL_BASE_CMD_HD_SEG_END; + break; + case SPI_CMD_HD_EN_QPI: + cmd_base = SPI_LL_BASE_CMD_HD_EN_QPI; + break; + case SPI_CMD_HD_WR_END: + cmd_base = SPI_LL_BASE_CMD_HD_WR_END; + break; + case SPI_CMD_HD_INT0: + cmd_base = SPI_LL_BASE_CMD_HD_INT0; + break; + case SPI_CMD_HD_INT1: + cmd_base = SPI_LL_BASE_CMD_HD_INT1; + break; + case SPI_CMD_HD_INT2: + cmd_base = SPI_LL_BASE_CMD_HD_INT2; + break; + default: + HAL_ASSERT(cmd_base); + } + return cmd_base; +} + +/** + * Get the spi communication command + * + * @param cmd_t Base command value + * @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN. + */ +static inline uint16_t spi_ll_get_slave_hd_command(spi_command_t cmd_t, spi_line_mode_t line_mode) +{ + uint8_t cmd_base = spi_ll_get_slave_hd_base_command(cmd_t); + uint8_t cmd_mod = 0x00; //CMD:1-bit, ADDR:1-bit, DATA:1-bit + + if (line_mode.data_lines == 2) { + if (line_mode.addr_lines == 2) { + cmd_mod = 0x50; //CMD:1-bit, ADDR:2-bit, DATA:2-bit + } else { + cmd_mod = 0x10; //CMD:1-bit, ADDR:1-bit, DATA:2-bit + } + } else if (line_mode.data_lines == 4) { + if (line_mode.addr_lines == 4) { + cmd_mod = 0xA0; //CMD:1-bit, ADDR:4-bit, DATA:4-bit + } else { + cmd_mod = 0x20; //CMD:1-bit, ADDR:1-bit, DATA:4-bit + } + } + if (cmd_base == SPI_LL_BASE_CMD_HD_SEG_END || cmd_base == SPI_LL_BASE_CMD_HD_EN_QPI) { + cmd_mod = 0x00; + } + + return cmd_base | cmd_mod; +} + +/** + * Get the dummy bits + * + * @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN. + */ +static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode) +{ + return 8; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/spimem_flash_ll.h b/components/hal/esp32c6/include/hal/spimem_flash_ll.h new file mode 100644 index 000000000000..27106133fd48 --- /dev/null +++ b/components/hal/esp32c6/include/hal/spimem_flash_ll.h @@ -0,0 +1,613 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +// The Lowlevel layer for SPI Flash + +#pragma once + +#include +#include // For MIN/MAX +#include +#include + +#include "soc/spi_periph.h" +#include "soc/spi_mem_struct.h" +#include "hal/assert.h" +#include "hal/spi_types.h" +#include "hal/spi_flash_types.h" +#include "soc/pcr_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL )) +#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1) + +typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t; + +/*------------------------------------------------------------------------------ + * Control + *----------------------------------------------------------------------------*/ +/** + * Reset peripheral registers before configuration and starting control + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_reset(spi_mem_dev_t *dev) +{ + dev->user.val = 0; + dev->ctrl.val = 0; +} + +/** + * Check whether the previous operation is done. + * + * @param dev Beginning address of the peripheral registers. + * + * @return true if last command is done, otherwise false. + */ +static inline bool spimem_flash_ll_cmd_is_done(const spi_mem_dev_t *dev) +{ + return (dev->cmd.val == 0); +} + +/** + * Erase the flash chip. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_erase_chip(spi_mem_dev_t *dev) +{ + dev->cmd.flash_ce = 1; +} + +/** + * Erase the sector, the address should be set by spimem_flash_ll_set_address. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_erase_sector(spi_mem_dev_t *dev) +{ + dev->ctrl.val = 0; + dev->cmd.flash_se = 1; +} + +/** + * Erase the block, the address should be set by spimem_flash_ll_set_address. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_erase_block(spi_mem_dev_t *dev) +{ + dev->cmd.flash_be = 1; +} + +/** + * Suspend erase/program operation. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_suspend(spi_mem_dev_t *dev) +{ + dev->flash_sus_ctrl.flash_pes = 1; +} + +/** + * Resume suspended erase/program operation. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_resume(spi_mem_dev_t *dev) +{ + dev->flash_sus_ctrl.flash_per = 1; +} + +/** + * Initialize auto suspend mode, and esp32c3 doesn't support disable auto-suspend. + * + * @param dev Beginning address of the peripheral registers. + * @param auto_sus Enable/disable Flash Auto-Suspend. + */ +static inline void spimem_flash_ll_auto_suspend_init(spi_mem_dev_t *dev, bool auto_sus) +{ + dev->flash_sus_ctrl.flash_pes_en = auto_sus; +} + +/** + * Initialize auto resume mode + * + * @param dev Beginning address of the peripheral registers. + * @param auto_res Enable/Disable Flash Auto-Resume. + * + */ +static inline void spimem_flash_ll_auto_resume_init(spi_mem_dev_t *dev, bool auto_res) +{ + dev->flash_sus_ctrl.pes_per_en = auto_res; +} + +/** + * Setup the flash suspend command, may vary from chips to chips. + * + * @param dev Beginning address of the peripheral registers. + * @param sus_cmd Flash suspend command. + * + */ +static inline void spimem_flash_ll_suspend_cmd_setup(spi_mem_dev_t *dev, uint32_t sus_cmd) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, flash_pes_command, sus_cmd); +} + +/** + * Setup the flash resume command, may vary from chips to chips. + * + * @param dev Beginning address of the peripheral registers. + * @param res_cmd Flash resume command. + * + */ +static inline void spimem_flash_ll_resume_cmd_setup(spi_mem_dev_t *dev, uint32_t res_cmd) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sus_status, flash_per_command, res_cmd); +} + +/** + * Setup the flash read suspend status command, may vary from chips to chips. + * + * @param dev Beginning address of the peripheral registers. + * @param pesr_cmd Flash read suspend status command. + * + */ +static inline void spimem_flash_ll_rd_sus_cmd_setup(spi_mem_dev_t *dev, uint32_t pesr_cmd) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, wait_pesr_command, pesr_cmd); +} + +/** + * Setup to check SUS/SUS1/SUS2 to ensure the suspend status of flashs. + * + * @param dev Beginning address of the peripheral registers. + * @param sus_check_sus_en 1: enable, 0: disable. + * + */ +static inline void spimem_flash_ll_sus_check_sus_setup(spi_mem_dev_t *dev, bool sus_check_sus_en) +{ + dev->flash_sus_ctrl.sus_timeout_cnt = 5; + dev->flash_sus_ctrl.pes_end_en = sus_check_sus_en; +} + +/** + * Setup to check SUS/SUS1/SUS2 to ensure the resume status of flashs. + * + * @param dev Beginning address of the peripheral registers. + * @param sus_check_sus_en 1: enable, 0: disable. + * + */ +static inline void spimem_flash_ll_res_check_sus_setup(spi_mem_dev_t *dev, bool res_check_sus_en) +{ + dev->flash_sus_ctrl.sus_timeout_cnt = 5; + dev->flash_sus_ctrl.per_end_en = res_check_sus_en; +} + +/** + * Set 8 bit command to read suspend status + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint32_t sus_conf) +{ + dev->flash_sus_ctrl.frd_sus_2b = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf); +} + +/** + * Initialize auto wait idle mode + * + * @param dev Beginning address of the peripheral registers. + * @param auto_waiti Enable/disable auto wait-idle function + */ +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); + dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; +} + +/** + * Return the suspend status of erase or program operations. + * + * @param dev Beginning address of the peripheral registers. + * + * @return true if suspended, otherwise false. + */ +static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev) +{ + return dev->sus_status.flash_sus; +} + +/** + * Enable/disable write protection for the flash chip. + * + * @param dev Beginning address of the peripheral registers. + * @param wp true to enable the protection, false to disable (write enable). + */ +static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp) +{ + if (wp) { + dev->cmd.flash_wrdi = 1; + } else { + dev->cmd.flash_wren = 1; + } +} + +/** + * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. + * + * @param dev Beginning address of the peripheral registers. + * @param buffer Buffer to hold the output data + * @param read_len Length to get out of the buffer + */ +static inline void spimem_flash_ll_get_buffer_data(spi_mem_dev_t *dev, void *buffer, uint32_t read_len) +{ + if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) { + // If everything is word-aligned, do a faster memcpy + memcpy(buffer, (void *)dev->data_buf, read_len); + } else { + // Otherwise, slow(er) path copies word by word + int copy_len = read_len; + for (int i = 0; i < (read_len + 3) / 4; i++) { + int word_len = MIN(sizeof(uint32_t), copy_len); + uint32_t word = dev->data_buf[i]; + memcpy(buffer, &word, word_len); + buffer = (void *)((intptr_t)buffer + word_len); + copy_len -= word_len; + } + } +} + +/** + * Set the data to be written in the data buffer. + * + * @param dev Beginning address of the peripheral registers. + * @param buffer Buffer holding the data + * @param length Length of data in bytes. + */ +static inline void spimem_flash_ll_set_buffer_data(spi_mem_dev_t *dev, const void *buffer, uint32_t length) +{ + // Load data registers, word at a time + int num_words = (length + 3) / 4; + for (int i = 0; i < num_words; i++) { + uint32_t word = 0; + uint32_t word_len = MIN(length, sizeof(word)); + memcpy(&word, buffer, word_len); + dev->data_buf[i] = word; + length -= word_len; + buffer = (void *)((intptr_t)buffer + word_len); + } +} + + +/** + * Program a page of the flash chip. Call ``spimem_flash_ll_set_address`` before + * this to set the address to program. + * + * @param dev Beginning address of the peripheral registers. + * @param buffer Buffer holding the data to program + * @param length Length to program. + */ +static inline void spimem_flash_ll_program_page(spi_mem_dev_t *dev, const void *buffer, uint32_t length) +{ + dev->user.usr_dummy = 0; + spimem_flash_ll_set_buffer_data(dev, buffer, length); + dev->cmd.flash_pp = 1; +} + +/** + * Trigger a user defined transaction. All phases, including command, address, dummy, and the data phases, + * should be configured before this is called. + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev) +{ + dev->cmd.usr = 1; +} + +/** + * Check whether the host is idle to perform new commands. + * + * @param dev Beginning address of the peripheral registers. + * + * @return true if the host is idle, otherwise false + */ +static inline bool spimem_flash_ll_host_idle(const spi_mem_dev_t *dev) +{ + return dev->cmd.mst_st == 0; +} + +/** + * Set phases for user-defined transaction to read + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_read_phase(spi_mem_dev_t *dev) +{ + typeof (dev->user) user = { + .usr_command = 1, + .usr_mosi = 0, + .usr_miso = 1, + .usr_addr = 1, + }; + dev->user = user; +} +/*------------------------------------------------------------------------------ + * Configs + *----------------------------------------------------------------------------*/ +/** + * Select which pin to use for the flash + * + * @param dev Beginning address of the peripheral registers. + * @param pin Pin ID to use, 0-2. Set to other values to disable all the CS pins. + */ +static inline void spimem_flash_ll_set_cs_pin(spi_mem_dev_t *dev, int pin) +{ + dev->misc.cs0_dis = (pin == 0) ? 0 : 1; + dev->misc.cs1_dis = (pin == 1) ? 0 : 1; +} + +/** + * Set the read io mode. + * + * @param dev Beginning address of the peripheral registers. + * @param read_mode I/O mode to use in the following transactions. + */ +static inline void spimem_flash_ll_set_read_mode(spi_mem_dev_t *dev, esp_flash_io_mode_t read_mode) +{ + typeof (dev->ctrl) ctrl = dev->ctrl; + ctrl.val &= ~(SPI_MEM_FREAD_QIO_M | SPI_MEM_FREAD_QUAD_M | SPI_MEM_FREAD_DIO_M | SPI_MEM_FREAD_DUAL_M); + ctrl.val |= SPI_MEM_FASTRD_MODE_M; + switch (read_mode) { + case SPI_FLASH_FASTRD: + //the default option + break; + case SPI_FLASH_QIO: + ctrl.fread_qio = 1; + break; + case SPI_FLASH_QOUT: + ctrl.fread_quad = 1; + break; + case SPI_FLASH_DIO: + ctrl.fread_dio = 1; + break; + case SPI_FLASH_DOUT: + ctrl.fread_dual = 1; + break; + case SPI_FLASH_SLOWRD: + ctrl.fastrd_mode = 0; + break; + default: + abort(); + } + dev->ctrl = ctrl; +} + +/** + * Set clock frequency to work at. + * + * @param dev Beginning address of the peripheral registers. + * @param clock_val pointer to the clock value to set + */ +static inline void spimem_flash_ll_set_clock(spi_mem_dev_t *dev, spimem_flash_ll_clock_reg_t *clock_val) +{ + dev->clock.val = *clock_val; +} + +/** + * Set the input length, in bits. + * + * @param dev Beginning address of the peripheral registers. + * @param bitlen Length of input, in bits. + */ +static inline void spimem_flash_ll_set_miso_bitlen(spi_mem_dev_t *dev, uint32_t bitlen) +{ + dev->user.usr_miso = bitlen > 0; + dev->miso_dlen.usr_miso_bit_len = bitlen ? (bitlen - 1) : 0; +} + +/** + * Set the output length, in bits (not including command, address and dummy + * phases) + * + * @param dev Beginning address of the peripheral registers. + * @param bitlen Length of output, in bits. + */ +static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t bitlen) +{ + dev->user.usr_mosi = bitlen > 0; + dev->mosi_dlen.usr_mosi_bit_len = bitlen ? (bitlen - 1) : 0; +} + +/** + * Set the command. + * + * @param dev Beginning address of the peripheral registers. + * @param command Command to send + * @param bitlen Length of the command + */ +static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) +{ + dev->user.usr_command = 1; + typeof(dev->user2) user2 = { + .usr_command_value = command, + .usr_command_bitlen = (bitlen - 1), + }; + dev->user2 = user2; +} + +/** + * Get the address length that is set in register, in bits. + * + * @param dev Beginning address of the peripheral registers. + * + */ +static inline int spimem_flash_ll_get_addr_bitlen(spi_mem_dev_t *dev) +{ + return dev->user.usr_addr ? dev->user1.usr_addr_bitlen + 1 : 0; +} + +/** + * Set the address length to send, in bits. Should be called before commands that requires the address e.g. erase sector, read, write... + * + * @param dev Beginning address of the peripheral registers. + * @param bitlen Length of the address, in bits + */ +static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t bitlen) +{ + dev->user1.usr_addr_bitlen = (bitlen - 1); + dev->user.usr_addr = bitlen ? 1 : 0; +} + +/** + * Set extra address for bits M0-M7 in DIO/QIO mode. + * + * @param dev Beginning address of the peripheral registers. + * @param extra_addr extra address(M0-M7) to send. + */ +static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) +{ + dev->cache_fctrl.usr_addr_4byte = 0; + dev->rd_status.wb_mode = extra_addr; +} + +/** + * Set the address to send. Should be called before commands that requires the address e.g. erase sector, read, write... + * + * @param dev Beginning address of the peripheral registers. + * @param addr Address to send + */ +static inline void spimem_flash_ll_set_address(spi_mem_dev_t *dev, uint32_t addr) +{ + dev->addr = addr; +} + +/** + * Set the address to send in user mode. Should be called before commands that requires the address e.g. erase sector, read, write... + * + * @param dev Beginning address of the peripheral registers. + * @param addr Address to send + */ +static inline void spimem_flash_ll_set_usr_address(spi_mem_dev_t *dev, uint32_t addr, uint32_t bitlen) +{ + (void)bitlen; + spimem_flash_ll_set_address(dev, addr); +} + +/** + * Set the length of dummy cycles. + * + * @param dev Beginning address of the peripheral registers. + * @param dummy_n Cycles of dummy phases + */ +static inline void spimem_flash_ll_set_dummy(spi_mem_dev_t *dev, uint32_t dummy_n) +{ + dev->user.usr_dummy = dummy_n ? 1 : 0; + dev->user1.usr_dummy_cyclelen = dummy_n - 1; +} + +/** + * Set CS hold time. + * + * @param dev Beginning address of the peripheral registers. + * @param hold_n CS hold time config used by the host. + */ +static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n) +{ + dev->ctrl2.cs_hold_time = hold_n - 1; + dev->user.cs_hold = (hold_n > 0? 1: 0); +} + +static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time) +{ + dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0); + dev->ctrl2.cs_setup_time = cs_setup_time - 1; +} + +/** + * Get the spi flash source clock frequency. Used for calculating + * the divider parameters. + * + * @param None + * + * @return the frequency of spi flash clock source.(MHz) + */ +static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void) +{ + // MAY CAN IMPROVE (ONLY rc_fast case is incorrect)! + // TODO: Default is PLL480M, this is hard-coded. + // In the future, we can get the CPU clock source by calling interface. + uint8_t clock_val = 0; + + if (PCR.sysclk_conf.soc_clk_sel == 1) { + switch (PCR.mspi_clk_conf.mspi_fast_hs_div_num) { + case 3: + clock_val = 120; + break; + case 4: + clock_val = 96; + break; + case 5: + clock_val = 80; + break; + default: + HAL_ASSERT(false); + } + } else { + // If the system clock source is XTAL/FOSC + switch (PCR.mspi_clk_conf.mspi_fast_ls_div_num) { + case 0: + clock_val = 40; + break; + case 1: + clock_val = 20; + break; + case 2: + clock_val = 10; + break; + default: + HAL_ASSERT(false); + } + } + + return clock_val; +} + +/** + * Calculate spi_flash clock frequency division parameters for register. + * + * @param clkdiv frequency division factor + * + * @return Register setting for the given clock division factor. + */ +static inline uint32_t spimem_flash_ll_calculate_clock_reg(uint8_t clkdiv) +{ + uint32_t div_parameter; + // See comments of `clock` in `spi_mem_struct.h` + if (clkdiv == 1) { + div_parameter = (1 << 31); + } else { + div_parameter = ((clkdiv - 1) | (((clkdiv - 1) / 2 & 0xff) << 8 ) | (((clkdiv - 1) & 0xff) << 16)); + } + return div_parameter; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/systimer_ll.h b/components/hal/esp32c6/include/hal/systimer_ll.h new file mode 100644 index 000000000000..d7e1a05e1842 --- /dev/null +++ b/components/hal/esp32c6/include/hal/systimer_ll.h @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "soc/systimer_struct.h" +#include "soc/clk_tree_defs.h" +#include "soc/pcr_struct.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYSTIMER_LL_COUNTER_CLOCK 0 +#define SYSTIMER_LL_COUNTER_OS_TICK 1 +#define SYSTIMER_LL_ALARM_OS_TICK_CORE0 0 +#define SYSTIMER_LL_ALARM_CLOCK 2 + +// All these functions get invoked either from ISR or HAL that linked to IRAM. +// Always inline these functions even no gcc optimization is applied. + +/******************* Clock *************************/ + +__attribute__((always_inline)) static inline void systimer_ll_enable_clock(systimer_dev_t *dev, bool en) +{ + dev->conf.clk_en = en; +} + +// Set clock source: XTAL(default) or RC_FAST +static inline void systimer_ll_set_clock_source(soc_periph_systimer_clk_src_t clk_src) +{ + PCR.systimer_func_clk_conf.systimer_func_clk_sel = (clk_src == SYSTIMER_CLK_SRC_RC_FAST) ? 1 : 0; +} + +static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) +{ + return (PCR.systimer_func_clk_conf.systimer_func_clk_sel == 1) ? SYSTIMER_CLK_SRC_RC_FAST : SYSTIMER_CLK_SRC_XTAL; +} + +/********************** ETM *****************************/ + +__attribute__((always_inline)) static inline void systimer_ll_enable_etm(systimer_dev_t *dev, bool en) +{ + dev->conf.etm_en = en; +} + +/******************* Counter *************************/ + +__attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en) +{ + if (en) { + dev->conf.val |= 1 << (30 - counter_id); + } else { + dev->conf.val &= ~(1 << (30 - counter_id)); + } +} + +__attribute__((always_inline)) static inline void systimer_ll_counter_can_stall_by_cpu(systimer_dev_t *dev, uint32_t counter_id, uint32_t cpu_id, bool can) +{ + if (can) { + dev->conf.val |= 1 << ((28 - counter_id * 2) - cpu_id); + } else { + dev->conf.val &= ~(1 << ((28 - counter_id * 2) - cpu_id)); + } +} + +__attribute__((always_inline)) static inline void systimer_ll_counter_snapshot(systimer_dev_t *dev, uint32_t counter_id) +{ + dev->unit_op[counter_id].timer_unit_update = 1; +} + +__attribute__((always_inline)) static inline bool systimer_ll_is_counter_value_valid(systimer_dev_t *dev, uint32_t counter_id) +{ + return dev->unit_op[counter_id].timer_unit_value_valid; +} + +__attribute__((always_inline)) static inline void systimer_ll_set_counter_value(systimer_dev_t *dev, uint32_t counter_id, uint64_t value) +{ + dev->unit_load_val[counter_id].hi.timer_unit_load_hi = value >> 32; + dev->unit_load_val[counter_id].lo.timer_unit_load_lo = value & 0xFFFFFFFF; +} + +__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_low(systimer_dev_t *dev, uint32_t counter_id) +{ + return dev->unit_val[counter_id].lo.timer_unit_value_lo; +} + +__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_high(systimer_dev_t *dev, uint32_t counter_id) +{ + return dev->unit_val[counter_id].hi.timer_unit_value_hi; +} + +__attribute__((always_inline)) static inline void systimer_ll_apply_counter_value(systimer_dev_t *dev, uint32_t counter_id) +{ + dev->unit_load[counter_id].val = 0x01; +} + +/******************* Alarm *************************/ + +__attribute__((always_inline)) static inline void systimer_ll_set_alarm_target(systimer_dev_t *dev, uint32_t alarm_id, uint64_t value) +{ + dev->target_val[alarm_id].hi.timer_target_hi = value >> 32; + dev->target_val[alarm_id].lo.timer_target_lo = value & 0xFFFFFFFF; +} + +__attribute__((always_inline)) static inline uint64_t systimer_ll_get_alarm_target(systimer_dev_t *dev, uint32_t alarm_id) +{ + return ((uint64_t)(dev->target_val[alarm_id].hi.timer_target_hi) << 32) | dev->target_val[alarm_id].lo.timer_target_lo; +} + +__attribute__((always_inline)) static inline void systimer_ll_connect_alarm_counter(systimer_dev_t *dev, uint32_t alarm_id, uint32_t counter_id) +{ + dev->target_conf[alarm_id].target_timer_unit_sel = counter_id; +} + +__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_oneshot(systimer_dev_t *dev, uint32_t alarm_id) +{ + dev->target_conf[alarm_id].target_period_mode = 0; +} + +__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_period(systimer_dev_t *dev, uint32_t alarm_id) +{ + dev->target_conf[alarm_id].target_period_mode = 1; +} + +__attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(systimer_dev_t *dev, uint32_t alarm_id, uint32_t period) +{ + HAL_ASSERT(period < (1 << 26)); + dev->target_conf[alarm_id].target_period = period; +} + +__attribute__((always_inline)) static inline uint32_t systimer_ll_get_alarm_period(systimer_dev_t *dev, uint32_t alarm_id) +{ + return dev->target_conf[alarm_id].target_period; +} + +__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id) +{ + dev->comp_load[alarm_id].val = 0x01; +} + +__attribute__((always_inline)) static inline void systimer_ll_enable_alarm(systimer_dev_t *dev, uint32_t alarm_id, bool en) +{ + if (en) { + dev->conf.val |= 1 << (24 - alarm_id); + } else { + dev->conf.val &= ~(1 << (24 - alarm_id)); + } +} + +/******************* Interrupt *************************/ + +__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_int(systimer_dev_t *dev, uint32_t alarm_id, bool en) +{ + if (en) { + dev->int_ena.val |= 1 << alarm_id; + } else { + dev->int_ena.val &= ~(1 << alarm_id); + } +} + +__attribute__((always_inline)) static inline bool systimer_ll_is_alarm_int_fired(systimer_dev_t *dev, uint32_t alarm_id) +{ + return dev->int_st.val & (1 << alarm_id); +} + +__attribute__((always_inline)) static inline void systimer_ll_clear_alarm_int(systimer_dev_t *dev, uint32_t alarm_id) +{ + dev->int_clr.val |= 1 << alarm_id; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/temperature_sensor_ll.h b/components/hal/esp32c6/include/hal/temperature_sensor_ll.h new file mode 100644 index 000000000000..b50ef578f02b --- /dev/null +++ b/components/hal/esp32c6/include/hal/temperature_sensor_ll.h @@ -0,0 +1,237 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in component/hal/readme.md + ******************************************************************************/ + +// The LL for temperature sensor + +#pragma once + +#include +#include +#include "hal/regi2c_ctrl.h" +#include "soc/regi2c_saradc.h" +#include "soc/apb_saradc_struct.h" +#include "soc/apb_saradc_reg.h" +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/pcr_struct.h" +#include "hal/temperature_sensor_types.h" +#include "hal/assert.h" +#include "hal/misc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEMPERATURE_SENSOR_LL_ADC_FACTOR (0.4386) +#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88) +#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52) +#define TEMPERATURE_SENSOR_LL_MEASURE_MAX (125) +#define TEMPERATURE_SENSOR_LL_MEASURE_MIN (-40) + +#define TEMPERATURE_SENSOR_LL_INTR_MASK APB_SARADC_APB_SARADC_TSENS_INT_ST + +typedef enum { + TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE = 0, + TEMPERATURE_SENSOR_LL_WAKE_DELTA = 1, +} temperature_sensor_ll_wakeup_mode_t; + +/** + * @brief Enable the temperature sensor power. + * + * @param enable true: enable the power. + */ +static inline void temperature_sensor_ll_enable(bool enable) +{ + APB_SARADC.saradc_apb_tsens_ctrl.saradc_tsens_pu = enable; +} + +/** + * @brief Enable the clock + */ +static inline void temperature_sensor_ll_clk_enable(bool enable) +{ + // clock enable duplicated with periph enable, no need to enable it again. +} + +/** + * @brief Select the clock source for temperature sensor. On ESP32-C6, temperautre sensor + * can use XTAL or FOSC. To make it convenience, suggest using XTAL all the time. + * + * @param clk_src refer to ``temperature_sensor_clk_src_t`` + */ +static inline void temperature_sensor_ll_clk_sel(temperature_sensor_clk_src_t clk_src) +{ + uint8_t clk_sel = 0; + switch (clk_src) { + case TEMPERATURE_SENSOR_CLK_SRC_XTAL: + clk_sel = 1; + break; + case TEMPERATURE_SENSOR_CLK_SRC_RC_FAST: + clk_sel = 0; + break; + default: + HAL_ASSERT(false); + break; + } + PCR.tsens_clk_conf.tsens_clk_sel = clk_sel; +} + +/** + * @brief Set the hardware range, you can refer to the table ``temperature_sensor_attributes`` + * + * @param tsens_dac ``reg_val`` in table ``temperature_sensor_attributes`` + */ +static inline void temperature_sensor_ll_set_range(uint32_t range) +{ + REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, range); +} + +/** + * @brief Get the raw value of temperature sensor. + * + * @return uint32_t raw_value + */ +__attribute__((always_inline)) +static inline uint32_t temperature_sensor_ll_get_raw_value(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.saradc_apb_tsens_ctrl, saradc_tsens_out); +} + +/** + * @brief Get the offset value of temperature sensor. + * + * @note This function is only used in legacy driver + * + * @return uint32_t offset value + */ +static inline uint32_t temperature_sensor_ll_get_offset(void) +{ + return REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC); +} + +/** + * @brief Get the clock division factor value. + * + * @note This function is only used in legacy driver + * + * @return uint32_t clock division factor + */ +static inline uint32_t temperature_sensor_ll_get_clk_div(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.saradc_apb_tsens_ctrl, saradc_tsens_clk_div); +} + +/** + * @brief Set the clock division factor value, actually this has no impact on temperature sensor. + * Suggest just keep it as default value 6. + * + * @note This function is only used in legacy driver + * + * @param clk_div clock division factor, range from 1-10 + */ +static inline void temperature_sensor_ll_set_clk_div(uint8_t clk_div) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_apb_tsens_ctrl, saradc_tsens_clk_div, clk_div); +} + +/** + * @brief Choose the wake-up mode for temperature sensor + * + * @note ESP32-C6 does not support difference mode. + * + * @param mode 0: Absolute value mode. 1: Difference mode. + */ +static inline void temperature_sensor_ll_wakeup_mode(uint8_t mode) +{ + APB_SARADC.tsens_wake.saradc_wakeup_mode = mode; +} + +/** + * @brief Configure whether to enable temperature sensor wake up + * + * @param en true: enable, false: disable. + */ +static inline void temperature_sensor_ll_wakeup_enable(bool en) +{ + APB_SARADC.tsens_wake.saradc_wakeup_en = en; +} + +/** + * @brief Configures the low threshold for temperature sensor to wakeup + * + * @param th_low low threshold value. + */ +static inline void temperature_sensor_ll_set_th_low_val(uint8_t th_low) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.tsens_wake, saradc_wakeup_th_low, th_low); +} + +/** + * @brief Configures the high threshold for temperature sensor to wakeup + * + * @param th_high high threshold value. + */ +static inline void temperature_sensor_ll_set_th_high_val(uint8_t th_high) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.tsens_wake, saradc_wakeup_th_high, th_high); +} + +/** + * @brief Enable temperature sensor interrupt + * + * @param enable true: enable. false: disable + */ +static inline void temperature_sensor_ll_enable_intr(bool enable) +{ + APB_SARADC.saradc_int_ena.saradc_apb_saradc_tsens_int_ena = enable; +} + +/** + * @brief Clear temperature sensor interrupt + */ +__attribute__((always_inline)) +static inline void temperature_sensor_ll_clear_intr(void) +{ + APB_SARADC.saradc_int_clr.saradc_apb_saradc_tsens_int_clr = 1; +} + +/** + * @brief Get temperature sensor interrupt status. + */ +static inline volatile void *temperature_sensor_ll_get_intr_status(void) +{ + return &APB_SARADC.saradc_int_st; +} + +/** + * @brief Configure whether to enable hardware sampling + * + * @param en true: enable, false: disable + */ +static inline void temperature_sensor_ll_sample_enable(bool en) +{ + APB_SARADC.tsens_sample.saradc_tsens_sample_en = en; +} + +/** + * @brief Configures the hardware sampling rate + * + * @param rate sampling rate + */ +static inline void temperature_sensor_ll_set_sample_rate(uint16_t rate) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.tsens_sample, saradc_tsens_sample_rate, rate); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/timer_ll.h b/components/hal/esp32c6/include/hal/timer_ll.h new file mode 100644 index 000000000000..592cf60e6c35 --- /dev/null +++ b/components/hal/esp32c6/include/hal/timer_ll.h @@ -0,0 +1,336 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/timer_types.h" +#include "soc/timer_group_struct.h" +#include "soc/pcr_struct.h" +#include "soc/soc_etm_source.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Get timer group register base address with giving group number +#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1)) +#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) + +#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \ + (uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \ + [GPTIMER_ETM_TASK_START_COUNT] = TIMER0_TASK_CNT_START_TIMER0, \ + [GPTIMER_ETM_TASK_STOP_COUNT] = TIMER0_TASK_CNT_STOP_TIMER0, \ + [GPTIMER_ETM_TASK_EN_ALARM] = TIMER0_TASK_ALARM_START_TIMER0, \ + [GPTIMER_ETM_TASK_RELOAD] = TIMER0_TASK_CNT_RELOAD_TIMER0, \ + [GPTIMER_ETM_TASK_CAPTURE] = TIMER0_TASK_CNT_CAP_TIMER0, \ + }}, \ + {{ \ + [GPTIMER_ETM_TASK_START_COUNT] = TIMER1_TASK_CNT_START_TIMER0, \ + [GPTIMER_ETM_TASK_STOP_COUNT] = TIMER1_TASK_CNT_STOP_TIMER0, \ + [GPTIMER_ETM_TASK_EN_ALARM] = TIMER1_TASK_ALARM_START_TIMER0, \ + [GPTIMER_ETM_TASK_RELOAD] = TIMER1_TASK_CNT_RELOAD_TIMER0, \ + [GPTIMER_ETM_TASK_CAPTURE] = TIMER1_TASK_CNT_CAP_TIMER0, \ + }}, \ + }[group][timer][task] + +#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \ + (uint32_t [2][1][GPTIMER_ETM_EVENT_MAX]){{{ \ + [GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER0_EVT_CNT_CMP_TIMER0, \ + }}, \ + {{ \ + [GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER1_EVT_CNT_CMP_TIMER0, \ + }}, \ + }[group][timer][event] + +/** + * @brief Set clock source for timer + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param clk_src Clock source + */ +static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src) +{ + (void)timer_num; // only one timer in each group + uint8_t clk_id = 0; + switch (clk_src) { + case GPTIMER_CLK_SRC_XTAL: + clk_id = 0; + break; + case GPTIMER_CLK_SRC_PLL_F80M: + clk_id = 1; + break; + case GPTIMER_CLK_SRC_RC_FAST: + clk_id = 2; + break; + default: + HAL_ASSERT(false); + break; + } + if (hw == &TIMERG0) { + PCR.timergroup0_timer_clk_conf.tg0_timer_clk_sel = clk_id; + } else { + PCR.timergroup1_timer_clk_conf.tg1_timer_clk_sel = clk_id; + } +} + +/** + * @brief Enable Timer Group (GPTimer) module clock + * + * @param hw Timer Group register base address + * @param timer_num Timer index in the group + * @param en true to enable, false to disable + */ +static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en) +{ + (void)timer_num; // only one timer in each group + if (hw == &TIMERG0) { + PCR.timergroup0_timer_clk_conf.tg0_timer_clk_en = en; + } else { + PCR.timergroup1_timer_clk_conf.tg1_timer_clk_en = en; + } +} + +/** + * @brief Enable alarm event + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param en True: enable alarm + * False: disable alarm + */ +__attribute__((always_inline)) +static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en) +{ + hw->hw_timer[timer_num].config.tx_alarm_en = en; +} + +/** + * @brief Set clock prescale for timer + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param divider Prescale value (0 and 1 are not valid) + */ +static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider) +{ + HAL_ASSERT(divider >= 2 && divider <= 65536); + if (divider >= 65536) { + divider = 0; + } + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider); + hw->hw_timer[timer_num].config.tx_divcnt_rst = 1; +} + +/** + * @brief Enable auto-reload mode + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param en True: enable auto reload mode + * False: disable auto reload mode + */ +__attribute__((always_inline)) +static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en) +{ + hw->hw_timer[timer_num].config.tx_autoreload = en; +} + +/** + * @brief Set count direction + * + * @param hw Timer peripheral register base address + * @param timer_num Timer number in the group + * @param direction Count direction + */ +static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction) +{ + hw->hw_timer[timer_num].config.tx_increase = (direction == GPTIMER_COUNT_UP); +} + +/** + * @brief Enable timer, start couting + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param en True: enable the counter + * False: disable the counter + */ +__attribute__((always_inline)) +static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en) +{ + hw->hw_timer[timer_num].config.tx_en = en; +} + +/** + * @brief Trigger software capture event + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + */ +__attribute__((always_inline)) +static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num) +{ + hw->hw_timer[timer_num].update.tx_update = 1; + // Timer register is in a different clock domain from Timer hardware logic + // We need to wait for the update to take effect before fetching the count value + while (hw->hw_timer[timer_num].update.tx_update) { + } +} + +/** + * @brief Get counter value + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * + * @return counter value + */ +__attribute__((always_inline)) +static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num) +{ + return ((uint64_t)hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo); +} + +/** + * @brief Set alarm value + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param alarm_value When counter reaches alarm value, alarm event will be triggered + */ +__attribute__((always_inline)) +static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value) +{ + hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t)(alarm_value >> 32); + hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t)alarm_value; +} + +/** + * @brief Set reload value + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @param reload_val Reload counter value + */ +__attribute__((always_inline)) +static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t reload_val) +{ + hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t)(reload_val >> 32); + hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t)reload_val; +} + +/** + * @brief Get reload value + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + * @return reload count value + */ +__attribute__((always_inline)) +static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) +{ + return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); +} + +/** + * @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately + * + * @param hw Timer Group register base address + * @param timer_num Timer number in the group + */ +__attribute__((always_inline)) +static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) +{ + hw->hw_timer[timer_num].load.tx_load = 1; +} + +/** + * @brief Enable ETM module + * + * @param hw Timer Group register base address + * @param en True: enable ETM module, False: disable ETM module + */ +static inline void timer_ll_enable_etm(timg_dev_t *hw, bool en) +{ + hw->regclk.etm_en = en; +} + +/** + * @brief Enable timer interrupt by mask + * + * @param hw Timer Group register base address + * @param mask Mask of interrupt events + * @param en True: enable interrupt + * False: disable interrupt + */ +__attribute__((always_inline)) +static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en) +{ + if (en) { + hw->int_ena_timers.val |= mask; + } else { + hw->int_ena_timers.val &= ~mask; + } +} + +/** + * @brief Get interrupt status + * + * @param hw Timer Group register base address + * + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw) +{ + return hw->int_st_timers.val & 0x01; +} + +/** + * @brief Clear interrupt status by mask + * + * @param hw Timer Group register base address + * @param mask Interrupt events mask + */ +__attribute__((always_inline)) +static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask) +{ + hw->int_clr_timers.val = mask; +} + +/** + * @brief Enable the register clock forever + * + * @param hw Timer Group register base address + * @param en True: Enable the register clock forever + * False: Register clock is enabled only when register operation happens + */ +static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en) +{ + hw->regclk.clk_en = en; +} + +/** + * @brief Get interrupt status register address + * + * @param hw Timer Group register base address + * + * @return Interrupt status register address + */ +static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw) +{ + return &hw->int_st_timers; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/twai_ll.h b/components/hal/esp32c6/include/hal/twai_ll.h new file mode 100644 index 000000000000..6b3a9d862567 --- /dev/null +++ b/components/hal/esp32c6/include/hal/twai_ll.h @@ -0,0 +1,761 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The Lowlevel layer for TWAI + +#pragma once + +#include +#include +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/twai_types.h" +#include "soc/twai_struct.h" +#include "soc/pcr_struct.h" + +#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : (&TWAI1)) + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------- Defines and Typedefs --------------------------- */ + +#define TWAI_LL_STATUS_RBS (0x1 << 0) //Receive Buffer Status +#define TWAI_LL_STATUS_DOS (0x1 << 1) //Data Overrun Status +#define TWAI_LL_STATUS_TBS (0x1 << 2) //Transmit Buffer Status +#define TWAI_LL_STATUS_TCS (0x1 << 3) //Transmission Complete Status +#define TWAI_LL_STATUS_RS (0x1 << 4) //Receive Status +#define TWAI_LL_STATUS_TS (0x1 << 5) //Transmit Status +#define TWAI_LL_STATUS_ES (0x1 << 6) //Error Status +#define TWAI_LL_STATUS_BS (0x1 << 7) //Bus Status +#define TWAI_LL_STATUS_MS (0x1 << 8) //Miss Status + +#define TWAI_LL_INTR_RI (0x1 << 0) //Receive Interrupt +#define TWAI_LL_INTR_TI (0x1 << 1) //Transmit Interrupt +#define TWAI_LL_INTR_EI (0x1 << 2) //Error Interrupt +//Data overrun interrupt not supported in SW due to HW peculiarities +#define TWAI_LL_INTR_EPI (0x1 << 5) //Error Passive Interrupt +#define TWAI_LL_INTR_ALI (0x1 << 6) //Arbitration Lost Interrupt +#define TWAI_LL_INTR_BEI (0x1 << 7) //Bus Error Interrupt +#define TWAI_LL_INTR_BISI (0x1 << 8) //Bus Idle Status Interrupt + +/* + * The following frame structure has an NEARLY identical bit field layout to + * each byte of the TX buffer. This allows for formatting and parsing frames to + * be done outside of time critical regions (i.e., ISRs). All the ISR needs to + * do is to copy byte by byte to/from the TX/RX buffer. The two reserved bits in + * TX buffer are used in the frame structure to store the self_reception and + * single_shot flags which in turn indicate the type of transmission to execute. + */ +typedef union { + struct { + struct { + uint8_t dlc: 4; //Data length code (0 to 8) of the frame + uint8_t self_reception: 1; //This frame should be transmitted using self reception command + uint8_t single_shot: 1; //This frame should be transmitted using single shot command + uint8_t rtr: 1; //This frame is a remote transmission request + uint8_t frame_format: 1; //Format of the frame (1 = extended, 0 = standard) + }; + union { + struct { + uint8_t id[2]; //11 bit standard frame identifier + uint8_t data[8]; //Data bytes (0 to 8) + uint8_t reserved8[2]; + } standard; + struct { + uint8_t id[4]; //29 bit extended frame identifier + uint8_t data[8]; //Data bytes (0 to 8) + } extended; + }; + }; + uint8_t bytes[13]; +} __attribute__((packed)) twai_ll_frame_buffer_t; + +_Static_assert(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type should be 13 bytes"); + +/* ---------------------------- Peripheral Control Register ----------------- */ + +/** + * @brief Enable TWAI module clock + * + * @param hw Start address of the TWAI registers + * @param en true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +{ + if (hw == &TWAI0) { + PCR.twai0_func_clk_conf.twai0_func_clk_en = en; + } else { + PCR.twai1_func_clk_conf.twai1_func_clk_en = en; + } +} + +/** + * @brief Set clock source for TWAI module + * + * @param hw Start address of the TWAI registers + * @param clk_src Clock source + */ +__attribute__((always_inline)) +static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +{ + uint32_t clk_id = 0; + bool valid = true; + + switch (clk_src) { + case TWAI_CLK_SRC_XTAL: + clk_id = 0; + break; + default: + valid = false; + HAL_ASSERT(false); + } + + if (valid) { + if (hw == &TWAI0) { + PCR.twai0_func_clk_conf.twai0_func_clk_sel = clk_id; + } else { + PCR.twai1_func_clk_conf.twai1_func_clk_sel = clk_id; + } + } +} + +/* ---------------------------- Mode Register ------------------------------- */ + +/** + * @brief Enter reset mode + * + * When in reset mode, the TWAI controller is effectively disconnected from the + * TWAI bus and will not participate in any bus activates. Reset mode is required + * in order to write the majority of configuration registers. + * + * @param hw Start address of the TWAI registers + * + * @note Reset mode is automatically entered on BUS OFF condition + */ +__attribute__((always_inline)) +static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) +{ + hw->mode.reset_mode = 1; +} + +/** + * @brief Exit reset mode + * + * When not in reset mode, the TWAI controller will take part in bus activities + * (e.g., send/receive/acknowledge messages and error frames) depending on the + * operating mode. + * + * @param hw Start address of the TWAI registers + * + * @note Reset mode must be exit to initiate BUS OFF recovery + */ +__attribute__((always_inline)) +static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) +{ + hw->mode.reset_mode = 0; +} + +/** + * @brief Check if in reset mode + * @param hw Start address of the TWAI registers + * @return true if in reset mode + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw) +{ + return hw->mode.reset_mode; +} + +/** + * @brief Set operating mode of TWAI controller + * + * @param hw Start address of the TWAI registers + * @param mode Operating mode + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode) +{ + if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 0; + } else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack) + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 1; + } else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode + hw->mode.listen_only_mode = 1; + hw->mode.self_test_mode = 0; + } +} + +/* --------------------------- Command Register ----------------------------- */ + +/** + * @brief Set TX command + * + * Setting the TX command will cause the TWAI controller to attempt to transmit + * the frame stored in the TX buffer. The TX buffer will be occupied (i.e., + * locked) until TX completes. + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) +{ + hw->cmd.tx_request = 1; +} + +/** + * @brief Set single shot TX command + * + * Similar to setting TX command, but the TWAI controller will not automatically + * retry transmission upon an error (e.g., due to an acknowledgement error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) +{ + hw->cmd.val = 0x03; //Set cmd.tx_request and cmd.abort_tx simultaneously for single shot transmitting request +} + +/** + * @brief Aborts TX + * + * Frames awaiting TX will be aborted. Frames already being TX are not aborted. + * Transmission Complete Status bit is automatically set to 1. + * Similar to setting TX command, but the TWAI controller will not automatically + * retry transmission upon an error (e.g., due to acknowledge error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw) +{ + hw->cmd.abort_tx = 1; +} + +/** + * @brief Release RX buffer + * + * Rotates RX buffer to the next frame in the RX FIFO. + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw) +{ + hw->cmd.release_buffer = 1; +} + +/** + * @brief Clear data overrun + * + * Clears the data overrun status bit + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw) +{ + hw->cmd.clear_data_overrun = 1; +} + +/** + * @brief Set self reception single shot command + * + * Similar to setting TX command, but the TWAI controller also simultaneously + * receive the transmitted frame and is generally used for self testing + * purposes. The TWAI controller will not ACK the received message, so consider + * using the NO_ACK operating mode. + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) +{ + hw->cmd.self_rx_request = 1; +} + +/** + * @brief Set self reception request command + * + * Similar to setting the self reception request, but the TWAI controller will + * not automatically retry transmission upon an error (e.g., due to and + * acknowledgement error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) +{ + hw->cmd.val = 0x12; //Set cmd.self_rx_request and cmd.abort_tx simultaneously for single shot self reception request +} + +/* --------------------------- Status Register ------------------------------ */ + +/** + * @brief Get all status bits + * + * @param hw Start address of the TWAI registers + * @return Status bits + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_status(twai_dev_t *hw) +{ + return hw->status.val; +} + +/** + * @brief Check if RX FIFO overrun status bit is set + * + * @param hw Start address of the TWAI registers + * @return Overrun status bit + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw) +{ + return hw->status.status_overrun; +} + +/** + * @brief Check if previously TX was successful + * + * @param hw Start address of the TWAI registers + * @return Whether previous TX was successful + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) +{ + return hw->status.status_transmission_complete; +} + +/* -------------------------- Interrupt Register ---------------------------- */ + +/** + * @brief Get currently set interrupts + * + * Reading the interrupt registers will automatically clear all interrupts + * except for the Receive Interrupt. + * + * @param hw Start address of the TWAI registers + * @return Bit mask of set interrupts + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) +{ + return hw->interrupt.val; +} + +/* ----------------------- Interrupt Enable Register ------------------------ */ + +/** + * @brief Set which interrupts are enabled + * + * @param hw Start address of the TWAI registers + * @param Bit mask of interrupts to enable + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) +{ + hw->interrupt_enable.val = intr_mask; +} + +/* ------------------------ Bus Timing Registers --------------------------- */ + +/** + * @brief Check if the brp value valid + * + * @param brp Bit rate prescaler value + * @return true or False + */ +__attribute__((always_inline)) +static inline bool twai_ll_check_brp_validation(uint32_t brp) +{ + bool valid = (brp >= SOC_TWAI_BRP_MIN) && (brp <= SOC_TWAI_BRP_MAX); + // should be an even number + valid = valid && !(brp & 0x01); + return valid; +} + +/** + * @brief Set bus timing + * + * @param hw Start address of the TWAI registers + * @param brp Baud Rate Prescaler + * @param sjw Synchronization Jump Width + * @param tseg1 Timing Segment 1 + * @param tseg2 Timing Segment 2 + * @param triple_sampling Triple Sampling enable/disable + * + * @note Must be called in reset mode + * @note ESP32C6 brp can be any even number between 2 to 32768 + */ +__attribute__((always_inline)) +static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling) +{ + hw->bus_timing_0.baud_presc = (brp / 2) - 1; + hw->bus_timing_0.sync_jump_width = sjw - 1; + hw->bus_timing_1.time_segment1 = tseg1 - 1; + hw->bus_timing_1.time_segment2 = tseg2 - 1; + hw->bus_timing_1.time_sampling = triple_sampling; +} + +/* ----------------------------- ALC Register ------------------------------- */ + +/** + * @brief Clear Arbitration Lost Capture Register + * + * Reading the ALC register rearms the Arbitration Lost Interrupt + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) +{ + (void)hw->arb_lost_cap.val; +} + +/* ----------------------------- ECC Register ------------------------------- */ + +/** + * @brief Clear Error Code Capture register + * + * Reading the ECC register rearms the Bus Error Interrupt + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) +{ + (void)hw->err_code_cap.val; +} + +/* ----------------------------- EWL Register ------------------------------- */ + +/** + * @brief Set Error Warning Limit + * + * @param hw Start address of the TWAI registers + * @param ewl Error Warning Limit + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->err_warning_limit, err_warning_limit, ewl); +} + +/** + * @brief Get Error Warning Limit + * + * @param hw Start address of the TWAI registers + * @return Error Warning Limit + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw) +{ + return hw->err_warning_limit.val; +} + +/* ------------------------ RX Error Count Register ------------------------- */ + +/** + * @brief Get RX Error Counter + * + * @param hw Start address of the TWAI registers + * @return REC value + * + * @note REC is not frozen in reset mode. Listen only mode will freeze it. A BUS + * OFF condition automatically sets the REC to 0. + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_rec(twai_dev_t *hw) +{ + return hw->rx_err_cnt.val; +} + +/** + * @brief Set RX Error Counter + * + * @param hw Start address of the TWAI registers + * @param rec REC value + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_err_cnt, rx_err_cnt, rec); +} + +/* ------------------------ TX Error Count Register ------------------------- */ + +/** + * @brief Get TX Error Counter + * + * @param hw Start address of the TWAI registers + * @return TEC value + * + * @note A BUS OFF condition will automatically set this to 128 + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_tec(twai_dev_t *hw) +{ + return hw->tx_err_cnt.val; +} + +/** + * @brief Set TX Error Counter + * + * @param hw Start address of the TWAI registers + * @param tec TEC value + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_err_cnt, tx_err_cnt, tec); +} + +/* ---------------------- Acceptance Filter Registers ----------------------- */ + +/** + * @brief Set Acceptance Filter + * @param hw Start address of the TWAI registers + * @param code Acceptance Code + * @param mask Acceptance Mask + * @param single_filter Whether to enable single filter mode + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_acc_filter(twai_dev_t *hw, uint32_t code, uint32_t mask, bool single_filter) +{ + uint32_t code_swapped = HAL_SWAP32(code); + uint32_t mask_swapped = HAL_SWAP32(mask); + for (int i = 0; i < 4; i++) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.acr[i], byte, ((code_swapped >> (i * 8)) & 0xFF)); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.amr[i], byte, ((mask_swapped >> (i * 8)) & 0xFF)); + } + hw->mode.acceptance_filter_mode = single_filter; +} + +/* ------------------------- TX/RX Buffer Registers ------------------------- */ + +/** + * @brief Copy a formatted TWAI frame into TX buffer for transmission + * + * @param hw Start address of the TWAI registers + * @param tx_frame Pointer to formatted frame + * + * @note Call twai_ll_format_frame_buffer() to format a frame + */ +__attribute__((always_inline)) +static inline void twai_ll_set_tx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *tx_frame) +{ + //Copy formatted frame into TX buffer + for (int i = 0; i < 13; i++) { + hw->tx_rx_buffer[i].val = tx_frame->bytes[i]; + } +} + +/** + * @brief Copy a received frame from the RX buffer for parsing + * + * @param hw Start address of the TWAI registers + * @param rx_frame Pointer to store formatted frame + * + * @note Call twai_ll_parse_frame_buffer() to parse the formatted frame + */ +__attribute__((always_inline)) +static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *rx_frame) +{ + //Copy RX buffer registers into frame + for (int i = 0; i < 13; i++) { + rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte); + } +} + +/** + * @brief Format contents of a TWAI frame into layout of TX Buffer + * + * This function encodes a message into a frame structure. The frame structure + * has an identical layout to the TX buffer, allowing the frame structure to be + * directly copied into TX buffer. + * + * @param[in] 11bit or 29bit ID + * @param[in] dlc Data length code + * @param[in] data Pointer to an 8 byte array containing data. NULL if no data + * @param[in] format Type of TWAI frame + * @param[in] single_shot Frame will not be retransmitted on failure + * @param[in] self_rx Frame will also be simultaneously received + * @param[out] tx_frame Pointer to store formatted frame + */ +__attribute__((always_inline)) +static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const uint8_t *data, + uint32_t flags, twai_ll_frame_buffer_t *tx_frame) +{ + bool is_extd = flags & TWAI_MSG_FLAG_EXTD; + bool is_rtr = flags & TWAI_MSG_FLAG_RTR; + + //Set frame information + tx_frame->dlc = dlc; + tx_frame->frame_format = is_extd; + tx_frame->rtr = is_rtr; + tx_frame->self_reception = (flags & TWAI_MSG_FLAG_SELF) ? 1 : 0; + tx_frame->single_shot = (flags & TWAI_MSG_FLAG_SS) ? 1 : 0; + + //Set ID. The ID registers are big endian and left aligned, therefore a bswap will be required + if (is_extd) { + uint32_t id_temp = HAL_SWAP32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i)) + for (int i = 0; i < 4; i++) { + tx_frame->extended.id[i] = (id_temp >> (8 * i)) & 0xFF; + } + } else { + uint32_t id_temp = HAL_SWAP16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i)) + for (int i = 0; i < 2; i++) { + tx_frame->standard.id[i] = (id_temp >> (8 * i)) & 0xFF; + } + } + + uint8_t *data_buffer = (is_extd) ? tx_frame->extended.data : tx_frame->standard.data; + if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not a remote frame) + for (int i = 0; (i < dlc) && (i < TWAI_FRAME_MAX_DLC); i++) { + data_buffer[i] = data[i]; + } + } +} + +/** + * @brief Parse formatted TWAI frame (RX Buffer Layout) into its constituent contents + * + * @param[in] rx_frame Pointer to formatted frame + * @param[out] id 11 or 29bit ID + * @param[out] dlc Data length code + * @param[out] data Data. Left over bytes set to 0. + * @param[out] format Type of TWAI frame + */ +__attribute__((always_inline)) +static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc, + uint8_t *data, uint32_t *flags) +{ + //Copy frame information + *dlc = rx_frame->dlc; + uint32_t flags_temp = 0; + flags_temp |= (rx_frame->frame_format) ? TWAI_MSG_FLAG_EXTD : 0; + flags_temp |= (rx_frame->rtr) ? TWAI_MSG_FLAG_RTR : 0; + flags_temp |= (rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_MSG_FLAG_DLC_NON_COMP : 0; + *flags = flags_temp; + + //Copy ID. The ID registers are big endian and left aligned, therefore a bswap will be required + if (rx_frame->frame_format) { + uint32_t id_temp = 0; + for (int i = 0; i < 4; i++) { + id_temp |= rx_frame->extended.id[i] << (8 * i); + } + id_temp = HAL_SWAP32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3) + *id = id_temp & TWAI_EXTD_ID_MASK; + } else { + uint32_t id_temp = 0; + for (int i = 0; i < 2; i++) { + id_temp |= rx_frame->standard.id[i] << (8 * i); + } + id_temp = HAL_SWAP16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5) + *id = id_temp & TWAI_STD_ID_MASK; + } + + uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data; + //Only copy data if the frame is a data frame (i.e. not a remote frame) + int data_length = (rx_frame->rtr) ? 0 : ((rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_FRAME_MAX_DLC : rx_frame->dlc); + for (int i = 0; i < data_length; i++) { + data[i] = data_buffer[i]; + } + //Set remaining bytes of data to 0 + for (int i = data_length; i < TWAI_FRAME_MAX_DLC; i++) { + data[i] = 0; + } +} + +/* ----------------------- RX Message Count Register ------------------------ */ + +/** + * @brief Get RX Message Counter + * + * @param hw Start address of the TWAI registers + * @return RX Message Counter + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) +{ + return hw->rx_message_counter.val; +} + +/* ------------------------- Clock Divider Register ------------------------- */ + +/** + * @brief Set CLKOUT Divider and enable/disable + * + * Configure CLKOUT. CLKOUT is a pre-scaled version of peripheral source clock. Divider can be + * 1, or any even number from 2 to 490. Set the divider to 0 to disable CLKOUT. + * + * @param hw Start address of the TWAI registers + * @param divider Divider for CLKOUT (any even number from 2 to 490). Set to 0 to disable CLKOUT + */ +__attribute__((always_inline)) +static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider) +{ + if (divider >= 2 && divider <= 490) { + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, (divider / 2) - 1); + } else if (divider == 1) { + //Setting the divider reg to max value (255) means a divider of 1 + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 255); + } else { + hw->clock_divider.clock_off = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 0); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h new file mode 100644 index 000000000000..0801d73dfb2a --- /dev/null +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -0,0 +1,1091 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for UART register operations. +// Note that most of the register operations in this layer are non-atomic operations. + + +#pragma once + +#include +#include "esp_attr.h" +#include "hal/misc.h" +#include "hal/uart_types.h" +#include "soc/uart_periph.h" +#include "soc/uart_struct.h" +#include "soc/pcr_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// The default fifo depth +#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN) +// Get UART hardware instance with giving uart num +#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) + +#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask + +#define UART_LL_FSM_IDLE (0x0) +#define UART_LL_FSM_TX_WAIT_SEND (0xf) + +#define UART_LL_PCR_REG_U32_SET(hw, reg_suffix, field_suffix, val) \ + if ((hw) == &UART0) { \ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.uart0_##reg_suffix, uart0_##field_suffix, (val)) \ + } else { \ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.uart1_##reg_suffix, uart1_##field_suffix, (val)) \ + } + +#define UART_LL_PCR_REG_U32_GET(hw, reg_suffix, field_suffix) \ + (((hw) == &UART0) ? \ + HAL_FORCE_READ_U32_REG_FIELD(PCR.uart0_##reg_suffix, uart0_##field_suffix) : \ + HAL_FORCE_READ_U32_REG_FIELD(PCR.uart1_##reg_suffix, uart1_##field_suffix)) + +#define UART_LL_PCR_REG_SET(hw, reg_suffix, field_suffix, val) \ + if ((hw) == &UART0) { \ + PCR.uart0_##reg_suffix.uart0_##field_suffix = (val); \ + } else { \ + PCR.uart1_##reg_suffix.uart1_##field_suffix = (val); \ + } + +#define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \ + (((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix) + +// Define UART interrupts +typedef enum { + UART_INTR_RXFIFO_FULL = (0x1 << 0), + UART_INTR_TXFIFO_EMPTY = (0x1 << 1), + UART_INTR_PARITY_ERR = (0x1 << 2), + UART_INTR_FRAM_ERR = (0x1 << 3), + UART_INTR_RXFIFO_OVF = (0x1 << 4), + UART_INTR_DSR_CHG = (0x1 << 5), + UART_INTR_CTS_CHG = (0x1 << 6), + UART_INTR_BRK_DET = (0x1 << 7), + UART_INTR_RXFIFO_TOUT = (0x1 << 8), + UART_INTR_SW_XON = (0x1 << 9), + UART_INTR_SW_XOFF = (0x1 << 10), + UART_INTR_GLITCH_DET = (0x1 << 11), + UART_INTR_TX_BRK_DONE = (0x1 << 12), + UART_INTR_TX_BRK_IDLE = (0x1 << 13), + UART_INTR_TX_DONE = (0x1 << 14), + UART_INTR_RS485_PARITY_ERR = (0x1 << 15), + UART_INTR_RS485_FRM_ERR = (0x1 << 16), + UART_INTR_RS485_CLASH = (0x1 << 17), + UART_INTR_CMD_CHAR_DET = (0x1 << 18), + UART_INTR_WAKEUP = (0x1 << 19), +} uart_intr_t; + +/** + * @brief Sync the update to UART core clock domain + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw) +{ + hw->reg_update.reg_update = 1; + while (hw->reg_update.reg_update); +} + +/** + * @brief Configure the UART core reset. + * + * @param hw Beginning address of the peripheral registers. + * @param core_rst_en True to enable the core reset, otherwise set it false. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) +{ + UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); +} + +/** + * @brief Enable the UART clock. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw) +{ + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); +} + +/** + * @brief Disable the UART clock. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw) +{ + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); +} + +/** + * @brief Set the UART source clock. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The UART source clock. The source clock can be PLL_F80M clock, RTC clock or XTAL clock. + * All clock sources can remain at their original frequencies during DFS. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) +{ + switch (source_clk) { + default: + case UART_SCLK_PLL_F80M: + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 1); + break; + case UART_SCLK_RTC: + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 2); + break; + case UART_SCLK_XTAL: + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 3); + break; + } +} + +/** + * @brief Get the UART source clock type. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The pointer to accept the UART source clock type. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) +{ + switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { + default: + case 1: + *source_clk = UART_SCLK_PLL_F80M; + break; + case 2: + *source_clk = UART_SCLK_RTC; + break; + case 3: + *source_clk = UART_SCLK_XTAL; + break; + } +} + +/** + * @brief Configure the baud-rate. + * + * @param hw Beginning address of the peripheral registers. + * @param baud The baud rate to be set. + * @param sclk_freq Frequency of the clock source of UART, in Hz. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) +{ +#define DIV_UP(a, b) (((a) + (b) - 1) / (b)) + const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits + uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); + + if (sclk_div == 0) abort(); + + uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); + // The baud rate configuration register is divided into + // an integer part and a fractional part. + hw->clkdiv_sync.clkdiv_int = clk_div >> 4; + hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; + UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); +#undef DIV_UP + uart_ll_update(hw); +} + +/** + * @brief Get the current baud-rate. + * + * @param hw Beginning address of the peripheral registers. + * @param sclk_freq Frequency of the clock source of UART, in Hz. + * + * @return The current baudrate + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) +{ + typeof(hw->clkdiv_sync) div_reg; + div_reg.val = hw->clkdiv_sync.val; + return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1)); +} + +/** + * @brief Enable the UART interrupt based on the given mask. + * + * @param hw Beginning address of the peripheral registers. + * @param mask The bitmap of the interrupts need to be enabled. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) +{ + hw->int_ena.val |= mask; +} + +/** + * @brief Disable the UART interrupt based on the given mask. + * + * @param hw Beginning address of the peripheral registers. + * @param mask The bitmap of the interrupts need to be disabled. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) +{ + hw->int_ena.val &= (~mask); +} + +/** + * @brief Get the UART raw interrupt status. + * + * @param hw Beginning address of the peripheral registers. + * + * @return The UART interrupt status. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) +{ + return hw->int_raw.val; +} + +/** + * @brief Get the UART interrupt status. + * + * @param hw Beginning address of the peripheral registers. + * + * @return The UART interrupt status. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) +{ + return hw->int_st.val; +} + +/** + * @brief Clear the UART interrupt status based on the given mask. + * + * @param hw Beginning address of the peripheral registers. + * @param mask The bitmap of the interrupts need to be cleared. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) +{ + hw->int_clr.val = mask; +} + +/** + * @brief Get status of enabled interrupt. + * + * @param hw Beginning address of the peripheral registers. + * + * @return interrupt enable value + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) +{ + return hw->int_ena.val; +} + +/** + * @brief Read the UART rxfifo. + * + * @param hw Beginning address of the peripheral registers. + * @param buf The data buffer. The buffer size should be large than 128 byts. + * @param rd_len The data length needs to be read. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) +{ + for (int i = 0; i < (int)rd_len; i++) { + buf[i] = hw->fifo.rxfifo_rd_byte; + } +} + +/** + * @brief Write byte to the UART txfifo. + * + * @param hw Beginning address of the peripheral registers. + * @param buf The data buffer. + * @param wr_len The data length needs to be written. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) +{ + for (int i = 0; i < (int)wr_len; i++) { + hw->fifo.rxfifo_rd_byte = buf[i]; + } +} + +/** + * @brief Reset the UART hw rxfifo. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_rxfifo_rst(uart_dev_t *hw) +{ + hw->conf0_sync.rxfifo_rst = 1; + uart_ll_update(hw); + hw->conf0_sync.rxfifo_rst = 0; + uart_ll_update(hw); +} + +/** + * @brief Reset the UART hw txfifo. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw) +{ + hw->conf0_sync.txfifo_rst = 1; + uart_ll_update(hw); + hw->conf0_sync.txfifo_rst = 0; + uart_ll_update(hw); +} + +/** + * @brief Get the length of readable data in UART rxfifo. + * + * @param hw Beginning address of the peripheral registers. + * + * @return The readable data length in rxfifo. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) +{ + return hw->status.rxfifo_cnt; +} + +/** + * @brief Get the writable data length of UART txfifo. + * + * @param hw Beginning address of the peripheral registers. + * + * @return The data length of txfifo can be written. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) +{ + return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt; +} + +/** + * @brief Configure the UART stop bit. + * + * @param hw Beginning address of the peripheral registers. + * @param stop_bit The stop bit number to be set. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) +{ + hw->conf0_sync.stop_bit_num = stop_bit; + uart_ll_update(hw); +} + +/** + * @brief Get the configuration of the UART stop bit. + * + * @param hw Beginning address of the peripheral registers. + * @param stop_bit The pointer to accept the stop bit configuration + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) +{ + *stop_bit = (uart_stop_bits_t)hw->conf0_sync.stop_bit_num; +} + +/** + * @brief Configure the UART parity check mode. + * + * @param hw Beginning address of the peripheral registers. + * @param parity_mode The parity check mode to be set. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) +{ + if (parity_mode != UART_PARITY_DISABLE) { + hw->conf0_sync.parity = parity_mode & 0x1; + } + hw->conf0_sync.parity_en = (parity_mode >> 1) & 0x1; + uart_ll_update(hw); +} + +/** + * @brief Get the UART parity check mode configuration. + * + * @param hw Beginning address of the peripheral registers. + * @param parity_mode The pointer to accept the parity check mode configuration. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) +{ + if (hw->conf0_sync.parity_en) { + *parity_mode = (uart_parity_t)(0x2 | hw->conf0_sync.parity); + } else { + *parity_mode = UART_PARITY_DISABLE; + } +} + +/** + * @brief Set the UART rxfifo full threshold value. When the data in rxfifo is more than the threshold value, + * it will produce rxfifo_full_int_raw interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param full_thrhd The full threshold value of the rxfifo. `full_thrhd` should be less than `UART_LL_FIFO_DEF_LEN`. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) +{ + hw->conf1.rxfifo_full_thrhd = full_thrhd; +} + +/** + * @brief Set the txfifo empty threshold. when the data length in txfifo is less than threshold value, + * it will produce txfifo_empty_int_raw interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param empty_thrhd The empty threshold of txfifo. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) +{ + hw->conf1.txfifo_empty_thrhd = empty_thrhd; +} + +/** + * @brief Set the UART rx-idle threshold value. when receiver takes more time than rx_idle_thrhd to receive a byte data, + * it will produce frame end signal for uhci to stop receiving data. + * + * @param hw Beginning address of the peripheral registers. + * @param rx_idle_thr The rx-idle threshold to be set. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) +{ + hw->idle_conf_sync.rx_idle_thrhd = rx_idle_thr; + uart_ll_update(hw); +} + +/** + * @brief Configure the duration time between transfers. + * + * @param hw Beginning address of the peripheral registers. + * @param idle_num the duration time between transfers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) +{ + hw->idle_conf_sync.tx_idle_num = idle_num; + uart_ll_update(hw); +} + +/** + * @brief Configure the transmiter to send break chars. + * + * @param hw Beginning address of the peripheral registers. + * @param break_num The number of the break chars need to be send. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) +{ + if (break_num > 0) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); + hw->conf0_sync.txd_brk = 1; + } else { + hw->conf0_sync.txd_brk = 0; + } + uart_ll_update(hw); +} + +/** + * @brief Configure the UART hardware flow control. + * + * @param hw Beginning address of the peripheral registers. + * @param flow_ctrl The hw flow control configuration. + * @param rx_thrs The rx flow control signal will be active if the data length in rxfifo is more than this value. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) +{ + //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. + if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { + hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs; + hw->hwfc_conf_sync.rx_flow_en = 1; + } else { + hw->hwfc_conf_sync.rx_flow_en = 0; + } + if (flow_ctrl & UART_HW_FLOWCTRL_CTS) { + hw->conf0_sync.tx_flow_en = 1; + } else { + hw->conf0_sync.tx_flow_en = 0; + } + uart_ll_update(hw); +} + +/** + * @brief Configure the hardware flow control. + * + * @param hw Beginning address of the peripheral registers. + * @param flow_ctrl A pointer to accept the hw flow control configuration. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) +{ + *flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + if (hw->hwfc_conf_sync.rx_flow_en) { + *flow_ctrl = (uart_hw_flowcontrol_t)((unsigned int)(*flow_ctrl) | (unsigned int)UART_HW_FLOWCTRL_RTS); + } + if (hw->conf0_sync.tx_flow_en) { + *flow_ctrl = (uart_hw_flowcontrol_t)((unsigned int)(*flow_ctrl) | (unsigned int)UART_HW_FLOWCTRL_CTS); + } +} + +/** + * @brief Configure the software flow control. + * + * @param hw Beginning address of the peripheral registers. + * @param flow_ctrl The UART sofware flow control settings. + * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) +{ + if (sw_flow_ctrl_en) { + hw->swfc_conf0_sync.xonoff_del = 1; + hw->swfc_conf0_sync.sw_flow_con_en = 1; + hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd; + hw->swfc_conf1.xoff_threshold = flow_ctrl->xoff_thrd; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xon_char, flow_ctrl->xon_char); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char); + } else { + hw->swfc_conf0_sync.sw_flow_con_en = 0; + hw->swfc_conf0_sync.xonoff_del = 0; + } + uart_ll_update(hw); +} + +/** + * @brief Configure the AT cmd char. When the receiver receives a continuous AT cmd char, it will produce at_cmd_char_det interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param cmd_char The AT cmd char configuration.The configuration member is: + * - cmd_char The AT cmd character + * - char_num The number of received AT cmd char must be equal to or greater than this value + * - gap_tout The interval between each AT cmd char, when the duration is less than this value, it will not take this data as AT cmd char + * - pre_idle The idle time before the first AT cmd char, when the duration is less than this value, it will not take the previous data as the last AT cmd char + * - post_idle The idle time after the last AT cmd char, when the duration is less than this value, it will not take this data as the first AT cmd char + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_postcnt_sync, post_idle_num, cmd_char->post_idle); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_precnt_sync, pre_idle_num, cmd_char->pre_idle); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_gaptout_sync, rx_gap_tout, cmd_char->gap_tout); + uart_ll_update(hw); +} + +/** + * @brief Set the UART data bit mode. + * + * @param hw Beginning address of the peripheral registers. + * @param data_bit The data bit mode to be set. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) +{ + hw->conf0_sync.bit_num = data_bit; + uart_ll_update(hw); +} + +/** + * @brief Set the rts active level. + * + * @param hw Beginning address of the peripheral registers. + * @param level The rts active level, 0 or 1. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) +{ + hw->conf0_sync.sw_rts = level & 0x1; + uart_ll_update(hw); +} + +/** + * @brief Set the dtr active level. + * + * @param hw Beginning address of the peripheral registers. + * @param level The dtr active level, 0 or 1. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) +{ + hw->conf1.sw_dtr = level & 0x1; +} + +/** + * @brief Set the UART wakeup threshold. + * + * @param hw Beginning address of the peripheral registers. + * @param wakeup_thrd The wakeup threshold value to be set. When the input rx edge changes more than this value, + * the UART will active from light sleeping mode. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) +{ + hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; +} + +/** + * @brief Configure the UART work in normal mode. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw) +{ + hw->rs485_conf_sync.rs485_en = 0; + hw->rs485_conf_sync.rs485tx_rx_en = 0; + hw->rs485_conf_sync.rs485rxby_tx_en = 0; + hw->conf0_sync.irda_en = 0; + uart_ll_update(hw); +} + +/** + * @brief Configure the UART work in rs485_app_ctrl mode. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) +{ + // Application software control, remove echo + hw->rs485_conf_sync.rs485rxby_tx_en = 1; + hw->conf0_sync.irda_en = 0; + hw->conf0_sync.sw_rts = 0; + hw->conf0_sync.irda_en = 0; + hw->rs485_conf_sync.dl0_en = 1; + hw->rs485_conf_sync.dl1_en = 1; + hw->rs485_conf_sync.rs485_en = 1; + uart_ll_update(hw); +} + +/** + * @brief Configure the UART work in rs485_half_duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) +{ + // Enable receiver, sw_rts = 1 generates low level on RTS pin + hw->conf0_sync.sw_rts = 1; + // Half duplex mode + hw->rs485_conf_sync.rs485tx_rx_en = 0; + // Setting this bit will allow data to be transmitted while receiving data(full-duplex mode). + // But note that this full-duplex mode has no conflict detection function + hw->rs485_conf_sync.rs485rxby_tx_en = 0; + hw->conf0_sync.irda_en = 0; + hw->rs485_conf_sync.dl0_en = 1; + hw->rs485_conf_sync.dl1_en = 1; + hw->rs485_conf_sync.rs485_en = 1; + uart_ll_update(hw); +} + +/** + * @brief Configure the UART work in collision_detect mode. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw) +{ + hw->conf0_sync.irda_en = 0; + // Enable full-duplex mode + hw->rs485_conf_sync.rs485tx_rx_en = 1; + // Transmitter should send data when the receiver is busy, + hw->rs485_conf_sync.rs485rxby_tx_en = 1; + hw->rs485_conf_sync.dl0_en = 1; + hw->rs485_conf_sync.dl1_en = 1; + hw->conf0_sync.sw_rts = 0; + hw->rs485_conf_sync.rs485_en = 1; + uart_ll_update(hw); +} + +/** + * @brief Configure the UART work in irda mode. + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw) +{ + hw->rs485_conf_sync.rs485_en = 0; + hw->rs485_conf_sync.rs485tx_rx_en = 0; + hw->rs485_conf_sync.rs485rxby_tx_en = 0; + hw->conf0_sync.sw_rts = 0; + hw->conf0_sync.irda_en = 1; + uart_ll_update(hw); +} + +/** + * @brief Set uart mode. + * + * @param hw Beginning address of the peripheral registers. + * @param mode The UART mode to be set. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) +{ + switch (mode) { + default: + case UART_MODE_UART: + uart_ll_set_mode_normal(hw); + break; + case UART_MODE_RS485_COLLISION_DETECT: + uart_ll_set_mode_collision_detect(hw); + break; + case UART_MODE_RS485_APP_CTRL: + uart_ll_set_mode_rs485_app_ctrl(hw); + break; + case UART_MODE_RS485_HALF_DUPLEX: + uart_ll_set_mode_rs485_half_duplex(hw); + break; + case UART_MODE_IRDA: + uart_ll_set_mode_irda(hw); + break; + } +} + +/** + * @brief Get the UART AT cmd char configuration. + * + * @param hw Beginning address of the peripheral registers. + * @param cmd_char The Pointer to accept value of UART AT cmd char. + * @param char_num Pointer to accept the repeat number of UART AT cmd char. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) +{ + *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data); + *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); +} + +/** + * @brief Get the UART wakeup threshold value. + * + * @param hw Beginning address of the peripheral registers. + * + * @return The UART wakeup threshold value. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) +{ + return hw->sleep_conf2.active_threshold + UART_LL_MIN_WAKEUP_THRESH; +} + +/** + * @brief Get the UART data bit configuration. + * + * @param hw Beginning address of the peripheral registers. + * @param data_bit The pointer to accept the UART data bit configuration. + * + * @return The bit mode. + */ +FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) +{ + *data_bit = (uart_word_length_t)hw->conf0_sync.bit_num; +} + +/** + * @brief Check if the UART sending state machine is in the IDLE state. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if the state machine is in the IDLE state, otherwise false is returned. + */ +FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw) +{ + return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0)); +} + +/** + * @brief Check if the UART rts flow control is enabled. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if hw rts flow control is enabled, otherwise false is returned. + */ +FORCE_INLINE_ATTR bool uart_ll_is_hw_rts_en(uart_dev_t *hw) +{ + return hw->hwfc_conf_sync.rx_flow_en; +} + +/** + * @brief Check if the UART cts flow control is enabled. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if hw cts flow control is enabled, otherwise false is returned. + */ +FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) +{ + return hw->conf0_sync.tx_flow_en; +} + +/** + * @brief Configure TX signal loop back to RX module, just for the testing purposes + * + * @param hw Beginning address of the peripheral registers. + * @param loop_back_en Set ture to enable the loop back function, else set it false. + * + * @return None + */ +FORCE_INLINE_ATTR void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) +{ + hw->conf0_sync.loopback = loop_back_en; + uart_ll_update(hw); +} + +FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) +{ + hw->swfc_conf0_sync.force_xon = 1; + uart_ll_update(hw); + if(!always_on) { + hw->swfc_conf0_sync.force_xon = 0; + uart_ll_update(hw); + } +} + +/** + * @brief Inverse the UART signal with the given mask. + * + * @param hw Beginning address of the peripheral registers. + * @param inv_mask The UART signal bitmap needs to be inversed. + * Use the ORred mask of `uart_signal_inv_t`; + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) +{ + typeof(hw->conf0_sync) conf0_reg; + conf0_reg.val = hw->conf0_sync.val; + conf0_reg.irda_tx_inv = (inv_mask & UART_SIGNAL_IRDA_TX_INV) ? 1 : 0; + conf0_reg.irda_rx_inv = (inv_mask & UART_SIGNAL_IRDA_RX_INV) ? 1 : 0; + conf0_reg.rxd_inv = (inv_mask & UART_SIGNAL_RXD_INV) ? 1 : 0; + conf0_reg.txd_inv = (inv_mask & UART_SIGNAL_TXD_INV) ? 1 : 0; + hw->conf0_sync.val = conf0_reg.val; + + typeof(hw->conf1) conf1_reg; + conf1_reg.val = hw->conf1.val; + conf1_reg.rts_inv = (inv_mask & UART_SIGNAL_RTS_INV) ? 1 : 0; + conf1_reg.dtr_inv = (inv_mask & UART_SIGNAL_DTR_INV) ? 1 : 0; + conf1_reg.cts_inv = (inv_mask & UART_SIGNAL_CTS_INV) ? 1 : 0; + conf1_reg.dsr_inv = (inv_mask & UART_SIGNAL_DSR_INV) ? 1 : 0; + hw->conf1.val = conf1_reg.val; + uart_ll_update(hw); +} + +/** + * @brief Configure the timeout value for receiver receiving a byte, and enable rx timeout function. + * + * @param hw Beginning address of the peripheral registers. + * @param tout_thrd The timeout value as UART bit time. The rx timeout function will be disabled if `tout_thrd == 0`. + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) +{ + uint16_t tout_val = tout_thrd; + if(tout_thrd > 0) { + hw->tout_conf_sync.rx_tout_thrhd = tout_val; + hw->tout_conf_sync.rx_tout_en = 1; + } else { + hw->tout_conf_sync.rx_tout_en = 0; + } + uart_ll_update(hw); +} + +/** + * @brief Get the timeout value for receiver receiving a byte. + * + * @param hw Beginning address of the peripheral registers. + * + * @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0. + */ +FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) +{ + uint16_t tout_thrd = 0; + if(hw->tout_conf_sync.rx_tout_en > 0) { + tout_thrd = hw->tout_conf_sync.rx_tout_thrhd; + } + return tout_thrd; +} + +/** + * @brief Get UART maximum timeout threshold. + * + * @param hw Beginning address of the peripheral registers. + * + * @return maximum timeout threshold. + */ +FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) +{ + return UART_RX_TOUT_THRHD_V; +} + +/** + * @brief Configure the auto baudrate. + * + * @param hw Beginning address of the peripheral registers. + * @param enable Boolean marking whether the auto baudrate should be enabled or not. + */ +FORCE_INLINE_ATTR void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) +{ + hw->conf0_sync.autobaud_en = enable ? 1 : 0; + uart_ll_update(hw); +} + +/** + * @brief Get the RXD edge count. + * + * @param hw Beginning address of the peripheral registers. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) +{ + return hw->rxd_cnt.rxd_edge_cnt; +} + +/** + * @brief Get the positive pulse minimum count. + * + * @param hw Beginning address of the peripheral registers. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) +{ + return hw->pospulse.posedge_min_cnt; +} + +/** + * @brief Get the negative pulse minimum count. + * + * @param hw Beginning address of the peripheral registers. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) +{ + return hw->negpulse.negedge_min_cnt; +} + +/** + * @brief Get the high pulse minimum count. + * + * @param hw Beginning address of the peripheral registers. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) +{ + return hw->highpulse.highpulse_min_cnt; +} + +/** + * @brief Get the low pulse minimum count. + * + * @param hw Beginning address of the peripheral registers. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) +{ + return hw->lowpulse.lowpulse_min_cnt; +} + +/** + * @brief Force UART xoff. + * + * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) +{ + REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); + REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); + uart_ll_update(UART_LL_GET_HW(uart_num)); +} + +/** + * @brief Force UART xon. + * + * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). + * + * @return None. + */ +FORCE_INLINE_ATTR void uart_ll_force_xon(uart_port_t uart_num) +{ + REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XOFF); + REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); + REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XON); + uart_ll_update(UART_LL_GET_HW(uart_num)); +} + +/** + * @brief Get UART finite-state machine status. + * + * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). + * + * @return UART module FSM status. + */ +FORCE_INLINE_ATTR uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) +{ + return REG_GET_FIELD(UART_FSM_STATUS_REG(uart_num), UART_ST_UTX_OUT); +} + +/** + * @brief Configure UART whether to discard when receiving wrong data + * + * @param hw Beginning address of the peripheral registers. + * @param discard true: Receiver stops storing data into FIFO when data is wrong + * false: Receiver continue storing data into FIFO when data is wrong + */ +FORCE_INLINE_ATTR void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) +{ + hw->conf0_sync.err_wr_mask = discard ? 1 : 0; + uart_ll_update(hw); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h new file mode 100644 index 000000000000..4893e96106de --- /dev/null +++ b/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/usb_serial_jtag_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configures the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) +{ + // USB_Serial_JTAG use internal PHY + hw->conf0.phy_sel = 0; + // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) + hw->conf0.pad_pull_override = 0; + // Enable USB D+ pullup + hw->conf0.dp_pullup = 1; + // Enable USB pad function + hw->conf0.usb_pad_enable = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h new file mode 100644 index 000000000000..f29f12604ac2 --- /dev/null +++ b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h @@ -0,0 +1,230 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer of the USB-serial-jtag controller + +#pragma once +#include +#include "esp_attr.h" +#include "soc/pcr_struct.h" +#include "soc/usb_serial_jtag_reg.h" +#include "soc/usb_serial_jtag_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//The in and out endpoints are this long. +#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 + +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask + +// Define USB_SERIAL_JTAG interrupts +// Note the hardware has more interrupts, but they're only useful for debugging +// the hardware. +typedef enum { + USB_SERIAL_JTAG_INTR_SOF = (1 << 1), + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT = (1 << 2), + USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY = (1 << 3), + USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1 = (1 << 8), + USB_SERIAL_JTAG_INTR_BUS_RESET = (1 << 9), + USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), +} usb_serial_jtag_ll_intr_t; + +/** + * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts need to be enabled. + * + * @return None + */ +static inline void usb_serial_jtag_ll_ena_intr_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_ena.val |= mask; +} + +/** + * @brief Disable the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts need to be disabled. + * + * @return None + */ +static inline void usb_serial_jtag_ll_disable_intr_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_ena.val &= (~mask); +} + +/** + * @brief Get the USB_SERIAL_JTAG interrupt status. + * + * @return The USB_SERIAL_JTAG interrupt status. + */ +static inline uint32_t usb_serial_jtag_ll_get_intsts_mask(void) +{ + return USB_SERIAL_JTAG.int_st.val; +} + +/** + * @brief Get the USB_SERIAL_JTAG raw interrupt status. + * + * @return The USB_SERIAL_JTAG raw interrupt status. + */ +static inline __attribute__((always_inline)) uint32_t usb_serial_jtag_ll_get_intraw_mask(void) +{ + return USB_SERIAL_JTAG.int_raw.val; +} + +/** + * @brief Clear the USB_SERIAL_JTAG interrupt status based on the given mask. + * + * @param mask The bitmap of the interrupts need to be cleared. + * + * @return None + */ +static inline __attribute__((always_inline)) void usb_serial_jtag_ll_clr_intsts_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_clr.val = mask; +} + +/** + * @brief Get status of enabled interrupt. + * + * @return interrupt enable value + */ +static inline uint32_t usb_serial_jtag_ll_get_intr_ena_status(void) +{ + return USB_SERIAL_JTAG.int_ena.val; +} + +/** + * @brief Read the bytes from the USB_SERIAL_JTAG rxfifo. + * + * @param buf The data buffer. + * @param rd_len The data length needs to be read. + * + * @return amount of bytes read + */ +static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) +{ + int i; + for (i = 0; i < (int)rd_len; i++) { + if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break; + buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte; + } + return i; +} + +/** + * @brief Write byte to the USB_SERIAL_JTAG txfifo. Only writes bytes as long / if there + * is room in the buffer. + * + * @param buf The data buffer. + * @param wr_len The data length needs to be writen. + * + * @return Amount of bytes actually written. May be less than wr_len. + */ +static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t wr_len) +{ + int i; + for (i = 0; i < (int)wr_len; i++) { + if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break; + USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i]; + } + return i; +} + +/** + * @brief Returns 1 if the USB_SERIAL_JTAG rxfifo has data available. + * + * @return 0 if no data available, 1 if data available + */ +static inline int usb_serial_jtag_ll_rxfifo_data_available(void) +{ + return USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail; +} + +/** + * @brief Returns 1 if the USB_SERIAL_JTAG txfifo has room. + * + * @return 0 if no data available, 1 if data available + */ +static inline int usb_serial_jtag_ll_txfifo_writable(void) +{ + return USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free; +} + +/** + * @brief Flushes the TX buffer, that is, make it available for the + * host to pick up. + * + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically. + * It won't be executed if there is nothing in the fifo. + * + * @return na + */ +static inline void usb_serial_jtag_ll_txfifo_flush(void) +{ + USB_SERIAL_JTAG.ep1_conf.wr_done=1; +} + + +/** + * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * + * @return Initial configuration of usb serial jtag pad enable before light sleep + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +{ + bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; + + // Disable USB pad function + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + + return pad_enabled; +} + +/** + * @brief Enable the internal USJ PHY control to D+/D- pad + * + * @param enable_pad Enable the USJ PHY control to D+/D- pad + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; +} + +/** + * @brief Enable the bus clock for USB Serial_JTAG module + * @param clk_en True if enable the clock of USB Serial_JTAG module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + PCR.usb_device_conf.usb_device_clk_en = clk_en; +} + +/** + * @brief Reset the usb serial jtag module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + PCR.usb_device_conf.usb_device_rst_en = 1; + PCR.usb_device_conf.usb_device_rst_en = 0; +} + +/** + * Get the enable status USB Serial_JTAG module + * + * @return Return true if USB Serial_JTAG module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (PCR.usb_device_conf.usb_device_clk_en && !PCR.usb_device_conf.usb_device_rst_en); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/modem_clock_hal.c b/components/hal/esp32c6/modem_clock_hal.c new file mode 100644 index 000000000000..ed242febec45 --- /dev/null +++ b/components/hal/esp32c6/modem_clock_hal.c @@ -0,0 +1,267 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for MODEM CLOCK (ESP32-C6 specific part) +#include +#include "soc/soc.h" +#include "esp_attr.h" +#include "hal/modem_clock_hal.h" +#include "hal/modem_clock_types.h" +#include "hal/efuse_hal.h" +#include "hal/assert.h" + +typedef enum { + MODEM_CLOCK_XTAL32K_CODE = 0, + MODEM_CLOCK_RC32K_CODE = 1, + MODEM_CLOCK_EXT32K_CODE = 2 +} modem_clock_32k_clk_src_code_t; + +void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap) +{ + HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX); + switch (domain) + { + case MODEM_CLOCK_DOMAIN_MODEM_APB: + modem_syscon_ll_set_modem_apb_icg_bitmap(hal->syscon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_MODEM_PERIPH: + modem_syscon_ll_set_modem_periph_icg_bitmap(hal->syscon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_WIFI: + modem_syscon_ll_set_wifi_icg_bitmap(hal->syscon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_BT: + modem_syscon_ll_set_bt_icg_bitmap(hal->syscon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_MODEM_FE: + modem_syscon_ll_set_fe_icg_bitmap(hal->syscon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_IEEE802154: + modem_syscon_ll_set_ieee802154_icg_bitmap(hal->syscon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_LP_APB: + modem_lpcon_ll_set_lp_apb_icg_bitmap(hal->lpcon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_I2C_MASTER: + modem_lpcon_ll_set_i2c_master_icg_bitmap(hal->lpcon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_COEX: + modem_lpcon_ll_set_coex_icg_bitmap(hal->lpcon_dev, bitmap); + break; + case MODEM_CLOCK_DOMAIN_WIFIPWR: + modem_lpcon_ll_set_wifipwr_icg_bitmap(hal->lpcon_dev, bitmap); + break; + default: + HAL_ASSERT(0); + } +} + +uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain) +{ + HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX); + uint32_t bitmap = 0; + switch (domain) + { + case MODEM_CLOCK_DOMAIN_MODEM_APB: + bitmap = modem_syscon_ll_get_modem_apb_icg_bitmap(hal->syscon_dev); + break; + case MODEM_CLOCK_DOMAIN_MODEM_PERIPH: + bitmap = modem_syscon_ll_get_modem_periph_icg_bitmap(hal->syscon_dev); + break; + case MODEM_CLOCK_DOMAIN_WIFI: + bitmap = modem_syscon_ll_get_wifi_icg_bitmap(hal->syscon_dev); + break; + case MODEM_CLOCK_DOMAIN_BT: + bitmap = modem_syscon_ll_get_bt_icg_bitmap(hal->syscon_dev); + break; + case MODEM_CLOCK_DOMAIN_MODEM_FE: + bitmap = modem_syscon_ll_get_fe_icg_bitmap(hal->syscon_dev); + break; + case MODEM_CLOCK_DOMAIN_IEEE802154: + bitmap = modem_syscon_ll_get_ieee802154_icg_bitmap(hal->syscon_dev); + break; + case MODEM_CLOCK_DOMAIN_LP_APB: + bitmap = modem_lpcon_ll_get_lp_apb_icg_bitmap(hal->lpcon_dev); + break; + case MODEM_CLOCK_DOMAIN_I2C_MASTER: + bitmap = modem_lpcon_ll_get_i2c_master_icg_bitmap(hal->lpcon_dev); + break; + case MODEM_CLOCK_DOMAIN_COEX: + bitmap = modem_lpcon_ll_get_coex_icg_bitmap(hal->lpcon_dev); + break; + case MODEM_CLOCK_DOMAIN_WIFIPWR: + bitmap = modem_lpcon_ll_get_wifipwr_icg_bitmap(hal->lpcon_dev); + break; + default: + HAL_ASSERT(0); + } + return bitmap; +} + +void IRAM_ATTR modem_clock_hal_enable_modem_adc_common_fe_clock(modem_clock_hal_context_t *hal, bool enable) +{ + if (enable) { + modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable); + modem_syscon_ll_enable_fe_80m_clock(hal->syscon_dev, enable); + } +} + +void IRAM_ATTR modem_clock_hal_enable_modem_private_fe_clock(modem_clock_hal_context_t *hal, bool enable) +{ + if (enable) { + modem_syscon_ll_enable_fe_cal_160m_clock(hal->syscon_dev, enable); + modem_syscon_ll_enable_fe_160m_clock(hal->syscon_dev, enable); + } +} + +void modem_clock_hal_set_ble_rtc_timer_divisor_value(modem_clock_hal_context_t *hal, uint32_t divider) +{ + modem_lpcon_ll_set_ble_rtc_timer_divisor_value(hal->lpcon_dev, divider); +} + +void modem_clock_hal_enable_ble_rtc_timer_clock(modem_clock_hal_context_t *hal, bool enable) +{ + modem_lpcon_ll_enable_ble_rtc_timer_clock(hal->lpcon_dev, enable); +} + +void modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(modem_clock_hal_context_t *hal) +{ + modem_lpcon_ll_enable_ble_rtc_timer_slow_osc(hal->lpcon_dev, false); + modem_lpcon_ll_enable_ble_rtc_timer_fast_osc(hal->lpcon_dev, false); + modem_lpcon_ll_enable_ble_rtc_timer_32k_xtal(hal->lpcon_dev, false); + modem_lpcon_ll_enable_ble_rtc_timer_main_xtal(hal->lpcon_dev, false); +} + +void modem_clock_hal_select_ble_rtc_timer_lpclk_source(modem_clock_hal_context_t *hal, modem_clock_lpclk_src_t src) +{ + HAL_ASSERT(src < MODEM_CLOCK_LPCLK_SRC_MAX); + + switch (src) + { + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + modem_lpcon_ll_enable_ble_rtc_timer_slow_osc(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_RC_FAST: + modem_lpcon_ll_enable_ble_rtc_timer_fast_osc(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: + modem_lpcon_ll_enable_ble_rtc_timer_main_xtal(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_RC32K: + modem_lpcon_ll_enable_ble_rtc_timer_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_RC32K_CODE); + break; + case MODEM_CLOCK_LPCLK_SRC_XTAL32K: + modem_lpcon_ll_enable_ble_rtc_timer_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_XTAL32K_CODE); + break; + case MODEM_CLOCK_LPCLK_SRC_EXT32K: + modem_lpcon_ll_enable_ble_rtc_timer_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_EXT32K_CODE); + break; + default: + HAL_ASSERT(0); + } +} + +void modem_clock_hal_deselect_all_coex_lpclk_source(modem_clock_hal_context_t *hal) +{ + modem_lpcon_ll_enable_coex_lpclk_slow_osc(hal->lpcon_dev, false); + modem_lpcon_ll_enable_coex_lpclk_fast_osc(hal->lpcon_dev, false); + modem_lpcon_ll_enable_coex_lpclk_32k_xtal(hal->lpcon_dev, false); + modem_lpcon_ll_enable_coex_lpclk_main_xtal(hal->lpcon_dev, false); +} + +void modem_clock_hal_select_coex_lpclk_source(modem_clock_hal_context_t *hal, modem_clock_lpclk_src_t src) +{ + HAL_ASSERT(src < MODEM_CLOCK_LPCLK_SRC_MAX); + + switch (src) + { + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + modem_lpcon_ll_enable_coex_lpclk_slow_osc(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_RC_FAST: + modem_lpcon_ll_enable_coex_lpclk_fast_osc(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: + modem_lpcon_ll_enable_coex_lpclk_main_xtal(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_RC32K: + modem_lpcon_ll_enable_coex_lpclk_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_RC32K_CODE); + break; + case MODEM_CLOCK_LPCLK_SRC_XTAL32K: + modem_lpcon_ll_enable_coex_lpclk_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_XTAL32K_CODE); + break; + case MODEM_CLOCK_LPCLK_SRC_EXT32K: + modem_lpcon_ll_enable_coex_lpclk_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_EXT32K_CODE); + break; + default: + HAL_ASSERT(0); + } +} + +void modem_clock_hal_deselect_all_wifi_lpclk_source(modem_clock_hal_context_t *hal) +{ + modem_lpcon_ll_enable_wifi_lpclk_slow_osc(hal->lpcon_dev, false); + modem_lpcon_ll_enable_wifi_lpclk_fast_osc(hal->lpcon_dev, false); + modem_lpcon_ll_enable_wifi_lpclk_32k_xtal(hal->lpcon_dev, false); + modem_lpcon_ll_enable_wifi_lpclk_main_xtal(hal->lpcon_dev, false); +} + +void modem_clock_hal_select_wifi_lpclk_source(modem_clock_hal_context_t *hal, modem_clock_lpclk_src_t src) +{ + HAL_ASSERT(src < MODEM_CLOCK_LPCLK_SRC_MAX); + + switch (src) + { + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + modem_lpcon_ll_enable_wifi_lpclk_slow_osc(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_RC_FAST: + modem_lpcon_ll_enable_wifi_lpclk_fast_osc(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: + modem_lpcon_ll_enable_wifi_lpclk_main_xtal(hal->lpcon_dev, true); + break; + case MODEM_CLOCK_LPCLK_SRC_RC32K: + modem_lpcon_ll_enable_wifi_lpclk_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_RC32K_CODE); + break; + case MODEM_CLOCK_LPCLK_SRC_XTAL32K: + modem_lpcon_ll_enable_wifi_lpclk_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_XTAL32K_CODE); + break; + case MODEM_CLOCK_LPCLK_SRC_EXT32K: + modem_lpcon_ll_enable_wifi_lpclk_32k_xtal(hal->lpcon_dev, true); + modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_EXT32K_CODE); + break; + default: + HAL_ASSERT(0); + } +} + +void modem_clock_hal_enable_wifipwr_clock(modem_clock_hal_context_t *hal, bool enable) +{ + if (efuse_hal_chip_revision() == 0) { /* eco0 */ + modem_lpcon_ll_enable_wifipwr_clock(hal->lpcon_dev, enable); + } else { + static int ref = 0; + if (enable) { + if (ref++ == 0) { + modem_lpcon_ll_enable_wifipwr_clock(hal->lpcon_dev, enable); + } + } else { + if (--ref == 0) { + modem_lpcon_ll_enable_wifipwr_clock(hal->lpcon_dev, enable); + } + } + HAL_ASSERT(ref > 0); + } +} diff --git a/components/hal/esp32c6/pau_hal.c b/components/hal/esp32c6/pau_hal.c new file mode 100644 index 000000000000..53be6120c300 --- /dev/null +++ b/components/hal/esp32c6/pau_hal.c @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PAU (ESP32-C6 specific part) + +#include "soc/soc.h" +#include "esp_attr.h" +#include "hal/pau_hal.h" +#include "hal/pau_types.h" + +void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr) +{ + pau_ll_set_regdma_link0_addr(hal->dev, (*link_addr)[0]); + pau_ll_set_regdma_link1_addr(hal->dev, (*link_addr)[1]); + pau_ll_set_regdma_link2_addr(hal->dev, (*link_addr)[2]); + /* The link 3 of REGDMA is reserved, PMU state switching will not use + * REGDMA link 3 */ +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +{ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); + pau_ll_set_regdma_select_wifimac_link(hal->dev); + pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); + pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); + + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) +{ + pau_ll_set_regdma_wifimac_link_backup_start_disable(hal->dev); + pau_ll_set_regdma_deselect_wifimac_link(hal->dev); + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); +} + +void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) +{ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); + /* The link 3 of REGDMA is reserved, we use it as an extra linked list to + * provide backup and restore services for BLE, IEEE802.15.4 and possibly + * other modules */ + pau_ll_select_regdma_entry_link(hal->dev, 3); + pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); + pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); + + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) +{ + pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); + pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); +} diff --git a/components/hal/esp32c6/pmu_hal.c b/components/hal/esp32c6/pmu_hal.c new file mode 100644 index 000000000000..1d0dfc49bb82 --- /dev/null +++ b/components/hal/esp32c6/pmu_hal.c @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PMU (ESP32-C6 specific part) + +#include "soc/soc.h" +#include "esp_attr.h" +#include "hal/pmu_hal.h" +#include "hal/pmu_types.h" + +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +{ + pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); + pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); +} + +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +{ + uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev); + uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev); + return power_supply_wait_cycle + power_up_wait_cycle; +} + +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +{ + pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); + pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); +} + +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +{ + uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev); + uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev); + return power_supply_wait_cycle + power_up_wait_cycle; +} + +void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_active_to_sleep_backup_enable(hal->dev); + pmu_ll_hp_set_sleep_to_active_backup_enable(hal->dev); +} + +void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_sleep_to_active_backup_disable(hal->dev); + pmu_ll_hp_set_active_to_sleep_backup_disable(hal->dev); +} + +void pmu_hal_hp_set_sleep_modem_backup_enable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_sleep_to_modem_backup_enable(hal->dev); +} + +void pmu_hal_hp_set_sleep_modem_backup_disable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_sleep_to_modem_backup_disable(hal->dev); +} + +void pmu_hal_hp_set_modem_active_backup_enable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_modem_to_active_backup_enable(hal->dev); +} + +void pmu_hal_hp_set_modem_active_backup_disable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_modem_to_active_backup_disable(hal->dev); +} diff --git a/components/hal/include/hal/clk_tree_hal.h b/components/hal/include/hal/clk_tree_hal.h new file mode 100644 index 000000000000..e05ab128c906 --- /dev/null +++ b/components/hal/include/hal/clk_tree_hal.h @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get SOC_ROOT_CLK frequency + * + * @param cpu_clk_src One of the clock sources in soc_cpu_clk_src_t + * + * @return SOC ROOT clock frequency, in MHz. Returns 0 if input argument is invalid. + */ +uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src); + +/** + * @brief Get CPU_CLK frequency + * + * @return CPU clock frequency, in Hz. Returns 0 if internal clock configuration is invalid. + */ +uint32_t clk_hal_cpu_get_freq_hz(void); + +/** + * @brief Get AHB_CLK frequency + * + * @return AHB clock frequency, in Hz. Returns 0 if internal clock configuration is invalid. + */ +uint32_t clk_hal_ahb_get_freq_hz(void); + +/** + * @brief Get APB_CLK frequency + * + * @return APB clock frequency, in Hz. Returns 0 if internal clock configuration is invalid. + */ +uint32_t clk_hal_apb_get_freq_hz(void); + +/** + * @brief Get LP_SLOW_CLK (i.e. RTC_SLOW_CLK) approximate frequency + * + * @return LP Slow clock frequency, in Hz. Returns 0 if LP_SLOW clock source is invalid. + */ +uint32_t clk_hal_lp_slow_get_freq_hz(void); + +/** + * @brief Get XTAL_CLK frequency + * + * @return XTAL clock frequency, in MHz + */ +uint32_t clk_hal_xtal_get_freq_mhz(void); + +#if SOC_CLK_APLL_SUPPORTED +/** + * @brief Get APLL_CLK frequency + * + * @return APLL clock frequency, in Hz + */ +uint32_t clk_hal_apll_get_freq_hz(void); +#endif //SOC_CLK_APLL_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/efuse_hal.h b/components/hal/include/hal/efuse_hal.h index 2f141b744045..bc2098ff20ab 100644 --- a/components/hal/include/hal/efuse_hal.h +++ b/components/hal/include/hal/efuse_hal.h @@ -26,6 +26,8 @@ void efuse_hal_get_mac(uint8_t *mac); */ uint32_t efuse_hal_chip_revision(void); +uint32_t efuse_hal_blk_version(void); + /** * @brief Returns major chip version */ diff --git a/components/hal/include/hal/gdma_types.h b/components/hal/include/hal/gdma_types.h new file mode 100644 index 000000000000..bc451852b7e3 --- /dev/null +++ b/components/hal/include/hal/gdma_types.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GDMA_TYPES_DECLARED +#define GDMA_TYPES_DECLARED +/** + * @brief Enumeration of peripherals which have the DMA capability + * @note Some peripheral might not be available on certain chip, please refer to `soc_caps.h` for detail. + * + */ +typedef enum { + GDMA_TRIG_PERIPH_M2M, /*!< GDMA trigger peripheral: M2M */ + GDMA_TRIG_PERIPH_UHCI, /*!< GDMA trigger peripheral: UHCI */ + GDMA_TRIG_PERIPH_SPI, /*!< GDMA trigger peripheral: SPI */ + GDMA_TRIG_PERIPH_I2S, /*!< GDMA trigger peripheral: I2S */ + GDMA_TRIG_PERIPH_AES, /*!< GDMA trigger peripheral: AES */ + GDMA_TRIG_PERIPH_SHA, /*!< GDMA trigger peripheral: SHA */ + GDMA_TRIG_PERIPH_ADC, /*!< GDMA trigger peripheral: ADC */ + GDMA_TRIG_PERIPH_DAC, /*!< GDMA trigger peripheral: DAC */ + GDMA_TRIG_PERIPH_LCD, /*!< GDMA trigger peripheral: LCD */ + GDMA_TRIG_PERIPH_CAM, /*!< GDMA trigger peripheral: CAM */ + GDMA_TRIG_PERIPH_RMT, /*!< GDMA trigger peripheral: RMT */ + GDMA_TRIG_PERIPH_PARLIO, /*!< GDMA trigger peripheral: PARLIO */ +} gdma_trigger_peripheral_t; + +/** + * @brief Enumeration of GDMA channel direction + * + */ +typedef enum { + GDMA_CHANNEL_DIRECTION_TX, /*!< GDMA channel direction: TX */ + GDMA_CHANNEL_DIRECTION_RX, /*!< GDMA channel direction: RX */ +} gdma_channel_direction_t; +#endif + +/** + * @brief GDMA channel events that supported by the ETM module + */ +typedef enum { + GDMA_ETM_EVENT_EOF, /*!< Event that the GDMA engine meets EOF descriptor */ + GDMA_ETM_EVENT_MAX, /*!< Maximum number of events */ +} gdma_etm_event_type_t; + +/** + * @brief GDMA channel tasks that supported by the ETM module + */ +typedef enum { + GDMA_ETM_TASK_START, /*!< Start the GDMA machine */ + GDMA_ETM_TASK_MAX, /*!< Maximum number of events */ +} gdma_etm_task_type_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/gpio_types.h b/components/hal/include/hal/gpio_types.h index dbc2208a075e..70043bbeda8a 100644 --- a/components/hal/include/hal/gpio_types.h +++ b/components/hal/include/hal/gpio_types.h @@ -348,6 +348,43 @@ typedef enum { GPIO_NUM_MAX, /** @endcond */ } gpio_num_t; +#elif CONFIG_IDF_TARGET_ESP32C6 +typedef enum { + GPIO_NUM_NC = -1, /*!< Use to signal not connected to S/W */ + GPIO_NUM_0 = 0, /*!< GPIO0, input and output */ + GPIO_NUM_1 = 1, /*!< GPIO1, input and output */ + GPIO_NUM_2 = 2, /*!< GPIO2, input and output */ + GPIO_NUM_3 = 3, /*!< GPIO3, input and output */ + GPIO_NUM_4 = 4, /*!< GPIO4, input and output */ + GPIO_NUM_5 = 5, /*!< GPIO5, input and output */ + GPIO_NUM_6 = 6, /*!< GPIO6, input and output */ + GPIO_NUM_7 = 7, /*!< GPIO7, input and output */ + GPIO_NUM_8 = 8, /*!< GPIO8, input and output */ + GPIO_NUM_9 = 9, /*!< GPIO9, input and output */ + GPIO_NUM_10 = 10, /*!< GPIO10, input and output */ + GPIO_NUM_11 = 11, /*!< GPIO11, input and output */ + GPIO_NUM_12 = 12, /*!< GPIO12, input and output */ + GPIO_NUM_13 = 13, /*!< GPIO13, input and output */ + GPIO_NUM_14 = 14, /*!< GPIO14, input and output */ + GPIO_NUM_15 = 15, /*!< GPIO15, input and output */ + GPIO_NUM_16 = 16, /*!< GPIO16, input and output */ + GPIO_NUM_17 = 17, /*!< GPIO17, input and output */ + GPIO_NUM_18 = 18, /*!< GPIO18, input and output */ + GPIO_NUM_19 = 19, /*!< GPIO19, input and output */ + GPIO_NUM_20 = 20, /*!< GPIO20, input and output */ + GPIO_NUM_21 = 21, /*!< GPIO21, input and output */ + GPIO_NUM_22 = 22, /*!< GPIO22, input and output */ + GPIO_NUM_23 = 23, /*!< GPIO23, input and output */ + GPIO_NUM_24 = 24, /*!< GPIO24, input and output */ + GPIO_NUM_25 = 25, /*!< GPIO25, input and output */ + GPIO_NUM_26 = 26, /*!< GPIO26, input and output */ + GPIO_NUM_27 = 27, /*!< GPIO27, input and output */ + GPIO_NUM_28 = 28, /*!< GPIO28, input and output */ + GPIO_NUM_29 = 29, /*!< GPIO29, input and output */ + GPIO_NUM_30 = 30, /*!< GPIO30, input and output */ + GPIO_NUM_MAX, +/** @endcond */ +} gpio_num_t; #endif typedef enum { diff --git a/components/hal/include/hal/lp_timer_hal.h b/components/hal/include/hal/lp_timer_hal.h new file mode 100644 index 000000000000..b9e551c5dd77 --- /dev/null +++ b/components/hal/include/hal/lp_timer_hal.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/soc.h" +#include "hal/lp_timer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @brief set alarm target value + * + * @param timer_id timer num of lp_timer, 0 or 1 for esp32c6 and esp32h2 + * + * @param value when counter reaches alarm value, alarm event will be triggered + */ +void lp_timer_hal_set_alarm_target(uint8_t timer_id, uint64_t value); + +/** + * @brief get current counter value + */ +uint64_t lp_timer_hal_get_cycle_count(void); + +/** + * @brief clear alarm interrupt status + */ +void lp_timer_hal_clear_alarm_intr_status(void); + +/** + * @brief clear overflow interrupt status + */ +void lp_timer_hal_clear_overflow_intr_status(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/lp_timer_types.h b/components/hal/include/hal/lp_timer_types.h new file mode 100644 index 000000000000..ebb808ca50e6 --- /dev/null +++ b/components/hal/include/hal/lp_timer_types.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "soc/soc_caps.h" + +/** + * @brief The structure of the counter value in lower power timer + */ +typedef struct { + union { + struct { + uint32_t lo: SOC_LP_TIMER_BIT_WIDTH_LO; /*!< Low part of counter value */ + uint32_t hi: SOC_LP_TIMER_BIT_WIDTH_HI; /*!< High part of counter value */ + uint32_t reserved: 16; + }; + uint64_t val; /*!< counter value */ + }; +} lp_timer_counter_value_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/mmu_types.h b/components/hal/include/hal/mmu_types.h index bc64830ef3d6..ea7fcac866e9 100644 --- a/components/hal/include/hal/mmu_types.h +++ b/components/hal/include/hal/mmu_types.h @@ -15,11 +15,20 @@ extern "C" { * MMU Page size */ typedef enum { + MMU_PAGE_8KB = 0x2000, MMU_PAGE_16KB = 0x4000, MMU_PAGE_32KB = 0x8000, MMU_PAGE_64KB = 0x10000, } mmu_page_size_t; +/** + * MMU virtual address flags type + */ +typedef enum { + MMU_VADDR_DATA = 1, + MMU_VADDR_INSTRUCTION = 2, +} mmu_vaddr_t; + /** * External physical memory */ diff --git a/components/hal/include/hal/modem_clock_hal.h b/components/hal/include/hal/modem_clock_hal.h new file mode 100644 index 000000000000..e3cb2b8e05f7 --- /dev/null +++ b/components/hal/include/hal/modem_clock_hal.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for MODEM CLOCK + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/soc_caps.h" +#include "hal/modem_syscon_ll.h" +#include "hal/modem_lpcon_ll.h" +#include "hal/modem_clock_types.h" + +typedef struct { + modem_syscon_dev_t *syscon_dev; + modem_lpcon_dev_t *lpcon_dev; +} modem_clock_hal_context_t; + +#if MAC_SUPPORT_PMU_MODEM_STATE +void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap); +uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain); +#endif + +void modem_clock_hal_enable_modem_adc_common_fe_clock(modem_clock_hal_context_t *hal, bool enable); +void modem_clock_hal_enable_modem_private_fe_clock(modem_clock_hal_context_t *hal, bool enable); + +#if SOC_BT_SUPPORTED +void modem_clock_hal_set_ble_rtc_timer_divisor_value(modem_clock_hal_context_t *hal, uint32_t divider); +void modem_clock_hal_enable_ble_rtc_timer_clock(modem_clock_hal_context_t *hal, bool enable); +void modem_clock_hal_select_ble_rtc_timer_lpclk_source(modem_clock_hal_context_t *hal, modem_clock_lpclk_src_t src); +void modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(modem_clock_hal_context_t *hal); +#endif + +void modem_clock_hal_select_coex_lpclk_source(modem_clock_hal_context_t *hal, modem_clock_lpclk_src_t src); +void modem_clock_hal_deselect_all_coex_lpclk_source(modem_clock_hal_context_t *hal); + +#if SOC_WIFI_SUPPORTED +void modem_clock_hal_select_wifi_lpclk_source(modem_clock_hal_context_t *hal, modem_clock_lpclk_src_t src); +void modem_clock_hal_deselect_all_wifi_lpclk_source(modem_clock_hal_context_t *hal); +void modem_clock_hal_enable_wifipwr_clock(modem_clock_hal_context_t *hal, bool enable); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/modem_clock_types.h b/components/hal/include/hal/modem_clock_types.h new file mode 100644 index 000000000000..bb972f7a7f46 --- /dev/null +++ b/components/hal/include/hal/modem_clock_types.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MODEM_CLOCK_DOMAIN_MODEM_APB = 0, + MODEM_CLOCK_DOMAIN_MODEM_PERIPH, + MODEM_CLOCK_DOMAIN_WIFI, + MODEM_CLOCK_DOMAIN_BT, + MODEM_CLOCK_DOMAIN_MODEM_FE, + MODEM_CLOCK_DOMAIN_IEEE802154, + MODEM_CLOCK_DOMAIN_LP_APB, + MODEM_CLOCK_DOMAIN_I2C_MASTER, + MODEM_CLOCK_DOMAIN_COEX, + MODEM_CLOCK_DOMAIN_WIFIPWR, + MODEM_CLOCK_DOMAIN_MAX +} modem_clock_domain_t; + +typedef enum { + MODEM_CLOCK_LPCLK_SRC_INVALID = -1, + MODEM_CLOCK_LPCLK_SRC_RC_SLOW = 0, + MODEM_CLOCK_LPCLK_SRC_RC_FAST, + MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL, + MODEM_CLOCK_LPCLK_SRC_RC32K, + MODEM_CLOCK_LPCLK_SRC_XTAL32K, + MODEM_CLOCK_LPCLK_SRC_EXT32K, + MODEM_CLOCK_LPCLK_SRC_MAX +} modem_clock_lpclk_src_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/pau_hal.h b/components/hal/include/hal/pau_hal.h new file mode 100644 index 000000000000..7a8456cf385a --- /dev/null +++ b/components/hal/include/hal/pau_hal.h @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PAU (Power Assist Unit) + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/soc_caps.h" +#include "hal/pau_ll.h" +#include "hal/pau_types.h" + +typedef struct { + pau_dev_t *dev; +} pau_hal_context_t; + +/** + * @brief Set regdma entry link address + * + * @param hal regdma hal context + * @param link_addr entry link address value + */ +void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr); + +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +/** + * @brief Set regdma modem link address + * + * @param hal regdma hal context + * @param link_addr modem link address value + */ +#define pau_hal_set_regdma_modem_link_addr(hal, addr) pau_ll_set_regdma_wifimac_link_addr((hal)->dev, (addr)) + +/** + * @brief Start transmission on regdma modem link + * + * @param hal regdma hal context + * @param backup_or_restore false:restore true:backup + */ +void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore); + +/** + * @brief Stop transmission on regdma modem link + * + * @param hal regdma hal context + */ +void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal); +#endif + +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA +/** + * @brief Set regdma system link address + * + * @param hal regdma hal context + * @param link_addr main link address value + */ +#define pau_hal_set_regdma_system_link_addr(hal, addr) pau_ll_set_regdma_link0_addr(hal->dev, (addr)) + +/** + * @brief Start transmission on regdma system link + * + * @param hal regdma hal context + * @param backup_or_restore false:restore true:backup + */ +void pau_hal_start_regdma_system_link(pau_hal_context_t *hal, bool backup_or_restore); +/** + * @brief Stop transmission on regdma system link + * + * @param hal regdma hal context + */ +void pau_hal_stop_regdma_system_link(pau_hal_context_t *hal); +#endif + +/** + * @brief Set regdma extra link address + * + * @param hal regdma hal context + * @param link_addr extra link address value + */ +#define pau_hal_set_regdma_extra_link_addr(hal, addr) pau_ll_set_regdma_link3_addr(hal->dev, (addr)) + +/** + * @brief Start transmission on regdma extra link + * + * @param hal regdma hal context + * @param backup_or_restore false:restore true:backup + */ +void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore); + +/** + * @brief Stop transmission on regdma extra link + * + * @param hal regdma hal context + */ +void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal); + +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA +/** + * @brief Enable or disable PAU module clock + * + * @param hal regdma hal context + */ +void pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enable); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/pau_types.h b/components/hal/include/hal/pau_types.h new file mode 100644 index 000000000000..19b4028f5a7a --- /dev/null +++ b/components/hal/include/hal/pau_types.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +#define PAU_REGDMA_LINK_NUM (SOC_PM_PAU_LINK_NUM) + +/** + * @brief PAU REGDMA all link address buffer + */ +typedef void * pau_regdma_link_addr_t[PAU_REGDMA_LINK_NUM]; diff --git a/components/hal/include/hal/pmu_types.h b/components/hal/include/hal/pmu_types.h new file mode 100644 index 000000000000..cd219752324a --- /dev/null +++ b/components/hal/include/hal/pmu_types.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "soc/soc_caps.h" + +/** + * @brief PMU modes of HP system + */ +typedef enum { + PMU_MODE_HP_ACTIVE = 0, /*!< PMU in HP_ACTIVE mode */ + PMU_MODE_HP_MODEM, /*!< PMU in HP_MODEM mode */ + PMU_MODE_HP_SLEEP, /*!< PMU in HP_SLEEP mode */ + PMU_MODE_HP_MAX, +} pmu_hp_mode_t; + +/** + * @brief PMU modes of LP system + */ +typedef enum { + PMU_MODE_LP_ACTIVE = 0, /*!< PMU in LP_ACTIVE mode */ + PMU_MODE_LP_SLEEP, /*!< PMU in LP_SLEEP mode */ + PMU_MODE_LP_MAX, +} pmu_lp_mode_t; + +typedef enum { + PMU_HP_PD_TOP = 0, /*!< Power domain of digital top */ +#if SOC_PM_SUPPORT_HP_AON_PD + PMU_HP_PD_HP_AON = 1, /*!< Power domain of always-on */ +#endif + PMU_HP_PD_CPU = 2, /*!< Power domain of HP CPU */ + PMU_HP_PD_RESERVED = 3, /*!< Reserved power domain */ + PMU_HP_PD_WIFI = 4, /*!< Power domain of WIFI */ +} pmu_hp_power_domain_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/rtc_io_hal.h b/components/hal/include/hal/rtc_io_hal.h index d3d9684a053c..9cd489e3fc44 100644 --- a/components/hal/include/hal/rtc_io_hal.h +++ b/components/hal/include/hal/rtc_io_hal.h @@ -27,6 +27,7 @@ extern "C" { #endif #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#include "hal/rtc_io_types.h" /** * Select the rtcio function. * diff --git a/components/hal/include/hal/sha_types.h b/components/hal/include/hal/sha_types.h index 6a9b6ea1c1a6..3946f1157ee3 100644 --- a/components/hal/include/hal/sha_types.h +++ b/components/hal/include/hal/sha_types.h @@ -21,6 +21,8 @@ #include "esp32h2/rom/sha.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/sha.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/sha.h" #endif #ifdef __cplusplus diff --git a/components/hal/include/hal/wdt_hal.h b/components/hal/include/hal/wdt_hal.h index 13d9f5d2f552..d101d2009f85 100644 --- a/components/hal/include/hal/wdt_hal.h +++ b/components/hal/include/hal/wdt_hal.h @@ -25,6 +25,7 @@ extern "C" { #endif #include +#include "sdkconfig.h" #include "soc/soc_caps.h" #include "hal/wdt_types.h" #include "hal/mwdt_ll.h" @@ -37,10 +38,21 @@ typedef struct { wdt_inst_t inst; /**< Which WDT instance this HAL context is using (i.e. MWDT0, MWDT1, RWDT)*/ union { timg_dev_t *mwdt_dev; /**< Starting address of the MWDT */ +#if CONFIG_IDF_TARGET_ESP32C6 + rwdt_dev_t *rwdt_dev; /**< Starting address of the RWDT */ +#else rtc_cntl_dev_t *rwdt_dev; /**< Starting address of the RWDT*/ +#endif }; } wdt_hal_context_t; +#if CONFIG_IDF_TARGET_ESP32C6 +#define RWDT_HAL_CONTEXT_DEFAULT() { \ + .inst = WDT_RWDT, \ + .rwdt_dev = RWDT_DEV_GET() \ +} +#endif + /* ---------------------------- Init and Config ----------------------------- */ /** diff --git a/components/hal/include/hal/wdt_types.h b/components/hal/include/hal/wdt_types.h index afc0dc498330..8c962bfdc1aa 100644 --- a/components/hal/include/hal/wdt_types.h +++ b/components/hal/include/hal/wdt_types.h @@ -65,6 +65,11 @@ typedef enum { WDT_RESET_SIG_LENGTH_3_2us = 7 /*!< 3.2 us */ } wdt_reset_sig_length_t; +#if CONFIG_IDF_TARGET_ESP32C6 +#include "soc/clk_tree_defs.h" +typedef soc_periph_mwdt_clk_src_t mwdt_clock_source_t; +#endif + #ifdef __cplusplus } diff --git a/components/hal/lp_timer_hal.c b/components/hal/lp_timer_hal.c new file mode 100644 index 000000000000..e70d868865c0 --- /dev/null +++ b/components/hal/lp_timer_hal.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_attr.h" +#include "hal/lp_timer_ll.h" + +static DRAM_ATTR struct { + lp_timer_dev_t *dev; +} lp_timer_context = { .dev = &LP_TIMER }; + +uint64_t IRAM_ATTR lp_timer_hal_get_cycle_count(void) +{ + lp_timer_ll_counter_snapshot(lp_timer_context.dev); + + uint32_t lo = lp_timer_ll_get_counter_value_low(lp_timer_context.dev, 0); + uint32_t hi = lp_timer_ll_get_counter_value_high(lp_timer_context.dev, 0); + + lp_timer_counter_value_t result = { + .lo = lo, + .hi = hi + }; + return result.val; +} diff --git a/components/hal/mmu_hal.c b/components/hal/mmu_hal.c index ad0e829bce31..74dab67ebcf4 100644 --- a/components/hal/mmu_hal.c +++ b/components/hal/mmu_hal.c @@ -84,14 +84,22 @@ void mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr, HAL_ASSERT(vaddr % page_size_in_bytes == 0); HAL_ASSERT(paddr % page_size_in_bytes == 0); HAL_ASSERT((paddr + len - 1) < mmu_hal_pages_to_bytes(mmu_id, MMU_MAX_PADDR_PAGE_NUM)); +#if CONFIG_IDF_TARGET_ESP32C6 + HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr, len, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION)); +#else HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr, len)); +#endif uint32_t page_num = (len + page_size_in_bytes - 1) / page_size_in_bytes; uint32_t entry_id = 0; uint32_t mmu_val; //This is the physical address in the format that MMU supported *out_len = mmu_hal_pages_to_bytes(mmu_id, page_num); +#if CONFIG_IDF_TARGET_ESP32C6 + mmu_val = mmu_ll_format_paddr(mmu_id, paddr, mem_type); +#else mmu_val = mmu_ll_format_paddr(mmu_id, paddr); +#endif while (page_num) { entry_id = mmu_ll_get_entry_id(mmu_id, vaddr); diff --git a/components/hal/platform_port/include/hal/misc.h b/components/hal/platform_port/include/hal/misc.h index 4afb49653ffb..f366873eaf2a 100644 --- a/components/hal/platform_port/include/hal/misc.h +++ b/components/hal/platform_port/include/hal/misc.h @@ -56,4 +56,6 @@ temp_reg.reg_field; \ }) +#define hal_memcpy(dst_mem, src_mem, len) (__extension__({memcpy(dst_mem, src_mem, len);})) + /** @endcond */ diff --git a/components/hal/wdt_hal_iram.c b/components/hal/wdt_hal_iram.c index 5afd38433cce..2e4cfc59266d 100644 --- a/components/hal/wdt_hal_iram.c +++ b/components/hal/wdt_hal_iram.c @@ -24,7 +24,11 @@ void wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescale } #endif else { +#if CONFIG_IDF_TARGET_ESP32C6 + hal->rwdt_dev = RWDT_DEV_GET(); +#else hal->rwdt_dev = &RTCCNTL; +#endif } hal->inst = wdt_inst; @@ -67,7 +71,7 @@ void wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescale mwdt_ll_disable_stage(hal->mwdt_dev, 1); mwdt_ll_disable_stage(hal->mwdt_dev, 2); mwdt_ll_disable_stage(hal->mwdt_dev, 3); -#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C2 +#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C2 && !CONFIG_IDF_TARGET_ESP32C6 //Enable or disable level interrupt. Edge interrupt is always disabled. mwdt_ll_set_edge_intr(hal->mwdt_dev, false); mwdt_ll_set_level_intr(hal->mwdt_dev, enable_intr); diff --git a/components/heap/port/esp32c6/memory_layout.c b/components/heap/port/esp32c6/memory_layout.c index e69de29bb2d1..ee8a134ed814 100644 --- a/components/heap/port/esp32c6/memory_layout.c +++ b/components/heap/port/esp32c6/memory_layout.c @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_attr.h" +#include "sdkconfig.h" +#include "soc/soc.h" +#include "heap_memory_layout.h" +#include "esp_heap_caps.h" + +/** + * @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC. + * Each type of memory map consists of one or more regions in the address space. + * Each type contains an array of prioritized capabilities. + * Types with later entries are only taken if earlier ones can't fulfill the memory request. + * + * - For a normal malloc (MALLOC_CAP_DEFAULT), give away the DRAM-only memory first, then pass off any dual-use IRAM regions, finally eat into the application memory. + * - For a malloc where 32-bit-aligned-only access is okay, first allocate IRAM, then DRAM, finally application IRAM. + * - Application mallocs (PIDx) will allocate IRAM first, if possible, then DRAM. + * - Most other malloc caps only fit in one region anyway. + * + */ + +/* Index of memory in `soc_memory_types[]` */ +enum { + SOC_MEMORY_TYPE_DRAM = 0, + SOC_MEMORY_TYPE_STACK_DRAM = 1, + SOC_MEMORY_TYPE_DIRAM = 2, + SOC_MEMORY_TYPE_STACK_DIRAM = 3, + SOC_MEMORY_TYPE_RTCRAM = 4, + SOC_MEMORY_TYPE_NUM, +}; + +const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { + // Type 0: DRAM + [SOC_MEMORY_TYPE_DRAM] = { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, + // Type 1: DRAM used for startup stacks + [SOC_MEMORY_TYPE_STACK_DRAM] = { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, MALLOC_CAP_RETENTION }, false, true}, + // Type 2: DRAM which has an alias on the I-port + [SOC_MEMORY_TYPE_DIRAM] = { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false}, + // Type 3: DIRAM used for startup stacks + [SOC_MEMORY_TYPE_STACK_DIRAM] = { "STACK/DIRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT | MALLOC_CAP_RETENTION, MALLOC_CAP_EXEC | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, true, true}, + // Type 4: RTCRAM // TODO: IDF-5667 Better to rename to LPRAM + [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false}, +}; + +#ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE +#define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DRAM +#define SOC_MEMORY_TYPE_STACK_DEFAULT SOC_MEMORY_TYPE_STACK_DRAM +#else +#define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DIRAM +#define SOC_MEMORY_TYPE_STACK_DEFAULT SOC_MEMORY_TYPE_STACK_DIRAM +#endif + +const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t); + +/** + * @brief Region descriptors. These describe all regions of memory available, and map them to a type in the above type. + * + * @note Because of requirements in the coalescing code which merges adjacent regions, + * this list should always be sorted from low to high by start address. + * + */ + +/** + * Register the shared buffer area of the last memory block into the heap during heap initialization + */ +#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) + +const soc_memory_region_t soc_memory_regions[] = { + { 0x40800000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40800000}, //D/IRAM level0, can be used as trace memory + { 0x40820000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40820000}, //D/IRAM level1, can be used as trace memory + { 0x40840000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40840000}, //D/IRAM level2, can be used as trace memory + { 0x40860000, (APP_USABLE_DRAM_END-0x40860000), SOC_MEMORY_TYPE_DEFAULT, 0x40860000}, //D/IRAM level3, can be used as trace memory + { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_STACK_DEFAULT, APP_USABLE_DRAM_END}, //D/IRAM level3, can be used as trace memory (ROM reserved area) +#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP + { 0x50000000, 0x4000, SOC_MEMORY_TYPE_RTCRAM, 0}, //LPRAM +#endif +}; + +const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t); + + +extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_slow_end; +extern int _rtc_reserved_start, _rtc_reserved_end; + +/** + * Reserved memory regions. + * These are removed from the soc_memory_regions array when heaps are created. + * + */ + +// Static data region. DRAM used by data+bss and possibly rodata +SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data); + +// Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips +SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); + +#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP +// TODO: IDF-6019 check reserved lp mem region +SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); +#endif + +SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_start, (intptr_t)&_rtc_reserved_end, rtc_reserved_data); diff --git a/components/newlib/locks.c b/components/newlib/locks.c index b11c07017e48..572f242a257d 100644 --- a/components/newlib/locks.c +++ b/components/newlib/locks.c @@ -384,7 +384,7 @@ void esp_newlib_locks_init(void) __sinit_recursive_mutex = (_lock_t) &s_common_recursive_mutex; extern _lock_t __sfp_recursive_mutex; __sfp_recursive_mutex = (_lock_t) &s_common_recursive_mutex; -#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C2) +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6) /* Newlib 3.3.0 is used in ROM, built with _RETARGETABLE_LOCKING. * No access to lock variables for the purpose of ECO forward compatibility, * however we have an API to initialize lock variables used in the ROM. diff --git a/components/newlib/newlib_init.c b/components/newlib/newlib_init.c index bfb0c81143e5..16af3f597312 100644 --- a/components/newlib/newlib_init.c +++ b/components/newlib/newlib_init.c @@ -33,6 +33,8 @@ #include "esp32h2/rom/libc_stubs.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/libc_stubs.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/libc_stubs.h" #endif static struct _reent s_reent; @@ -109,7 +111,7 @@ static struct syscall_stub_table s_stub_table = { ._printf_float = NULL, ._scanf_float = NULL, #endif -#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 /* TODO IDF-2570 : mark that this assert failed in ROM, to avoid confusion between IDF & ROM assertion failures (as function names & source file names will be similar) */ @@ -132,7 +134,7 @@ void esp_newlib_init(void) syscall_table_ptr_pro = syscall_table_ptr_app = &s_stub_table; #elif CONFIG_IDF_TARGET_ESP32S2 syscall_table_ptr_pro = &s_stub_table; -#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 syscall_table_ptr = &s_stub_table; #endif diff --git a/components/riscv/include/riscv/csr.h b/components/riscv/include/riscv/csr.h index 4fae673232ef..a4dec5db36cf 100644 --- a/components/riscv/include/riscv/csr.h +++ b/components/riscv/include/riscv/csr.h @@ -136,6 +136,24 @@ extern "C" { #define _CSR_STRINGIFY(REG) #REG /* needed so the 'reg' argument can be a macro or a register name */ +/* C6 physical memory attributes. C3 does not use these. */ +#define CSR_PMACFG0 0xBC0 +#define CSR_PMAADDR0 0xBD0 +#define PMA_EN (1U << 0) +#define PMA_X (1U << 2) +#define PMA_W (1U << 3) +#define PMA_R (1U << 4) +#define PMA_L (1U << 29) +#define PMA_SHIFT 2 +#define PMA_TOR 0x40000000 +#define PMA_NA4 0x80000000 +#define PMA_NAPOT 0xC0000000 +#define PMA_ENTRY_SET_TOR(ENTRY, ADDR, CFG) \ + do { \ + RV_WRITE_CSR((CSR_PMAADDR0) + (ENTRY), (ADDR) >> (PMA_SHIFT)); \ + RV_WRITE_CSR((CSR_PMACFG0) + (ENTRY), CFG); \ + } while (0) + #ifdef __cplusplus } #endif diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index f0c2e5f8ddb9..ae6b61a347e5 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -10,7 +10,11 @@ #include "soc/soc_caps.h" #include "soc/assist_debug_reg.h" +#if defined(SOC_ESP32_C6) +#include "soc/interrupt_reg.h" +#else #include "soc/interrupt_core0_reg.h" +#endif #include "esp_attr.h" #include "riscv/csr.h" #include "riscv/interrupt.h" @@ -107,6 +111,16 @@ FORCE_INLINE_ATTR void rv_utils_intr_edge_ack(int intr_num) REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr_num); } +FORCE_INLINE_ATTR void rv_utils_intr_global_enable(void) +{ + RV_SET_CSR(mstatus, MSTATUS_MIE); +} + +FORCE_INLINE_ATTR void rv_utils_intr_global_disable(void) +{ + RV_CLEAR_CSR(mstatus, MSTATUS_MIE); +} + /* -------------------------------------------------- Memory Ports ----------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ */ diff --git a/components/soc/esp32c6/adc_periph.c b/components/soc/esp32c6/adc_periph.c new file mode 100644 index 000000000000..34e69f81b619 --- /dev/null +++ b/components/soc/esp32c6/adc_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/adc_periph.h" + +/* Store IO number corresponding to the ADC channel number. */ +const int adc_channel_io_map[SOC_ADC_PERIPH_NUM][SOC_ADC_MAX_CHANNEL_NUM] = { + /* ADC1 */ + { + ADC1_CHANNEL_0_GPIO_NUM, + ADC1_CHANNEL_1_GPIO_NUM, + ADC1_CHANNEL_2_GPIO_NUM, + ADC1_CHANNEL_3_GPIO_NUM, + ADC1_CHANNEL_4_GPIO_NUM, + ADC1_CHANNEL_5_GPIO_NUM, + ADC1_CHANNEL_6_GPIO_NUM, + }, +}; diff --git a/components/soc/esp32c6/dedic_gpio_periph.c b/components/soc/esp32c6/dedic_gpio_periph.c new file mode 100644 index 000000000000..1321608a3eb5 --- /dev/null +++ b/components/soc/esp32c6/dedic_gpio_periph.c @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/gpio_sig_map.h" +#include "soc/dedic_gpio_periph.h" + +const dedic_gpio_signal_conn_t dedic_gpio_periph_signals = { + .module = -1, + .irq = -1, + .cores = { + [0] = { + .in_sig_per_channel = { + [0] = CPU_GPIO_IN0_IDX, + [1] = CPU_GPIO_IN1_IDX, + [2] = CPU_GPIO_IN2_IDX, + [3] = CPU_GPIO_IN3_IDX, + [4] = CPU_GPIO_IN4_IDX, + [5] = CPU_GPIO_IN5_IDX, + [6] = CPU_GPIO_IN6_IDX, + [7] = CPU_GPIO_IN7_IDX, + }, + .out_sig_per_channel = { + [0] = CPU_GPIO_OUT0_IDX, + [1] = CPU_GPIO_OUT1_IDX, + [2] = CPU_GPIO_OUT2_IDX, + [3] = CPU_GPIO_OUT3_IDX, + [4] = CPU_GPIO_OUT4_IDX, + [5] = CPU_GPIO_OUT5_IDX, + [6] = CPU_GPIO_OUT6_IDX, + [7] = CPU_GPIO_OUT7_IDX, + } + }, + }, +}; diff --git a/components/soc/esp32c6/gdma_periph.c b/components/soc/esp32c6/gdma_periph.c new file mode 100644 index 000000000000..83fe4ddbb53b --- /dev/null +++ b/components/soc/esp32c6/gdma_periph.c @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/gdma_periph.h" + +const gdma_signal_conn_t gdma_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_GDMA_MODULE, + .pairs = { + [0] = { + .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, + .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + }, + [1] = { + .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, + .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + }, + [2] = { + .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, + .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + } + } + } + } +}; diff --git a/components/soc/esp32c6/gpio_periph.c b/components/soc/esp32c6/gpio_periph.c new file mode 100644 index 000000000000..d04df9fc9770 --- /dev/null +++ b/components/soc/esp32c6/gpio_periph.c @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/gpio_periph.h" + +const uint32_t GPIO_PIN_MUX_REG[] = { + IO_MUX_GPIO0_REG, + IO_MUX_GPIO1_REG, + IO_MUX_GPIO2_REG, + IO_MUX_GPIO3_REG, + IO_MUX_GPIO4_REG, + IO_MUX_GPIO5_REG, + IO_MUX_GPIO6_REG, + IO_MUX_GPIO7_REG, + IO_MUX_GPIO8_REG, + IO_MUX_GPIO9_REG, + IO_MUX_GPIO10_REG, + IO_MUX_GPIO11_REG, + IO_MUX_GPIO12_REG, + IO_MUX_GPIO13_REG, + IO_MUX_GPIO14_REG, + IO_MUX_GPIO15_REG, + IO_MUX_GPIO16_REG, + IO_MUX_GPIO17_REG, + IO_MUX_GPIO18_REG, + IO_MUX_GPIO19_REG, + IO_MUX_GPIO20_REG, + IO_MUX_GPIO21_REG, + IO_MUX_GPIO22_REG, + IO_MUX_GPIO23_REG, + IO_MUX_GPIO24_REG, + IO_MUX_GPIO25_REG, + IO_MUX_GPIO26_REG, + IO_MUX_GPIO27_REG, + IO_MUX_GPIO28_REG, + IO_MUX_GPIO29_REG, + IO_MUX_GPIO30_REG, +}; + +_Static_assert(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG"); + +const uint32_t GPIO_HOLD_MASK[] = { + BIT(0), //GPIO0 // LP_AON_GPIO_HOLD0_REG + BIT(1), //GPIO1 + BIT(2), //GPIO2 + BIT(3), //GPIO3 + BIT(4), //GPIO4 + BIT(5), //GPIO5 + BIT(6), //GPIO6 + BIT(7), //GPIO7 + BIT(8), //GPIO8 + BIT(9), //GPIO9 + BIT(10), //GPIO10 + BIT(11), //GPIO11 + BIT(12), //GPIO12 + BIT(13), //GPIO13 + BIT(14), //GPIO14 + BIT(15), //GPIO15 + BIT(16), //GPIO16 + BIT(17), //GPIO17 + BIT(18), //GPIO18 + BIT(19), //GPIO19 + BIT(20), //GPIO20 + BIT(21), //GPIO21 + BIT(22), //GPIO22 + BIT(23), //GPIO23 + BIT(24), //GPIO24 + BIT(25), //GPIO25 + BIT(26), //GPIO26 + BIT(27), //GPIO27 + BIT(28), //GPIO28 + BIT(29), //GPIO29 + BIT(30), //GPIO30 +}; + +_Static_assert(sizeof(GPIO_HOLD_MASK) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_HOLD_MASK"); diff --git a/components/soc/esp32c6/i2c_periph.c b/components/soc/esp32c6/i2c_periph.c new file mode 100644 index 000000000000..95a1a0fe16a5 --- /dev/null +++ b/components/soc/esp32c6/i2c_periph.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/i2c_periph.h" +#include "soc/gpio_sig_map.h" + +/* + Bunch of constants for every I2C peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { + { + .sda_out_sig = I2CEXT0_SDA_OUT_IDX, + .sda_in_sig = I2CEXT0_SDA_IN_IDX, + .scl_out_sig = I2CEXT0_SCL_OUT_IDX, + .scl_in_sig = I2CEXT0_SCL_IN_IDX, + .irq = ETS_I2C_EXT0_INTR_SOURCE, + .module = PERIPH_I2C0_MODULE, + }, +}; diff --git a/components/soc/esp32c6/i2s_periph.c b/components/soc/esp32c6/i2s_periph.c new file mode 100644 index 000000000000..89f49e26171a --- /dev/null +++ b/components/soc/esp32c6/i2s_periph.c @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/i2s_periph.h" +#include "soc/gpio_sig_map.h" + +/* + Bunch of constants for every I2S peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = { + { + .mck_out_sig = I2S_MCLK_OUT_IDX, + + .m_tx_bck_sig = I2SO_BCK_OUT_IDX, + .m_rx_bck_sig = I2SI_BCK_OUT_IDX, + .m_tx_ws_sig = I2SO_WS_OUT_IDX, + .m_rx_ws_sig = I2SI_WS_OUT_IDX, + + .s_tx_bck_sig = I2SO_BCK_IN_IDX, + .s_rx_bck_sig = I2SI_BCK_IN_IDX, + .s_tx_ws_sig = I2SO_WS_IN_IDX, + .s_rx_ws_sig = I2SI_WS_IN_IDX, + + .data_out_sigs[0] = I2SO_SD_OUT_IDX, + .data_out_sigs[1] = I2SO_SD1_OUT_IDX, + .data_in_sig = I2SI_SD_IN_IDX, + + .irq = -1, + .module = PERIPH_I2S1_MODULE, + } +}; diff --git a/components/soc/esp32c6/ieee802154_periph.c b/components/soc/esp32c6/ieee802154_periph.c new file mode 100644 index 000000000000..275c83bc596b --- /dev/null +++ b/components/soc/esp32c6/ieee802154_periph.c @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/ieee802154_periph.h" + +const ieee802154_conn_t ieee802154_periph = { + .module = PERIPH_IEEE802154_MODULE, + .irq_id = ETS_ZB_MAC_SOURCE, +}; diff --git a/components/soc/esp32c6/include/modem/modem_lpcon_reg.h b/components/soc/esp32c6/include/modem/modem_lpcon_reg.h new file mode 100644 index 000000000000..3cddba41bc1a --- /dev/null +++ b/components/soc/esp32c6/include/modem/modem_lpcon_reg.h @@ -0,0 +1,382 @@ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "modem/reg_base.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define MODEM_LPCON_TEST_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x0) +/* MODEM_LPCON_CLK_EN : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_EN (BIT(0)) +#define MODEM_LPCON_CLK_EN_M (MODEM_LPCON_CLK_EN_V << MODEM_LPCON_CLK_EN_S) +#define MODEM_LPCON_CLK_EN_V 0x00000001U +#define MODEM_LPCON_CLK_EN_S 0 +/* MODEM_LPCON_CLK_DEBUG_ENA : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_DEBUG_ENA (BIT(1)) +#define MODEM_LPCON_CLK_DEBUG_ENA_M (MODEM_LPCON_CLK_DEBUG_ENA_V << MODEM_LPCON_CLK_DEBUG_ENA_S) +#define MODEM_LPCON_CLK_DEBUG_ENA_V 0x00000001U +#define MODEM_LPCON_CLK_DEBUG_ENA_S 1 + +#define MODEM_LPCON_LP_TIMER_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x4) +/* MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW (BIT(0)) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW_M (MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW_V << MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW_S) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW_V 0x00000001U +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_SLOW_S 0 +/* MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST (BIT(1)) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST_M (MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST_V << MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST_S) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST_V 0x00000001U +#define MODEM_LPCON_CLK_LP_TIMER_SEL_OSC_FAST_S 1 +/* MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL (BIT(2)) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL_M (MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL_V << MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL_S) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL_V 0x00000001U +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL_S 2 +/* MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K (BIT(3)) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K_M (MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K_V << MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K_S) +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K_V 0x00000001U +#define MODEM_LPCON_CLK_LP_TIMER_SEL_XTAL32K_S 3 +/* MODEM_LPCON_CLK_LP_TIMER_DIV_NUM : R/W; bitpos: [15:4]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_DIV_NUM 0x00000FFFU +#define MODEM_LPCON_CLK_LP_TIMER_DIV_NUM_M (MODEM_LPCON_CLK_LP_TIMER_DIV_NUM_V << MODEM_LPCON_CLK_LP_TIMER_DIV_NUM_S) +#define MODEM_LPCON_CLK_LP_TIMER_DIV_NUM_V 0x00000FFFU +#define MODEM_LPCON_CLK_LP_TIMER_DIV_NUM_S 4 + +#define MODEM_LPCON_COEX_LP_CLK_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x8) +/* MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW (BIT(0)) +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW_M (MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW_V << MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW_S) +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW_V 0x00000001U +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_SLOW_S 0 +/* MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST (BIT(1)) +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST_M (MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST_V << MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST_S) +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST_V 0x00000001U +#define MODEM_LPCON_CLK_COEX_LP_SEL_OSC_FAST_S 1 +/* MODEM_LPCON_CLK_COEX_LP_SEL_XTAL : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL (BIT(2)) +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL_M (MODEM_LPCON_CLK_COEX_LP_SEL_XTAL_V << MODEM_LPCON_CLK_COEX_LP_SEL_XTAL_S) +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL_V 0x00000001U +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL_S 2 +/* MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K (BIT(3)) +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K_M (MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K_V << MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K_S) +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K_V 0x00000001U +#define MODEM_LPCON_CLK_COEX_LP_SEL_XTAL32K_S 3 +/* MODEM_LPCON_CLK_COEX_LP_DIV_NUM : R/W; bitpos: [15:4]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_LP_DIV_NUM 0x00000FFFU +#define MODEM_LPCON_CLK_COEX_LP_DIV_NUM_M (MODEM_LPCON_CLK_COEX_LP_DIV_NUM_V << MODEM_LPCON_CLK_COEX_LP_DIV_NUM_S) +#define MODEM_LPCON_CLK_COEX_LP_DIV_NUM_V 0x00000FFFU +#define MODEM_LPCON_CLK_COEX_LP_DIV_NUM_S 4 + +#define MODEM_LPCON_WIFI_LP_CLK_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0xc) +/* MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW (BIT(0)) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW_M (MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW_V << MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW_S) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW_V 0x00000001U +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_SLOW_S 0 +/* MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST (BIT(1)) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST_M (MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST_V << MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST_S) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST_V 0x00000001U +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_OSC_FAST_S 1 +/* MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL (BIT(2)) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL_M (MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL_V << MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL_S) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL_V 0x00000001U +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL_S 2 +/* MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K (BIT(3)) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K_M (MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K_V << MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K_S) +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K_V 0x00000001U +#define MODEM_LPCON_CLK_WIFIPWR_LP_SEL_XTAL32K_S 3 +/* MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM : R/W; bitpos: [15:4]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM 0x00000FFFU +#define MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM_M (MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM_V << MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM_S) +#define MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM_V 0x00000FFFU +#define MODEM_LPCON_CLK_WIFIPWR_LP_DIV_NUM_S 4 + +#define MODEM_LPCON_I2C_MST_CLK_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x10) +/* MODEM_LPCON_CLK_I2C_MST_SEL_160M : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_I2C_MST_SEL_160M (BIT(0)) +#define MODEM_LPCON_CLK_I2C_MST_SEL_160M_M (MODEM_LPCON_CLK_I2C_MST_SEL_160M_V << MODEM_LPCON_CLK_I2C_MST_SEL_160M_S) +#define MODEM_LPCON_CLK_I2C_MST_SEL_160M_V 0x00000001U +#define MODEM_LPCON_CLK_I2C_MST_SEL_160M_S 0 + +#define MODEM_LPCON_MODEM_32K_CLK_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x14) +/* MODEM_LPCON_CLK_MODEM_32K_SEL : R/W; bitpos: [1:0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_MODEM_32K_SEL 0x00000003U +#define MODEM_LPCON_CLK_MODEM_32K_SEL_M (MODEM_LPCON_CLK_MODEM_32K_SEL_V << MODEM_LPCON_CLK_MODEM_32K_SEL_S) +#define MODEM_LPCON_CLK_MODEM_32K_SEL_V 0x00000003U +#define MODEM_LPCON_CLK_MODEM_32K_SEL_S 0 + +#define MODEM_LPCON_CLK_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x18) +/* MODEM_LPCON_CLK_WIFIPWR_EN : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_EN (BIT(0)) +#define MODEM_LPCON_CLK_WIFIPWR_EN_M (MODEM_LPCON_CLK_WIFIPWR_EN_V << MODEM_LPCON_CLK_WIFIPWR_EN_S) +#define MODEM_LPCON_CLK_WIFIPWR_EN_V 0x00000001U +#define MODEM_LPCON_CLK_WIFIPWR_EN_S 0 +/* MODEM_LPCON_CLK_COEX_EN : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_EN (BIT(1)) +#define MODEM_LPCON_CLK_COEX_EN_M (MODEM_LPCON_CLK_COEX_EN_V << MODEM_LPCON_CLK_COEX_EN_S) +#define MODEM_LPCON_CLK_COEX_EN_V 0x00000001U +#define MODEM_LPCON_CLK_COEX_EN_S 1 +/* MODEM_LPCON_CLK_I2C_MST_EN : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_I2C_MST_EN (BIT(2)) +#define MODEM_LPCON_CLK_I2C_MST_EN_M (MODEM_LPCON_CLK_I2C_MST_EN_V << MODEM_LPCON_CLK_I2C_MST_EN_S) +#define MODEM_LPCON_CLK_I2C_MST_EN_V 0x00000001U +#define MODEM_LPCON_CLK_I2C_MST_EN_S 2 +/* MODEM_LPCON_CLK_LP_TIMER_EN : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_EN (BIT(3)) +#define MODEM_LPCON_CLK_LP_TIMER_EN_M (MODEM_LPCON_CLK_LP_TIMER_EN_V << MODEM_LPCON_CLK_LP_TIMER_EN_S) +#define MODEM_LPCON_CLK_LP_TIMER_EN_V 0x00000001U +#define MODEM_LPCON_CLK_LP_TIMER_EN_S 3 + +#define MODEM_LPCON_CLK_CONF_FORCE_ON_REG (DR_REG_MODEM_LPCON_BASE + 0x1c) +/* MODEM_LPCON_CLK_WIFIPWR_FO : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_FO (BIT(0)) +#define MODEM_LPCON_CLK_WIFIPWR_FO_M (MODEM_LPCON_CLK_WIFIPWR_FO_V << MODEM_LPCON_CLK_WIFIPWR_FO_S) +#define MODEM_LPCON_CLK_WIFIPWR_FO_V 0x00000001U +#define MODEM_LPCON_CLK_WIFIPWR_FO_S 0 +/* MODEM_LPCON_CLK_COEX_FO : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_FO (BIT(1)) +#define MODEM_LPCON_CLK_COEX_FO_M (MODEM_LPCON_CLK_COEX_FO_V << MODEM_LPCON_CLK_COEX_FO_S) +#define MODEM_LPCON_CLK_COEX_FO_V 0x00000001U +#define MODEM_LPCON_CLK_COEX_FO_S 1 +/* MODEM_LPCON_CLK_I2C_MST_FO : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_I2C_MST_FO (BIT(2)) +#define MODEM_LPCON_CLK_I2C_MST_FO_M (MODEM_LPCON_CLK_I2C_MST_FO_V << MODEM_LPCON_CLK_I2C_MST_FO_S) +#define MODEM_LPCON_CLK_I2C_MST_FO_V 0x00000001U +#define MODEM_LPCON_CLK_I2C_MST_FO_S 2 +/* MODEM_LPCON_CLK_LP_TIMER_FO : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_TIMER_FO (BIT(3)) +#define MODEM_LPCON_CLK_LP_TIMER_FO_M (MODEM_LPCON_CLK_LP_TIMER_FO_V << MODEM_LPCON_CLK_LP_TIMER_FO_S) +#define MODEM_LPCON_CLK_LP_TIMER_FO_V 0x00000001U +#define MODEM_LPCON_CLK_LP_TIMER_FO_S 3 +/* MODEM_LPCON_CLK_BCMEM_FO : R/W; bitpos: [4]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_BCMEM_FO (BIT(4)) +#define MODEM_LPCON_CLK_BCMEM_FO_M (MODEM_LPCON_CLK_BCMEM_FO_V << MODEM_LPCON_CLK_BCMEM_FO_S) +#define MODEM_LPCON_CLK_BCMEM_FO_V 0x00000001U +#define MODEM_LPCON_CLK_BCMEM_FO_S 4 +/* MODEM_LPCON_CLK_I2C_MST_MEM_FO : R/W; bitpos: [5]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_I2C_MST_MEM_FO (BIT(5)) +#define MODEM_LPCON_CLK_I2C_MST_MEM_FO_M (MODEM_LPCON_CLK_I2C_MST_MEM_FO_V << MODEM_LPCON_CLK_I2C_MST_MEM_FO_S) +#define MODEM_LPCON_CLK_I2C_MST_MEM_FO_V 0x00000001U +#define MODEM_LPCON_CLK_I2C_MST_MEM_FO_S 5 +/* MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO : R/W; bitpos: [6]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO (BIT(6)) +#define MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO_M (MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO_V << MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO_S) +#define MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO_V 0x00000001U +#define MODEM_LPCON_CLK_CHAN_FREQ_MEM_FO_S 6 +/* MODEM_LPCON_CLK_PBUS_MEM_FO : R/W; bitpos: [7]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_PBUS_MEM_FO (BIT(7)) +#define MODEM_LPCON_CLK_PBUS_MEM_FO_M (MODEM_LPCON_CLK_PBUS_MEM_FO_V << MODEM_LPCON_CLK_PBUS_MEM_FO_S) +#define MODEM_LPCON_CLK_PBUS_MEM_FO_V 0x00000001U +#define MODEM_LPCON_CLK_PBUS_MEM_FO_S 7 +/* MODEM_LPCON_CLK_AGC_MEM_FO : R/W; bitpos: [8]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_AGC_MEM_FO (BIT(8)) +#define MODEM_LPCON_CLK_AGC_MEM_FO_M (MODEM_LPCON_CLK_AGC_MEM_FO_V << MODEM_LPCON_CLK_AGC_MEM_FO_S) +#define MODEM_LPCON_CLK_AGC_MEM_FO_V 0x00000001U +#define MODEM_LPCON_CLK_AGC_MEM_FO_S 8 +/* MODEM_LPCON_CLK_DC_MEM_FO : R/W; bitpos: [9]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_DC_MEM_FO (BIT(9)) +#define MODEM_LPCON_CLK_DC_MEM_FO_M (MODEM_LPCON_CLK_DC_MEM_FO_V << MODEM_LPCON_CLK_DC_MEM_FO_S) +#define MODEM_LPCON_CLK_DC_MEM_FO_V 0x00000001U +#define MODEM_LPCON_CLK_DC_MEM_FO_S 9 + +#define MODEM_LPCON_CLK_CONF_POWER_ST_REG (DR_REG_MODEM_LPCON_BASE + 0x20) +/* MODEM_LPCON_CLK_WIFIPWR_ST_MAP : R/W; bitpos: [19:16]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_WIFIPWR_ST_MAP 0x0000000FU +#define MODEM_LPCON_CLK_WIFIPWR_ST_MAP_M (MODEM_LPCON_CLK_WIFIPWR_ST_MAP_V << MODEM_LPCON_CLK_WIFIPWR_ST_MAP_S) +#define MODEM_LPCON_CLK_WIFIPWR_ST_MAP_V 0x0000000FU +#define MODEM_LPCON_CLK_WIFIPWR_ST_MAP_S 16 +/* MODEM_LPCON_CLK_COEX_ST_MAP : R/W; bitpos: [23:20]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_COEX_ST_MAP 0x0000000FU +#define MODEM_LPCON_CLK_COEX_ST_MAP_M (MODEM_LPCON_CLK_COEX_ST_MAP_V << MODEM_LPCON_CLK_COEX_ST_MAP_S) +#define MODEM_LPCON_CLK_COEX_ST_MAP_V 0x0000000FU +#define MODEM_LPCON_CLK_COEX_ST_MAP_S 20 +/* MODEM_LPCON_CLK_I2C_MST_ST_MAP : R/W; bitpos: [27:24]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_I2C_MST_ST_MAP 0x0000000FU +#define MODEM_LPCON_CLK_I2C_MST_ST_MAP_M (MODEM_LPCON_CLK_I2C_MST_ST_MAP_V << MODEM_LPCON_CLK_I2C_MST_ST_MAP_S) +#define MODEM_LPCON_CLK_I2C_MST_ST_MAP_V 0x0000000FU +#define MODEM_LPCON_CLK_I2C_MST_ST_MAP_S 24 +/* MODEM_LPCON_CLK_LP_APB_ST_MAP : R/W; bitpos: [31:28]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CLK_LP_APB_ST_MAP 0x0000000FU +#define MODEM_LPCON_CLK_LP_APB_ST_MAP_M (MODEM_LPCON_CLK_LP_APB_ST_MAP_V << MODEM_LPCON_CLK_LP_APB_ST_MAP_S) +#define MODEM_LPCON_CLK_LP_APB_ST_MAP_V 0x0000000FU +#define MODEM_LPCON_CLK_LP_APB_ST_MAP_S 28 + +#define MODEM_LPCON_RST_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x24) +/* MODEM_LPCON_RST_WIFIPWR : WO; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_LPCON_RST_WIFIPWR (BIT(0)) +#define MODEM_LPCON_RST_WIFIPWR_M (MODEM_LPCON_RST_WIFIPWR_V << MODEM_LPCON_RST_WIFIPWR_S) +#define MODEM_LPCON_RST_WIFIPWR_V 0x00000001U +#define MODEM_LPCON_RST_WIFIPWR_S 0 +/* MODEM_LPCON_RST_COEX : WO; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_RST_COEX (BIT(1)) +#define MODEM_LPCON_RST_COEX_M (MODEM_LPCON_RST_COEX_V << MODEM_LPCON_RST_COEX_S) +#define MODEM_LPCON_RST_COEX_V 0x00000001U +#define MODEM_LPCON_RST_COEX_S 1 +/* MODEM_LPCON_RST_I2C_MST : WO; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_LPCON_RST_I2C_MST (BIT(2)) +#define MODEM_LPCON_RST_I2C_MST_M (MODEM_LPCON_RST_I2C_MST_V << MODEM_LPCON_RST_I2C_MST_S) +#define MODEM_LPCON_RST_I2C_MST_V 0x00000001U +#define MODEM_LPCON_RST_I2C_MST_S 2 +/* MODEM_LPCON_RST_LP_TIMER : WO; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_RST_LP_TIMER (BIT(3)) +#define MODEM_LPCON_RST_LP_TIMER_M (MODEM_LPCON_RST_LP_TIMER_V << MODEM_LPCON_RST_LP_TIMER_S) +#define MODEM_LPCON_RST_LP_TIMER_V 0x00000001U +#define MODEM_LPCON_RST_LP_TIMER_S 3 + +#define MODEM_LPCON_MEM_CONF_REG (DR_REG_MODEM_LPCON_BASE + 0x28) +/* MODEM_LPCON_DC_MEM_FORCE_PU : R/W; bitpos: [0]; default: 1; */ +/*description: */ +#define MODEM_LPCON_DC_MEM_FORCE_PU (BIT(0)) +#define MODEM_LPCON_DC_MEM_FORCE_PU_M (MODEM_LPCON_DC_MEM_FORCE_PU_V << MODEM_LPCON_DC_MEM_FORCE_PU_S) +#define MODEM_LPCON_DC_MEM_FORCE_PU_V 0x00000001U +#define MODEM_LPCON_DC_MEM_FORCE_PU_S 0 +/* MODEM_LPCON_DC_MEM_FORCE_PD : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_LPCON_DC_MEM_FORCE_PD (BIT(1)) +#define MODEM_LPCON_DC_MEM_FORCE_PD_M (MODEM_LPCON_DC_MEM_FORCE_PD_V << MODEM_LPCON_DC_MEM_FORCE_PD_S) +#define MODEM_LPCON_DC_MEM_FORCE_PD_V 0x00000001U +#define MODEM_LPCON_DC_MEM_FORCE_PD_S 1 +/* MODEM_LPCON_AGC_MEM_FORCE_PU : R/W; bitpos: [2]; default: 1; */ +/*description: */ +#define MODEM_LPCON_AGC_MEM_FORCE_PU (BIT(2)) +#define MODEM_LPCON_AGC_MEM_FORCE_PU_M (MODEM_LPCON_AGC_MEM_FORCE_PU_V << MODEM_LPCON_AGC_MEM_FORCE_PU_S) +#define MODEM_LPCON_AGC_MEM_FORCE_PU_V 0x00000001U +#define MODEM_LPCON_AGC_MEM_FORCE_PU_S 2 +/* MODEM_LPCON_AGC_MEM_FORCE_PD : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_LPCON_AGC_MEM_FORCE_PD (BIT(3)) +#define MODEM_LPCON_AGC_MEM_FORCE_PD_M (MODEM_LPCON_AGC_MEM_FORCE_PD_V << MODEM_LPCON_AGC_MEM_FORCE_PD_S) +#define MODEM_LPCON_AGC_MEM_FORCE_PD_V 0x00000001U +#define MODEM_LPCON_AGC_MEM_FORCE_PD_S 3 +/* MODEM_LPCON_PBUS_MEM_FORCE_PU : R/W; bitpos: [4]; default: 1; */ +/*description: */ +#define MODEM_LPCON_PBUS_MEM_FORCE_PU (BIT(4)) +#define MODEM_LPCON_PBUS_MEM_FORCE_PU_M (MODEM_LPCON_PBUS_MEM_FORCE_PU_V << MODEM_LPCON_PBUS_MEM_FORCE_PU_S) +#define MODEM_LPCON_PBUS_MEM_FORCE_PU_V 0x00000001U +#define MODEM_LPCON_PBUS_MEM_FORCE_PU_S 4 +/* MODEM_LPCON_PBUS_MEM_FORCE_PD : R/W; bitpos: [5]; default: 0; */ +/*description: */ +#define MODEM_LPCON_PBUS_MEM_FORCE_PD (BIT(5)) +#define MODEM_LPCON_PBUS_MEM_FORCE_PD_M (MODEM_LPCON_PBUS_MEM_FORCE_PD_V << MODEM_LPCON_PBUS_MEM_FORCE_PD_S) +#define MODEM_LPCON_PBUS_MEM_FORCE_PD_V 0x00000001U +#define MODEM_LPCON_PBUS_MEM_FORCE_PD_S 5 +/* MODEM_LPCON_BC_MEM_FORCE_PU : R/W; bitpos: [6]; default: 0; */ +/*description: */ +#define MODEM_LPCON_BC_MEM_FORCE_PU (BIT(6)) +#define MODEM_LPCON_BC_MEM_FORCE_PU_M (MODEM_LPCON_BC_MEM_FORCE_PU_V << MODEM_LPCON_BC_MEM_FORCE_PU_S) +#define MODEM_LPCON_BC_MEM_FORCE_PU_V 0x00000001U +#define MODEM_LPCON_BC_MEM_FORCE_PU_S 6 +/* MODEM_LPCON_BC_MEM_FORCE_PD : R/W; bitpos: [7]; default: 0; */ +/*description: */ +#define MODEM_LPCON_BC_MEM_FORCE_PD (BIT(7)) +#define MODEM_LPCON_BC_MEM_FORCE_PD_M (MODEM_LPCON_BC_MEM_FORCE_PD_V << MODEM_LPCON_BC_MEM_FORCE_PD_S) +#define MODEM_LPCON_BC_MEM_FORCE_PD_V 0x00000001U +#define MODEM_LPCON_BC_MEM_FORCE_PD_S 7 +/* MODEM_LPCON_I2C_MST_MEM_FORCE_PU : R/W; bitpos: [8]; default: 0; */ +/*description: */ +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PU (BIT(8)) +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PU_M (MODEM_LPCON_I2C_MST_MEM_FORCE_PU_V << MODEM_LPCON_I2C_MST_MEM_FORCE_PU_S) +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PU_V 0x00000001U +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PU_S 8 +/* MODEM_LPCON_I2C_MST_MEM_FORCE_PD : R/W; bitpos: [9]; default: 0; */ +/*description: */ +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PD (BIT(9)) +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PD_M (MODEM_LPCON_I2C_MST_MEM_FORCE_PD_V << MODEM_LPCON_I2C_MST_MEM_FORCE_PD_S) +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PD_V 0x00000001U +#define MODEM_LPCON_I2C_MST_MEM_FORCE_PD_S 9 +/* MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU : R/W; bitpos: [10]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU (BIT(10)) +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU_M (MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU_V << MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU_S) +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU_V 0x00000001U +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PU_S 10 +/* MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD : R/W; bitpos: [11]; default: 0; */ +/*description: */ +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD (BIT(11)) +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD_M (MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD_V << MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD_S) +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD_V 0x00000001U +#define MODEM_LPCON_CHAN_FREQ_MEM_FORCE_PD_S 11 +/* MODEM_LPCON_MODEM_PWR_MEM_WP : R/W; bitpos: [14:12]; default: 0; */ +/*description: */ +#define MODEM_LPCON_MODEM_PWR_MEM_WP 0x00000007U +#define MODEM_LPCON_MODEM_PWR_MEM_WP_M (MODEM_LPCON_MODEM_PWR_MEM_WP_V << MODEM_LPCON_MODEM_PWR_MEM_WP_S) +#define MODEM_LPCON_MODEM_PWR_MEM_WP_V 0x00000007U +#define MODEM_LPCON_MODEM_PWR_MEM_WP_S 12 +/* MODEM_LPCON_MODEM_PWR_MEM_WA : R/W; bitpos: [17:15]; default: 4; */ +/*description: */ +#define MODEM_LPCON_MODEM_PWR_MEM_WA 0x00000007U +#define MODEM_LPCON_MODEM_PWR_MEM_WA_M (MODEM_LPCON_MODEM_PWR_MEM_WA_V << MODEM_LPCON_MODEM_PWR_MEM_WA_S) +#define MODEM_LPCON_MODEM_PWR_MEM_WA_V 0x00000007U +#define MODEM_LPCON_MODEM_PWR_MEM_WA_S 15 +/* MODEM_LPCON_MODEM_PWR_MEM_RA : R/W; bitpos: [19:18]; default: 0; */ +/*description: */ +#define MODEM_LPCON_MODEM_PWR_MEM_RA 0x00000003U +#define MODEM_LPCON_MODEM_PWR_MEM_RA_M (MODEM_LPCON_MODEM_PWR_MEM_RA_V << MODEM_LPCON_MODEM_PWR_MEM_RA_S) +#define MODEM_LPCON_MODEM_PWR_MEM_RA_V 0x00000003U +#define MODEM_LPCON_MODEM_PWR_MEM_RA_S 18 + +#define MODEM_LPCON_DATE_REG (DR_REG_MODEM_LPCON_BASE + 0x2c) +/* MODEM_LPCON_DATE : R/W; bitpos: [27:0]; default: 35676736; */ +/*description: */ +#define MODEM_LPCON_DATE 0x0FFFFFFFU +#define MODEM_LPCON_DATE_M (MODEM_LPCON_DATE_V << MODEM_LPCON_DATE_S) +#define MODEM_LPCON_DATE_V 0x0FFFFFFFU +#define MODEM_LPCON_DATE_S 0 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/modem/modem_lpcon_struct.h b/components/soc/esp32c6/include/modem/modem_lpcon_struct.h new file mode 100644 index 000000000000..eafb7933e617 --- /dev/null +++ b/components/soc/esp32c6/include/modem/modem_lpcon_struct.h @@ -0,0 +1,178 @@ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { + struct { + uint32_t clk_en:1; + uint32_t clk_debug_ena:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} modem_lpcon_test_conf_reg_t; + +typedef union { + struct { + uint32_t clk_lp_timer_sel_osc_slow:1; + uint32_t clk_lp_timer_sel_osc_fast:1; + uint32_t clk_lp_timer_sel_xtal:1; + uint32_t clk_lp_timer_sel_xtal32k:1; + uint32_t clk_lp_timer_div_num:12; + uint32_t reserved_16:16; + }; + uint32_t val; +} modem_lpcon_lp_timer_conf_reg_t; + +typedef union { + struct { + uint32_t clk_coex_lp_sel_osc_slow:1; + uint32_t clk_coex_lp_sel_osc_fast:1; + uint32_t clk_coex_lp_sel_xtal:1; + uint32_t clk_coex_lp_sel_xtal32k:1; + uint32_t clk_coex_lp_div_num:12; + uint32_t reserved_16:16; + }; + uint32_t val; +} modem_lpcon_coex_lp_clk_conf_reg_t; + +typedef union { + struct { + uint32_t clk_wifipwr_lp_sel_osc_slow:1; + uint32_t clk_wifipwr_lp_sel_osc_fast:1; + uint32_t clk_wifipwr_lp_sel_xtal:1; + uint32_t clk_wifipwr_lp_sel_xtal32k:1; + uint32_t clk_wifipwr_lp_div_num:12; + uint32_t reserved_16:16; + }; + uint32_t val; +} modem_lpcon_wifi_lp_clk_conf_reg_t; + +typedef union { + struct { + uint32_t clk_i2c_mst_sel_160m:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} modem_lpcon_i2c_mst_clk_conf_reg_t; + +typedef union { + struct { + uint32_t clk_modem_32k_sel:2; + uint32_t reserved_2:30; + }; + uint32_t val; +} modem_lpcon_modem_32k_clk_conf_reg_t; + +typedef union { + struct { + uint32_t clk_wifipwr_en:1; + uint32_t clk_coex_en:1; + uint32_t clk_i2c_mst_en:1; + uint32_t clk_lp_timer_en:1; + uint32_t reserved_4:28; + }; + uint32_t val; +} modem_lpcon_clk_conf_reg_t; + +typedef union { + struct { + uint32_t clk_wifipwr_fo:1; + uint32_t clk_coex_fo:1; + uint32_t clk_i2c_mst_fo:1; + uint32_t clk_lp_timer_fo:1; + uint32_t clk_bcmem_fo:1; + uint32_t clk_i2c_mst_mem_fo:1; + uint32_t clk_chan_freq_mem_fo:1; + uint32_t clk_pbus_mem_fo:1; + uint32_t clk_agc_mem_fo:1; + uint32_t clk_dc_mem_fo:1; + uint32_t reserved_10:22; + }; + uint32_t val; +} modem_lpcon_clk_conf_force_on_reg_t; + +typedef union { + struct { + uint32_t reserved_0:16; + uint32_t clk_wifipwr_st_map:4; + uint32_t clk_coex_st_map:4; + uint32_t clk_i2c_mst_st_map:4; + uint32_t clk_lp_apb_st_map:4; + }; + uint32_t val; +} modem_lpcon_clk_conf_power_st_reg_t; + +typedef union { + struct { + uint32_t rst_wifipwr:1; + uint32_t rst_coex:1; + uint32_t rst_i2c_mst:1; + uint32_t rst_lp_timer:1; + uint32_t reserved_4:28; + }; + uint32_t val; +} modem_lpcon_rst_conf_reg_t; + +typedef union { + struct { + uint32_t dc_mem_force_pu:1; + uint32_t dc_mem_force_pd:1; + uint32_t agc_mem_force_pu:1; + uint32_t agc_mem_force_pd:1; + uint32_t pbus_mem_force_pu:1; + uint32_t pbus_mem_force_pd:1; + uint32_t bc_mem_force_pu:1; + uint32_t bc_mem_force_pd:1; + uint32_t i2c_mst_mem_force_pu:1; + uint32_t i2c_mst_mem_force_pd:1; + uint32_t chan_freq_mem_force_pu:1; + uint32_t chan_freq_mem_force_pd:1; + uint32_t modem_pwr_mem_wp:3; + uint32_t modem_pwr_mem_wa:3; + uint32_t modem_pwr_mem_ra:2; + uint32_t reserved_20:12; + }; + uint32_t val; +} modem_lpcon_mem_conf_reg_t; + +typedef union { + struct { + uint32_t date:28; + uint32_t reserved_28:4; + }; + uint32_t val; +} modem_lpcon_date_reg_t; + + +typedef struct { + volatile modem_lpcon_test_conf_reg_t test_conf; + volatile modem_lpcon_lp_timer_conf_reg_t lp_timer_conf; + volatile modem_lpcon_coex_lp_clk_conf_reg_t coex_lp_clk_conf; + volatile modem_lpcon_wifi_lp_clk_conf_reg_t wifi_lp_clk_conf; + volatile modem_lpcon_i2c_mst_clk_conf_reg_t i2c_mst_clk_conf; + volatile modem_lpcon_modem_32k_clk_conf_reg_t modem_32k_clk_conf; + volatile modem_lpcon_clk_conf_reg_t clk_conf; + volatile modem_lpcon_clk_conf_force_on_reg_t clk_conf_force_on; + volatile modem_lpcon_clk_conf_power_st_reg_t clk_conf_power_st; + volatile modem_lpcon_rst_conf_reg_t rst_conf; + volatile modem_lpcon_mem_conf_reg_t mem_conf; + volatile modem_lpcon_date_reg_t date; +} modem_lpcon_dev_t; + +extern modem_lpcon_dev_t MODEM_LPCON; + +#ifndef __cplusplus +_Static_assert(sizeof(modem_lpcon_dev_t) == 0x30, "Invalid size of modem_lpcon_dev_t structure"); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/modem/modem_syscon_reg.h b/components/soc/esp32c6/include/modem/modem_syscon_reg.h new file mode 100644 index 000000000000..ddfdf32b0052 --- /dev/null +++ b/components/soc/esp32c6/include/modem/modem_syscon_reg.h @@ -0,0 +1,612 @@ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + *//*description: */ +#pragma once + +#include +#include "modem/reg_base.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define MODEM_SYSCON_TEST_CONF_REG (DR_REG_MODEM_SYSCON_BASE + 0x0) +/* MODEM_SYSCON_CLK_EN : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_EN (BIT(0)) +#define MODEM_SYSCON_CLK_EN_M (MODEM_SYSCON_CLK_EN_V << MODEM_SYSCON_CLK_EN_S) +#define MODEM_SYSCON_CLK_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_EN_S 0 + +#define MODEM_SYSCON_CLK_CONF_REG (DR_REG_MODEM_SYSCON_BASE + 0x4) +/* MODEM_SYSCON_CLK_DATA_DUMP_MUX : R/W; bitpos: [21]; default: 1; */ +/*description: */ +#define MODEM_SYSCON_CLK_DATA_DUMP_MUX (BIT(21)) +#define MODEM_SYSCON_CLK_DATA_DUMP_MUX_M (MODEM_SYSCON_CLK_DATA_DUMP_MUX_V << MODEM_SYSCON_CLK_DATA_DUMP_MUX_S) +#define MODEM_SYSCON_CLK_DATA_DUMP_MUX_V 0x00000001U +#define MODEM_SYSCON_CLK_DATA_DUMP_MUX_S 21 +/* MODEM_SYSCON_CLK_ETM_EN : R/W; bitpos: [22]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ETM_EN (BIT(22)) +#define MODEM_SYSCON_CLK_ETM_EN_M (MODEM_SYSCON_CLK_ETM_EN_V << MODEM_SYSCON_CLK_ETM_EN_S) +#define MODEM_SYSCON_CLK_ETM_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_ETM_EN_S 22 +/* MODEM_SYSCON_CLK_ZB_APB_EN : R/W; bitpos: [23]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ZB_APB_EN (BIT(23)) +#define MODEM_SYSCON_CLK_ZB_APB_EN_M (MODEM_SYSCON_CLK_ZB_APB_EN_V << MODEM_SYSCON_CLK_ZB_APB_EN_S) +#define MODEM_SYSCON_CLK_ZB_APB_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_ZB_APB_EN_S 23 +/* MODEM_SYSCON_CLK_ZB_MAC_EN : R/W; bitpos: [24]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ZB_MAC_EN (BIT(24)) +#define MODEM_SYSCON_CLK_ZB_MAC_EN_M (MODEM_SYSCON_CLK_ZB_MAC_EN_V << MODEM_SYSCON_CLK_ZB_MAC_EN_S) +#define MODEM_SYSCON_CLK_ZB_MAC_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_ZB_MAC_EN_S 24 +/* MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN : R/W; bitpos: [25]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN (BIT(25)) +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN_M (MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN_V << MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_EN_S 25 +/* MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN : R/W; bitpos: [26]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN (BIT(26)) +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN_M (MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN_V << MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_EN_S 26 +/* MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN : R/W; bitpos: [27]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN (BIT(27)) +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN_M (MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN_V << MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_EN_S 27 +/* MODEM_SYSCON_CLK_MODEM_SEC_APB_EN : R/W; bitpos: [28]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_EN (BIT(28)) +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_EN_M (MODEM_SYSCON_CLK_MODEM_SEC_APB_EN_V << MODEM_SYSCON_CLK_MODEM_SEC_APB_EN_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_EN_S 28 +/* MODEM_SYSCON_CLK_MODEM_SEC_EN : R/W; bitpos: [29]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_EN (BIT(29)) +#define MODEM_SYSCON_CLK_MODEM_SEC_EN_M (MODEM_SYSCON_CLK_MODEM_SEC_EN_V << MODEM_SYSCON_CLK_MODEM_SEC_EN_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_EN_S 29 +/* MODEM_SYSCON_CLK_BLE_TIMER_EN : R/W; bitpos: [30]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BLE_TIMER_EN (BIT(30)) +#define MODEM_SYSCON_CLK_BLE_TIMER_EN_M (MODEM_SYSCON_CLK_BLE_TIMER_EN_V << MODEM_SYSCON_CLK_BLE_TIMER_EN_S) +#define MODEM_SYSCON_CLK_BLE_TIMER_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_BLE_TIMER_EN_S 30 +/* MODEM_SYSCON_CLK_DATA_DUMP_EN : R/W; bitpos: [31]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_DATA_DUMP_EN (BIT(31)) +#define MODEM_SYSCON_CLK_DATA_DUMP_EN_M (MODEM_SYSCON_CLK_DATA_DUMP_EN_V << MODEM_SYSCON_CLK_DATA_DUMP_EN_S) +#define MODEM_SYSCON_CLK_DATA_DUMP_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_DATA_DUMP_EN_S 31 + +#define MODEM_SYSCON_CLK_CONF_FORCE_ON_REG (DR_REG_MODEM_SYSCON_BASE + 0x8) +/* MODEM_SYSCON_CLK_ETM_FO : R/W; bitpos: [22]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ETM_FO (BIT(22)) +#define MODEM_SYSCON_CLK_ETM_FO_M (MODEM_SYSCON_CLK_ETM_FO_V << MODEM_SYSCON_CLK_ETM_FO_S) +#define MODEM_SYSCON_CLK_ETM_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_ETM_FO_S 22 +/* MODEM_SYSCON_CLK_ZB_APB_FO : R/W; bitpos: [23]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ZB_APB_FO (BIT(23)) +#define MODEM_SYSCON_CLK_ZB_APB_FO_M (MODEM_SYSCON_CLK_ZB_APB_FO_V << MODEM_SYSCON_CLK_ZB_APB_FO_S) +#define MODEM_SYSCON_CLK_ZB_APB_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_ZB_APB_FO_S 23 +/* MODEM_SYSCON_CLK_ZB_MAC_FO : R/W; bitpos: [24]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ZB_MAC_FO (BIT(24)) +#define MODEM_SYSCON_CLK_ZB_MAC_FO_M (MODEM_SYSCON_CLK_ZB_MAC_FO_V << MODEM_SYSCON_CLK_ZB_MAC_FO_S) +#define MODEM_SYSCON_CLK_ZB_MAC_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_ZB_MAC_FO_S 24 +/* MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO : R/W; bitpos: [25]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO (BIT(25)) +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO_M (MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO_V << MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_ECB_FO_S 25 +/* MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO : R/W; bitpos: [26]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO (BIT(26)) +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO_M (MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO_V << MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_CCM_FO_S 26 +/* MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO : R/W; bitpos: [27]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO (BIT(27)) +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO_M (MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO_V << MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_BAH_FO_S 27 +/* MODEM_SYSCON_CLK_MODEM_SEC_APB_FO : R/W; bitpos: [28]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_FO (BIT(28)) +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_FO_M (MODEM_SYSCON_CLK_MODEM_SEC_APB_FO_V << MODEM_SYSCON_CLK_MODEM_SEC_APB_FO_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_APB_FO_S 28 +/* MODEM_SYSCON_CLK_MODEM_SEC_FO : R/W; bitpos: [29]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_SEC_FO (BIT(29)) +#define MODEM_SYSCON_CLK_MODEM_SEC_FO_M (MODEM_SYSCON_CLK_MODEM_SEC_FO_V << MODEM_SYSCON_CLK_MODEM_SEC_FO_S) +#define MODEM_SYSCON_CLK_MODEM_SEC_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_MODEM_SEC_FO_S 29 +/* MODEM_SYSCON_CLK_BLE_TIMER_FO : R/W; bitpos: [30]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BLE_TIMER_FO (BIT(30)) +#define MODEM_SYSCON_CLK_BLE_TIMER_FO_M (MODEM_SYSCON_CLK_BLE_TIMER_FO_V << MODEM_SYSCON_CLK_BLE_TIMER_FO_S) +#define MODEM_SYSCON_CLK_BLE_TIMER_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_BLE_TIMER_FO_S 30 +/* MODEM_SYSCON_CLK_DATA_DUMP_FO : R/W; bitpos: [31]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_DATA_DUMP_FO (BIT(31)) +#define MODEM_SYSCON_CLK_DATA_DUMP_FO_M (MODEM_SYSCON_CLK_DATA_DUMP_FO_V << MODEM_SYSCON_CLK_DATA_DUMP_FO_S) +#define MODEM_SYSCON_CLK_DATA_DUMP_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_DATA_DUMP_FO_S 31 + +#define MODEM_SYSCON_CLK_CONF_POWER_ST_REG (DR_REG_MODEM_SYSCON_BASE + 0xc) +/* MODEM_SYSCON_CLK_ZB_ST_MAP : R/W; bitpos: [11:8]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_ZB_ST_MAP 0x0000000FU +#define MODEM_SYSCON_CLK_ZB_ST_MAP_M (MODEM_SYSCON_CLK_ZB_ST_MAP_V << MODEM_SYSCON_CLK_ZB_ST_MAP_S) +#define MODEM_SYSCON_CLK_ZB_ST_MAP_V 0x0000000FU +#define MODEM_SYSCON_CLK_ZB_ST_MAP_S 8 +/* MODEM_SYSCON_CLK_FE_ST_MAP : R/W; bitpos: [15:12]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ST_MAP 0x0000000FU +#define MODEM_SYSCON_CLK_FE_ST_MAP_M (MODEM_SYSCON_CLK_FE_ST_MAP_V << MODEM_SYSCON_CLK_FE_ST_MAP_S) +#define MODEM_SYSCON_CLK_FE_ST_MAP_V 0x0000000FU +#define MODEM_SYSCON_CLK_FE_ST_MAP_S 12 +/* MODEM_SYSCON_CLK_BT_ST_MAP : R/W; bitpos: [19:16]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BT_ST_MAP 0x0000000FU +#define MODEM_SYSCON_CLK_BT_ST_MAP_M (MODEM_SYSCON_CLK_BT_ST_MAP_V << MODEM_SYSCON_CLK_BT_ST_MAP_S) +#define MODEM_SYSCON_CLK_BT_ST_MAP_V 0x0000000FU +#define MODEM_SYSCON_CLK_BT_ST_MAP_S 16 +/* MODEM_SYSCON_CLK_WIFI_ST_MAP : R/W; bitpos: [23:20]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFI_ST_MAP 0x0000000FU +#define MODEM_SYSCON_CLK_WIFI_ST_MAP_M (MODEM_SYSCON_CLK_WIFI_ST_MAP_V << MODEM_SYSCON_CLK_WIFI_ST_MAP_S) +#define MODEM_SYSCON_CLK_WIFI_ST_MAP_V 0x0000000FU +#define MODEM_SYSCON_CLK_WIFI_ST_MAP_S 20 +/* MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP : R/W; bitpos: [27:24]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP 0x0000000FU +#define MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP_M (MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP_V << MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP_S) +#define MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP_V 0x0000000FU +#define MODEM_SYSCON_CLK_MODEM_PERI_ST_MAP_S 24 +/* MODEM_SYSCON_CLK_MODEM_APB_ST_MAP : R/W; bitpos: [31:28]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_MODEM_APB_ST_MAP 0x0000000FU +#define MODEM_SYSCON_CLK_MODEM_APB_ST_MAP_M (MODEM_SYSCON_CLK_MODEM_APB_ST_MAP_V << MODEM_SYSCON_CLK_MODEM_APB_ST_MAP_S) +#define MODEM_SYSCON_CLK_MODEM_APB_ST_MAP_V 0x0000000FU +#define MODEM_SYSCON_CLK_MODEM_APB_ST_MAP_S 28 + +#define MODEM_SYSCON_MODEM_RST_CONF_REG (DR_REG_MODEM_SYSCON_BASE + 0x10) +/* MODEM_SYSCON_RST_WIFIBB : R/W; bitpos: [8]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_WIFIBB (BIT(8)) +#define MODEM_SYSCON_RST_WIFIBB_M (MODEM_SYSCON_RST_WIFIBB_V << MODEM_SYSCON_RST_WIFIBB_S) +#define MODEM_SYSCON_RST_WIFIBB_V 0x00000001U +#define MODEM_SYSCON_RST_WIFIBB_S 8 +/* MODEM_SYSCON_RST_WIFIMAC : R/W; bitpos: [10]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_WIFIMAC (BIT(10)) +#define MODEM_SYSCON_RST_WIFIMAC_M (MODEM_SYSCON_RST_WIFIMAC_V << MODEM_SYSCON_RST_WIFIMAC_S) +#define MODEM_SYSCON_RST_WIFIMAC_V 0x00000001U +#define MODEM_SYSCON_RST_WIFIMAC_S 10 +/* MODEM_SYSCON_RST_FE : R/W; bitpos: [14]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_FE (BIT(14)) +#define MODEM_SYSCON_RST_FE_M (MODEM_SYSCON_RST_FE_V << MODEM_SYSCON_RST_FE_S) +#define MODEM_SYSCON_RST_FE_V 0x00000001U +#define MODEM_SYSCON_RST_FE_S 14 +/* MODEM_SYSCON_RST_BTMAC_APB : R/W; bitpos: [15]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_BTMAC_APB (BIT(15)) +#define MODEM_SYSCON_RST_BTMAC_APB_M (MODEM_SYSCON_RST_BTMAC_APB_V << MODEM_SYSCON_RST_BTMAC_APB_S) +#define MODEM_SYSCON_RST_BTMAC_APB_V 0x00000001U +#define MODEM_SYSCON_RST_BTMAC_APB_S 15 +/* MODEM_SYSCON_RST_BTMAC : R/W; bitpos: [16]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_BTMAC (BIT(16)) +#define MODEM_SYSCON_RST_BTMAC_M (MODEM_SYSCON_RST_BTMAC_V << MODEM_SYSCON_RST_BTMAC_S) +#define MODEM_SYSCON_RST_BTMAC_V 0x00000001U +#define MODEM_SYSCON_RST_BTMAC_S 16 +/* MODEM_SYSCON_RST_BTBB_APB : R/W; bitpos: [17]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_BTBB_APB (BIT(17)) +#define MODEM_SYSCON_RST_BTBB_APB_M (MODEM_SYSCON_RST_BTBB_APB_V << MODEM_SYSCON_RST_BTBB_APB_S) +#define MODEM_SYSCON_RST_BTBB_APB_V 0x00000001U +#define MODEM_SYSCON_RST_BTBB_APB_S 17 +/* MODEM_SYSCON_RST_BTBB : R/W; bitpos: [18]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_BTBB (BIT(18)) +#define MODEM_SYSCON_RST_BTBB_M (MODEM_SYSCON_RST_BTBB_V << MODEM_SYSCON_RST_BTBB_S) +#define MODEM_SYSCON_RST_BTBB_V 0x00000001U +#define MODEM_SYSCON_RST_BTBB_S 18 +/* MODEM_SYSCON_RST_ETM : R/W; bitpos: [22]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_ETM (BIT(22)) +#define MODEM_SYSCON_RST_ETM_M (MODEM_SYSCON_RST_ETM_V << MODEM_SYSCON_RST_ETM_S) +#define MODEM_SYSCON_RST_ETM_V 0x00000001U +#define MODEM_SYSCON_RST_ETM_S 22 +/* MODEM_SYSCON_RST_ZBMAC : R/W; bitpos: [24]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_ZBMAC (BIT(24)) +#define MODEM_SYSCON_RST_ZBMAC_M (MODEM_SYSCON_RST_ZBMAC_V << MODEM_SYSCON_RST_ZBMAC_S) +#define MODEM_SYSCON_RST_ZBMAC_V 0x00000001U +#define MODEM_SYSCON_RST_ZBMAC_S 24 +/* MODEM_SYSCON_RST_MODEM_ECB : R/W; bitpos: [25]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_MODEM_ECB (BIT(25)) +#define MODEM_SYSCON_RST_MODEM_ECB_M (MODEM_SYSCON_RST_MODEM_ECB_V << MODEM_SYSCON_RST_MODEM_ECB_S) +#define MODEM_SYSCON_RST_MODEM_ECB_V 0x00000001U +#define MODEM_SYSCON_RST_MODEM_ECB_S 25 +/* MODEM_SYSCON_RST_MODEM_CCM : R/W; bitpos: [26]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_MODEM_CCM (BIT(26)) +#define MODEM_SYSCON_RST_MODEM_CCM_M (MODEM_SYSCON_RST_MODEM_CCM_V << MODEM_SYSCON_RST_MODEM_CCM_S) +#define MODEM_SYSCON_RST_MODEM_CCM_V 0x00000001U +#define MODEM_SYSCON_RST_MODEM_CCM_S 26 +/* MODEM_SYSCON_RST_MODEM_BAH : R/W; bitpos: [27]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_MODEM_BAH (BIT(27)) +#define MODEM_SYSCON_RST_MODEM_BAH_M (MODEM_SYSCON_RST_MODEM_BAH_V << MODEM_SYSCON_RST_MODEM_BAH_S) +#define MODEM_SYSCON_RST_MODEM_BAH_V 0x00000001U +#define MODEM_SYSCON_RST_MODEM_BAH_S 27 +/* MODEM_SYSCON_RST_MODEM_SEC : R/W; bitpos: [29]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_MODEM_SEC (BIT(29)) +#define MODEM_SYSCON_RST_MODEM_SEC_M (MODEM_SYSCON_RST_MODEM_SEC_V << MODEM_SYSCON_RST_MODEM_SEC_S) +#define MODEM_SYSCON_RST_MODEM_SEC_V 0x00000001U +#define MODEM_SYSCON_RST_MODEM_SEC_S 29 +/* MODEM_SYSCON_RST_BLE_TIMER : R/W; bitpos: [30]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_BLE_TIMER (BIT(30)) +#define MODEM_SYSCON_RST_BLE_TIMER_M (MODEM_SYSCON_RST_BLE_TIMER_V << MODEM_SYSCON_RST_BLE_TIMER_S) +#define MODEM_SYSCON_RST_BLE_TIMER_V 0x00000001U +#define MODEM_SYSCON_RST_BLE_TIMER_S 30 +/* MODEM_SYSCON_RST_DATA_DUMP : R/W; bitpos: [31]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_RST_DATA_DUMP (BIT(31)) +#define MODEM_SYSCON_RST_DATA_DUMP_M (MODEM_SYSCON_RST_DATA_DUMP_V << MODEM_SYSCON_RST_DATA_DUMP_S) +#define MODEM_SYSCON_RST_DATA_DUMP_V 0x00000001U +#define MODEM_SYSCON_RST_DATA_DUMP_S 31 + +#define MODEM_SYSCON_CLK_CONF1_REG (DR_REG_MODEM_SYSCON_BASE + 0x14) +/* MODEM_SYSCON_CLK_WIFIBB_22M_EN : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_22M_EN (BIT(0)) +#define MODEM_SYSCON_CLK_WIFIBB_22M_EN_M (MODEM_SYSCON_CLK_WIFIBB_22M_EN_V << MODEM_SYSCON_CLK_WIFIBB_22M_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_22M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_22M_EN_S 0 +/* MODEM_SYSCON_CLK_WIFIBB_40M_EN : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_40M_EN (BIT(1)) +#define MODEM_SYSCON_CLK_WIFIBB_40M_EN_M (MODEM_SYSCON_CLK_WIFIBB_40M_EN_V << MODEM_SYSCON_CLK_WIFIBB_40M_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_40M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_40M_EN_S 1 +/* MODEM_SYSCON_CLK_WIFIBB_44M_EN : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_44M_EN (BIT(2)) +#define MODEM_SYSCON_CLK_WIFIBB_44M_EN_M (MODEM_SYSCON_CLK_WIFIBB_44M_EN_V << MODEM_SYSCON_CLK_WIFIBB_44M_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_44M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_44M_EN_S 2 +/* MODEM_SYSCON_CLK_WIFIBB_80M_EN : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_80M_EN (BIT(3)) +#define MODEM_SYSCON_CLK_WIFIBB_80M_EN_M (MODEM_SYSCON_CLK_WIFIBB_80M_EN_V << MODEM_SYSCON_CLK_WIFIBB_80M_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_80M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_80M_EN_S 3 +/* MODEM_SYSCON_CLK_WIFIBB_40X_EN : R/W; bitpos: [4]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_40X_EN (BIT(4)) +#define MODEM_SYSCON_CLK_WIFIBB_40X_EN_M (MODEM_SYSCON_CLK_WIFIBB_40X_EN_V << MODEM_SYSCON_CLK_WIFIBB_40X_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_40X_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_40X_EN_S 4 +/* MODEM_SYSCON_CLK_WIFIBB_80X_EN : R/W; bitpos: [5]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_80X_EN (BIT(5)) +#define MODEM_SYSCON_CLK_WIFIBB_80X_EN_M (MODEM_SYSCON_CLK_WIFIBB_80X_EN_V << MODEM_SYSCON_CLK_WIFIBB_80X_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_80X_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_80X_EN_S 5 +/* MODEM_SYSCON_CLK_WIFIBB_40X1_EN : R/W; bitpos: [6]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_40X1_EN (BIT(6)) +#define MODEM_SYSCON_CLK_WIFIBB_40X1_EN_M (MODEM_SYSCON_CLK_WIFIBB_40X1_EN_V << MODEM_SYSCON_CLK_WIFIBB_40X1_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_40X1_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_40X1_EN_S 6 +/* MODEM_SYSCON_CLK_WIFIBB_80X1_EN : R/W; bitpos: [7]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_80X1_EN (BIT(7)) +#define MODEM_SYSCON_CLK_WIFIBB_80X1_EN_M (MODEM_SYSCON_CLK_WIFIBB_80X1_EN_V << MODEM_SYSCON_CLK_WIFIBB_80X1_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_80X1_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_80X1_EN_S 7 +/* MODEM_SYSCON_CLK_WIFIBB_160X1_EN : R/W; bitpos: [8]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_160X1_EN (BIT(8)) +#define MODEM_SYSCON_CLK_WIFIBB_160X1_EN_M (MODEM_SYSCON_CLK_WIFIBB_160X1_EN_V << MODEM_SYSCON_CLK_WIFIBB_160X1_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_160X1_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_160X1_EN_S 8 +/* MODEM_SYSCON_CLK_WIFIMAC_EN : R/W; bitpos: [9]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIMAC_EN (BIT(9)) +#define MODEM_SYSCON_CLK_WIFIMAC_EN_M (MODEM_SYSCON_CLK_WIFIMAC_EN_V << MODEM_SYSCON_CLK_WIFIMAC_EN_S) +#define MODEM_SYSCON_CLK_WIFIMAC_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIMAC_EN_S 9 +/* MODEM_SYSCON_CLK_WIFI_APB_EN : R/W; bitpos: [10]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFI_APB_EN (BIT(10)) +#define MODEM_SYSCON_CLK_WIFI_APB_EN_M (MODEM_SYSCON_CLK_WIFI_APB_EN_V << MODEM_SYSCON_CLK_WIFI_APB_EN_S) +#define MODEM_SYSCON_CLK_WIFI_APB_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFI_APB_EN_S 10 +/* MODEM_SYSCON_CLK_FE_20M_EN : R/W; bitpos: [11]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_20M_EN (BIT(11)) +#define MODEM_SYSCON_CLK_FE_20M_EN_M (MODEM_SYSCON_CLK_FE_20M_EN_V << MODEM_SYSCON_CLK_FE_20M_EN_S) +#define MODEM_SYSCON_CLK_FE_20M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_20M_EN_S 11 +/* MODEM_SYSCON_CLK_FE_40M_EN : R/W; bitpos: [12]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_40M_EN (BIT(12)) +#define MODEM_SYSCON_CLK_FE_40M_EN_M (MODEM_SYSCON_CLK_FE_40M_EN_V << MODEM_SYSCON_CLK_FE_40M_EN_S) +#define MODEM_SYSCON_CLK_FE_40M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_40M_EN_S 12 +/* MODEM_SYSCON_CLK_FE_80M_EN : R/W; bitpos: [13]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_80M_EN (BIT(13)) +#define MODEM_SYSCON_CLK_FE_80M_EN_M (MODEM_SYSCON_CLK_FE_80M_EN_V << MODEM_SYSCON_CLK_FE_80M_EN_S) +#define MODEM_SYSCON_CLK_FE_80M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_80M_EN_S 13 +/* MODEM_SYSCON_CLK_FE_160M_EN : R/W; bitpos: [14]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_160M_EN (BIT(14)) +#define MODEM_SYSCON_CLK_FE_160M_EN_M (MODEM_SYSCON_CLK_FE_160M_EN_V << MODEM_SYSCON_CLK_FE_160M_EN_S) +#define MODEM_SYSCON_CLK_FE_160M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_160M_EN_S 14 +/* MODEM_SYSCON_CLK_FE_CAL_160M_EN : R/W; bitpos: [15]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_CAL_160M_EN (BIT(15)) +#define MODEM_SYSCON_CLK_FE_CAL_160M_EN_M (MODEM_SYSCON_CLK_FE_CAL_160M_EN_V << MODEM_SYSCON_CLK_FE_CAL_160M_EN_S) +#define MODEM_SYSCON_CLK_FE_CAL_160M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_CAL_160M_EN_S 15 +/* MODEM_SYSCON_CLK_FE_APB_EN : R/W; bitpos: [16]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_APB_EN (BIT(16)) +#define MODEM_SYSCON_CLK_FE_APB_EN_M (MODEM_SYSCON_CLK_FE_APB_EN_V << MODEM_SYSCON_CLK_FE_APB_EN_S) +#define MODEM_SYSCON_CLK_FE_APB_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_APB_EN_S 16 +/* MODEM_SYSCON_CLK_BT_APB_EN : R/W; bitpos: [17]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BT_APB_EN (BIT(17)) +#define MODEM_SYSCON_CLK_BT_APB_EN_M (MODEM_SYSCON_CLK_BT_APB_EN_V << MODEM_SYSCON_CLK_BT_APB_EN_S) +#define MODEM_SYSCON_CLK_BT_APB_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_BT_APB_EN_S 17 +/* MODEM_SYSCON_CLK_BT_EN : R/W; bitpos: [18]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BT_EN (BIT(18)) +#define MODEM_SYSCON_CLK_BT_EN_M (MODEM_SYSCON_CLK_BT_EN_V << MODEM_SYSCON_CLK_BT_EN_S) +#define MODEM_SYSCON_CLK_BT_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_BT_EN_S 18 +/* MODEM_SYSCON_CLK_WIFIBB_480M_EN : R/W; bitpos: [19]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_480M_EN (BIT(19)) +#define MODEM_SYSCON_CLK_WIFIBB_480M_EN_M (MODEM_SYSCON_CLK_WIFIBB_480M_EN_V << MODEM_SYSCON_CLK_WIFIBB_480M_EN_S) +#define MODEM_SYSCON_CLK_WIFIBB_480M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_480M_EN_S 19 +/* MODEM_SYSCON_CLK_FE_480M_EN : R/W; bitpos: [20]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_480M_EN (BIT(20)) +#define MODEM_SYSCON_CLK_FE_480M_EN_M (MODEM_SYSCON_CLK_FE_480M_EN_V << MODEM_SYSCON_CLK_FE_480M_EN_S) +#define MODEM_SYSCON_CLK_FE_480M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_480M_EN_S 20 +/* MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN : R/W; bitpos: [21]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN (BIT(21)) +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN_M (MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN_V << MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN_S) +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_EN_S 21 +/* MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN : R/W; bitpos: [22]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN (BIT(22)) +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN_M (MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN_V << MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN_S) +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_EN_S 22 +/* MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN : R/W; bitpos: [23]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN (BIT(23)) +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN_M (MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN_V << MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN_S) +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_EN_S 23 + +#define MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG (DR_REG_MODEM_SYSCON_BASE + 0x18) +/* MODEM_SYSCON_CLK_WIFIBB_22M_FO : R/W; bitpos: [0]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_22M_FO (BIT(0)) +#define MODEM_SYSCON_CLK_WIFIBB_22M_FO_M (MODEM_SYSCON_CLK_WIFIBB_22M_FO_V << MODEM_SYSCON_CLK_WIFIBB_22M_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_22M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_22M_FO_S 0 +/* MODEM_SYSCON_CLK_WIFIBB_40M_FO : R/W; bitpos: [1]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_40M_FO (BIT(1)) +#define MODEM_SYSCON_CLK_WIFIBB_40M_FO_M (MODEM_SYSCON_CLK_WIFIBB_40M_FO_V << MODEM_SYSCON_CLK_WIFIBB_40M_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_40M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_40M_FO_S 1 +/* MODEM_SYSCON_CLK_WIFIBB_44M_FO : R/W; bitpos: [2]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_44M_FO (BIT(2)) +#define MODEM_SYSCON_CLK_WIFIBB_44M_FO_M (MODEM_SYSCON_CLK_WIFIBB_44M_FO_V << MODEM_SYSCON_CLK_WIFIBB_44M_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_44M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_44M_FO_S 2 +/* MODEM_SYSCON_CLK_WIFIBB_80M_FO : R/W; bitpos: [3]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_80M_FO (BIT(3)) +#define MODEM_SYSCON_CLK_WIFIBB_80M_FO_M (MODEM_SYSCON_CLK_WIFIBB_80M_FO_V << MODEM_SYSCON_CLK_WIFIBB_80M_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_80M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_80M_FO_S 3 +/* MODEM_SYSCON_CLK_WIFIBB_40X_FO : R/W; bitpos: [4]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_40X_FO (BIT(4)) +#define MODEM_SYSCON_CLK_WIFIBB_40X_FO_M (MODEM_SYSCON_CLK_WIFIBB_40X_FO_V << MODEM_SYSCON_CLK_WIFIBB_40X_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_40X_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_40X_FO_S 4 +/* MODEM_SYSCON_CLK_WIFIBB_80X_FO : R/W; bitpos: [5]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_80X_FO (BIT(5)) +#define MODEM_SYSCON_CLK_WIFIBB_80X_FO_M (MODEM_SYSCON_CLK_WIFIBB_80X_FO_V << MODEM_SYSCON_CLK_WIFIBB_80X_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_80X_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_80X_FO_S 5 +/* MODEM_SYSCON_CLK_WIFIBB_40X1_FO : R/W; bitpos: [6]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_40X1_FO (BIT(6)) +#define MODEM_SYSCON_CLK_WIFIBB_40X1_FO_M (MODEM_SYSCON_CLK_WIFIBB_40X1_FO_V << MODEM_SYSCON_CLK_WIFIBB_40X1_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_40X1_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_40X1_FO_S 6 +/* MODEM_SYSCON_CLK_WIFIBB_80X1_FO : R/W; bitpos: [7]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_80X1_FO (BIT(7)) +#define MODEM_SYSCON_CLK_WIFIBB_80X1_FO_M (MODEM_SYSCON_CLK_WIFIBB_80X1_FO_V << MODEM_SYSCON_CLK_WIFIBB_80X1_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_80X1_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_80X1_FO_S 7 +/* MODEM_SYSCON_CLK_WIFIBB_160X1_FO : R/W; bitpos: [8]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_160X1_FO (BIT(8)) +#define MODEM_SYSCON_CLK_WIFIBB_160X1_FO_M (MODEM_SYSCON_CLK_WIFIBB_160X1_FO_V << MODEM_SYSCON_CLK_WIFIBB_160X1_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_160X1_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_160X1_FO_S 8 +/* MODEM_SYSCON_CLK_WIFIMAC_FO : R/W; bitpos: [9]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIMAC_FO (BIT(9)) +#define MODEM_SYSCON_CLK_WIFIMAC_FO_M (MODEM_SYSCON_CLK_WIFIMAC_FO_V << MODEM_SYSCON_CLK_WIFIMAC_FO_S) +#define MODEM_SYSCON_CLK_WIFIMAC_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIMAC_FO_S 9 +/* MODEM_SYSCON_CLK_WIFI_APB_FO : R/W; bitpos: [10]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFI_APB_FO (BIT(10)) +#define MODEM_SYSCON_CLK_WIFI_APB_FO_M (MODEM_SYSCON_CLK_WIFI_APB_FO_V << MODEM_SYSCON_CLK_WIFI_APB_FO_S) +#define MODEM_SYSCON_CLK_WIFI_APB_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFI_APB_FO_S 10 +/* MODEM_SYSCON_CLK_FE_20M_FO : R/W; bitpos: [11]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_20M_FO (BIT(11)) +#define MODEM_SYSCON_CLK_FE_20M_FO_M (MODEM_SYSCON_CLK_FE_20M_FO_V << MODEM_SYSCON_CLK_FE_20M_FO_S) +#define MODEM_SYSCON_CLK_FE_20M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_20M_FO_S 11 +/* MODEM_SYSCON_CLK_FE_40M_FO : R/W; bitpos: [12]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_40M_FO (BIT(12)) +#define MODEM_SYSCON_CLK_FE_40M_FO_M (MODEM_SYSCON_CLK_FE_40M_FO_V << MODEM_SYSCON_CLK_FE_40M_FO_S) +#define MODEM_SYSCON_CLK_FE_40M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_40M_FO_S 12 +/* MODEM_SYSCON_CLK_FE_80M_FO : R/W; bitpos: [13]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_80M_FO (BIT(13)) +#define MODEM_SYSCON_CLK_FE_80M_FO_M (MODEM_SYSCON_CLK_FE_80M_FO_V << MODEM_SYSCON_CLK_FE_80M_FO_S) +#define MODEM_SYSCON_CLK_FE_80M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_80M_FO_S 13 +/* MODEM_SYSCON_CLK_FE_160M_FO : R/W; bitpos: [14]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_160M_FO (BIT(14)) +#define MODEM_SYSCON_CLK_FE_160M_FO_M (MODEM_SYSCON_CLK_FE_160M_FO_V << MODEM_SYSCON_CLK_FE_160M_FO_S) +#define MODEM_SYSCON_CLK_FE_160M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_160M_FO_S 14 +/* MODEM_SYSCON_CLK_FE_CAL_160M_FO : R/W; bitpos: [15]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_CAL_160M_FO (BIT(15)) +#define MODEM_SYSCON_CLK_FE_CAL_160M_FO_M (MODEM_SYSCON_CLK_FE_CAL_160M_FO_V << MODEM_SYSCON_CLK_FE_CAL_160M_FO_S) +#define MODEM_SYSCON_CLK_FE_CAL_160M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_CAL_160M_FO_S 15 +/* MODEM_SYSCON_CLK_FE_APB_FO : R/W; bitpos: [16]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_APB_FO (BIT(16)) +#define MODEM_SYSCON_CLK_FE_APB_FO_M (MODEM_SYSCON_CLK_FE_APB_FO_V << MODEM_SYSCON_CLK_FE_APB_FO_S) +#define MODEM_SYSCON_CLK_FE_APB_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_APB_FO_S 16 +/* MODEM_SYSCON_CLK_BT_APB_FO : R/W; bitpos: [17]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BT_APB_FO (BIT(17)) +#define MODEM_SYSCON_CLK_BT_APB_FO_M (MODEM_SYSCON_CLK_BT_APB_FO_V << MODEM_SYSCON_CLK_BT_APB_FO_S) +#define MODEM_SYSCON_CLK_BT_APB_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_BT_APB_FO_S 17 +/* MODEM_SYSCON_CLK_BT_FO : R/W; bitpos: [18]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_BT_FO (BIT(18)) +#define MODEM_SYSCON_CLK_BT_FO_M (MODEM_SYSCON_CLK_BT_FO_V << MODEM_SYSCON_CLK_BT_FO_S) +#define MODEM_SYSCON_CLK_BT_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_BT_FO_S 18 +/* MODEM_SYSCON_CLK_WIFIBB_480M_FO : R/W; bitpos: [19]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_WIFIBB_480M_FO (BIT(19)) +#define MODEM_SYSCON_CLK_WIFIBB_480M_FO_M (MODEM_SYSCON_CLK_WIFIBB_480M_FO_V << MODEM_SYSCON_CLK_WIFIBB_480M_FO_S) +#define MODEM_SYSCON_CLK_WIFIBB_480M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_WIFIBB_480M_FO_S 19 +/* MODEM_SYSCON_CLK_FE_480M_FO : R/W; bitpos: [20]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_480M_FO (BIT(20)) +#define MODEM_SYSCON_CLK_FE_480M_FO_M (MODEM_SYSCON_CLK_FE_480M_FO_V << MODEM_SYSCON_CLK_FE_480M_FO_S) +#define MODEM_SYSCON_CLK_FE_480M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_480M_FO_S 20 +/* MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO : R/W; bitpos: [21]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO (BIT(21)) +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO_M (MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO_V << MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO_S) +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_ANAMODE_40M_FO_S 21 +/* MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO : R/W; bitpos: [22]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO (BIT(22)) +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO_M (MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO_V << MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO_S) +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_ANAMODE_80M_FO_S 22 +/* MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO : R/W; bitpos: [23]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO (BIT(23)) +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO_M (MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO_V << MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO_S) +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO_V 0x00000001U +#define MODEM_SYSCON_CLK_FE_ANAMODE_160M_FO_S 23 + +#define MODEM_SYSCON_WIFI_BB_CFG_REG (DR_REG_MODEM_SYSCON_BASE + 0x1c) +/* MODEM_SYSCON_WIFI_BB_CFG : R/W; bitpos: [31:0]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_WIFI_BB_CFG 0xFFFFFFFFU +#define MODEM_SYSCON_WIFI_BB_CFG_M (MODEM_SYSCON_WIFI_BB_CFG_V << MODEM_SYSCON_WIFI_BB_CFG_S) +#define MODEM_SYSCON_WIFI_BB_CFG_V 0xFFFFFFFFU +#define MODEM_SYSCON_WIFI_BB_CFG_S 0 + +#define MODEM_SYSCON_MEM_CONF_REG (DR_REG_MODEM_SYSCON_BASE + 0x20) +/* MODEM_SYSCON_MODEM_MEM_WP : R/W; bitpos: [2:0]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_MODEM_MEM_WP 0x00000007U +#define MODEM_SYSCON_MODEM_MEM_WP_M (MODEM_SYSCON_MODEM_MEM_WP_V << MODEM_SYSCON_MODEM_MEM_WP_S) +#define MODEM_SYSCON_MODEM_MEM_WP_V 0x00000007U +#define MODEM_SYSCON_MODEM_MEM_WP_S 0 +/* MODEM_SYSCON_MODEM_MEM_WA : R/W; bitpos: [5:3]; default: 4; */ +/*description: */ +#define MODEM_SYSCON_MODEM_MEM_WA 0x00000007U +#define MODEM_SYSCON_MODEM_MEM_WA_M (MODEM_SYSCON_MODEM_MEM_WA_V << MODEM_SYSCON_MODEM_MEM_WA_S) +#define MODEM_SYSCON_MODEM_MEM_WA_V 0x00000007U +#define MODEM_SYSCON_MODEM_MEM_WA_S 3 +/* MODEM_SYSCON_MODEM_MEM_RA : R/W; bitpos: [7:6]; default: 0; */ +/*description: */ +#define MODEM_SYSCON_MODEM_MEM_RA 0x00000003U +#define MODEM_SYSCON_MODEM_MEM_RA_M (MODEM_SYSCON_MODEM_MEM_RA_V << MODEM_SYSCON_MODEM_MEM_RA_S) +#define MODEM_SYSCON_MODEM_MEM_RA_V 0x00000003U +#define MODEM_SYSCON_MODEM_MEM_RA_S 6 + +#define MODEM_SYSCON_DATE_REG (DR_REG_MODEM_SYSCON_BASE + 0x24) +/* MODEM_SYSCON_DATE : R/W; bitpos: [27:0]; default: 35676928; */ +/*description: */ +#define MODEM_SYSCON_DATE 0x0FFFFFFFU +#define MODEM_SYSCON_DATE_M (MODEM_SYSCON_DATE_V << MODEM_SYSCON_DATE_S) +#define MODEM_SYSCON_DATE_V 0x0FFFFFFFU +#define MODEM_SYSCON_DATE_S 0 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/modem/modem_syscon_struct.h b/components/soc/esp32c6/include/modem/modem_syscon_struct.h new file mode 100644 index 000000000000..bb95c39ed915 --- /dev/null +++ b/components/soc/esp32c6/include/modem/modem_syscon_struct.h @@ -0,0 +1,205 @@ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { + struct { + uint32_t clk_en:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} modem_syscon_test_conf_reg_t; + +typedef union { + struct { + uint32_t reserved_0:21; + uint32_t clk_data_dump_mux:1; + uint32_t clk_etm_en:1; + uint32_t clk_zb_apb_en:1; + uint32_t clk_zb_mac_en:1; + uint32_t clk_modem_sec_ecb_en:1; + uint32_t clk_modem_sec_ccm_en:1; + uint32_t clk_modem_sec_bah_en:1; + uint32_t clk_modem_sec_apb_en:1; + uint32_t clk_modem_sec_en:1; + uint32_t clk_ble_timer_en:1; + uint32_t clk_data_dump_en:1; + }; + uint32_t val; +} modem_syscon_clk_conf_reg_t; + +typedef union { + struct { + uint32_t reserved_0:22; + uint32_t clk_etm_fo:1; + uint32_t clk_zb_apb_fo:1; + uint32_t clk_zb_mac_fo:1; + uint32_t clk_modem_sec_ecb_fo:1; + uint32_t clk_modem_sec_ccm_fo:1; + uint32_t clk_modem_sec_bah_fo:1; + uint32_t clk_modem_sec_apb_fo:1; + uint32_t clk_modem_sec_fo:1; + uint32_t clk_ble_timer_fo:1; + uint32_t clk_data_dump_fo:1; + }; + uint32_t val; +} modem_syscon_clk_conf_force_on_reg_t; + +typedef union { + struct { + uint32_t reserved_0:8; + uint32_t clk_zb_st_map:4; + uint32_t clk_fe_st_map:4; + uint32_t clk_bt_st_map:4; + uint32_t clk_wifi_st_map:4; + uint32_t clk_modem_peri_st_map:4; + uint32_t clk_modem_apb_st_map:4; + }; + uint32_t val; +} modem_syscon_clk_conf_power_st_reg_t; + +typedef union { + struct { + uint32_t reserved_0:8; + uint32_t rst_wifibb:1; + uint32_t reserved_9:1; + uint32_t rst_wifimac:1; + uint32_t reserved_11:3; + uint32_t rst_fe:1; + uint32_t rst_btmac_apb:1; + uint32_t rst_btmac:1; + uint32_t rst_btbb_apb:1; + uint32_t rst_btbb:1; + uint32_t reserved_19:3; + uint32_t rst_etm:1; + uint32_t reserved_23:1; + uint32_t rst_zbmac:1; + uint32_t rst_modem_ecb:1; + uint32_t rst_modem_ccm:1; + uint32_t rst_modem_bah:1; + uint32_t reserved_28:1; + uint32_t rst_modem_sec:1; + uint32_t rst_ble_timer:1; + uint32_t rst_data_dump:1; + }; + uint32_t val; +} modem_syscon_modem_rst_conf_reg_t; + +typedef union { + struct { + uint32_t clk_wifibb_22m_en:1; + uint32_t clk_wifibb_40m_en:1; + uint32_t clk_wifibb_44m_en:1; + uint32_t clk_wifibb_80m_en:1; + uint32_t clk_wifibb_40x_en:1; + uint32_t clk_wifibb_80x_en:1; + uint32_t clk_wifibb_40x1_en:1; + uint32_t clk_wifibb_80x1_en:1; + uint32_t clk_wifibb_160x1_en:1; + uint32_t clk_wifimac_en:1; + uint32_t clk_wifi_apb_en:1; + uint32_t clk_fe_20m_en:1; + uint32_t clk_fe_40m_en:1; + uint32_t clk_fe_80m_en:1; + uint32_t clk_fe_160m_en:1; + uint32_t clk_fe_cal_160m_en:1; + uint32_t clk_fe_apb_en:1; + uint32_t clk_bt_apb_en:1; + uint32_t clk_bt_en:1; + uint32_t clk_wifibb_480m_en:1; + uint32_t clk_fe_480m_en:1; + uint32_t clk_fe_anamode_40m_en:1; + uint32_t clk_fe_anamode_80m_en:1; + uint32_t clk_fe_anamode_160m_en:1; + uint32_t reserved_24:8; + }; + uint32_t val; +} modem_syscon_clk_conf1_reg_t; + +typedef union { + struct { + uint32_t clk_wifibb_22m_fo:1; + uint32_t clk_wifibb_40m_fo:1; + uint32_t clk_wifibb_44m_fo:1; + uint32_t clk_wifibb_80m_fo:1; + uint32_t clk_wifibb_40x_fo:1; + uint32_t clk_wifibb_80x_fo:1; + uint32_t clk_wifibb_40x1_fo:1; + uint32_t clk_wifibb_80x1_fo:1; + uint32_t clk_wifibb_160x1_fo:1; + uint32_t clk_wifimac_fo:1; + uint32_t clk_wifi_apb_fo:1; + uint32_t clk_fe_20m_fo:1; + uint32_t clk_fe_40m_fo:1; + uint32_t clk_fe_80m_fo:1; + uint32_t clk_fe_160m_fo:1; + uint32_t clk_fe_cal_160m_fo:1; + uint32_t clk_fe_apb_fo:1; + uint32_t clk_bt_apb_fo:1; + uint32_t clk_bt_fo:1; + uint32_t clk_wifibb_480m_fo:1; + uint32_t clk_fe_480m_fo:1; + uint32_t clk_fe_anamode_40m_fo:1; + uint32_t clk_fe_anamode_80m_fo:1; + uint32_t clk_fe_anamode_160m_fo:1; + uint32_t reserved_24:8; + }; + uint32_t val; +} modem_syscon_clk_conf1_force_on_reg_t; + +typedef union { + struct { + uint32_t wifi_bb_cfg:32; + }; + uint32_t val; +} modem_syscon_wifi_bb_cfg_reg_t; + +typedef union { + struct { + uint32_t modem_mem_wp:3; + uint32_t modem_mem_wa:3; + uint32_t modem_mem_ra:2; + uint32_t reserved_8:24; + }; + uint32_t val; +} modem_syscon_mem_conf_reg_t; + +typedef union { + struct { + uint32_t date:28; + uint32_t reserved_28:4; + }; + uint32_t val; +} modem_syscon_date_reg_t; + + +typedef struct { + volatile modem_syscon_test_conf_reg_t test_conf; + volatile modem_syscon_clk_conf_reg_t clk_conf; + volatile modem_syscon_clk_conf_force_on_reg_t clk_conf_force_on; + volatile modem_syscon_clk_conf_power_st_reg_t clk_conf_power_st; + volatile modem_syscon_modem_rst_conf_reg_t modem_rst_conf; + volatile modem_syscon_clk_conf1_reg_t clk_conf1; + volatile modem_syscon_clk_conf1_force_on_reg_t clk_conf1_force_on; + volatile modem_syscon_wifi_bb_cfg_reg_t wifi_bb_cfg; + volatile modem_syscon_mem_conf_reg_t mem_conf; + volatile modem_syscon_date_reg_t date; +} modem_syscon_dev_t; + +extern modem_syscon_dev_t MODEM_SYSCON; + +#ifndef __cplusplus +_Static_assert(sizeof(modem_syscon_dev_t) == 0x28, "Invalid size of modem_syscon_dev_t structure"); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/modem/reg_base.h b/components/soc/esp32c6/include/modem/reg_base.h new file mode 100644 index 000000000000..4e7b619f926d --- /dev/null +++ b/components/soc/esp32c6/include/modem/reg_base.h @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#define DR_REG_MODEM_SYSCON_BASE 0x600A9800 +#define DR_REG_MODEM_LPCON_BASE 0x600AF000 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in new file mode 100644 index 000000000000..bd125d1f6f20 --- /dev/null +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -0,0 +1,1300 @@ +##################################################### +# This file is auto-generated from SoC caps +# using gen_soc_caps_kconfig.py, do not edit manually +##################################################### + +config SOC_ADC_SUPPORTED + bool + default y + +config SOC_DEDICATED_GPIO_SUPPORTED + bool + default y + +config SOC_UART_SUPPORTED + bool + default y + +config SOC_GDMA_SUPPORTED + bool + default y + +config SOC_GPTIMER_SUPPORTED + bool + default y + +config SOC_PCNT_SUPPORTED + bool + default y + +config SOC_MCPWM_SUPPORTED + bool + default y + +config SOC_TWAI_SUPPORTED + bool + default y + +config SOC_ETM_SUPPORTED + bool + default y + +config SOC_PARLIO_SUPPORTED + bool + default y + +config SOC_BT_SUPPORTED + bool + default y + +config SOC_IEEE802154_SUPPORTED + bool + default y + +config SOC_ASYNC_MEMCPY_SUPPORTED + bool + default y + +config SOC_USB_SERIAL_JTAG_SUPPORTED + bool + default y + +config SOC_TEMP_SENSOR_SUPPORTED + bool + default y + +config SOC_WIFI_SUPPORTED + bool + default y + +config SOC_SUPPORTS_SECURE_DL_MODE + bool + default y + +config SOC_ULP_SUPPORTED + bool + default y + +config SOC_LP_CORE_SUPPORTED + bool + default y + +config SOC_EFUSE_KEY_PURPOSE_FIELD + bool + default y + +config SOC_RTC_FAST_MEM_SUPPORTED + bool + default y + +config SOC_RTC_MEM_SUPPORTED + bool + default y + +config SOC_I2S_SUPPORTED + bool + default y + +config SOC_RMT_SUPPORTED + bool + default y + +config SOC_SDM_SUPPORTED + bool + default y + +config SOC_GPSPI_SUPPORTED + bool + default y + +config SOC_LEDC_SUPPORTED + bool + default y + +config SOC_I2C_SUPPORTED + bool + default y + +config SOC_SYSTIMER_SUPPORTED + bool + default y + +config SOC_SUPPORT_COEXISTENCE + bool + default y + +config SOC_AES_SUPPORTED + bool + default y + +config SOC_MPI_SUPPORTED + bool + default y + +config SOC_SHA_SUPPORTED + bool + default y + +config SOC_HMAC_SUPPORTED + bool + default y + +config SOC_DIG_SIGN_SUPPORTED + bool + default y + +config SOC_ECC_SUPPORTED + bool + default y + +config SOC_FLASH_ENC_SUPPORTED + bool + default y + +config SOC_SECURE_BOOT_SUPPORTED + bool + default y + +config SOC_SDIO_SLAVE_SUPPORTED + bool + default y + +config SOC_BOD_SUPPORTED + bool + default y + +config SOC_APM_SUPPORTED + bool + default y + +config SOC_PMU_SUPPORTED + bool + default y + +config SOC_PAU_SUPPORTED + bool + default y + +config SOC_LP_TIMER_SUPPORTED + bool + default y + +config SOC_LP_AON_SUPPORTED + bool + default y + +config SOC_LP_I2C_SUPPORTED + bool + default y + +config SOC_XTAL_SUPPORT_40M + bool + default y + +config SOC_AES_SUPPORT_DMA + bool + default y + +config SOC_AES_GDMA + bool + default y + +config SOC_AES_SUPPORT_AES_128 + bool + default y + +config SOC_AES_SUPPORT_AES_256 + bool + default y + +config SOC_ADC_DIG_CTRL_SUPPORTED + bool + default y + +config SOC_ADC_DIG_IIR_FILTER_SUPPORTED + bool + default y + +config SOC_ADC_MONITOR_SUPPORTED + bool + default y + +config SOC_ADC_DMA_SUPPORTED + bool + default y + +config SOC_ADC_PERIPH_NUM + int + default 1 + +config SOC_ADC_MAX_CHANNEL_NUM + int + default 7 + +config SOC_ADC_ATTEN_NUM + int + default 4 + +config SOC_ADC_DIGI_CONTROLLER_NUM + int + default 1 + +config SOC_ADC_PATT_LEN_MAX + int + default 8 + +config SOC_ADC_DIGI_MAX_BITWIDTH + int + default 12 + +config SOC_ADC_DIGI_MIN_BITWIDTH + int + default 12 + +config SOC_ADC_DIGI_IIR_FILTER_NUM + int + default 2 + +config SOC_ADC_DIGI_MONITOR_NUM + int + default 2 + +config SOC_ADC_DIGI_RESULT_BYTES + int + default 4 + +config SOC_ADC_DIGI_DATA_BYTES_PER_CONV + int + default 4 + +config SOC_ADC_SAMPLE_FREQ_THRES_HIGH + int + default 83333 + +config SOC_ADC_SAMPLE_FREQ_THRES_LOW + int + default 611 + +config SOC_ADC_RTC_MIN_BITWIDTH + int + default 12 + +config SOC_ADC_RTC_MAX_BITWIDTH + int + default 12 + +config SOC_ADC_CALIBRATION_V1_SUPPORTED + bool + default y + +config SOC_ADC_SELF_HW_CALI_SUPPORTED + bool + default y + +config SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + bool + default y + +config SOC_ADC_TEMPERATURE_SHARE_INTR + bool + default y + +config SOC_APB_BACKUP_DMA + bool + default n + +config SOC_BROWNOUT_RESET_SUPPORTED + bool + default y + +config SOC_SHARED_IDCACHE_SUPPORTED + bool + default y + +config SOC_CACHE_FREEZE_SUPPORTED + bool + default y + +config SOC_CPU_CORES_NUM + int + default 1 + +config SOC_CPU_INTR_NUM + int + default 32 + +config SOC_CPU_HAS_FLEXIBLE_INTC + bool + default y + +config SOC_INT_PLIC_SUPPORTED + bool + default y + +config SOC_CPU_BREAKPOINTS_NUM + int + default 4 + +config SOC_CPU_WATCHPOINTS_NUM + int + default 4 + +config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE + hex + default 0x80000000 + +config SOC_CPU_HAS_PMA + bool + default y + +config SOC_CPU_IDRAM_SPLIT_USING_PMP + bool + default y + +config SOC_DS_SIGNATURE_MAX_BIT_LEN + int + default 3072 + +config SOC_DS_KEY_PARAM_MD_IV_LENGTH + int + default 16 + +config SOC_DS_KEY_CHECK_MAX_WAIT_US + int + default 1100 + +config SOC_GDMA_GROUPS + int + default 1 + +config SOC_GDMA_PAIRS_PER_GROUP + int + default 3 + +config SOC_GDMA_SUPPORT_ETM + bool + default y + +config SOC_ETM_GROUPS + int + default 1 + +config SOC_ETM_CHANNELS_PER_GROUP + int + default 50 + +config SOC_GPIO_PORT + int + default 1 + +config SOC_GPIO_PIN_COUNT + int + default 31 + +config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER + bool + default y + +config SOC_GPIO_FLEX_GLITCH_FILTER_NUM + int + default 8 + +config SOC_GPIO_SUPPORT_ETM + bool + default y + +config SOC_GPIO_ETM_EVENTS_PER_GROUP + int + default 8 + +config SOC_GPIO_ETM_TASKS_PER_GROUP + int + default 8 + +config SOC_GPIO_SUPPORT_RTC_INDEPENDENT + bool + default y + +config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + bool + default y + +config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK + int + default 0 + +config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK + hex + default 0x000000007FFFFF00 + +config SOC_GPIO_SUPPORT_FORCE_HOLD + bool + default y + +config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP + bool + default y + +config SOC_RTCIO_PIN_COUNT + int + default 8 + +config SOC_RTCIO_INPUT_OUTPUT_SUPPORTED + bool + default y + +config SOC_RTCIO_HOLD_SUPPORTED + bool + default y + +config SOC_RTCIO_WAKE_SUPPORTED + bool + default y + +config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM + int + default 8 + +config SOC_DEDIC_GPIO_IN_CHANNELS_NUM + int + default 8 + +config SOC_DEDIC_PERIPH_ALWAYS_ENABLE + bool + default y + +config SOC_I2C_NUM + int + default 1 + +config SOC_I2C_FIFO_LEN + int + default 32 + +config SOC_I2C_CMD_REG_NUM + int + default 8 + +config SOC_I2C_SUPPORT_SLAVE + bool + default y + +config SOC_I2C_SUPPORT_HW_CLR_BUS + bool + default y + +config SOC_I2C_SUPPORT_XTAL + bool + default y + +config SOC_I2C_SUPPORT_RTC + bool + default y + +config SOC_LP_I2C_NUM + int + default 1 + +config SOC_LP_I2C_FIFO_LEN + int + default 16 + +config SOC_I2S_NUM + int + default 1 + +config SOC_I2S_HW_VERSION_2 + bool + default y + +config SOC_I2S_SUPPORTS_XTAL + bool + default y + +config SOC_I2S_SUPPORTS_PLL_F160M + bool + default y + +config SOC_I2S_SUPPORTS_PCM + bool + default y + +config SOC_I2S_SUPPORTS_PDM + bool + default y + +config SOC_I2S_SUPPORTS_PDM_TX + bool + default y + +config SOC_I2S_PDM_MAX_TX_LINES + int + default 2 + +config SOC_I2S_SUPPORTS_TDM + bool + default y + +config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK + bool + default y + +config SOC_LEDC_SUPPORT_XTAL_CLOCK + bool + default y + +config SOC_LEDC_CHANNEL_NUM + int + default 6 + +config SOC_LEDC_TIMER_BIT_WIDTH + int + default 20 + +config SOC_LEDC_SUPPORT_FADE_STOP + bool + default y + +config SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED + bool + default y + +config SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX + int + default 16 + +config SOC_LEDC_FADE_PARAMS_BIT_WIDTH + int + default 10 + +config SOC_MMU_PAGE_SIZE_CONFIGURABLE + bool + default y + +config SOC_MMU_PERIPH_NUM + int + default 1 + +config SOC_MMU_LINEAR_ADDRESS_REGION_NUM + int + default 1 + +config SOC_MMU_DI_VADDR_SHARED + bool + default y + +config SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED + bool + default n + +config SOC_MPU_MIN_REGION_SIZE + hex + default 0x20000000 + +config SOC_MPU_REGIONS_MAX_NUM + int + default 8 + +config SOC_MPU_REGION_RO_SUPPORTED + bool + default n + +config SOC_MPU_REGION_WO_SUPPORTED + bool + default n + +config SOC_PCNT_GROUPS + int + default 1 + +config SOC_PCNT_UNITS_PER_GROUP + int + default 4 + +config SOC_PCNT_CHANNELS_PER_UNIT + int + default 2 + +config SOC_PCNT_THRES_POINT_PER_UNIT + int + default 2 + +config SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE + bool + default y + +config SOC_RMT_GROUPS + int + default 1 + +config SOC_RMT_TX_CANDIDATES_PER_GROUP + int + default 2 + +config SOC_RMT_RX_CANDIDATES_PER_GROUP + int + default 2 + +config SOC_RMT_CHANNELS_PER_GROUP + int + default 4 + +config SOC_RMT_MEM_WORDS_PER_CHANNEL + int + default 48 + +config SOC_RMT_SUPPORT_RX_PINGPONG + bool + default y + +config SOC_RMT_SUPPORT_RX_DEMODULATION + bool + default y + +config SOC_RMT_SUPPORT_TX_ASYNC_STOP + bool + default y + +config SOC_RMT_SUPPORT_TX_LOOP_COUNT + bool + default y + +config SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP + bool + default y + +config SOC_RMT_SUPPORT_TX_SYNCHRO + bool + default y + +config SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY + bool + default y + +config SOC_RMT_SUPPORT_XTAL + bool + default y + +config SOC_RMT_SUPPORT_RC_FAST + bool + default y + +config SOC_MCPWM_GROUPS + int + default 1 + +config SOC_MCPWM_TIMERS_PER_GROUP + int + default 3 + +config SOC_MCPWM_OPERATORS_PER_GROUP + int + default 3 + +config SOC_MCPWM_COMPARATORS_PER_OPERATOR + int + default 2 + +config SOC_MCPWM_GENERATORS_PER_OPERATOR + int + default 2 + +config SOC_MCPWM_TRIGGERS_PER_OPERATOR + int + default 2 + +config SOC_MCPWM_GPIO_FAULTS_PER_GROUP + int + default 3 + +config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP + bool + default y + +config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER + int + default 3 + +config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP + int + default 3 + +config SOC_MCPWM_SWSYNC_CAN_PROPAGATE + bool + default y + +config SOC_MCPWM_SUPPORT_ETM + bool + default y + +config SOC_MCPWM_CAPTURE_CLK_FROM_GROUP + bool + default y + +config SOC_PARLIO_GROUPS + int + default 1 + +config SOC_PARLIO_TX_UNITS_PER_GROUP + int + default 1 + +config SOC_PARLIO_RX_UNITS_PER_GROUP + int + default 1 + +config SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH + int + default 16 + +config SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH + int + default 16 + +config SOC_PARLIO_TX_RX_SHARE_INTERRUPT + bool + default y + +config SOC_RSA_MAX_BIT_LEN + int + default 3072 + +config SOC_SHA_DMA_MAX_BUFFER_SIZE + int + default 3968 + +config SOC_SHA_SUPPORT_DMA + bool + default y + +config SOC_SHA_SUPPORT_RESUME + bool + default y + +config SOC_SHA_GDMA + bool + default y + +config SOC_SHA_SUPPORT_SHA1 + bool + default y + +config SOC_SHA_SUPPORT_SHA224 + bool + default y + +config SOC_SHA_SUPPORT_SHA256 + bool + default y + +config SOC_SDM_GROUPS + int + default 1 + +config SOC_SDM_CHANNELS_PER_GROUP + int + default 4 + +config SOC_SDM_CLK_SUPPORT_PLL_F80M + bool + default y + +config SOC_SDM_CLK_SUPPORT_XTAL + bool + default y + +config SOC_SPI_PERIPH_NUM + int + default 2 + +config SOC_SPI_MAX_CS_NUM + int + default 6 + +config SOC_SPI_MAXIMUM_BUFFER_SIZE + int + default 64 + +config SOC_SPI_SUPPORT_DDRCLK + bool + default y + +config SOC_SPI_SLAVE_SUPPORT_SEG_TRANS + bool + default y + +config SOC_SPI_SUPPORT_CD_SIG + bool + default y + +config SOC_SPI_SUPPORT_CONTINUOUS_TRANS + bool + default y + +config SOC_SPI_SUPPORT_SLAVE_HD_VER2 + bool + default y + +config SOC_SPI_SUPPORT_CLK_XTAL + bool + default y + +config SOC_SPI_SUPPORT_CLK_PLL_F80M + bool + default y + +config SOC_SPI_SUPPORT_CLK_RC_FAST + bool + default y + +config SOC_MEMSPI_IS_INDEPENDENT + bool + default y + +config SOC_SPI_MAX_PRE_DIVIDER + int + default 16 + +config SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE + bool + default y + +config SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND + bool + default y + +config SOC_SPI_MEM_SUPPORT_AUTO_RESUME + bool + default y + +config SOC_SPI_MEM_SUPPORT_IDLE_INTR + bool + default y + +config SOC_SPI_MEM_SUPPORT_SW_SUSPEND + bool + default y + +config SOC_SPI_MEM_SUPPORT_CHECK_SUS + bool + default y + +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + +config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED + bool + default y + +config SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED + bool + default y + +config SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED + bool + default y + +config SOC_SYSTIMER_COUNTER_NUM + int + default 2 + +config SOC_SYSTIMER_ALARM_NUM + int + default 3 + +config SOC_SYSTIMER_BIT_WIDTH_LO + int + default 32 + +config SOC_SYSTIMER_BIT_WIDTH_HI + int + default 20 + +config SOC_SYSTIMER_FIXED_DIVIDER + bool + default y + +config SOC_SYSTIMER_SUPPORT_RC_FAST + bool + default y + +config SOC_SYSTIMER_INT_LEVEL + bool + default y + +config SOC_SYSTIMER_ALARM_MISS_COMPENSATE + bool + default y + +config SOC_SYSTIMER_SUPPORT_ETM + bool + default y + +config SOC_LP_TIMER_BIT_WIDTH_LO + int + default 32 + +config SOC_LP_TIMER_BIT_WIDTH_HI + int + default 16 + +config SOC_TIMER_GROUPS + int + default 2 + +config SOC_TIMER_GROUP_TIMERS_PER_GROUP + int + default 1 + +config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH + int + default 54 + +config SOC_TIMER_GROUP_SUPPORT_XTAL + bool + default y + +config SOC_TIMER_GROUP_SUPPORT_RC_FAST + bool + default y + +config SOC_TIMER_GROUP_TOTAL_TIMERS + int + default 2 + +config SOC_TIMER_SUPPORT_ETM + bool + default y + +config SOC_MWDT_SUPPORT_XTAL + bool + default y + +config SOC_TWAI_CONTROLLER_NUM + int + default 2 + +config SOC_TWAI_CLK_SUPPORT_XTAL + bool + default y + +config SOC_TWAI_BRP_MIN + int + default 2 + +config SOC_TWAI_BRP_MAX + int + default 32768 + +config SOC_TWAI_SUPPORTS_RX_STATUS + bool + default y + +config SOC_EFUSE_DIS_DOWNLOAD_ICACHE + bool + default y + +config SOC_EFUSE_DIS_PAD_JTAG + bool + default y + +config SOC_EFUSE_DIS_USB_JTAG + bool + default y + +config SOC_EFUSE_DIS_DIRECT_BOOT + bool + default y + +config SOC_EFUSE_SOFT_DIS_JTAG + bool + default y + +config SOC_EFUSE_DIS_ICACHE + bool + default y + +config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + bool + default y + +config SOC_SECURE_BOOT_V2_RSA + bool + default y + +config SOC_SECURE_BOOT_V2_ECC + bool + default y + +config SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS + int + default 3 + +config SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS + bool + default y + +config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY + bool + default y + +config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX + int + default 32 + +config SOC_FLASH_ENCRYPTION_XTS_AES + bool + default y + +config SOC_FLASH_ENCRYPTION_XTS_AES_128 + bool + default y + +config SOC_CRYPTO_DPA_PROTECTION_SUPPORTED + bool + default y + +config SOC_UART_NUM + int + default 2 + +config SOC_UART_FIFO_LEN + int + default 128 + +config SOC_UART_BITRATE_MAX + int + default 5000000 + +config SOC_UART_SUPPORT_PLL_F80M_CLK + bool + default y + +config SOC_UART_SUPPORT_RTC_CLK + bool + default y + +config SOC_UART_SUPPORT_XTAL_CLK + bool + default y + +config SOC_UART_SUPPORT_WAKEUP_INT + bool + default y + +config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND + bool + default y + +config SOC_COEX_HW_PTI + bool + default y + +config SOC_EXTERNAL_COEX_ADVANCE + bool + default y + +config SOC_EXTERNAL_COEX_LEADER_TX_LINE + bool + default n + +config SOC_PHY_DIG_REGS_MEM_SIZE + int + default 21 + +config SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH + int + default 12 + +config SOC_PM_SUPPORT_WIFI_WAKEUP + bool + default y + +config SOC_PM_SUPPORT_BEACON_WAKEUP + bool + default y + +config SOC_PM_SUPPORT_BT_WAKEUP + bool + default y + +config SOC_PM_SUPPORT_EXT1_WAKEUP + bool + default y + +config SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN + bool + default y + +config SOC_PM_SUPPORT_CPU_PD + bool + default y + +config SOC_PM_SUPPORT_MODEM_PD + bool + default y + +config SOC_PM_SUPPORT_XTAL32K_PD + bool + default y + +config SOC_PM_SUPPORT_RC32K_PD + bool + default y + +config SOC_PM_SUPPORT_RC_FAST_PD + bool + default y + +config SOC_PM_SUPPORT_VDDSDIO_PD + bool + default y + +config SOC_PM_SUPPORT_TOP_PD + bool + default y + +config SOC_PM_SUPPORT_HP_AON_PD + bool + default y + +config SOC_PM_SUPPORT_MAC_BB_PD + bool + default y + +config SOC_PM_SUPPORT_RTC_PERIPH_PD + bool + default y + +config SOC_PM_SUPPORT_PMU_MODEM_STATE + bool + default y + +config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY + bool + default y + +config SOC_PM_CPU_RETENTION_BY_SW + bool + default y + +config SOC_PM_MODEM_RETENTION_BY_REGDMA + bool + default y + +config SOC_PM_RETENTION_HAS_CLOCK_BUG + bool + default y + +config SOC_PM_PAU_LINK_NUM + int + default 4 + +config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION + bool + default y + +config SOC_MODEM_CLOCK_IS_INDEPENDENT + bool + default y + +config SOC_CLK_XTAL32K_SUPPORTED + bool + default y + +config SOC_CLK_OSC_SLOW_SUPPORTED + bool + default y + +config SOC_CLK_RC32K_SUPPORTED + bool + default y + +config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC + bool + default y + +config SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL + bool + default y + +config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT + bool + default y + +config SOC_WIFI_HW_TSF + bool + default y + +config SOC_WIFI_FTM_SUPPORT + bool + default y + +config SOC_WIFI_GCMP_SUPPORT + bool + default y + +config SOC_WIFI_WAPI_SUPPORT + bool + default y + +config SOC_WIFI_CSI_SUPPORT + bool + default y + +config SOC_WIFI_MESH_SUPPORT + bool + default y + +config SOC_WIFI_HE_SUPPORT + bool + default y + +config SOC_BLE_SUPPORTED + bool + default y + +config SOC_BLE_MESH_SUPPORTED + bool + default y + +config SOC_ESP_NIMBLE_CONTROLLER + bool + default y + +config SOC_BLE_50_SUPPORTED + bool + default y + +config SOC_BLE_DEVICE_PRIVACY_SUPPORTED + bool + default y + +config SOC_BLE_POWER_CONTROL_SUPPORTED + bool + default y + +config SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED + bool + default y + +config SOC_BLUFI_SUPPORTED + bool + default y + +config SOC_BLE_MULTI_CONN_OPTIMIZATION + bool + default y + +config SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND + bool + default y + +config SOC_PHY_COMBO_MODULE + bool + default y + +config SOC_CAPS_NO_RESET_BY_ANA_BOD + bool + default y diff --git a/components/soc/esp32c6/include/soc/adc_channel.h b/components/soc/esp32c6/include/soc/adc_channel.h new file mode 100644 index 000000000000..dcdfb8633b94 --- /dev/null +++ b/components/soc/esp32c6/include/soc/adc_channel.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define ADC1_GPIO0_CHANNEL 0 +#define ADC1_CHANNEL_0_GPIO_NUM 0 + +#define ADC1_GPIO1_CHANNEL 1 +#define ADC1_CHANNEL_1_GPIO_NUM 1 + +#define ADC1_GPIO2_CHANNEL 2 +#define ADC1_CHANNEL_2_GPIO_NUM 2 + +#define ADC1_GPIO3_CHANNEL 3 +#define ADC1_CHANNEL_3_GPIO_NUM 3 + +#define ADC1_GPIO4_CHANNEL 4 +#define ADC1_CHANNEL_4_GPIO_NUM 4 + +#define ADC1_GPIO5_CHANNEL 5 +#define ADC1_CHANNEL_5_GPIO_NUM 5 + +#define ADC1_GPIO6_CHANNEL 6 +#define ADC1_CHANNEL_6_GPIO_NUM 6 diff --git a/components/soc/esp32c6/include/soc/boot_mode.h b/components/soc/esp32c6/include/soc/boot_mode.h new file mode 100644 index 000000000000..3921a29c564a --- /dev/null +++ b/components/soc/esp32c6/include/soc/boot_mode.h @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_BOOT_MODE_H_ +#define _SOC_BOOT_MODE_H_ + +#include "soc.h" + +/*SPI Boot*/ +#define IS_1XXX(v) (((v)&0x08)==0x08) + +/*Download Boot, SPI(or SDIO_V2)/UART0*/ +#define IS_00XX(v) (((v)&0x0c)==0x00) + +/*Download Boot, SDIO/UART0/UART1,FEI_FEO V2*/ +#define IS_0000(v) (((v)&0x0f)==0x00) + +/*Download Boot, SDIO/UART0/UART1,FEI_REO V2*/ +#define IS_0001(v) (((v)&0x0f)==0x01) + +/*Download Boot, SDIO/UART0/UART1,REI_FEO V2*/ +#define IS_0010(v) (((v)&0x0f)==0x02) + +/*Download Boot, SDIO/UART0/UART1,REI_REO V2*/ +#define IS_0011(v) (((v)&0x0f)==0x03) + +/*legacy SPI Boot*/ +#define IS_0100(v) (((v)&0x0f)==0x04) + +/*ATE/ANALOG Mode*/ +#define IS_0101(v) (((v)&0x0f)==0x05) + +/*SPI(or SDIO_V1) download Mode*/ +#define IS_0110(v) (((v)&0x0f)==0x06) + +/*Diagnostic Mode+UART0 download Mode*/ +#define IS_0111(v) (((v)&0x0f)==0x07) + + + +#define BOOT_MODE_GET() (GPIO_REG_READ(GPIO_STRAP_REG)) + +/*do not include download mode*/ +#define ETS_IS_UART_BOOT() IS_0111(BOOT_MODE_GET()) + +/*all spi boot including spi/legacy*/ +#define ETS_IS_FLASH_BOOT() (IS_1XXX(BOOT_MODE_GET()) || IS_0100(BOOT_MODE_GET())) + +/*all faster spi boot including spi*/ +#define ETS_IS_FAST_FLASH_BOOT() IS_1XXX(BOOT_MODE_GET()) + +#if SUPPORT_SDIO_DOWNLOAD + +/*all sdio V2 of failing edge input, failing edge output*/ +#define ETS_IS_SDIO_FEI_FEO_V2_BOOT() IS_0000(BOOT_MODE_GET()) + +/*all sdio V2 of failing edge input, raising edge output*/ +#define ETS_IS_SDIO_FEI_REO_V2_BOOT() IS_0001(BOOT_MODE_GET()) + +/*all sdio V2 of raising edge input, failing edge output*/ +#define ETS_IS_SDIO_REI_FEO_V2_BOOT() IS_0010(BOOT_MODE_GET()) + +/*all sdio V2 of raising edge input, raising edge output*/ +#define ETS_IS_SDIO_REI_REO_V2_BOOT() IS_0011(BOOT_MODE_GET()) + +/*all sdio V1 of raising edge input, failing edge output*/ +#define ETS_IS_SDIO_REI_FEO_V1_BOOT() IS_0110(BOOT_MODE_GET()) + +/*do not include joint download mode*/ +#define ETS_IS_SDIO_BOOT() IS_0110(BOOT_MODE_GET()) +#else + +/*do not include joint download mode*/ +#define ETS_IS_SPI_DOWNLOAD_BOOT() IS_0110(BOOT_MODE_GET()) + +#endif + +/*joint download boot*/ +#define ETS_IS_JOINT_DOWNLOAD_BOOT() IS_00XX(BOOT_MODE_GET()) + +/*ATE mode*/ +#define ETS_IS_ATE_BOOT() IS_0101(BOOT_MODE_GET()) + +/*used by ETS_IS_SDIO_UART_BOOT*/ +#define SEL_NO_BOOT 0 +#define SEL_SDIO_BOOT BIT0 +#define SEL_UART_BOOT BIT1 +#define SEL_SPI_SLAVE_BOOT BIT2 + +#endif /* _SOC_BOOT_MODE_H_ */ diff --git a/components/soc/esp32c6/include/soc/clint_reg.h b/components/soc/esp32c6/include/soc/clint_reg.h index 94e3ef1f499b..08ab89c5244c 100644 --- a/components/soc/esp32c6/include/soc/clint_reg.h +++ b/components/soc/esp32c6/include/soc/clint_reg.h @@ -5,7 +5,7 @@ */ #pragma once - +#include "soc/soc.h" #ifdef __cplusplus extern "C" { #endif diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h new file mode 100644 index 000000000000..3693ab12f8c8 --- /dev/null +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -0,0 +1,456 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ************************* ESP32C6 Root Clock Source **************************** + * 1) Internal 17.5MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description) + * + * This RC oscillator generates a ~17.5MHz clock signal output as the RC_FAST_CLK. + * + * The exact frequency of RC_FAST_CLK can be computed in runtime through calibration. + * + * 2) External 40MHz Crystal Clock: XTAL + * + * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description) + * + * This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock + * can be computed in runtime through calibration. + * + * 4) Internal 32kHz RC Oscillator: RC32K + * + * The exact frequency of this clock can be computed in runtime through calibration. + * + * 5) External 32kHz Crystal Clock (optional): XTAL32K + * + * The clock source for this XTAL32K_CLK should be a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N + * pins. + * + * XTAL32K_CLK can also be calibrated to get its exact frequency. + * + * 6) External Slow Clock (optional): OSC_SLOW + * + * A slow clock signal generated by an external circuit can be connected to GPIO0 to be the clock source for the + * RTC_SLOW_CLK. + * + * OSC_SLOW_CLK can also be calibrated to get its exact frequency. + */ + +/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */ +#define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */ +#define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */ +#define SOC_CLK_RC32K_FREQ_APPROX 32768 /*!< Approximate RC32K_CLK frequency in Hz */ +#define SOC_CLK_XTAL32K_FREQ_APPROX 32768 /*!< Approximate XTAL32K_CLK frequency in Hz */ +#define SOC_CLK_OSC_SLOW_FREQ_APPROX 32768 /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */ + +// Naming convention: SOC_ROOT_CLK_{loc}_{type}_[attr] +// {loc}: EXT, INT +// {type}: XTAL, RC +// [attr] - optional: [frequency], FAST, SLOW +/** + * @brief Root clock + */ +typedef enum { + SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */ + SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 136kHz RC oscillator */ + SOC_ROOT_CLK_EXT_XTAL, /*!< External 40MHz crystal */ + SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */ + SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */ + SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin0 */ +} soc_root_clk_t; + +/** + * @brief CPU_CLK mux inputs, which are the supported clock sources for the CPU_CLK + * @note Enum values are matched with the register field values on purpose + */ +typedef enum { + SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */ + SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 480MHz) */ + SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */ + SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */ +} soc_cpu_clk_src_t; + +/** + * @brief RTC_SLOW_CLK mux inputs, which are the supported clock sources for the RTC_SLOW_CLK + * @note Enum values are matched with the register field values on purpose + */ +typedef enum { + SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */ + SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ + SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ + SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ + SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ +} soc_rtc_slow_clk_src_t; + +/** + * @brief RTC_FAST_CLK mux inputs, which are the supported clock sources for the RTC_FAST_CLK + * @note Enum values are matched with the register field values on purpose + */ +typedef enum { + SOC_RTC_FAST_CLK_SRC_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */ + SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< Select XTAL_D2_CLK as RTC_FAST_CLK source */ + SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */ + SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */ +} soc_rtc_fast_clk_src_t; + +// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr] +// {[upstream]clock_name}: XTAL, (BB)PLL, etc. +// [attr] - optional: FAST, SLOW, D, F +/** + * @brief Supported clock sources for modules (CPU, peripherals, RTC, etc.) + * + * @note enum starts from 1, to save 0 for special purpose + */ +typedef enum { + // For CPU domain + SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, PLL, or RC_FAST by configuring soc_cpu_clk_src_t */ + // For RTC domain + SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */ + SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, RC32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */ + // For digital domain: peripherals, WIFI, BLE + SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */ + SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */ + SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */ + SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */ + SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */ + SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */ + SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */ + SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */ +} soc_module_clk_t; + +//////////////////////////////////////////////////SYSTIMER////////////////////////////////////////////////////////////// + +/** + * @brief Type of SYSTIMER clock source + */ +typedef enum { + SYSTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< SYSTIMER source clock is XTAL */ + SYSTIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< SYSTIMER source clock is RC_FAST */ + SYSTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< SYSTIMER source clock default choice is XTAL */ +} soc_periph_systimer_clk_src_t; + +//////////////////////////////////////////////////GPTimer/////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of GPTimer + * + * The following code can be used to iterate all possible clocks: + * @code{c} + * soc_periph_gptimer_clk_src_t gptimer_clks[] = (soc_periph_gptimer_clk_src_t)SOC_GPTIMER_CLKS; + * for (size_t i = 0; i< sizeof(gptimer_clks) / sizeof(gptimer_clks[0]); i++) { + * soc_periph_gptimer_clk_src_t clk = gptimer_clks[i]; + * // Test GPTimer with the clock `clk` + * } + * @endcode + */ +#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL} + +/** + * @brief Type of GPTimer clock source + */ +typedef enum { + GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */ + GPTIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */ +} soc_periph_gptimer_clk_src_t; + +/** + * @brief Type of Timer Group clock source, reserved for the legacy timer group driver + */ +typedef enum { + TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source is PLL_F80M */ + TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */ + TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source default choice is PLL_F80M */ +} soc_periph_tg_clk_src_legacy_t; + +//////////////////////////////////////////////////RMT/////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of RMT + */ +#define SOC_RMT_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL} + +/** + * @brief Type of RMT clock source + */ +typedef enum { + RMT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */ + RMT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */ +} soc_periph_rmt_clk_src_t; + +/** + * @brief Type of RMT clock source, reserved for the legacy RMT driver + */ +typedef enum { + RMT_BASECLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock is PLL_F80M */ + RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */ + RMT_BASECLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock default choice is PLL_F80M */ +} soc_periph_rmt_clk_src_legacy_t; + +//////////////////////////////////////////////////Temp Sensor/////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Temperature Sensor + */ +#define SOC_TEMP_SENSOR_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + +/** + * @brief Type of Temp Sensor clock source + */ +typedef enum { + TEMPERATURE_SENSOR_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + TEMPERATURE_SENSOR_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + TEMPERATURE_SENSOR_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */ +} soc_periph_temperature_sensor_clk_src_t; + +///////////////////////////////////////////////////UART///////////////////////////////////////////////////////////////// + +/** + * @brief Type of UART clock source, reserved for the legacy UART driver + */ +typedef enum { + UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */ + UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */ + UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */ + UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */ +} soc_periph_uart_clk_src_legacy_t; + +//////////////////////////////////////////////////MCPWM///////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of MCPWM Timer + */ +#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL} + +/** + * @brief Type of MCPWM timer clock source + */ +typedef enum { + MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ + MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */ +} soc_periph_mcpwm_timer_clk_src_t; + +/** + * @brief Array initializer for all supported clock sources of MCPWM Capture Timer + */ +#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL} + +/** + * @brief Type of MCPWM capture clock source + */ +typedef enum { + MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ + MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */ +} soc_periph_mcpwm_capture_clk_src_t; + +/** + * @brief Array initializer for all supported clock sources of MCPWM Carrier + */ +#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL} + +/** + * @brief Type of MCPWM carrier clock source + */ +typedef enum { + MCPWM_CARRIER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ + MCPWM_CARRIER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */ +} soc_periph_mcpwm_carrier_clk_src_t; + +///////////////////////////////////////////////////// I2S ////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of I2S + */ +#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL} + +/** + * @brief I2S clock source enum + */ +typedef enum { + I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */ + I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ + I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ +} soc_periph_i2s_clk_src_t; + +/////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of I2C + */ +#define SOC_I2C_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + +/** + * @brief Type of I2C clock source. + */ +typedef enum { + I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default source clock */ +} soc_periph_i2c_clk_src_t; + +///////////////////////////////////////////////LP_I2C/////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of LP_I2C + */ +#define SOC_LP_I2C_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL_D2} + +/** + * @brief Type of LP_I2C clock source. + */ +typedef enum { + LP_I2C_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_I2C source clock is RTC_FAST */ + LP_I2C_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_I2C source clock is XTAL_D2 */ + LP_I2C_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_I2C source clock default choice is RTC_FAST */ +} soc_periph_lp_i2c_clk_src_t; + +/////////////////////////////////////////////////SPI//////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of SPI + */ +#define SOC_SPI_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + +/** + * @brief Type of SPI clock source. + */ +typedef enum { + SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_80M as SPI source clock */ + SPI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_80M as SPI source clock */ + SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */ + SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */ +} soc_periph_spi_clk_src_t; + +//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of SDM + */ +#define SOC_SDM_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL} + +/** + * @brief Sigma Delta Modulator clock source + */ +typedef enum { + SDM_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL clock as the source clock */ + SDM_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */ + SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */ +} soc_periph_sdm_clk_src_t; + +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL clock as the source clock */ + GLITCH_FILTER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + +//////////////////////////////////////////////////TWAI////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of TWAI + */ +#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL} + +/** + * @brief TWAI clock source + */ +typedef enum { + TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ +} soc_periph_twai_clk_src_t; + +//////////////////////////////////////////////////ADC/////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of ADC digital controller + */ +#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST} + +/** + * @brief ADC digital controller clock source + */ +typedef enum { + ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */ + ADC_DIGI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */ +} soc_periph_adc_digi_clk_src_t; + +//////////////////////////////////////////////////MWDT///////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of MWDT + */ +#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST} + +/** + * @brief MWDT clock source + */ +typedef enum { + MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + MWDT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the source clock */ + MWDT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RTC fast as the source clock */ + MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select PLL fixed 80 MHz as the default clock choice */ +} soc_periph_mwdt_clk_src_t; + +//////////////////////////////////////////////////LEDC///////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of LEDC + */ +#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST} + +/** + * @brief Type of LEDC clock source, reserved for the legacy LEDC driver + */ +typedef enum { + LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/ + LEDC_USE_PLL_DIV_CLK = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */ + LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + + LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */ +} soc_periph_ledc_clk_src_legacy_t; + +//////////////////////////////////////////////////PARLIO//////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of PARLIO + */ +#define SOC_PARLIO_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F240M} + +/** + * @brief PARLIO clock source + */ +typedef enum { + PARLIO_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + PARLIO_CLK_SRC_PLL_F240M = SOC_MOD_CLK_PLL_F240M, /*!< Select PLL_F240M as the source clock */ + PARLIO_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F240M, /*!< Select PLL_F240M as the default clock choice */ +} soc_periph_parlio_clk_src_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/clkout_channel.h b/components/soc/esp32c6/include/soc/clkout_channel.h new file mode 100644 index 000000000000..035248b78d31 --- /dev/null +++ b/components/soc/esp32c6/include/soc/clkout_channel.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +// ESP32C6 CLKOUT signals has no corresponding iomux pins diff --git a/components/soc/esp32c6/include/soc/dport_access.h b/components/soc/esp32c6/include/soc/dport_access.h new file mode 100644 index 000000000000..000b58c36a1c --- /dev/null +++ b/components/soc/esp32c6/include/soc/dport_access.h @@ -0,0 +1,112 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _DPORT_ACCESS_H_ +#define _DPORT_ACCESS_H_ + +#include +#include "soc.h" +#include "uart_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Target does not have DPORT bus, so these macros are all same as the non-DPORT versions + +#define DPORT_INTERRUPT_DISABLE() +#define DPORT_INTERRUPT_RESTORE() + +/** + * @brief Read a sequence of DPORT registers to the buffer. + * + * @param[out] buff_out Contains the read data. + * @param[in] address Initial address for reading registers. + * @param[in] num_words The number of words. + */ +void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words); + +// _DPORT_REG_WRITE & DPORT_REG_WRITE are equivalent. +#define _DPORT_REG_READ(_r) (*(volatile uint32_t *)(_r)) +#define _DPORT_REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v) + +// Write value to DPORT register (does not require protecting) +#define DPORT_REG_WRITE(_r, _v) _DPORT_REG_WRITE((_r), (_v)) + +#define DPORT_REG_READ(_r) _DPORT_REG_READ(_r) +#define DPORT_SEQUENCE_REG_READ(_r) _DPORT_REG_READ(_r) + +//get bit or get bits from register +#define DPORT_REG_GET_BIT(_r, _b) (DPORT_REG_READ(_r) & (_b)) + +//set bit or set bits to register +#define DPORT_REG_SET_BIT(_r, _b) DPORT_REG_WRITE((_r), (DPORT_REG_READ(_r)|(_b))) + +//clear bit or clear bits of register +#define DPORT_REG_CLR_BIT(_r, _b) DPORT_REG_WRITE((_r), (DPORT_REG_READ(_r) & (~(_b)))) + +//set bits of register controlled by mask +#define DPORT_REG_SET_BITS(_r, _b, _m) DPORT_REG_WRITE((_r), ((DPORT_REG_READ(_r) & (~(_m))) | ((_b) & (_m)))) + +//get field from register, uses field _S & _V to determine mask +#define DPORT_REG_GET_FIELD(_r, _f) ((DPORT_REG_READ(_r) >> (_f##_S)) & (_f##_V)) + +//set field to register, used when _f is not left shifted by _f##_S +#define DPORT_REG_SET_FIELD(_r, _f, _v) DPORT_REG_WRITE((_r), ((DPORT_REG_READ(_r) & (~((_f##_V) << (_f##_S))))|(((_v) & (_f##_V))<<(_f##_S)))) + +//get field value from a variable, used when _f is not left shifted by _f##_S +#define DPORT_VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f)) + +//get field value from a variable, used when _f is left shifted by _f##_S +#define DPORT_VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S)) + +//set field value to a variable, used when _f is not left shifted by _f##_S +#define DPORT_VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S)))) + +//set field value to a variable, used when _f is left shifted by _f##_S +#define DPORT_VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S)))) + +//generate a value from a field value, used when _f is not left shifted by _f##_S +#define DPORT_FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S) + +//generate a value from a field value, used when _f is left shifted by _f##_S +#define DPORT_FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f)) + +//Register read macros with an underscore prefix access DPORT memory directly. In IDF apps, use the non-underscore versions to be SMP-safe. +#define _DPORT_READ_PERI_REG(addr) (*((volatile uint32_t *)(addr))) +#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val) +#define _DPORT_REG_SET_BIT(_r, _b) _DPORT_REG_WRITE((_r), (_DPORT_REG_READ(_r)|(_b))) +#define _DPORT_REG_CLR_BIT(_r, _b) _DPORT_REG_WRITE((_r), (_DPORT_REG_READ(_r) & (~(_b)))) + +#define DPORT_READ_PERI_REG(addr) _DPORT_READ_PERI_REG(addr) + +//write value to register +#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val)) + +//clear bits of register controlled by mask +#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask)))) + +//set bits of register controlled by mask +#define DPORT_SET_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask))) + +//get bits of register controlled by mask +#define DPORT_GET_PERI_REG_MASK(reg, mask) (DPORT_READ_PERI_REG(reg) & (mask)) + +//get bits of register controlled by highest bit and lowest bit +#define DPORT_GET_PERI_REG_BITS(reg, hipos,lowpos) ((DPORT_READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)) + +//set bits of register controlled by mask and shift +#define DPORT_SET_PERI_REG_BITS(reg,bit_map,value,shift) DPORT_WRITE_PERI_REG((reg), ((DPORT_READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & bit_map)<<(shift)))) + +//get field of register +#define DPORT_GET_PERI_REG_BITS2(reg, mask,shift) ((DPORT_READ_PERI_REG(reg)>>(shift))&(mask)) +//}} + +#ifdef __cplusplus +} +#endif + +#endif /* _DPORT_ACCESS_H_ */ diff --git a/components/soc/esp32c6/include/soc/efuse_defs.h b/components/soc/esp32c6/include/soc/efuse_defs.h new file mode 100644 index 000000000000..55f3abff5604 --- /dev/null +++ b/components/soc/esp32c6/include/soc/efuse_defs.h @@ -0,0 +1,17 @@ +/** + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define EFUSE_WRITE_OP_CODE 0x5a5a +#define EFUSE_READ_OP_CODE 0x5aa5 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/efuse_reg.h b/components/soc/esp32c6/include/soc/efuse_reg.h index 7b55a151d600..882041ac4137 100644 --- a/components/soc/esp32c6/include/soc/efuse_reg.h +++ b/components/soc/esp32c6/include/soc/efuse_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #include #include "soc/soc.h" +#include "efuse_defs.h" #ifdef __cplusplus extern "C" { #endif @@ -222,13 +223,13 @@ extern "C" { #define EFUSE_SPI_DOWNLOAD_MSPI_DIS_M (EFUSE_SPI_DOWNLOAD_MSPI_DIS_V << EFUSE_SPI_DOWNLOAD_MSPI_DIS_S) #define EFUSE_SPI_DOWNLOAD_MSPI_DIS_V 0x00000001U #define EFUSE_SPI_DOWNLOAD_MSPI_DIS_S 13 -/** EFUSE_DIS_CAN : RO; bitpos: [14]; default: 0; +/** EFUSE_DIS_TWAI : RO; bitpos: [14]; default: 0; * Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled. */ -#define EFUSE_DIS_CAN (BIT(14)) -#define EFUSE_DIS_CAN_M (EFUSE_DIS_CAN_V << EFUSE_DIS_CAN_S) -#define EFUSE_DIS_CAN_V 0x00000001U -#define EFUSE_DIS_CAN_S 14 +#define EFUSE_DIS_TWAI (BIT(14)) +#define EFUSE_DIS_TWAI_M (EFUSE_DIS_TWAI_V << EFUSE_DIS_TWAI_S) +#define EFUSE_DIS_TWAI_V 0x00000001U +#define EFUSE_DIS_TWAI_S 14 /** EFUSE_JTAG_SEL_ENABLE : RO; bitpos: [15]; default: 0; * Represents whether the selection between usb_to_jtag and pad_to_jtag through * strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 @@ -411,27 +412,27 @@ extern "C" { #define EFUSE_KEY_PURPOSE_5_M (EFUSE_KEY_PURPOSE_5_V << EFUSE_KEY_PURPOSE_5_S) #define EFUSE_KEY_PURPOSE_5_V 0x0000000FU #define EFUSE_KEY_PURPOSE_5_S 12 -/** EFUSE_DPA_SEC_LEVEL : RO; bitpos: [17:16]; default: 0; +/** EFUSE_SEC_DPA_LEVEL : RO; bitpos: [17:16]; default: 0; * Represents the spa secure level by configuring the clock random divide mode. */ -#define EFUSE_DPA_SEC_LEVEL 0x00000003U -#define EFUSE_DPA_SEC_LEVEL_M (EFUSE_DPA_SEC_LEVEL_V << EFUSE_DPA_SEC_LEVEL_S) -#define EFUSE_DPA_SEC_LEVEL_V 0x00000003U -#define EFUSE_DPA_SEC_LEVEL_S 16 -/** EFUSE_RPT4_RESERVED2_1 : RO; bitpos: [18]; default: 0; - * Reserved. - */ -#define EFUSE_RPT4_RESERVED2_1 (BIT(18)) -#define EFUSE_RPT4_RESERVED2_1_M (EFUSE_RPT4_RESERVED2_1_V << EFUSE_RPT4_RESERVED2_1_S) -#define EFUSE_RPT4_RESERVED2_1_V 0x00000001U -#define EFUSE_RPT4_RESERVED2_1_S 18 -/** EFUSE_CRYPT_DPA_ENABLE : RO; bitpos: [19]; default: 1; +#define EFUSE_SEC_DPA_LEVEL 0x00000003U +#define EFUSE_SEC_DPA_LEVEL_M (EFUSE_SEC_DPA_LEVEL_V << EFUSE_SEC_DPA_LEVEL_S) +#define EFUSE_SEC_DPA_LEVEL_V 0x00000003U +#define EFUSE_SEC_DPA_LEVEL_S 16 +/** EFUSE_CRYPT_DPA_ENABLE : RO; bitpos: [18]; default: 0; * Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled. */ -#define EFUSE_CRYPT_DPA_ENABLE (BIT(19)) +#define EFUSE_CRYPT_DPA_ENABLE (BIT(18)) #define EFUSE_CRYPT_DPA_ENABLE_M (EFUSE_CRYPT_DPA_ENABLE_V << EFUSE_CRYPT_DPA_ENABLE_S) #define EFUSE_CRYPT_DPA_ENABLE_V 0x00000001U -#define EFUSE_CRYPT_DPA_ENABLE_S 19 +#define EFUSE_CRYPT_DPA_ENABLE_S 18 +/** EFUSE_RPT4_RESERVED2_1 : RO; bitpos: [19]; default: 1; + * Reserved. + */ +#define EFUSE_RPT4_RESERVED2_1 (BIT(19)) +#define EFUSE_RPT4_RESERVED2_1_M (EFUSE_RPT4_RESERVED2_1_V << EFUSE_RPT4_RESERVED2_1_S) +#define EFUSE_RPT4_RESERVED2_1_V 0x00000001U +#define EFUSE_RPT4_RESERVED2_1_S 19 /** EFUSE_SECURE_BOOT_EN : RO; bitpos: [20]; default: 0; * Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled. */ @@ -482,14 +483,14 @@ extern "C" { #define EFUSE_DIS_DIRECT_BOOT_M (EFUSE_DIS_DIRECT_BOOT_V << EFUSE_DIS_DIRECT_BOOT_S) #define EFUSE_DIS_DIRECT_BOOT_V 0x00000001U #define EFUSE_DIS_DIRECT_BOOT_S 1 -/** EFUSE_DIS_USB_PRINT : RO; bitpos: [2]; default: 0; +/** EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT : RO; bitpos: [2]; default: 0; * Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. * 0: enabled. */ -#define EFUSE_DIS_USB_PRINT (BIT(2)) -#define EFUSE_DIS_USB_PRINT_M (EFUSE_DIS_USB_PRINT_V << EFUSE_DIS_USB_PRINT_S) -#define EFUSE_DIS_USB_PRINT_V 0x00000001U -#define EFUSE_DIS_USB_PRINT_S 2 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_M (EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_V << EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_S) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_V 0x00000001U +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_S 2 /** EFUSE_RPT4_RESERVED3_5 : RO; bitpos: [3]; default: 0; * Reserved. */ @@ -585,13 +586,27 @@ extern "C" { * BLOCK0 data register 5. */ #define EFUSE_RD_REPEAT_DATA4_REG (DR_REG_EFUSE_BASE + 0x40) -/** EFUSE_RPT4_RESERVED4_1 : RO; bitpos: [23:0]; default: 0; - * Reserved. - */ -#define EFUSE_RPT4_RESERVED4_1 0x00FFFFFFU -#define EFUSE_RPT4_RESERVED4_1_M (EFUSE_RPT4_RESERVED4_1_V << EFUSE_RPT4_RESERVED4_1_S) -#define EFUSE_RPT4_RESERVED4_1_V 0x00FFFFFFU -#define EFUSE_RPT4_RESERVED4_1_S 0 +/** EFUSE_DISABLE_WAFER_VERSION_MAJOR : R; bitpos: [0]; default: 0; + * Disables check of wafer version major + */ +#define EFUSE_DISABLE_WAFER_VERSION_MAJOR (BIT(0)) +#define EFUSE_DISABLE_WAFER_VERSION_MAJOR_M (EFUSE_DISABLE_WAFER_VERSION_MAJOR_V << EFUSE_DISABLE_WAFER_VERSION_MAJOR_S) +#define EFUSE_DISABLE_WAFER_VERSION_MAJOR_V 0x00000001U +#define EFUSE_DISABLE_WAFER_VERSION_MAJOR_S 0 +/** EFUSE_DISABLE_BLK_VERSION_MAJOR : R; bitpos: [1]; default: 0; + * Disables check of blk version major + */ +#define EFUSE_DISABLE_BLK_VERSION_MAJOR (BIT(1)) +#define EFUSE_DISABLE_BLK_VERSION_MAJOR_M (EFUSE_DISABLE_BLK_VERSION_MAJOR_V << EFUSE_DISABLE_BLK_VERSION_MAJOR_S) +#define EFUSE_DISABLE_BLK_VERSION_MAJOR_V 0x00000001U +#define EFUSE_DISABLE_BLK_VERSION_MAJOR_S 1 +/** EFUSE_RESERVED_0_162 : R; bitpos: [23:2]; default: 0; + * reserved + */ +#define EFUSE_RESERVED_0_162 0x003FFFFFU +#define EFUSE_RESERVED_0_162_M (EFUSE_RESERVED_0_162_V << EFUSE_RESERVED_0_162_S) +#define EFUSE_RESERVED_0_162_V 0x003FFFFFU +#define EFUSE_RESERVED_0_162_S 2 /** EFUSE_RPT4_RESERVED4_0 : RO; bitpos: [31:24]; default: 0; * Reserved. */ @@ -635,20 +650,62 @@ extern "C" { * BLOCK1 data register $n. */ #define EFUSE_RD_MAC_SPI_SYS_2_REG (DR_REG_EFUSE_BASE + 0x4c) -/** EFUSE_MAC_SPI_RESERVED : RO; bitpos: [13:0]; default: 0; - * Reserved. - */ -#define EFUSE_MAC_SPI_RESERVED 0x00003FFFU -#define EFUSE_MAC_SPI_RESERVED_M (EFUSE_MAC_SPI_RESERVED_V << EFUSE_MAC_SPI_RESERVED_S) -#define EFUSE_MAC_SPI_RESERVED_V 0x00003FFFU -#define EFUSE_MAC_SPI_RESERVED_S 0 -/** EFUSE_SPI_PAD_CONF_1 : RO; bitpos: [31:14]; default: 0; +/** EFUSE_ACTIVE_HP_DBIAS : RO; bitpos: [4:0]; default: 0; + * Stores the active hp dbias. + */ +#define EFUSE_ACTIVE_HP_DBIAS 0x0000001FU +#define EFUSE_ACTIVE_HP_DBIAS_M (EFUSE_ACTIVE_HP_DBIAS_V << EFUSE_ACTIVE_HP_DBIAS_S) +#define EFUSE_ACTIVE_HP_DBIAS_V 0x0000001FU +#define EFUSE_ACTIVE_HP_DBIAS_S 0 +/** EFUSE_ACTIVE_LP_DBIAS : RO; bitpos: [9:5]; default: 0; + * Stores the active lp dbias. + */ +#define EFUSE_ACTIVE_LP_DBIAS 0x0000001FU +#define EFUSE_ACTIVE_LP_DBIAS_M (EFUSE_ACTIVE_LP_DBIAS_V << EFUSE_ACTIVE_LP_DBIAS_S) +#define EFUSE_ACTIVE_LP_DBIAS_V 0x0000001FU +#define EFUSE_ACTIVE_LP_DBIAS_S 5 +/** EFUSE_LSLP_HP_DBG : RO; bitpos: [11:10]; default: 0; + * Stores the lslp hp dbg. + */ +#define EFUSE_LSLP_HP_DBG 0x00000003U +#define EFUSE_LSLP_HP_DBG_M (EFUSE_LSLP_HP_DBG_V << EFUSE_LSLP_HP_DBG_S) +#define EFUSE_LSLP_HP_DBG_V 0x00000003U +#define EFUSE_LSLP_HP_DBG_S 10 +/** EFUSE_LSLP_HP_DBIAS : RO; bitpos: [15:12]; default: 0; + * Stores the lslp hp dbias. + */ +#define EFUSE_LSLP_HP_DBIAS 0x0000000FU +#define EFUSE_LSLP_HP_DBIAS_M (EFUSE_LSLP_HP_DBIAS_V << EFUSE_LSLP_HP_DBIAS_S) +#define EFUSE_LSLP_HP_DBIAS_V 0x0000000FU +#define EFUSE_LSLP_HP_DBIAS_S 12 +/** EFUSE_DSLP_LP_DBG : RO; bitpos: [18:16]; default: 0; + * Stores the dslp lp dbg. + */ +#define EFUSE_DSLP_LP_DBG 0x00000007U +#define EFUSE_DSLP_LP_DBG_M (EFUSE_DSLP_LP_DBG_V << EFUSE_DSLP_LP_DBG_S) +#define EFUSE_DSLP_LP_DBG_V 0x00000007U +#define EFUSE_DSLP_LP_DBG_S 16 +/** EFUSE_DSLP_LP_DBIAS : RO; bitpos: [22:19]; default: 0; + * Stores the dslp lp dbias. + */ +#define EFUSE_DSLP_LP_DBIAS 0x0000000FU +#define EFUSE_DSLP_LP_DBIAS_M (EFUSE_DSLP_LP_DBIAS_V << EFUSE_DSLP_LP_DBIAS_S) +#define EFUSE_DSLP_LP_DBIAS_V 0x0000000FU +#define EFUSE_DSLP_LP_DBIAS_S 19 +/** EFUSE_DBIAS_VOL_GAP : RO; bitpos: [27:23]; default: 0; + * Stores the hp and lp dbias vol gap. + */ +#define EFUSE_DBIAS_VOL_GAP 0x0000001FU +#define EFUSE_DBIAS_VOL_GAP_M (EFUSE_DBIAS_VOL_GAP_V << EFUSE_DBIAS_VOL_GAP_S) +#define EFUSE_DBIAS_VOL_GAP_V 0x0000001FU +#define EFUSE_DBIAS_VOL_GAP_S 23 +/** EFUSE_SPI_PAD_CONF_1 : RO; bitpos: [31:28]; default: 0; * Stores the first part of SPI_PAD_CONF. */ -#define EFUSE_SPI_PAD_CONF_1 0x0003FFFFU +#define EFUSE_SPI_PAD_CONF_1 0x0000000FU #define EFUSE_SPI_PAD_CONF_1_M (EFUSE_SPI_PAD_CONF_1_V << EFUSE_SPI_PAD_CONF_1_S) -#define EFUSE_SPI_PAD_CONF_1_V 0x0003FFFFU -#define EFUSE_SPI_PAD_CONF_1_S 14 +#define EFUSE_SPI_PAD_CONF_1_V 0x0000000FU +#define EFUSE_SPI_PAD_CONF_1_S 28 /** EFUSE_RD_MAC_SPI_SYS_3_REG register * BLOCK1 data register $n. @@ -661,25 +718,64 @@ extern "C" { #define EFUSE_SPI_PAD_CONF_2_M (EFUSE_SPI_PAD_CONF_2_V << EFUSE_SPI_PAD_CONF_2_S) #define EFUSE_SPI_PAD_CONF_2_V 0x0003FFFFU #define EFUSE_SPI_PAD_CONF_2_S 0 -/** EFUSE_SYS_DATA_PART0_0 : RO; bitpos: [31:18]; default: 0; - * Stores the first 14 bits of the zeroth part of system data. - */ -#define EFUSE_SYS_DATA_PART0_0 0x00003FFFU -#define EFUSE_SYS_DATA_PART0_0_M (EFUSE_SYS_DATA_PART0_0_V << EFUSE_SYS_DATA_PART0_0_S) -#define EFUSE_SYS_DATA_PART0_0_V 0x00003FFFU -#define EFUSE_SYS_DATA_PART0_0_S 18 +/** EFUSE_WAFER_VERSION_MINOR : R; bitpos: [21:18]; default: 0; */ +#define EFUSE_WAFER_VERSION_MINOR 0x0000000FU +#define EFUSE_WAFER_VERSION_MINOR_M (EFUSE_WAFER_VERSION_MINOR_V << EFUSE_WAFER_VERSION_MINOR_S) +#define EFUSE_WAFER_VERSION_MINOR_V 0x0000000FU +#define EFUSE_WAFER_VERSION_MINOR_S 18 +/** EFUSE_WAFER_VERSION_MAJOR : R; bitpos: [23:22]; default: 0; */ +#define EFUSE_WAFER_VERSION_MAJOR 0x00000003U +#define EFUSE_WAFER_VERSION_MAJOR_M (EFUSE_WAFER_VERSION_MAJOR_V << EFUSE_WAFER_VERSION_MAJOR_S) +#define EFUSE_WAFER_VERSION_MAJOR_V 0x00000003U +#define EFUSE_WAFER_VERSION_MAJOR_S 22 +/** EFUSE_PKG_VERSION : R; bitpos: [26:24]; default: 0; + * Package version + */ +#define EFUSE_PKG_VERSION 0x00000007U +#define EFUSE_PKG_VERSION_M (EFUSE_PKG_VERSION_V << EFUSE_PKG_VERSION_S) +#define EFUSE_PKG_VERSION_V 0x00000007U +#define EFUSE_PKG_VERSION_S 24 +/** EFUSE_BLK_VERSION_MINOR : R; bitpos: [29:27]; default: 0; + * BLK_VERSION_MINOR of BLOCK2 + */ +#define EFUSE_BLK_VERSION_MINOR 0x00000007U +#define EFUSE_BLK_VERSION_MINOR_M (EFUSE_BLK_VERSION_MINOR_V << EFUSE_BLK_VERSION_MINOR_S) +#define EFUSE_BLK_VERSION_MINOR_V 0x00000007U +#define EFUSE_BLK_VERSION_MINOR_S 27 +/** EFUSE_BLK_VERSION_MAJOR : R; bitpos: [31:30]; default: 0; + * BLK_VERSION_MAJOR of BLOCK2 + */ +#define EFUSE_BLK_VERSION_MAJOR 0x00000003U +#define EFUSE_BLK_VERSION_MAJOR_M (EFUSE_BLK_VERSION_MAJOR_V << EFUSE_BLK_VERSION_MAJOR_S) +#define EFUSE_BLK_VERSION_MAJOR_V 0x00000003U +#define EFUSE_BLK_VERSION_MAJOR_S 30 /** EFUSE_RD_MAC_SPI_SYS_4_REG register * BLOCK1 data register $n. */ #define EFUSE_RD_MAC_SPI_SYS_4_REG (DR_REG_EFUSE_BASE + 0x54) -/** EFUSE_SYS_DATA_PART0_1 : RO; bitpos: [31:0]; default: 0; - * Stores the first 32 bits of the zeroth part of system data. - */ -#define EFUSE_SYS_DATA_PART0_1 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART0_1_M (EFUSE_SYS_DATA_PART0_1_V << EFUSE_SYS_DATA_PART0_1_S) -#define EFUSE_SYS_DATA_PART0_1_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART0_1_S 0 +/** EFUSE_FLASH_CAP : R; bitpos: [2:0]; default: 0; */ +#define EFUSE_FLASH_CAP 0x00000007U +#define EFUSE_FLASH_CAP_M (EFUSE_FLASH_CAP_V << EFUSE_FLASH_CAP_S) +#define EFUSE_FLASH_CAP_V 0x00000007U +#define EFUSE_FLASH_CAP_S 0 +/** EFUSE_FLASH_TEMP : R; bitpos: [4:3]; default: 0; */ +#define EFUSE_FLASH_TEMP 0x00000003U +#define EFUSE_FLASH_TEMP_M (EFUSE_FLASH_TEMP_V << EFUSE_FLASH_TEMP_S) +#define EFUSE_FLASH_TEMP_V 0x00000003U +#define EFUSE_FLASH_TEMP_S 3 +/** EFUSE_FLASH_VENDOR : R; bitpos: [7:5]; default: 0; */ +#define EFUSE_FLASH_VENDOR 0x00000007U +#define EFUSE_FLASH_VENDOR_M (EFUSE_FLASH_VENDOR_V << EFUSE_FLASH_VENDOR_S) +#define EFUSE_FLASH_VENDOR_V 0x00000007U +#define EFUSE_FLASH_VENDOR_S 5 +/** EFUSE_RESERVED_1_136 : R; bitpos: [31:8]; default: 0; + * reserved + */ +#define EFUSE_RESERVED_1_136 0x00FFFFFFU +#define EFUSE_RESERVED_1_136_M (EFUSE_RESERVED_1_136_V << EFUSE_RESERVED_1_136_S) +#define EFUSE_RESERVED_1_136_V 0x00FFFFFFU +#define EFUSE_RESERVED_1_136_S 8 /** EFUSE_RD_MAC_SPI_SYS_5_REG register * BLOCK1 data register $n. @@ -697,97 +793,216 @@ extern "C" { * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA0_REG (DR_REG_EFUSE_BASE + 0x5c) -/** EFUSE_SYS_DATA_PART1_0 : RO; bitpos: [31:0]; default: 0; - * Stores the zeroth 32 bits of the first part of system data. +/** EFUSE_OPTIONAL_UNIQUE_ID : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ -#define EFUSE_SYS_DATA_PART1_0 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_0_M (EFUSE_SYS_DATA_PART1_0_V << EFUSE_SYS_DATA_PART1_0_S) -#define EFUSE_SYS_DATA_PART1_0_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_0_S 0 +#define EFUSE_OPTIONAL_UNIQUE_ID 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_M (EFUSE_OPTIONAL_UNIQUE_ID_V << EFUSE_OPTIONAL_UNIQUE_ID_S) +#define EFUSE_OPTIONAL_UNIQUE_ID_V 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_S 0 /** EFUSE_RD_SYS_PART1_DATA1_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA1_REG (DR_REG_EFUSE_BASE + 0x60) -/** EFUSE_SYS_DATA_PART1_1 : RO; bitpos: [31:0]; default: 0; - * Stores the first 32 bits of the first part of system data. +/** EFUSE_OPTIONAL_UNIQUE_ID_1 : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ -#define EFUSE_SYS_DATA_PART1_1 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_1_M (EFUSE_SYS_DATA_PART1_1_V << EFUSE_SYS_DATA_PART1_1_S) -#define EFUSE_SYS_DATA_PART1_1_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_1_S 0 +#define EFUSE_OPTIONAL_UNIQUE_ID_1 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_1_M (EFUSE_OPTIONAL_UNIQUE_ID_1_V << EFUSE_OPTIONAL_UNIQUE_ID_1_S) +#define EFUSE_OPTIONAL_UNIQUE_ID_1_V 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_1_S 0 /** EFUSE_RD_SYS_PART1_DATA2_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA2_REG (DR_REG_EFUSE_BASE + 0x64) -/** EFUSE_SYS_DATA_PART1_2 : RO; bitpos: [31:0]; default: 0; - * Stores the second 32 bits of the first part of system data. +/** EFUSE_OPTIONAL_UNIQUE_ID_2 : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ -#define EFUSE_SYS_DATA_PART1_2 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_2_M (EFUSE_SYS_DATA_PART1_2_V << EFUSE_SYS_DATA_PART1_2_S) -#define EFUSE_SYS_DATA_PART1_2_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_2_S 0 +#define EFUSE_OPTIONAL_UNIQUE_ID_2 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_2_M (EFUSE_OPTIONAL_UNIQUE_ID_2_V << EFUSE_OPTIONAL_UNIQUE_ID_2_S) +#define EFUSE_OPTIONAL_UNIQUE_ID_2_V 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_2_S 0 /** EFUSE_RD_SYS_PART1_DATA3_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA3_REG (DR_REG_EFUSE_BASE + 0x68) -/** EFUSE_SYS_DATA_PART1_3 : RO; bitpos: [31:0]; default: 0; - * Stores the third 32 bits of the first part of system data. +/** EFUSE_OPTIONAL_UNIQUE_ID_3 : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ -#define EFUSE_SYS_DATA_PART1_3 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_3_M (EFUSE_SYS_DATA_PART1_3_V << EFUSE_SYS_DATA_PART1_3_S) -#define EFUSE_SYS_DATA_PART1_3_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_3_S 0 +#define EFUSE_OPTIONAL_UNIQUE_ID_3 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_3_M (EFUSE_OPTIONAL_UNIQUE_ID_3_V << EFUSE_OPTIONAL_UNIQUE_ID_3_S) +#define EFUSE_OPTIONAL_UNIQUE_ID_3_V 0xFFFFFFFFU +#define EFUSE_OPTIONAL_UNIQUE_ID_3_S 0 /** EFUSE_RD_SYS_PART1_DATA4_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA4_REG (DR_REG_EFUSE_BASE + 0x6c) -/** EFUSE_SYS_DATA_PART1_4 : RO; bitpos: [31:0]; default: 0; - * Stores the fourth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_4 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_4_M (EFUSE_SYS_DATA_PART1_4_V << EFUSE_SYS_DATA_PART1_4_S) -#define EFUSE_SYS_DATA_PART1_4_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_4_S 0 +/** EFUSE_TEMP_CALIB : R; bitpos: [8:0]; default: 0; + * Temperature calibration data + */ +#define EFUSE_TEMP_CALIB 0x000001FFU +#define EFUSE_TEMP_CALIB_M (EFUSE_TEMP_CALIB_V << EFUSE_TEMP_CALIB_S) +#define EFUSE_TEMP_CALIB_V 0x000001FFU +#define EFUSE_TEMP_CALIB_S 0 +/** EFUSE_OCODE : R; bitpos: [16:9]; default: 0; + * ADC OCode + */ +#define EFUSE_OCODE 0x000000FFU +#define EFUSE_OCODE_M (EFUSE_OCODE_V << EFUSE_OCODE_S) +#define EFUSE_OCODE_V 0x000000FFU +#define EFUSE_OCODE_S 9 +/** EFUSE_ADC1_INIT_CODE_ATTEN0 : R; bitpos: [26:17]; default: 0; + * ADC1 init code at atten0 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_M (EFUSE_ADC1_INIT_CODE_ATTEN0_V << EFUSE_ADC1_INIT_CODE_ATTEN0_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_V 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_S 17 +/** EFUSE_ADC1_INIT_CODE_ATTEN1 : R; bitpos: [31:27]; default: 0; + * ADC1 init code at atten1 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN1 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_M (EFUSE_ADC1_INIT_CODE_ATTEN1_V << EFUSE_ADC1_INIT_CODE_ATTEN1_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN1_V 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_S 27 /** EFUSE_RD_SYS_PART1_DATA5_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA5_REG (DR_REG_EFUSE_BASE + 0x70) -/** EFUSE_SYS_DATA_PART1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_5 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_M (EFUSE_SYS_DATA_PART1_5_V << EFUSE_SYS_DATA_PART1_5_S) -#define EFUSE_SYS_DATA_PART1_5_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_S 0 +/** EFUSE_ADC1_INIT_CODE_ATTEN1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 init code at atten1 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1_M (EFUSE_ADC1_INIT_CODE_ATTEN1_1_V << EFUSE_ADC1_INIT_CODE_ATTEN1_1_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1_V 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1_S 0 +/** EFUSE_ADC1_INIT_CODE_ATTEN2 : R; bitpos: [14:5]; default: 0; + * ADC1 init code at atten2 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN2 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN2_M (EFUSE_ADC1_INIT_CODE_ATTEN2_V << EFUSE_ADC1_INIT_CODE_ATTEN2_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN2_S 5 +/** EFUSE_ADC1_INIT_CODE_ATTEN3 : R; bitpos: [24:15]; default: 0; + * ADC1 init code at atten3 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN3 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN3_M (EFUSE_ADC1_INIT_CODE_ATTEN3_V << EFUSE_ADC1_INIT_CODE_ATTEN3_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN3_V 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN3_S 15 +/** EFUSE_ADC1_CAL_VOL_ATTEN0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration voltage at atten0 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN0 0x0000007FU +#define EFUSE_ADC1_CAL_VOL_ATTEN0_M (EFUSE_ADC1_CAL_VOL_ATTEN0_V << EFUSE_ADC1_CAL_VOL_ATTEN0_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN0_V 0x0000007FU +#define EFUSE_ADC1_CAL_VOL_ATTEN0_S 25 /** EFUSE_RD_SYS_PART1_DATA6_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA6_REG (DR_REG_EFUSE_BASE + 0x74) -/** EFUSE_SYS_DATA_PART1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_6 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_M (EFUSE_SYS_DATA_PART1_6_V << EFUSE_SYS_DATA_PART1_6_S) -#define EFUSE_SYS_DATA_PART1_6_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_S 0 +/** EFUSE_ADC1_CAL_VOL_ATTEN0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration voltage at atten0 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1 0x00000007U +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1_M (EFUSE_ADC1_CAL_VOL_ATTEN0_1_V << EFUSE_ADC1_CAL_VOL_ATTEN0_1_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1_V 0x00000007U +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1_S 0 +/** EFUSE_ADC1_CAL_VOL_ATTEN1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration voltage at atten1 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN1 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN1_M (EFUSE_ADC1_CAL_VOL_ATTEN1_V << EFUSE_ADC1_CAL_VOL_ATTEN1_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN1_V 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN1_S 3 +/** EFUSE_ADC1_CAL_VOL_ATTEN2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration voltage at atten2 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN2 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN2_M (EFUSE_ADC1_CAL_VOL_ATTEN2_V << EFUSE_ADC1_CAL_VOL_ATTEN2_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN2_S 13 +/** EFUSE_ADC1_CAL_VOL_ATTEN3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration voltage at atten3 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN3 0x000001FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN3_M (EFUSE_ADC1_CAL_VOL_ATTEN3_V << EFUSE_ADC1_CAL_VOL_ATTEN3_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN3_V 0x000001FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN3_S 23 /** EFUSE_RD_SYS_PART1_DATA7_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA7_REG (DR_REG_EFUSE_BASE + 0x78) -/** EFUSE_SYS_DATA_PART1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_7 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_M (EFUSE_SYS_DATA_PART1_7_V << EFUSE_SYS_DATA_PART1_7_S) -#define EFUSE_SYS_DATA_PART1_7_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_S 0 +/** EFUSE_ADC1_CAL_VOL_ATTEN3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration voltage at atten3 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1 (BIT(0)) +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1_M (EFUSE_ADC1_CAL_VOL_ATTEN3_1_V << EFUSE_ADC1_CAL_VOL_ATTEN3_1_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1_V 0x00000001U +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1_S 0 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH0 : R; bitpos: [4:1]; default: 0; + * ADC1 init code at atten0 ch0 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_S 1 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH1 : R; bitpos: [8:5]; default: 0; + * ADC1 init code at atten0 ch1 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_S 5 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH2 : R; bitpos: [12:9]; default: 0; + * ADC1 init code at atten0 ch2 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_S 9 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH3 : R; bitpos: [16:13]; default: 0; + * ADC1 init code at atten0 ch3 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_S 13 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH4 : R; bitpos: [20:17]; default: 0; + * ADC1 init code at atten0 ch4 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_S 17 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH5 : R; bitpos: [24:21]; default: 0; + * ADC1 init code at atten0 ch5 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_S 21 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH6 : R; bitpos: [28:25]; default: 0; + * ADC1 init code at atten0 ch6 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_S 25 +/** EFUSE_RESERVED_2_253 : R; bitpos: [31:29]; default: 0; + * reserved + */ +#define EFUSE_RESERVED_2_253 0x00000007U +#define EFUSE_RESERVED_2_253_M (EFUSE_RESERVED_2_253_V << EFUSE_RESERVED_2_253_S) +#define EFUSE_RESERVED_2_253_V 0x00000007U +#define EFUSE_RESERVED_2_253_S 29 /** EFUSE_RD_USR_DATA0_REG register * Register $n of BLOCK3 (user). @@ -865,25 +1080,39 @@ extern "C" { * Register $n of BLOCK3 (user). */ #define EFUSE_RD_USR_DATA6_REG (DR_REG_EFUSE_BASE + 0x94) -/** EFUSE_USR_DATA6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of BLOCK3 (user). +/** EFUSE_RESERVED_3_192 : R; bitpos: [7:0]; default: 0; + * reserved + */ +#define EFUSE_RESERVED_3_192 0x000000FFU +#define EFUSE_RESERVED_3_192_M (EFUSE_RESERVED_3_192_V << EFUSE_RESERVED_3_192_S) +#define EFUSE_RESERVED_3_192_V 0x000000FFU +#define EFUSE_RESERVED_3_192_S 0 +/** EFUSE_CUSTOM_MAC : R; bitpos: [31:8]; default: 0; + * Custom MAC */ -#define EFUSE_USR_DATA6 0xFFFFFFFFU -#define EFUSE_USR_DATA6_M (EFUSE_USR_DATA6_V << EFUSE_USR_DATA6_S) -#define EFUSE_USR_DATA6_V 0xFFFFFFFFU -#define EFUSE_USR_DATA6_S 0 +#define EFUSE_CUSTOM_MAC 0x00FFFFFFU +#define EFUSE_CUSTOM_MAC_M (EFUSE_CUSTOM_MAC_V << EFUSE_CUSTOM_MAC_S) +#define EFUSE_CUSTOM_MAC_V 0x00FFFFFFU +#define EFUSE_CUSTOM_MAC_S 8 /** EFUSE_RD_USR_DATA7_REG register * Register $n of BLOCK3 (user). */ #define EFUSE_RD_USR_DATA7_REG (DR_REG_EFUSE_BASE + 0x98) -/** EFUSE_USR_DATA7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of BLOCK3 (user). +/** EFUSE_CUSTOM_MAC_1 : R; bitpos: [23:0]; default: 0; + * Custom MAC */ -#define EFUSE_USR_DATA7 0xFFFFFFFFU -#define EFUSE_USR_DATA7_M (EFUSE_USR_DATA7_V << EFUSE_USR_DATA7_S) -#define EFUSE_USR_DATA7_V 0xFFFFFFFFU -#define EFUSE_USR_DATA7_S 0 +#define EFUSE_CUSTOM_MAC_1 0x00FFFFFFU +#define EFUSE_CUSTOM_MAC_1_M (EFUSE_CUSTOM_MAC_1_V << EFUSE_CUSTOM_MAC_1_S) +#define EFUSE_CUSTOM_MAC_1_V 0x00FFFFFFU +#define EFUSE_CUSTOM_MAC_1_S 0 +/** EFUSE_RESERVED_3_248 : R; bitpos: [31:24]; default: 0; + * reserved + */ +#define EFUSE_RESERVED_3_248 0x000000FFU +#define EFUSE_RESERVED_3_248_M (EFUSE_RESERVED_3_248_V << EFUSE_RESERVED_3_248_S) +#define EFUSE_RESERVED_3_248_V 0x000000FFU +#define EFUSE_RESERVED_3_248_S 24 /** EFUSE_RD_KEY0_DATA0_REG register * Register $n of BLOCK4 (KEY0). @@ -2172,9 +2401,6 @@ extern "C" { #define EFUSE_OP_CODE_V 0x0000FFFFU #define EFUSE_OP_CODE_S 0 -#define EFUSE_WRITE_OP_CODE 0x5a5a -#define EFUSE_READ_OP_CODE 0x5aa5 - /** EFUSE_STATUS_REG register * eFuse status register. */ diff --git a/components/soc/esp32c6/include/soc/efuse_struct.h b/components/soc/esp32c6/include/soc/efuse_struct.h index 2090d26ce286..e6971b4d5836 100644 --- a/components/soc/esp32c6/include/soc/efuse_struct.h +++ b/components/soc/esp32c6/include/soc/efuse_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -155,7 +155,7 @@ typedef union { } efuse_pgm_check_value2_reg_t; -/** Group: ******** Registers */ +/** Group: Read Data Register */ /** Type of rd_wr_dis register * BLOCK0 data register 0. */ @@ -213,10 +213,10 @@ typedef union { * enabled. 1: disabled. 0: enabled. */ uint32_t spi_download_mspi_dis:1; - /** dis_can : RO; bitpos: [14]; default: 0; + /** dis_twai : RO; bitpos: [14]; default: 0; * Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled. */ - uint32_t dis_can:1; + uint32_t dis_twai:1; /** jtag_sel_enable : RO; bitpos: [15]; default: 0; * Represents whether the selection between usb_to_jtag and pad_to_jtag through * strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 @@ -338,18 +338,18 @@ typedef union { * Represents the purpose of Key5. */ uint32_t key_purpose_5:4; - /** dpa_sec_level : RO; bitpos: [17:16]; default: 0; + /** sec_dpa_level : RO; bitpos: [17:16]; default: 0; * Represents the spa secure level by configuring the clock random divide mode. */ - uint32_t dpa_sec_level:2; - /** rpt4_reserved2_1 : RO; bitpos: [18]; default: 0; - * Reserved. - */ - uint32_t rpt4_reserved2_1:1; - /** crypt_dpa_enable : RO; bitpos: [19]; default: 1; + uint32_t sec_dpa_level:2; + /** crypt_dpa_enable : RO; bitpos: [18]; default: 0; * Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled. */ uint32_t crypt_dpa_enable:1; + /** rpt4_reserved2_1 : RO; bitpos: [19]; default: 1; + * Reserved. + */ + uint32_t rpt4_reserved2_1:1; /** secure_boot_en : RO; bitpos: [20]; default: 0; * Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled. */ @@ -386,11 +386,11 @@ typedef union { * Represents whether direct boot mode is disabled or enabled. 1: disabled. 0: enabled. */ uint32_t dis_direct_boot:1; - /** dis_usb_print : RO; bitpos: [2]; default: 0; + /** dis_usb_serial_jtag_rom_print : RO; bitpos: [2]; default: 0; * Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. * 0: enabled. */ - uint32_t dis_usb_print:1; + uint32_t dis_usb_serial_jtag_rom_print:1; /** rpt4_reserved3_5 : RO; bitpos: [3]; default: 0; * Reserved. */ @@ -454,10 +454,22 @@ typedef union { */ typedef union { struct { + /** disable_wafer_version_major : R; bitpos: [0]; default: 0; + * Disables check of wafer version major + */ uint32_t disable_wafer_version_major:1; - uint32_t disable_blk_version_major: 1; - uint32_t rpt4_reserved4:22; /*Reserved.*/ - uint32_t reserved24:8; /*Reserved.*/ + /** disable_blk_version_major : R; bitpos: [1]; default: 0; + * Disables check of blk version major + */ + uint32_t disable_blk_version_major:1; + /** reserved_0_162 : R; bitpos: [23:2]; default: 0; + * reserved + */ + uint32_t reserved_0_162:22; + /** rpt4_reserved4_0 : RO; bitpos: [31:24]; default: 0; + * Reserved. + */ + uint32_t rpt4_reserved4_0:8; }; uint32_t val; } efuse_rd_repeat_data4_reg_t; @@ -484,10 +496,10 @@ typedef union { * Stores the high 16 bits of MAC address. */ uint32_t mac_1:16; - /** spi_pad_conf_0 : RO; bitpos: [31:16]; default: 0; - * Stores the zeroth part of SPI_PAD_CONF. + /** mac_ext : RO; bitpos: [31:16]; default: 0; + * Stores the extended bits of MAC address. */ - uint32_t spi_pad_conf_0:16; + uint32_t mac_ext:16; }; uint32_t val; } efuse_rd_mac_spi_sys_1_reg_t; @@ -497,7 +509,38 @@ typedef union { */ typedef union { struct { - uint32_t reserved:32; + /** active_hp_dbias : RO; bitpos: [4:0]; default: 0; + * Stores the active hp dbias. + */ + uint32_t active_hp_dbias:5; + /** active_lp_dbias : RO; bitpos: [9:5]; default: 0; + * Stores the active lp dbias. + */ + uint32_t active_lp_dbias:5; + /** lslp_hp_dbg : RO; bitpos: [11:10]; default: 0; + * Stores the lslp hp dbg. + */ + uint32_t lslp_hp_dbg:2; + /** lslp_hp_dbias : RO; bitpos: [15:12]; default: 0; + * Stores the lslp hp dbias. + */ + uint32_t lslp_hp_dbias:4; + /** dslp_lp_dbg : RO; bitpos: [18:16]; default: 0; + * Stores the dslp lp dbg. + */ + uint32_t dslp_lp_dbg:3; + /** dslp_lp_dbias : RO; bitpos: [22:19]; default: 0; + * Stores the dslp lp dbias. + */ + uint32_t dslp_lp_dbias:4; + /** dbias_vol_gap : RO; bitpos: [27:23]; default: 0; + * Stores the hp and lp dbias vol gap. + */ + uint32_t dbias_vol_gap:5; + /** spi_pad_conf_1 : RO; bitpos: [31:28]; default: 0; + * Stores the first part of SPI_PAD_CONF. + */ + uint32_t spi_pad_conf_1:4; }; uint32_t val; } efuse_rd_mac_spi_sys_2_reg_t; @@ -511,13 +554,22 @@ typedef union { * Stores the second part of SPI_PAD_CONF. */ uint32_t spi_pad_conf_2:18; - uint32_t wafer_version_minor_low:3; + /** wafer_version_minor : R; bitpos: [21:18]; default: 0; */ + uint32_t wafer_version_minor:4; + /** wafer_version_major : R; bitpos: [23:22]; default: 0; */ + uint32_t wafer_version_major:2; + /** pkg_version : R; bitpos: [26:24]; default: 0; + * Package version + */ uint32_t pkg_version:3; + /** blk_version_minor : R; bitpos: [29:27]; default: 0; + * BLK_VERSION_MINOR of BLOCK2 + */ uint32_t blk_version_minor:3; - /** sys_data_part0_0 : RO; bitpos: [31:27]; default: 0; - * Stores the first 5 bits of the zeroth part of system data. + /** blk_version_major : R; bitpos: [31:30]; default: 0; + * BLK_VERSION_MAJOR of BLOCK2 */ - uint32_t sys_data_part0_0:5; + uint32_t blk_version_major:2; }; uint32_t val; } efuse_rd_mac_spi_sys_3_reg_t; @@ -527,7 +579,16 @@ typedef union { */ typedef union { struct { - uint32_t reserved:32; + /** flash_cap : R; bitpos: [2:0]; default: 0; */ + uint32_t flash_cap:3; + /** flash_temp : R; bitpos: [4:3]; default: 0; */ + uint32_t flash_temp:2; + /** flash_vendor : R; bitpos: [7:5]; default: 0; */ + uint32_t flash_vendor:3; + /** reserved_1_136 : R; bitpos: [31:8]; default: 0; + * reserved + */ + uint32_t reserved_1_136:24; }; uint32_t val; } efuse_rd_mac_spi_sys_4_reg_t; @@ -537,10 +598,10 @@ typedef union { */ typedef union { struct { - uint32_t reserved1:23; - uint32_t wafer_version_minor_high:1; - uint32_t wafer_version_major:2; - uint32_t reserved2:6; + /** sys_data_part0_2 : RO; bitpos: [31:0]; default: 0; + * Stores the second 32 bits of the zeroth part of system data. + */ + uint32_t sys_data_part0_2:32; }; uint32_t val; } efuse_rd_mac_spi_sys_5_reg_t; @@ -550,10 +611,10 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_0 : RO; bitpos: [31:0]; default: 0; - * Stores the zeroth 32 bits of the first part of system data. + /** optional_unique_id : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ - uint32_t sys_data_part1_0:32; + uint32_t optional_unique_id:32; }; uint32_t val; } efuse_rd_sys_part1_data0_reg_t; @@ -563,10 +624,10 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_1 : RO; bitpos: [31:0]; default: 0; - * Stores the first 32 bits of the first part of system data. + /** optional_unique_id_1 : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ - uint32_t sys_data_part1_1:32; + uint32_t optional_unique_id_1:32; }; uint32_t val; } efuse_rd_sys_part1_data1_reg_t; @@ -576,10 +637,10 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_2 : RO; bitpos: [31:0]; default: 0; - * Stores the second 32 bits of the first part of system data. + /** optional_unique_id_2 : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ - uint32_t sys_data_part1_2:32; + uint32_t optional_unique_id_2:32; }; uint32_t val; } efuse_rd_sys_part1_data2_reg_t; @@ -589,10 +650,10 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_3 : RO; bitpos: [31:0]; default: 0; - * Stores the third 32 bits of the first part of system data. + /** optional_unique_id_3 : R; bitpos: [31:0]; default: 0; + * Optional unique 128-bit ID */ - uint32_t sys_data_part1_3:32; + uint32_t optional_unique_id_3:32; }; uint32_t val; } efuse_rd_sys_part1_data3_reg_t; @@ -602,8 +663,22 @@ typedef union { */ typedef union { struct { - uint32_t blk_version_major :2; - uint32_t reserved1:30; + /** temp_calib : R; bitpos: [8:0]; default: 0; + * Temperature calibration data + */ + uint32_t temp_calib:9; + /** ocode : R; bitpos: [16:9]; default: 0; + * ADC OCode + */ + uint32_t ocode:8; + /** adc1_init_code_atten0 : R; bitpos: [26:17]; default: 0; + * ADC1 init code at atten0 + */ + uint32_t adc1_init_code_atten0:10; + /** adc1_init_code_atten1 : R; bitpos: [31:27]; default: 0; + * ADC1 init code at atten1 + */ + uint32_t adc1_init_code_atten1:5; }; uint32_t val; } efuse_rd_sys_part1_data4_reg_t; @@ -613,10 +688,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. + /** adc1_init_code_atten1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 init code at atten1 + */ + uint32_t adc1_init_code_atten1_1:5; + /** adc1_init_code_atten2 : R; bitpos: [14:5]; default: 0; + * ADC1 init code at atten2 + */ + uint32_t adc1_init_code_atten2:10; + /** adc1_init_code_atten3 : R; bitpos: [24:15]; default: 0; + * ADC1 init code at atten3 */ - uint32_t sys_data_part1_5:32; + uint32_t adc1_init_code_atten3:10; + /** adc1_cal_vol_atten0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration voltage at atten0 + */ + uint32_t adc1_cal_vol_atten0:7; }; uint32_t val; } efuse_rd_sys_part1_data5_reg_t; @@ -626,10 +713,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. + /** adc1_cal_vol_atten0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration voltage at atten0 + */ + uint32_t adc1_cal_vol_atten0_1:3; + /** adc1_cal_vol_atten1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration voltage at atten1 + */ + uint32_t adc1_cal_vol_atten1:10; + /** adc1_cal_vol_atten2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration voltage at atten2 + */ + uint32_t adc1_cal_vol_atten2:10; + /** adc1_cal_vol_atten3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration voltage at atten3 */ - uint32_t sys_data_part1_6:32; + uint32_t adc1_cal_vol_atten3:9; }; uint32_t val; } efuse_rd_sys_part1_data6_reg_t; @@ -639,10 +738,42 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. + /** adc1_cal_vol_atten3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration voltage at atten3 */ - uint32_t sys_data_part1_7:32; + uint32_t adc1_cal_vol_atten3_1:1; + /** adc1_init_code_atten0_ch0 : R; bitpos: [4:1]; default: 0; + * ADC1 init code at atten0 ch0 + */ + uint32_t adc1_init_code_atten0_ch0:4; + /** adc1_init_code_atten0_ch1 : R; bitpos: [8:5]; default: 0; + * ADC1 init code at atten0 ch1 + */ + uint32_t adc1_init_code_atten0_ch1:4; + /** adc1_init_code_atten0_ch2 : R; bitpos: [12:9]; default: 0; + * ADC1 init code at atten0 ch2 + */ + uint32_t adc1_init_code_atten0_ch2:4; + /** adc1_init_code_atten0_ch3 : R; bitpos: [16:13]; default: 0; + * ADC1 init code at atten0 ch3 + */ + uint32_t adc1_init_code_atten0_ch3:4; + /** adc1_init_code_atten0_ch4 : R; bitpos: [20:17]; default: 0; + * ADC1 init code at atten0 ch4 + */ + uint32_t adc1_init_code_atten0_ch4:4; + /** adc1_init_code_atten0_ch5 : R; bitpos: [24:21]; default: 0; + * ADC1 init code at atten0 ch5 + */ + uint32_t adc1_init_code_atten0_ch5:4; + /** adc1_init_code_atten0_ch6 : R; bitpos: [28:25]; default: 0; + * ADC1 init code at atten0 ch6 + */ + uint32_t adc1_init_code_atten0_ch6:4; + /** reserved_2_253 : R; bitpos: [31:29]; default: 0; + * reserved + */ + uint32_t reserved_2_253:3; }; uint32_t val; } efuse_rd_sys_part1_data7_reg_t; @@ -730,10 +861,14 @@ typedef union { */ typedef union { struct { - /** usr_data6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of BLOCK3 (user). + /** reserved_3_192 : R; bitpos: [7:0]; default: 0; + * reserved + */ + uint32_t reserved_3_192:8; + /** custom_mac : R; bitpos: [31:8]; default: 0; + * Custom MAC */ - uint32_t usr_data6:32; + uint32_t custom_mac:24; }; uint32_t val; } efuse_rd_usr_data6_reg_t; @@ -743,10 +878,14 @@ typedef union { */ typedef union { struct { - /** usr_data7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of BLOCK3 (user). + /** custom_mac_1 : R; bitpos: [23:0]; default: 0; + * Custom MAC */ - uint32_t usr_data7:32; + uint32_t custom_mac_1:24; + /** reserved_3_248 : R; bitpos: [31:24]; default: 0; + * reserved + */ + uint32_t reserved_3_248:8; }; uint32_t val; } efuse_rd_usr_data7_reg_t; @@ -1479,6 +1618,8 @@ typedef union { uint32_t val; } efuse_rd_sys_part2_data7_reg_t; + +/** Group: Report Register */ /** Type of rd_repeat_err0 register * Programming error record register 0 of BLOCK0. */ @@ -1853,6 +1994,8 @@ typedef union { uint32_t val; } efuse_rd_rs_err1_reg_t; + +/** Group: Configuration Register */ /** Type of clk register * eFuse clcok configuration register. */ @@ -1894,48 +2037,6 @@ typedef union { uint32_t val; } efuse_conf_reg_t; -/** Type of status register - * eFuse status register. - */ -typedef union { - struct { - /** state : RO; bitpos: [3:0]; default: 0; - * Indicates the state of the eFuse state machine. - */ - uint32_t state:4; - /** otp_load_sw : RO; bitpos: [4]; default: 0; - * The value of OTP_LOAD_SW. - */ - uint32_t otp_load_sw:1; - /** otp_vddq_c_sync2 : RO; bitpos: [5]; default: 0; - * The value of OTP_VDDQ_C_SYNC2. - */ - uint32_t otp_vddq_c_sync2:1; - /** otp_strobe_sw : RO; bitpos: [6]; default: 0; - * The value of OTP_STROBE_SW. - */ - uint32_t otp_strobe_sw:1; - /** otp_csb_sw : RO; bitpos: [7]; default: 0; - * The value of OTP_CSB_SW. - */ - uint32_t otp_csb_sw:1; - /** otp_pgenb_sw : RO; bitpos: [8]; default: 0; - * The value of OTP_PGENB_SW. - */ - uint32_t otp_pgenb_sw:1; - /** otp_vddq_is_sw : RO; bitpos: [9]; default: 0; - * The value of OTP_VDDQ_IS_SW. - */ - uint32_t otp_vddq_is_sw:1; - /** blk0_valid_bit_cnt : RO; bitpos: [19:10]; default: 0; - * Indicates the number of block valid bit. - */ - uint32_t blk0_valid_bit_cnt:10; - uint32_t reserved_20:12; - }; - uint32_t val; -} efuse_status_reg_t; - /** Type of cmd register * eFuse command register. */ @@ -1959,78 +2060,6 @@ typedef union { uint32_t val; } efuse_cmd_reg_t; -/** Type of int_raw register - * eFuse raw interrupt register. - */ -typedef union { - struct { - /** read_done_int_raw : R/SS/WTC; bitpos: [0]; default: 0; - * The raw bit signal for read_done interrupt. - */ - uint32_t read_done_int_raw:1; - /** pgm_done_int_raw : R/SS/WTC; bitpos: [1]; default: 0; - * The raw bit signal for pgm_done interrupt. - */ - uint32_t pgm_done_int_raw:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} efuse_int_raw_reg_t; - -/** Type of int_st register - * eFuse interrupt status register. - */ -typedef union { - struct { - /** read_done_int_st : RO; bitpos: [0]; default: 0; - * The status signal for read_done interrupt. - */ - uint32_t read_done_int_st:1; - /** pgm_done_int_st : RO; bitpos: [1]; default: 0; - * The status signal for pgm_done interrupt. - */ - uint32_t pgm_done_int_st:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} efuse_int_st_reg_t; - -/** Type of int_ena register - * eFuse interrupt enable register. - */ -typedef union { - struct { - /** read_done_int_ena : R/W; bitpos: [0]; default: 0; - * The enable signal for read_done interrupt. - */ - uint32_t read_done_int_ena:1; - /** pgm_done_int_ena : R/W; bitpos: [1]; default: 0; - * The enable signal for pgm_done interrupt. - */ - uint32_t pgm_done_int_ena:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} efuse_int_ena_reg_t; - -/** Type of int_clr register - * eFuse interrupt clear register. - */ -typedef union { - struct { - /** read_done_int_clr : WO; bitpos: [0]; default: 0; - * The clear signal for read_done interrupt. - */ - uint32_t read_done_int_clr:1; - /** pgm_done_int_clr : WO; bitpos: [1]; default: 0; - * The clear signal for pgm_done interrupt. - */ - uint32_t pgm_done_int_clr:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} efuse_int_clr_reg_t; - /** Type of dac_conf register * Controls the eFuse programming voltage. */ @@ -2147,6 +2176,126 @@ typedef union { uint32_t val; } efuse_wr_tim_conf0_rs_bypass_reg_t; + +/** Group: Status Register */ +/** Type of status register + * eFuse status register. + */ +typedef union { + struct { + /** state : RO; bitpos: [3:0]; default: 0; + * Indicates the state of the eFuse state machine. + */ + uint32_t state:4; + /** otp_load_sw : RO; bitpos: [4]; default: 0; + * The value of OTP_LOAD_SW. + */ + uint32_t otp_load_sw:1; + /** otp_vddq_c_sync2 : RO; bitpos: [5]; default: 0; + * The value of OTP_VDDQ_C_SYNC2. + */ + uint32_t otp_vddq_c_sync2:1; + /** otp_strobe_sw : RO; bitpos: [6]; default: 0; + * The value of OTP_STROBE_SW. + */ + uint32_t otp_strobe_sw:1; + /** otp_csb_sw : RO; bitpos: [7]; default: 0; + * The value of OTP_CSB_SW. + */ + uint32_t otp_csb_sw:1; + /** otp_pgenb_sw : RO; bitpos: [8]; default: 0; + * The value of OTP_PGENB_SW. + */ + uint32_t otp_pgenb_sw:1; + /** otp_vddq_is_sw : RO; bitpos: [9]; default: 0; + * The value of OTP_VDDQ_IS_SW. + */ + uint32_t otp_vddq_is_sw:1; + /** blk0_valid_bit_cnt : RO; bitpos: [19:10]; default: 0; + * Indicates the number of block valid bit. + */ + uint32_t blk0_valid_bit_cnt:10; + uint32_t reserved_20:12; + }; + uint32_t val; +} efuse_status_reg_t; + + +/** Group: Interrupt Register */ +/** Type of int_raw register + * eFuse raw interrupt register. + */ +typedef union { + struct { + /** read_done_int_raw : R/SS/WTC; bitpos: [0]; default: 0; + * The raw bit signal for read_done interrupt. + */ + uint32_t read_done_int_raw:1; + /** pgm_done_int_raw : R/SS/WTC; bitpos: [1]; default: 0; + * The raw bit signal for pgm_done interrupt. + */ + uint32_t pgm_done_int_raw:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} efuse_int_raw_reg_t; + +/** Type of int_st register + * eFuse interrupt status register. + */ +typedef union { + struct { + /** read_done_int_st : RO; bitpos: [0]; default: 0; + * The status signal for read_done interrupt. + */ + uint32_t read_done_int_st:1; + /** pgm_done_int_st : RO; bitpos: [1]; default: 0; + * The status signal for pgm_done interrupt. + */ + uint32_t pgm_done_int_st:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} efuse_int_st_reg_t; + +/** Type of int_ena register + * eFuse interrupt enable register. + */ +typedef union { + struct { + /** read_done_int_ena : R/W; bitpos: [0]; default: 0; + * The enable signal for read_done interrupt. + */ + uint32_t read_done_int_ena:1; + /** pgm_done_int_ena : R/W; bitpos: [1]; default: 0; + * The enable signal for pgm_done interrupt. + */ + uint32_t pgm_done_int_ena:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} efuse_int_ena_reg_t; + +/** Type of int_clr register + * eFuse interrupt clear register. + */ +typedef union { + struct { + /** read_done_int_clr : WO; bitpos: [0]; default: 0; + * The clear signal for read_done interrupt. + */ + uint32_t read_done_int_clr:1; + /** pgm_done_int_clr : WO; bitpos: [1]; default: 0; + * The clear signal for pgm_done interrupt. + */ + uint32_t pgm_done_int_clr:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} efuse_int_clr_reg_t; + + +/** Group: Version Register */ /** Type of date register * eFuse version register. */ @@ -2162,7 +2311,7 @@ typedef union { } efuse_date_reg_t; -typedef struct efuse_dev_t { +typedef struct { volatile efuse_pgm_data0_reg_t pgm_data0; volatile efuse_pgm_data1_reg_t pgm_data1; volatile efuse_pgm_data2_reg_t pgm_data2; diff --git a/components/soc/esp32c6/include/soc/ext_mem_defs.h b/components/soc/esp32c6/include/soc/ext_mem_defs.h new file mode 100644 index 000000000000..8e5022a23ad2 --- /dev/null +++ b/components/soc/esp32c6/include/soc/ext_mem_defs.h @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !SOC_MMU_PAGE_SIZE +/** + * We define `SOC_MMU_PAGE_SIZE` in soc/CMakeLists.txt. + * Here we give a default definition, if SOC_MMU_PAGE_SIZE doesn't exist. This is to pass the check_public_headers.py + */ +#define SOC_MMU_PAGE_SIZE 0x10000 +#endif + + +#define IRAM0_CACHE_ADDRESS_LOW 0x42000000 +#define IRAM0_CACHE_ADDRESS_HIGH (IRAM0_CACHE_ADDRESS_LOW + ((SOC_MMU_PAGE_SIZE) * MMU_ENTRY_NUM)) + +#define DRAM0_CACHE_ADDRESS_LOW IRAM0_CACHE_ADDRESS_LOW //I/D share the same vaddr range +#define DRAM0_CACHE_ADDRESS_HIGH IRAM0_CACHE_ADDRESS_HIGH //I/D share the same vaddr range +#define DRAM0_CACHE_OPERATION_HIGH DRAM0_CACHE_ADDRESS_HIGH + +#define BUS_SIZE(bus_name) (bus_name##_ADDRESS_HIGH - bus_name##_ADDRESS_LOW) +#define ADDRESS_IN_BUS(bus_name, vaddr) ((vaddr) >= bus_name##_ADDRESS_LOW && (vaddr) < bus_name##_ADDRESS_HIGH) + +#define ADDRESS_IN_IRAM0(vaddr) ADDRESS_IN_BUS(IRAM0, vaddr) +#define ADDRESS_IN_IRAM0_CACHE(vaddr) ADDRESS_IN_BUS(IRAM0_CACHE, vaddr) +#define ADDRESS_IN_DRAM0(vaddr) ADDRESS_IN_BUS(DRAM0, vaddr) +#define ADDRESS_IN_DRAM0_CACHE(vaddr) ADDRESS_IN_BUS(DRAM0_CACHE, vaddr) + +#define BUS_IRAM0_CACHE_SIZE BUS_SIZE(IRAM0_CACHE) +#define BUS_DRAM0_CACHE_SIZE BUS_SIZE(DRAM0_CACHE) + +//TODO, remove these cache function dependencies +#define CACHE_IROM_MMU_START 0 +#define CACHE_IROM_MMU_END Cache_Get_IROM_MMU_End() +#define CACHE_IROM_MMU_SIZE (CACHE_IROM_MMU_END - CACHE_IROM_MMU_START) + +#define CACHE_DROM_MMU_START CACHE_IROM_MMU_END +#define CACHE_DROM_MMU_END Cache_Get_DROM_MMU_End() +#define CACHE_DROM_MMU_SIZE (CACHE_DROM_MMU_END - CACHE_DROM_MMU_START) + +#define CACHE_DROM_MMU_MAX_END 0x400 + +#define ICACHE_MMU_SIZE 0x200 +#define DCACHE_MMU_SIZE 0x200 + +#define MMU_BUS_START(i) 0 +#define MMU_BUS_SIZE(i) 0x200 + +#define MMU_MSPI_ACCESS_FLASH 0 +#define MMU_MSPI_VALID BIT(9) +#define MMU_MSPI_INVALID 0 +#define MMU_MSPI_SENSITIVE BIT(10) + +#define MMU_ACCESS_FLASH MMU_MSPI_ACCESS_FLASH +#define MMU_VALID MMU_MSPI_VALID +#define MMU_SENSITIVE MMU_MSPI_SENSITIVE + +#define MMU_INVALID_MASK MMU_MSPI_VALID +#define MMU_INVALID MMU_MSPI_INVALID + + + +#define CACHE_MAX_SYNC_NUM 0x400000 +#define CACHE_MAX_LOCK_NUM 0x8000 + +/** + * MMU entry valid bit mask for mapping value. For an entry: + * valid bit + value bits + * valid bit is BIT(9), so value bits are 0x1ff + */ +#define MMU_VALID_VAL_MASK 0x1ff +/** + * Max MMU available paddr page num. + * `MMU_MAX_PADDR_PAGE_NUM * SOC_MMU_PAGE_SIZE` means the max paddr address supported by the MMU. e.g.: + * 256 * 64KB, means MMU can support 16MB paddr at most + */ +#define MMU_MAX_PADDR_PAGE_NUM 256 +//MMU entry num +#define MMU_ENTRY_NUM 256 + +/** + * This is the mask used for mapping. e.g.: + * 0x4200_0000 & MMU_VADDR_MASK + */ +#define MMU_VADDR_MASK ((SOC_MMU_PAGE_SIZE) * MMU_ENTRY_NUM - 1) + +#define CACHE_MEMORY_IBANK0_ADDR 0x40800000 + + +#define SOC_MMU_DBUS_VADDR_BASE 0x42000000 +#define SOC_MMU_IBUS_VADDR_BASE 0x42000000 + +/*------------------------------------------------------------------------------ + * MMU Linear Address + *----------------------------------------------------------------------------*/ +#if (SOC_MMU_PAGE_SIZE == 0x10000) +/** + * - 64KB MMU page size: the last 0xFFFF, which is the offset + * - 128 MMU entries, needs 0x7F to hold it. + * + * Therefore, 0x7F,FFFF + */ +#define SOC_MMU_LINEAR_ADDR_MASK 0x7FFFFF + +#elif (SOC_MMU_PAGE_SIZE == 0x8000) +/** + * - 32KB MMU page size: the last 0x7FFF, which is the offset + * - 128 MMU entries, needs 0x7F to hold it. + * + * Therefore, 0x3F,FFFF + */ +#define SOC_MMU_LINEAR_ADDR_MASK 0x3FFFFF + +#elif (SOC_MMU_PAGE_SIZE == 0x4000) +/** + * - 16KB MMU page size: the last 0x3FFF, which is the offset + * - 128 MMU entries, needs 0x7F to hold it. + * + * Therefore, 0x1F,FFFF + */ +#define SOC_MMU_LINEAR_ADDR_MASK 0x1FFFFF +#endif //SOC_MMU_PAGE_SIZE + +/** + * - If high linear address isn't 0, this means MMU can recognize these addresses + * - If high linear address is 0, this means MMU linear address range is equal or smaller than vaddr range. + * Under this condition, we use the max linear space. + */ +#define SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW (IRAM0_CACHE_ADDRESS_LOW & SOC_MMU_LINEAR_ADDR_MASK) +#if ((IRAM0_CACHE_ADDRESS_HIGH & SOC_MMU_LINEAR_ADDR_MASK) > 0) +#define SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH (IRAM0_CACHE_ADDRESS_HIGH & SOC_MMU_LINEAR_ADDR_MASK) +#else +#define SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH (SOC_MMU_LINEAR_ADDR_MASK + 1) +#endif + +#define SOC_MMU_DRAM0_LINEAR_ADDRESS_LOW (DRAM0_CACHE_ADDRESS_LOW & SOC_MMU_LINEAR_ADDR_MASK) +#if ((DRAM0_CACHE_ADDRESS_HIGH & SOC_MMU_LINEAR_ADDR_MASK) > 0) +#define SOC_MMU_DRAM0_LINEAR_ADDRESS_HIGH (DRAM0_CACHE_ADDRESS_HIGH & SOC_MMU_LINEAR_ADDR_MASK) +#else +#define SOC_MMU_DRAM0_LINEAR_ADDRESS_HIGH (SOC_MMU_LINEAR_ADDR_MASK + 1) +#endif + +/** + * I/D share the MMU linear address range + */ +_Static_assert(SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW == SOC_MMU_DRAM0_LINEAR_ADDRESS_LOW, "IRAM0 and DRAM0 linear address should be same"); + + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/extmem_reg.h b/components/soc/esp32c6/include/soc/extmem_reg.h index 7af994acca88..a9cb6935862f 100644 --- a/components/soc/esp32c6/include/soc/extmem_reg.h +++ b/components/soc/esp32c6/include/soc/extmem_reg.h @@ -1,7 +1,7 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +/** + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 + * SPDX-License-Identifier: Apache-2.0 */ #pragma once @@ -11,930 +11,851 @@ extern "C" { #endif -// TODO: IDF-5797 - -#define EXTMEM_ICACHE_CTRL_REG (DR_REG_EXTMEM_BASE + 0x0) - -#define EXTMEM_DCACHE_CTRL_REG (DR_REG_EXTMEM_BASE + 0x4) -/* EXTMEM_DCACHE_SHUT_DBUS1 : R/W ;bitpos:[1] ;default: 1'h0 ; */ -/*description: The bit is used to disable core1 dbus access L1-DCache, 0: enable, 1: disable.*/ -#define EXTMEM_DCACHE_SHUT_DBUS1 (BIT(1)) -#define EXTMEM_DCACHE_SHUT_DBUS1_M (BIT(1)) -#define EXTMEM_DCACHE_SHUT_DBUS1_V 0x1 -#define EXTMEM_DCACHE_SHUT_DBUS1_S 1 -/* EXTMEM_DCACHE_SHUT_DBUS0 : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: The bit is used to disable core0 dbus access L1-DCache, 0: enable, 1: disable.*/ -#define EXTMEM_DCACHE_SHUT_DBUS0 (BIT(0)) -#define EXTMEM_DCACHE_SHUT_DBUS0_M (BIT(0)) -#define EXTMEM_DCACHE_SHUT_DBUS0_V 0x1 -#define EXTMEM_DCACHE_SHUT_DBUS0_S 0 - -#define EXTMEM_CACHE_WRAP_AROUND_CTRL_REG (DR_REG_EXTMEM_BASE + 0x20) -/* EXTMEM_DCACHE_WRAP : R/W ;bitpos:[4] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_CTRL_REG (DR_REG_EXTMEM_BASE + 0x4) +/* EXTMEM_L1_CACHE_SHUT_DBUS : R/W ;bitpos:[1] ;default: 1'h0 ; */ +/*description: The bit is used to disable core0 dbus access L1-Cache, 0: enable, 1: disable.*/ +#define EXTMEM_L1_CACHE_SHUT_DBUS (BIT(1)) +#define EXTMEM_L1_CACHE_SHUT_DBUS_M (BIT(1)) +#define EXTMEM_L1_CACHE_SHUT_DBUS_V 0x1 +#define EXTMEM_L1_CACHE_SHUT_DBUS_S 1 +/* EXTMEM_L1_CACHE_SHUT_IBUS : R/W ;bitpos:[0] ;default: 1'h0 ; */ +/*description: The bit is used to disable core0 dbus access L1-Cache, 0: enable, 1: disable.*/ +#define EXTMEM_L1_CACHE_SHUT_IBUS (BIT(0)) +#define EXTMEM_L1_CACHE_SHUT_IBUS_M (BIT(0)) +#define EXTMEM_L1_CACHE_SHUT_IBUS_V 0x1 +#define EXTMEM_L1_CACHE_SHUT_IBUS_S 0 + +#define EXTMEM_L1_CACHE_WRAP_AROUND_CTRL_REG (DR_REG_EXTMEM_BASE + 0x20) +/* EXTMEM_L1_CACHE_WRAP : R/W ;bitpos:[4] ;default: 1'h0 ; */ /*description: Set this bit as 1 to enable L1-DCache wrap around mode..*/ -#define EXTMEM_DCACHE_WRAP (BIT(4)) -#define EXTMEM_DCACHE_WRAP_M (BIT(4)) -#define EXTMEM_DCACHE_WRAP_V 0x1 -#define EXTMEM_DCACHE_WRAP_S 4 - -#define EXTMEM_CACHE_TAG_MEM_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x24) -/* EXTMEM_DCACHE_TAG_MEM_FORCE_PU : R/W ;bitpos:[18] ;default: 1'h1 ; */ -/*description: The bit is used to power L1-DCache tag memory up. 0: follow rtc_lslp, 1: power u +#define EXTMEM_L1_CACHE_WRAP (BIT(4)) +#define EXTMEM_L1_CACHE_WRAP_M (BIT(4)) +#define EXTMEM_L1_CACHE_WRAP_V 0x1 +#define EXTMEM_L1_CACHE_WRAP_S 4 + +#define EXTMEM_L1_CACHE_TAG_MEM_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x24) +/* EXTMEM_L1_CACHE_TAG_MEM_FORCE_PU : R/W ;bitpos:[18] ;default: 1'h1 ; */ +/*description: The bit is used to power L1-Cache tag memory up. 0: follow rtc_lslp, 1: power up.*/ +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PU (BIT(18)) +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PU_M (BIT(18)) +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PU_V 0x1 +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PU_S 18 +/* EXTMEM_L1_CACHE_TAG_MEM_FORCE_PD : R/W ;bitpos:[17] ;default: 1'h0 ; */ +/*description: The bit is used to power L1-Cache tag memory down. 0: follow rtc_lslp, 1: power +down.*/ +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PD (BIT(17)) +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PD_M (BIT(17)) +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PD_V 0x1 +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_PD_S 17 +/* EXTMEM_L1_CACHE_TAG_MEM_FORCE_ON : R/W ;bitpos:[16] ;default: 1'h1 ; */ +/*description: The bit is used to close clock gating of L1-Cache tag memory. 1: close gating, +0: open clock gating..*/ +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_ON (BIT(16)) +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_ON_M (BIT(16)) +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_ON_V 0x1 +#define EXTMEM_L1_CACHE_TAG_MEM_FORCE_ON_S 16 + +#define EXTMEM_L1_CACHE_DATA_MEM_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x28) +/* EXTMEM_L1_CACHE_DATA_MEM_FORCE_PU : R/W ;bitpos:[18] ;default: 1'h1 ; */ +/*description: The bit is used to power L1-Cache data memory up. 0: follow rtc_lslp, 1: power u p.*/ -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PU (BIT(18)) -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PU_M (BIT(18)) -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PU_V 0x1 -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PU_S 18 -/* EXTMEM_DCACHE_TAG_MEM_FORCE_PD : R/W ;bitpos:[17] ;default: 1'h0 ; */ -/*description: The bit is used to power L1-DCache tag memory down. 0: follow rtc_lslp, 1: power +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PU (BIT(18)) +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PU_M (BIT(18)) +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PU_V 0x1 +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PU_S 18 +/* EXTMEM_L1_CACHE_DATA_MEM_FORCE_PD : R/W ;bitpos:[17] ;default: 1'h0 ; */ +/*description: The bit is used to power L1-Cache data memory down. 0: follow rtc_lslp, 1: power down.*/ -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PD (BIT(17)) -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PD_M (BIT(17)) -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PD_V 0x1 -#define EXTMEM_DCACHE_TAG_MEM_FORCE_PD_S 17 -/* EXTMEM_DCACHE_TAG_MEM_FORCE_ON : R/W ;bitpos:[16] ;default: 1'h1 ; */ -/*description: The bit is used to close clock gating of L1-DCache tag memory. 1: close gating, +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PD (BIT(17)) +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PD_M (BIT(17)) +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PD_V 0x1 +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_PD_S 17 +/* EXTMEM_L1_CACHE_DATA_MEM_FORCE_ON : R/W ;bitpos:[16] ;default: 1'h1 ; */ +/*description: The bit is used to close clock gating of L1-Cache data memory. 1: close gating, 0: open clock gating..*/ -#define EXTMEM_DCACHE_TAG_MEM_FORCE_ON (BIT(16)) -#define EXTMEM_DCACHE_TAG_MEM_FORCE_ON_M (BIT(16)) -#define EXTMEM_DCACHE_TAG_MEM_FORCE_ON_V 0x1 -#define EXTMEM_DCACHE_TAG_MEM_FORCE_ON_S 16 - -#define EXTMEM_CACHE_DATA_MEM_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x28) -/* EXTMEM_DCACHE_DATA_MEM_FORCE_PU : R/W ;bitpos:[18] ;default: 1'h1 ; */ -/*description: The bit is used to power L1-DCache data memory up. 0: follow rtc_lslp, 1: power -up.*/ -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PU (BIT(18)) -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PU_M (BIT(18)) -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PU_V 0x1 -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PU_S 18 -/* EXTMEM_DCACHE_DATA_MEM_FORCE_PD : R/W ;bitpos:[17] ;default: 1'h0 ; */ -/*description: The bit is used to power L1-DCache data memory down. 0: follow rtc_lslp, 1: powe -r down.*/ -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PD (BIT(17)) -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PD_M (BIT(17)) -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PD_V 0x1 -#define EXTMEM_DCACHE_DATA_MEM_FORCE_PD_S 17 -/* EXTMEM_DCACHE_DATA_MEM_FORCE_ON : R/W ;bitpos:[16] ;default: 1'h1 ; */ -/*description: The bit is used to close clock gating of L1-DCache data memory. 1: close gating -, 0: open clock gating..*/ -#define EXTMEM_DCACHE_DATA_MEM_FORCE_ON (BIT(16)) -#define EXTMEM_DCACHE_DATA_MEM_FORCE_ON_M (BIT(16)) -#define EXTMEM_DCACHE_DATA_MEM_FORCE_ON_V 0x1 -#define EXTMEM_DCACHE_DATA_MEM_FORCE_ON_S 16 - -#define EXTMEM_CACHE_FREEZE_CTRL_REG (DR_REG_EXTMEM_BASE + 0x2C) -/* EXTMEM_DCACHE_FREEZE_DONE : RO ;bitpos:[18] ;default: 1'h0 ; */ -/*description: The bit is used to indicate whether freeze operation on L1-DCache is finished or - not. 0: not finished. 1: finished..*/ -#define EXTMEM_DCACHE_FREEZE_DONE (BIT(18)) -#define EXTMEM_DCACHE_FREEZE_DONE_M (BIT(18)) -#define EXTMEM_DCACHE_FREEZE_DONE_V 0x1 -#define EXTMEM_DCACHE_FREEZE_DONE_S 18 -/* EXTMEM_DCACHE_FREEZE_MODE : R/W ;bitpos:[17] ;default: 1'h0 ; */ -/*description: The bit is used to configure mode of freeze operation L1-DCache. 0: a miss-acces -s will not stuck. 1: a miss-access will stuck..*/ -#define EXTMEM_DCACHE_FREEZE_MODE (BIT(17)) -#define EXTMEM_DCACHE_FREEZE_MODE_M (BIT(17)) -#define EXTMEM_DCACHE_FREEZE_MODE_V 0x1 -#define EXTMEM_DCACHE_FREEZE_MODE_S 17 -/* EXTMEM_DCACHE_FREEZE_EN : R/W ;bitpos:[16] ;default: 1'h0 ; */ -/*description: The bit is used to enable freeze operation on L1-DCache. It can be cleared by so -ftware..*/ -#define EXTMEM_DCACHE_FREEZE_EN (BIT(16)) -#define EXTMEM_DCACHE_FREEZE_EN_M (BIT(16)) -#define EXTMEM_DCACHE_FREEZE_EN_V 0x1 -#define EXTMEM_DCACHE_FREEZE_EN_S 16 - -#define EXTMEM_CACHE_DATA_MEM_ACS_CONF_REG (DR_REG_EXTMEM_BASE + 0x30) -/* EXTMEM_DCACHE_DATA_MEM_WR_EN : R/W ;bitpos:[17] ;default: 1'h1 ; */ -/*description: The bit is used to enable config-bus write L1-DCache data memoryory. 0: disable, - 1: enable..*/ -#define EXTMEM_DCACHE_DATA_MEM_WR_EN (BIT(17)) -#define EXTMEM_DCACHE_DATA_MEM_WR_EN_M (BIT(17)) -#define EXTMEM_DCACHE_DATA_MEM_WR_EN_V 0x1 -#define EXTMEM_DCACHE_DATA_MEM_WR_EN_S 17 -/* EXTMEM_DCACHE_DATA_MEM_RD_EN : R/W ;bitpos:[16] ;default: 1'h1 ; */ -/*description: The bit is used to enable config-bus read L1-DCache data memoryory. 0: disable, +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_ON (BIT(16)) +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_ON_M (BIT(16)) +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_ON_V 0x1 +#define EXTMEM_L1_CACHE_DATA_MEM_FORCE_ON_S 16 + +#define EXTMEM_L1_CACHE_FREEZE_CTRL_REG (DR_REG_EXTMEM_BASE + 0x2C) +/* EXTMEM_L1_CACHE_FREEZE_DONE : RO ;bitpos:[18] ;default: 1'h0 ; */ +/*description: The bit is used to indicate whether freeze operation on L1-Cache is finished or +not. 0: not finished. 1: finished..*/ +#define EXTMEM_L1_CACHE_FREEZE_DONE (BIT(18)) +#define EXTMEM_L1_CACHE_FREEZE_DONE_M (BIT(18)) +#define EXTMEM_L1_CACHE_FREEZE_DONE_V 0x1 +#define EXTMEM_L1_CACHE_FREEZE_DONE_S 18 +/* EXTMEM_L1_CACHE_FREEZE_MODE : R/W ;bitpos:[17] ;default: 1'h0 ; */ +/*description: The bit is used to configure mode of freeze operation L1-Cache. 0: a miss-access + will not stuck. 1: a miss-access will stuck..*/ +#define EXTMEM_L1_CACHE_FREEZE_MODE (BIT(17)) +#define EXTMEM_L1_CACHE_FREEZE_MODE_M (BIT(17)) +#define EXTMEM_L1_CACHE_FREEZE_MODE_V 0x1 +#define EXTMEM_L1_CACHE_FREEZE_MODE_S 17 +/* EXTMEM_L1_CACHE_FREEZE_EN : R/W ;bitpos:[16] ;default: 1'h0 ; */ +/*description: The bit is used to enable freeze operation on L1-Cache. It can be cleared by sof +tware..*/ +#define EXTMEM_L1_CACHE_FREEZE_EN (BIT(16)) +#define EXTMEM_L1_CACHE_FREEZE_EN_M (BIT(16)) +#define EXTMEM_L1_CACHE_FREEZE_EN_V 0x1 +#define EXTMEM_L1_CACHE_FREEZE_EN_S 16 + +#define EXTMEM_L1_CACHE_DATA_MEM_ACS_CONF_REG (DR_REG_EXTMEM_BASE + 0x30) +/* EXTMEM_L1_CACHE_DATA_MEM_WR_EN : R/W ;bitpos:[17] ;default: 1'h1 ; */ +/*description: The bit is used to enable config-bus write L1-Cache data memoryory. 0: disable, 1: enable..*/ -#define EXTMEM_DCACHE_DATA_MEM_RD_EN (BIT(16)) -#define EXTMEM_DCACHE_DATA_MEM_RD_EN_M (BIT(16)) -#define EXTMEM_DCACHE_DATA_MEM_RD_EN_V 0x1 -#define EXTMEM_DCACHE_DATA_MEM_RD_EN_S 16 - -#define EXTMEM_CACHE_TAG_MEM_ACS_CONF_REG (DR_REG_EXTMEM_BASE + 0x34) -/* EXTMEM_DCACHE_TAG_MEM_WR_EN : R/W ;bitpos:[17] ;default: 1'h1 ; */ -/*description: The bit is used to enable config-bus write L1-DCache tag memoryory. 0: disable, -1: enable..*/ -#define EXTMEM_DCACHE_TAG_MEM_WR_EN (BIT(17)) -#define EXTMEM_DCACHE_TAG_MEM_WR_EN_M (BIT(17)) -#define EXTMEM_DCACHE_TAG_MEM_WR_EN_V 0x1 -#define EXTMEM_DCACHE_TAG_MEM_WR_EN_S 17 -/* EXTMEM_DCACHE_TAG_MEM_RD_EN : R/W ;bitpos:[16] ;default: 1'h1 ; */ -/*description: The bit is used to enable config-bus read L1-DCache tag memoryory. 0: disable, 1 +#define EXTMEM_L1_CACHE_DATA_MEM_WR_EN (BIT(17)) +#define EXTMEM_L1_CACHE_DATA_MEM_WR_EN_M (BIT(17)) +#define EXTMEM_L1_CACHE_DATA_MEM_WR_EN_V 0x1 +#define EXTMEM_L1_CACHE_DATA_MEM_WR_EN_S 17 +/* EXTMEM_L1_CACHE_DATA_MEM_RD_EN : R/W ;bitpos:[16] ;default: 1'h1 ; */ +/*description: The bit is used to enable config-bus read L1-Cache data memoryory. 0: disable, 1 +: enable..*/ +#define EXTMEM_L1_CACHE_DATA_MEM_RD_EN (BIT(16)) +#define EXTMEM_L1_CACHE_DATA_MEM_RD_EN_M (BIT(16)) +#define EXTMEM_L1_CACHE_DATA_MEM_RD_EN_V 0x1 +#define EXTMEM_L1_CACHE_DATA_MEM_RD_EN_S 16 + +#define EXTMEM_L1_CACHE_TAG_MEM_ACS_CONF_REG (DR_REG_EXTMEM_BASE + 0x34) +/* EXTMEM_L1_CACHE_TAG_MEM_WR_EN : R/W ;bitpos:[17] ;default: 1'h1 ; */ +/*description: The bit is used to enable config-bus write L1-Cache tag memoryory. 0: disable, 1 : enable..*/ -#define EXTMEM_DCACHE_TAG_MEM_RD_EN (BIT(16)) -#define EXTMEM_DCACHE_TAG_MEM_RD_EN_M (BIT(16)) -#define EXTMEM_DCACHE_TAG_MEM_RD_EN_V 0x1 -#define EXTMEM_DCACHE_TAG_MEM_RD_EN_S 16 - -#define EXTMEM_DCACHE_PRELOCK_CONF_REG (DR_REG_EXTMEM_BASE + 0x78) -/* EXTMEM_DCACHE_PRELOCK_RGID : HRO ;bitpos:[5:2] ;default: 4'h0 ; */ -/*description: The bit is used to set the gid of l1 dcache prelock..*/ -#define EXTMEM_DCACHE_PRELOCK_RGID 0x0000000F -#define EXTMEM_DCACHE_PRELOCK_RGID_M ((EXTMEM_DCACHE_PRELOCK_RGID_V)<<(EXTMEM_DCACHE_PRELOCK_RGID_S)) -#define EXTMEM_DCACHE_PRELOCK_RGID_V 0xF -#define EXTMEM_DCACHE_PRELOCK_RGID_S 2 -/* EXTMEM_DCACHE_PRELOCK_SCT1_EN : R/W ;bitpos:[1] ;default: 1'h0 ; */ -/*description: The bit is used to enable the second section of prelock function on L1-DCache..*/ -#define EXTMEM_DCACHE_PRELOCK_SCT1_EN (BIT(1)) -#define EXTMEM_DCACHE_PRELOCK_SCT1_EN_M (BIT(1)) -#define EXTMEM_DCACHE_PRELOCK_SCT1_EN_V 0x1 -#define EXTMEM_DCACHE_PRELOCK_SCT1_EN_S 1 -/* EXTMEM_DCACHE_PRELOCK_SCT0_EN : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: The bit is used to enable the first section of prelock function on L1-DCache..*/ -#define EXTMEM_DCACHE_PRELOCK_SCT0_EN (BIT(0)) -#define EXTMEM_DCACHE_PRELOCK_SCT0_EN_M (BIT(0)) -#define EXTMEM_DCACHE_PRELOCK_SCT0_EN_V 0x1 -#define EXTMEM_DCACHE_PRELOCK_SCT0_EN_S 0 - -#define EXTMEM_DCACHE_PRELOCK_SCT0_ADDR_REG (DR_REG_EXTMEM_BASE + 0x7C) -/* EXTMEM_DCACHE_PRELOCK_SCT0_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +#define EXTMEM_L1_CACHE_TAG_MEM_WR_EN (BIT(17)) +#define EXTMEM_L1_CACHE_TAG_MEM_WR_EN_M (BIT(17)) +#define EXTMEM_L1_CACHE_TAG_MEM_WR_EN_V 0x1 +#define EXTMEM_L1_CACHE_TAG_MEM_WR_EN_S 17 +/* EXTMEM_L1_CACHE_TAG_MEM_RD_EN : R/W ;bitpos:[16] ;default: 1'h1 ; */ +/*description: The bit is used to enable config-bus read L1-Cache tag memoryory. 0: disable, 1: + enable..*/ +#define EXTMEM_L1_CACHE_TAG_MEM_RD_EN (BIT(16)) +#define EXTMEM_L1_CACHE_TAG_MEM_RD_EN_M (BIT(16)) +#define EXTMEM_L1_CACHE_TAG_MEM_RD_EN_V 0x1 +#define EXTMEM_L1_CACHE_TAG_MEM_RD_EN_S 16 + +#define EXTMEM_L1_CACHE_PRELOCK_CONF_REG (DR_REG_EXTMEM_BASE + 0x78) +/* EXTMEM_L1_CACHE_PRELOCK_SCT1_EN : R/W ;bitpos:[1] ;default: 1'h0 ; */ +/*description: The bit is used to enable the second section of prelock function on L1-Cache..*/ +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_EN (BIT(1)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_EN_M (BIT(1)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_EN_V 0x1 +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_EN_S 1 +/* EXTMEM_L1_CACHE_PRELOCK_SCT0_EN : R/W ;bitpos:[0] ;default: 1'h0 ; */ +/*description: The bit is used to enable the first section of prelock function on L1-Cache..*/ +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_EN (BIT(0)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_EN_M (BIT(0)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_EN_V 0x1 +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_EN_S 0 + +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR_REG (DR_REG_EXTMEM_BASE + 0x7C) +/* EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: Those bits are used to configure the start virtual address of the first section -of prelock on L1-DCache, which should be used together with L1_DCACHE_PRELOCK_SC -T0_SIZE_REG.*/ -#define EXTMEM_DCACHE_PRELOCK_SCT0_ADDR 0xFFFFFFFF -#define EXTMEM_DCACHE_PRELOCK_SCT0_ADDR_M ((EXTMEM_DCACHE_PRELOCK_SCT0_ADDR_V)<<(EXTMEM_DCACHE_PRELOCK_SCT0_ADDR_S)) -#define EXTMEM_DCACHE_PRELOCK_SCT0_ADDR_V 0xFFFFFFFF -#define EXTMEM_DCACHE_PRELOCK_SCT0_ADDR_S 0 - -#define EXTMEM_DCACHE_PRELOCK_SCT1_ADDR_REG (DR_REG_EXTMEM_BASE + 0x80) -/* EXTMEM_DCACHE_PRELOCK_SCT1_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +of prelock on L1-Cache, which should be used together with L1_CACHE_PRELOCK_SCT0 +_SIZE_REG.*/ +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR_M ((EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR_V)<<(EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR_S)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_ADDR_S 0 + +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR_REG (DR_REG_EXTMEM_BASE + 0x80) +/* EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: Those bits are used to configure the start virtual address of the second section - of prelock on L1-DCache, which should be used together with L1_DCACHE_PRELOCK_S -CT1_SIZE_REG.*/ -#define EXTMEM_DCACHE_PRELOCK_SCT1_ADDR 0xFFFFFFFF -#define EXTMEM_DCACHE_PRELOCK_SCT1_ADDR_M ((EXTMEM_DCACHE_PRELOCK_SCT1_ADDR_V)<<(EXTMEM_DCACHE_PRELOCK_SCT1_ADDR_S)) -#define EXTMEM_DCACHE_PRELOCK_SCT1_ADDR_V 0xFFFFFFFF -#define EXTMEM_DCACHE_PRELOCK_SCT1_ADDR_S 0 - -#define EXTMEM_DCACHE_PRELOCK_SCT_SIZE_REG (DR_REG_EXTMEM_BASE + 0x84) -/* EXTMEM_DCACHE_PRELOCK_SCT1_SIZE : R/W ;bitpos:[29:16] ;default: 14'h3fff ; */ + of prelock on L1-Cache, which should be used together with L1_CACHE_PRELOCK_SCT +1_SIZE_REG.*/ +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR_M ((EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR_V)<<(EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR_S)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_ADDR_S 0 + +#define EXTMEM_L1_CACHE_PRELOCK_SCT_SIZE_REG (DR_REG_EXTMEM_BASE + 0x84) +/* EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE : R/W ;bitpos:[29:16] ;default: 14'h3fff ; */ /*description: Those bits are used to configure the size of the second section of prelock on L1 --DCache, which should be used together with L1_DCACHE_PRELOCK_SCT1_ADDR_REG.*/ -#define EXTMEM_DCACHE_PRELOCK_SCT1_SIZE 0x00003FFF -#define EXTMEM_DCACHE_PRELOCK_SCT1_SIZE_M ((EXTMEM_DCACHE_PRELOCK_SCT1_SIZE_V)<<(EXTMEM_DCACHE_PRELOCK_SCT1_SIZE_S)) -#define EXTMEM_DCACHE_PRELOCK_SCT1_SIZE_V 0x3FFF -#define EXTMEM_DCACHE_PRELOCK_SCT1_SIZE_S 16 -/* EXTMEM_DCACHE_PRELOCK_SCT0_SIZE : R/W ;bitpos:[13:0] ;default: 14'h3fff ; */ +-Cache, which should be used together with L1_CACHE_PRELOCK_SCT1_ADDR_REG.*/ +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE 0x00003FFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE_M ((EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE_V)<<(EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE_S)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE_V 0x3FFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT1_SIZE_S 16 +/* EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE : R/W ;bitpos:[13:0] ;default: 14'h3fff ; */ /*description: Those bits are used to configure the size of the first section of prelock on L1- -DCache, which should be used together with L1_DCACHE_PRELOCK_SCT0_ADDR_REG.*/ -#define EXTMEM_DCACHE_PRELOCK_SCT0_SIZE 0x00003FFF -#define EXTMEM_DCACHE_PRELOCK_SCT0_SIZE_M ((EXTMEM_DCACHE_PRELOCK_SCT0_SIZE_V)<<(EXTMEM_DCACHE_PRELOCK_SCT0_SIZE_S)) -#define EXTMEM_DCACHE_PRELOCK_SCT0_SIZE_V 0x3FFF -#define EXTMEM_DCACHE_PRELOCK_SCT0_SIZE_S 0 - -#define EXTMEM_CACHE_LOCK_CTRL_REG (DR_REG_EXTMEM_BASE + 0x88) -/* EXTMEM_CACHE_LOCK_RGID : HRO ;bitpos:[6:3] ;default: 4'h0 ; */ -/*description: The bit is used to set the gid of cache lock/unlock..*/ -#define EXTMEM_CACHE_LOCK_RGID 0x0000000F -#define EXTMEM_CACHE_LOCK_RGID_M ((EXTMEM_CACHE_LOCK_RGID_V)<<(EXTMEM_CACHE_LOCK_RGID_S)) -#define EXTMEM_CACHE_LOCK_RGID_V 0xF -#define EXTMEM_CACHE_LOCK_RGID_S 3 -/* EXTMEM_CACHE_LOCK_DONE : RO ;bitpos:[2] ;default: 1'h1 ; */ +Cache, which should be used together with L1_CACHE_PRELOCK_SCT0_ADDR_REG.*/ +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE 0x00003FFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE_M ((EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE_V)<<(EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE_S)) +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE_V 0x3FFF +#define EXTMEM_L1_CACHE_PRELOCK_SCT0_SIZE_S 0 + +#define EXTMEM_L1_CACHE_LOCK_CTRL_REG (DR_REG_EXTMEM_BASE + 0x88) +/* EXTMEM_L1_CACHE_LOCK_DONE : RO ;bitpos:[2] ;default: 1'h1 ; */ /*description: The bit is used to indicate whether unlock/lock operation is finished or not. 0: not finished. 1: finished..*/ -#define EXTMEM_CACHE_LOCK_DONE (BIT(2)) -#define EXTMEM_CACHE_LOCK_DONE_M (BIT(2)) -#define EXTMEM_CACHE_LOCK_DONE_V 0x1 -#define EXTMEM_CACHE_LOCK_DONE_S 2 -/* EXTMEM_CACHE_UNLOCK_ENA : R/W/SC ;bitpos:[1] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_LOCK_DONE (BIT(2)) +#define EXTMEM_L1_CACHE_LOCK_DONE_M (BIT(2)) +#define EXTMEM_L1_CACHE_LOCK_DONE_V 0x1 +#define EXTMEM_L1_CACHE_LOCK_DONE_S 2 +/* EXTMEM_L1_CACHE_UNLOCK_ENA : R/W/SC ;bitpos:[1] ;default: 1'h0 ; */ /*description: The bit is used to enable unlock operation. It will be cleared by hardware after - unlock operation done. Note that (1) this bit and lock_ena bit are mutually exc -lusive, that is, those bits can not be set to 1 at the same time. (2) unlock ope -ration can be applied on L1-ICache, L1-DCache and L2-Cache..*/ -#define EXTMEM_CACHE_UNLOCK_ENA (BIT(1)) -#define EXTMEM_CACHE_UNLOCK_ENA_M (BIT(1)) -#define EXTMEM_CACHE_UNLOCK_ENA_V 0x1 -#define EXTMEM_CACHE_UNLOCK_ENA_S 1 -/* EXTMEM_CACHE_LOCK_ENA : R/W/SC ;bitpos:[0] ;default: 1'h0 ; */ + unlock operation done.*/ +#define EXTMEM_L1_CACHE_UNLOCK_ENA (BIT(1)) +#define EXTMEM_L1_CACHE_UNLOCK_ENA_M (BIT(1)) +#define EXTMEM_L1_CACHE_UNLOCK_ENA_V 0x1 +#define EXTMEM_L1_CACHE_UNLOCK_ENA_S 1 +/* EXTMEM_L1_CACHE_LOCK_ENA : R/W/SC ;bitpos:[0] ;default: 1'h0 ; */ /*description: The bit is used to enable lock operation. It will be cleared by hardware after l -ock operation done. Note that (1) this bit and unlock_ena bit are mutually exclu -sive, that is, those bits can not be set to 1 at the same time. (2) lock operati -on can be applied on LL1-ICache, L1-DCache and L2-Cache..*/ -#define EXTMEM_CACHE_LOCK_ENA (BIT(0)) -#define EXTMEM_CACHE_LOCK_ENA_M (BIT(0)) -#define EXTMEM_CACHE_LOCK_ENA_V 0x1 -#define EXTMEM_CACHE_LOCK_ENA_S 0 - -#define EXTMEM_CACHE_LOCK_MAP_REG (DR_REG_EXTMEM_BASE + 0x8C) -/* EXTMEM_CACHE_LOCK_MAP : R/W ;bitpos:[5:0] ;default: 6'h0 ; */ +ock operation done.*/ +#define EXTMEM_L1_CACHE_LOCK_ENA (BIT(0)) +#define EXTMEM_L1_CACHE_LOCK_ENA_M (BIT(0)) +#define EXTMEM_L1_CACHE_LOCK_ENA_V 0x1 +#define EXTMEM_L1_CACHE_LOCK_ENA_S 0 + +#define EXTMEM_L1_CACHE_LOCK_MAP_REG (DR_REG_EXTMEM_BASE + 0x8C) +/* EXTMEM_L1_CACHE_LOCK_MAP : R/W ;bitpos:[5:0] ;default: 6'h0 ; */ /*description: Those bits are used to indicate which caches in the two-level cache structure wi -ll apply this lock/unlock operation. [0]: L1-ICache0, [1]: L1-ICache1, [2]: L1-I -Cache2, [3]: L1-ICache3, [4]: L1-DCache, [5]: L2-Cache..*/ -#define EXTMEM_CACHE_LOCK_MAP 0x0000003F -#define EXTMEM_CACHE_LOCK_MAP_M ((EXTMEM_CACHE_LOCK_MAP_V)<<(EXTMEM_CACHE_LOCK_MAP_S)) -#define EXTMEM_CACHE_LOCK_MAP_V 0x3F -#define EXTMEM_CACHE_LOCK_MAP_S 0 - -#define EXTMEM_CACHE_LOCK_ADDR_REG (DR_REG_EXTMEM_BASE + 0x90) -/* EXTMEM_CACHE_LOCK_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +ll apply this lock/unlock operation. [4]: L1-Cache.*/ +#define EXTMEM_L1_CACHE_LOCK_MAP 0x0000003F +#define EXTMEM_L1_CACHE_LOCK_MAP_M ((EXTMEM_L1_CACHE_LOCK_MAP_V)<<(EXTMEM_L1_CACHE_LOCK_MAP_S)) +#define EXTMEM_L1_CACHE_LOCK_MAP_V 0x3F +#define EXTMEM_L1_CACHE_LOCK_MAP_S 0 + +#define EXTMEM_L1_CACHE_LOCK_ADDR_REG (DR_REG_EXTMEM_BASE + 0x90) +/* EXTMEM_L1_CACHE_LOCK_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: Those bits are used to configure the start virtual address of the lock/unlock op eration, which should be used together with CACHE_LOCK_SIZE_REG.*/ -#define EXTMEM_CACHE_LOCK_ADDR 0xFFFFFFFF -#define EXTMEM_CACHE_LOCK_ADDR_M ((EXTMEM_CACHE_LOCK_ADDR_V)<<(EXTMEM_CACHE_LOCK_ADDR_S)) -#define EXTMEM_CACHE_LOCK_ADDR_V 0xFFFFFFFF -#define EXTMEM_CACHE_LOCK_ADDR_S 0 +#define EXTMEM_L1_CACHE_LOCK_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_LOCK_ADDR_M ((EXTMEM_L1_CACHE_LOCK_ADDR_V)<<(EXTMEM_L1_CACHE_LOCK_ADDR_S)) +#define EXTMEM_L1_CACHE_LOCK_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_LOCK_ADDR_S 0 -#define EXTMEM_CACHE_LOCK_SIZE_REG (DR_REG_EXTMEM_BASE + 0x94) -/* EXTMEM_CACHE_LOCK_SIZE : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ +#define EXTMEM_L1_CACHE_LOCK_SIZE_REG (DR_REG_EXTMEM_BASE + 0x94) +/* EXTMEM_L1_CACHE_LOCK_SIZE : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ /*description: Those bits are used to configure the size of the lock/unlock operation, which sh ould be used together with CACHE_LOCK_ADDR_REG.*/ -#define EXTMEM_CACHE_LOCK_SIZE 0x0000FFFF -#define EXTMEM_CACHE_LOCK_SIZE_M ((EXTMEM_CACHE_LOCK_SIZE_V)<<(EXTMEM_CACHE_LOCK_SIZE_S)) -#define EXTMEM_CACHE_LOCK_SIZE_V 0xFFFF -#define EXTMEM_CACHE_LOCK_SIZE_S 0 - -#define EXTMEM_CACHE_SYNC_CTRL_REG (DR_REG_EXTMEM_BASE + 0x98) -/* EXTMEM_CACHE_SYNC_RGID : HRO ;bitpos:[8:5] ;default: 4'h0 ; */ -/*description: The bit is used to set the gid of cache sync operation (invalidate, clean, writ -eback, writeback_invalidate).*/ -#define EXTMEM_CACHE_SYNC_RGID 0x0000000F -#define EXTMEM_CACHE_SYNC_RGID_M ((EXTMEM_CACHE_SYNC_RGID_V)<<(EXTMEM_CACHE_SYNC_RGID_S)) -#define EXTMEM_CACHE_SYNC_RGID_V 0xF -#define EXTMEM_CACHE_SYNC_RGID_S 5 -/* EXTMEM_CACHE_SYNC_DONE : RO ;bitpos:[4] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_LOCK_SIZE 0x0000FFFF +#define EXTMEM_L1_CACHE_LOCK_SIZE_M ((EXTMEM_L1_CACHE_LOCK_SIZE_V)<<(EXTMEM_L1_CACHE_LOCK_SIZE_S)) +#define EXTMEM_L1_CACHE_LOCK_SIZE_V 0xFFFF +#define EXTMEM_L1_CACHE_LOCK_SIZE_S 0 + +#define EXTMEM_L1_CACHE_SYNC_CTRL_REG (DR_REG_EXTMEM_BASE + 0x98) +/* EXTMEM_L1_CACHE_SYNC_DONE : RO ;bitpos:[4] ;default: 1'h0 ; */ /*description: The bit is used to indicate whether sync operation (invalidate, clean, writeback , writeback_invalidate) is finished or not. 0: not finished. 1: finished..*/ -#define EXTMEM_CACHE_SYNC_DONE (BIT(4)) -#define EXTMEM_CACHE_SYNC_DONE_M (BIT(4)) -#define EXTMEM_CACHE_SYNC_DONE_V 0x1 -#define EXTMEM_CACHE_SYNC_DONE_S 4 -/* EXTMEM_CACHE_WRITEBACK_INVALIDATE_ENA : R/W/SC ;bitpos:[3] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_SYNC_DONE (BIT(4)) +#define EXTMEM_L1_CACHE_SYNC_DONE_M (BIT(4)) +#define EXTMEM_L1_CACHE_SYNC_DONE_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_DONE_S 4 +/* EXTMEM_L1_CACHE_WRITEBACK_INVALIDATE_ENA : R/W/SC ;bitpos:[3] ;default: 1'h0 ; */ /*description: The bit is used to enable writeback-invalidate operation. It will be cleared by hardware after writeback-invalidate operation done. Note that this bit and the o ther sync-bits (invalidate_ena, clean_ena, writeback_ena) are mutually exclusive , that is, those bits can not be set to 1 at the same time..*/ -#define EXTMEM_CACHE_WRITEBACK_INVALIDATE_ENA (BIT(3)) -#define EXTMEM_CACHE_WRITEBACK_INVALIDATE_ENA_M (BIT(3)) -#define EXTMEM_CACHE_WRITEBACK_INVALIDATE_ENA_V 0x1 -#define EXTMEM_CACHE_WRITEBACK_INVALIDATE_ENA_S 3 -/* EXTMEM_CACHE_WRITEBACK_ENA : R/W/SC ;bitpos:[2] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_WRITEBACK_INVALIDATE_ENA (BIT(3)) +#define EXTMEM_L1_CACHE_WRITEBACK_INVALIDATE_ENA_M (BIT(3)) +#define EXTMEM_L1_CACHE_WRITEBACK_INVALIDATE_ENA_V 0x1 +#define EXTMEM_L1_CACHE_WRITEBACK_INVALIDATE_ENA_S 3 +/* EXTMEM_L1_CACHE_WRITEBACK_ENA : R/W/SC ;bitpos:[2] ;default: 1'h0 ; */ /*description: The bit is used to enable writeback operation. It will be cleared by hardware af ter writeback operation done. Note that this bit and the other sync-bits (invali date_ena, clean_ena, writeback_invalidate_ena) are mutually exclusive, that is, those bits can not be set to 1 at the same time..*/ -#define EXTMEM_CACHE_WRITEBACK_ENA (BIT(2)) -#define EXTMEM_CACHE_WRITEBACK_ENA_M (BIT(2)) -#define EXTMEM_CACHE_WRITEBACK_ENA_V 0x1 -#define EXTMEM_CACHE_WRITEBACK_ENA_S 2 -/* EXTMEM_CACHE_CLEAN_ENA : R/W/SC ;bitpos:[1] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_WRITEBACK_ENA (BIT(2)) +#define EXTMEM_L1_CACHE_WRITEBACK_ENA_M (BIT(2)) +#define EXTMEM_L1_CACHE_WRITEBACK_ENA_V 0x1 +#define EXTMEM_L1_CACHE_WRITEBACK_ENA_S 2 +/* EXTMEM_L1_CACHE_CLEAN_ENA : R/W/SC ;bitpos:[1] ;default: 1'h0 ; */ /*description: The bit is used to enable clean operation. It will be cleared by hardware after clean operation done. Note that this bit and the other sync-bits (invalidate_ena , writeback_ena, writeback_invalidate_ena) are mutually exclusive, that is, thos e bits can not be set to 1 at the same time..*/ -#define EXTMEM_CACHE_CLEAN_ENA (BIT(1)) -#define EXTMEM_CACHE_CLEAN_ENA_M (BIT(1)) -#define EXTMEM_CACHE_CLEAN_ENA_V 0x1 -#define EXTMEM_CACHE_CLEAN_ENA_S 1 -/* EXTMEM_CACHE_INVALIDATE_ENA : R/W/SC ;bitpos:[0] ;default: 1'h1 ; */ +#define EXTMEM_L1_CACHE_CLEAN_ENA (BIT(1)) +#define EXTMEM_L1_CACHE_CLEAN_ENA_M (BIT(1)) +#define EXTMEM_L1_CACHE_CLEAN_ENA_V 0x1 +#define EXTMEM_L1_CACHE_CLEAN_ENA_S 1 +/* EXTMEM_L1_CACHE_INVALIDATE_ENA : R/W/SC ;bitpos:[0] ;default: 1'h1 ; */ /*description: The bit is used to enable invalidate operation. It will be cleared by hardware a fter invalidate operation done. Note that this bit and the other sync-bits (clea n_ena, writeback_ena, writeback_invalidate_ena) are mutually exclusive, that is, those bits can not be set to 1 at the same time..*/ -#define EXTMEM_CACHE_INVALIDATE_ENA (BIT(0)) -#define EXTMEM_CACHE_INVALIDATE_ENA_M (BIT(0)) -#define EXTMEM_CACHE_INVALIDATE_ENA_V 0x1 -#define EXTMEM_CACHE_INVALIDATE_ENA_S 0 +#define EXTMEM_L1_CACHE_INVALIDATE_ENA (BIT(0)) +#define EXTMEM_L1_CACHE_INVALIDATE_ENA_M (BIT(0)) +#define EXTMEM_L1_CACHE_INVALIDATE_ENA_V 0x1 +#define EXTMEM_L1_CACHE_INVALIDATE_ENA_S 0 -#define EXTMEM_CACHE_SYNC_MAP_REG (DR_REG_EXTMEM_BASE + 0x9C) -/* EXTMEM_CACHE_SYNC_MAP : R/W ;bitpos:[5:0] ;default: 6'h3f ; */ +#define EXTMEM_L1_CACHE_SYNC_MAP_REG (DR_REG_EXTMEM_BASE + 0x9C) +/* EXTMEM_L1_CACHE_SYNC_MAP : R/W ;bitpos:[5:0] ;default: 6'h3f ; */ /*description: Those bits are used to indicate which caches in the two-level cache structure wi -ll apply the sync operation. [0]: L1-ICache0, [1]: L1-ICache1, [2]: L1-ICache2, -[3]: L1-ICache3, [4]: L1-DCache, [5]: L2-Cache..*/ -#define EXTMEM_CACHE_SYNC_MAP 0x0000003F -#define EXTMEM_CACHE_SYNC_MAP_M ((EXTMEM_CACHE_SYNC_MAP_V)<<(EXTMEM_CACHE_SYNC_MAP_S)) -#define EXTMEM_CACHE_SYNC_MAP_V 0x3F -#define EXTMEM_CACHE_SYNC_MAP_S 0 - -#define EXTMEM_CACHE_SYNC_ADDR_REG (DR_REG_EXTMEM_BASE + 0xA0) -/* EXTMEM_CACHE_SYNC_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +ll apply the sync operation. [4]: L1-Cache.*/ +#define EXTMEM_L1_CACHE_SYNC_MAP 0x0000003F +#define EXTMEM_L1_CACHE_SYNC_MAP_M ((EXTMEM_L1_CACHE_SYNC_MAP_V)<<(EXTMEM_L1_CACHE_SYNC_MAP_S)) +#define EXTMEM_L1_CACHE_SYNC_MAP_V 0x3F +#define EXTMEM_L1_CACHE_SYNC_MAP_S 0 + +#define EXTMEM_L1_CACHE_SYNC_ADDR_REG (DR_REG_EXTMEM_BASE + 0xA0) +/* EXTMEM_L1_CACHE_SYNC_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: Those bits are used to configure the start virtual address of the sync operation , which should be used together with CACHE_SYNC_SIZE_REG.*/ -#define EXTMEM_CACHE_SYNC_ADDR 0xFFFFFFFF -#define EXTMEM_CACHE_SYNC_ADDR_M ((EXTMEM_CACHE_SYNC_ADDR_V)<<(EXTMEM_CACHE_SYNC_ADDR_S)) -#define EXTMEM_CACHE_SYNC_ADDR_V 0xFFFFFFFF -#define EXTMEM_CACHE_SYNC_ADDR_S 0 +#define EXTMEM_L1_CACHE_SYNC_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_SYNC_ADDR_M ((EXTMEM_L1_CACHE_SYNC_ADDR_V)<<(EXTMEM_L1_CACHE_SYNC_ADDR_S)) +#define EXTMEM_L1_CACHE_SYNC_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_SYNC_ADDR_S 0 -#define EXTMEM_CACHE_SYNC_SIZE_REG (DR_REG_EXTMEM_BASE + 0xA4) -/* EXTMEM_CACHE_SYNC_SIZE : R/W ;bitpos:[23:0] ;default: 24'h0 ; */ +#define EXTMEM_L1_CACHE_SYNC_SIZE_REG (DR_REG_EXTMEM_BASE + 0xA4) +/* EXTMEM_L1_CACHE_SYNC_SIZE : R/W ;bitpos:[23:0] ;default: 24'h0 ; */ /*description: Those bits are used to configure the size of the sync operation, which should be used together with CACHE_SYNC_ADDR_REG.*/ -#define EXTMEM_CACHE_SYNC_SIZE 0x00FFFFFF -#define EXTMEM_CACHE_SYNC_SIZE_M ((EXTMEM_CACHE_SYNC_SIZE_V)<<(EXTMEM_CACHE_SYNC_SIZE_S)) -#define EXTMEM_CACHE_SYNC_SIZE_V 0xFFFFFF -#define EXTMEM_CACHE_SYNC_SIZE_S 0 - -#define EXTMEM_DCACHE_PRELOAD_CTRL_REG (DR_REG_EXTMEM_BASE + 0xD8) -/* EXTMEM_DCACHE_PRELOAD_RGID : HRO ;bitpos:[6:3] ;default: 4'h0 ; */ -/*description: The bit is used to set the gid of l1 dcache preload..*/ -#define EXTMEM_DCACHE_PRELOAD_RGID 0x0000000F -#define EXTMEM_DCACHE_PRELOAD_RGID_M ((EXTMEM_DCACHE_PRELOAD_RGID_V)<<(EXTMEM_DCACHE_PRELOAD_RGID_S)) -#define EXTMEM_DCACHE_PRELOAD_RGID_V 0xF -#define EXTMEM_DCACHE_PRELOAD_RGID_S 3 -/* EXTMEM_DCACHE_PRELOAD_ORDER : R/W ;bitpos:[2] ;default: 1'h0 ; */ +#define EXTMEM_L1_CACHE_SYNC_SIZE 0x00FFFFFF +#define EXTMEM_L1_CACHE_SYNC_SIZE_M ((EXTMEM_L1_CACHE_SYNC_SIZE_V)<<(EXTMEM_L1_CACHE_SYNC_SIZE_S)) +#define EXTMEM_L1_CACHE_SYNC_SIZE_V 0xFFFFFF +#define EXTMEM_L1_CACHE_SYNC_SIZE_S 0 + +#define EXTMEM_L1_CACHE_PRELOAD_CTRL_REG (DR_REG_EXTMEM_BASE + 0xD8) +/* EXTMEM_L1_CACHE_PRELOAD_RGID : HRO ;bitpos:[6:3] ;default: 4'h0 ; */ +/*description: The bit is used to set the gid of l1 cache preload..*/ +#define EXTMEM_L1_CACHE_PRELOAD_RGID 0x0000000F +#define EXTMEM_L1_CACHE_PRELOAD_RGID_M ((EXTMEM_L1_CACHE_PRELOAD_RGID_V)<<(EXTMEM_L1_CACHE_PRELOAD_RGID_S)) +#define EXTMEM_L1_CACHE_PRELOAD_RGID_V 0xF +#define EXTMEM_L1_CACHE_PRELOAD_RGID_S 3 +/* EXTMEM_L1_CACHE_PRELOAD_ORDER : R/W ;bitpos:[2] ;default: 1'h0 ; */ /*description: The bit is used to configure the direction of preload operation. 0: ascending, 1 : descending..*/ -#define EXTMEM_DCACHE_PRELOAD_ORDER (BIT(2)) -#define EXTMEM_DCACHE_PRELOAD_ORDER_M (BIT(2)) -#define EXTMEM_DCACHE_PRELOAD_ORDER_V 0x1 -#define EXTMEM_DCACHE_PRELOAD_ORDER_S 2 -/* EXTMEM_DCACHE_PRELOAD_DONE : RO ;bitpos:[1] ;default: 1'h1 ; */ +#define EXTMEM_L1_CACHE_PRELOAD_ORDER (BIT(2)) +#define EXTMEM_L1_CACHE_PRELOAD_ORDER_M (BIT(2)) +#define EXTMEM_L1_CACHE_PRELOAD_ORDER_V 0x1 +#define EXTMEM_L1_CACHE_PRELOAD_ORDER_S 2 +/* EXTMEM_L1_CACHE_PRELOAD_DONE : RO ;bitpos:[1] ;default: 1'h1 ; */ /*description: The bit is used to indicate whether preload operation is finished or not. 0: not finished. 1: finished..*/ -#define EXTMEM_DCACHE_PRELOAD_DONE (BIT(1)) -#define EXTMEM_DCACHE_PRELOAD_DONE_M (BIT(1)) -#define EXTMEM_DCACHE_PRELOAD_DONE_V 0x1 -#define EXTMEM_DCACHE_PRELOAD_DONE_S 1 -/* EXTMEM_DCACHE_PRELOAD_ENA : R/W/SC ;bitpos:[0] ;default: 1'h0 ; */ -/*description: The bit is used to enable preload operation on L1-DCache. It will be cleared by -hardware automatically after preload operation is done..*/ -#define EXTMEM_DCACHE_PRELOAD_ENA (BIT(0)) -#define EXTMEM_DCACHE_PRELOAD_ENA_M (BIT(0)) -#define EXTMEM_DCACHE_PRELOAD_ENA_V 0x1 -#define EXTMEM_DCACHE_PRELOAD_ENA_S 0 - -#define EXTMEM_DCACHE_PRELOAD_ADDR_REG (DR_REG_EXTMEM_BASE + 0xDC) -/* EXTMEM_DCACHE_PRELOAD_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: Those bits are used to configure the start virtual address of preload on L1-DCac -he, which should be used together with L1_DCACHE_PRELOAD_SIZE_REG.*/ -#define EXTMEM_DCACHE_PRELOAD_ADDR 0xFFFFFFFF -#define EXTMEM_DCACHE_PRELOAD_ADDR_M ((EXTMEM_DCACHE_PRELOAD_ADDR_V)<<(EXTMEM_DCACHE_PRELOAD_ADDR_S)) -#define EXTMEM_DCACHE_PRELOAD_ADDR_V 0xFFFFFFFF -#define EXTMEM_DCACHE_PRELOAD_ADDR_S 0 - -#define EXTMEM_DCACHE_PRELOAD_SIZE_REG (DR_REG_EXTMEM_BASE + 0xE0) -/* EXTMEM_DCACHE_PRELOAD_SIZE : R/W ;bitpos:[13:0] ;default: 14'h0 ; */ +#define EXTMEM_L1_CACHE_PRELOAD_DONE (BIT(1)) +#define EXTMEM_L1_CACHE_PRELOAD_DONE_M (BIT(1)) +#define EXTMEM_L1_CACHE_PRELOAD_DONE_V 0x1 +#define EXTMEM_L1_CACHE_PRELOAD_DONE_S 1 +/* EXTMEM_L1_CACHE_PRELOAD_ENA : R/W/SC ;bitpos:[0] ;default: 1'h0 ; */ +/*description: The bit is used to enable preload operation on L1-Cache. It will be cleared by h +ardware automatically after preload operation is done..*/ +#define EXTMEM_L1_CACHE_PRELOAD_ENA (BIT(0)) +#define EXTMEM_L1_CACHE_PRELOAD_ENA_M (BIT(0)) +#define EXTMEM_L1_CACHE_PRELOAD_ENA_V 0x1 +#define EXTMEM_L1_CACHE_PRELOAD_ENA_S 0 + +#define EXTMEM_L1_DCACHE_PRELOAD_ADDR_REG (DR_REG_EXTMEM_BASE + 0xDC) +/* EXTMEM_L1_CACHE_PRELOAD_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: Those bits are used to configure the start virtual address of preload on L1-Cach +e, which should be used together with L1_CACHE_PRELOAD_SIZE_REG.*/ +#define EXTMEM_L1_CACHE_PRELOAD_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_PRELOAD_ADDR_M ((EXTMEM_L1_CACHE_PRELOAD_ADDR_V)<<(EXTMEM_L1_CACHE_PRELOAD_ADDR_S)) +#define EXTMEM_L1_CACHE_PRELOAD_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_PRELOAD_ADDR_S 0 + +#define EXTMEM_L1_DCACHE_PRELOAD_SIZE_REG (DR_REG_EXTMEM_BASE + 0xE0) +/* EXTMEM_L1_CACHE_PRELOAD_SIZE : R/W ;bitpos:[13:0] ;default: 14'h0 ; */ /*description: Those bits are used to configure the size of the first section of prelock on L1- -DCache, which should be used together with L1_DCACHE_PRELOAD_ADDR_REG.*/ -#define EXTMEM_DCACHE_PRELOAD_SIZE 0x00003FFF -#define EXTMEM_DCACHE_PRELOAD_SIZE_M ((EXTMEM_DCACHE_PRELOAD_SIZE_V)<<(EXTMEM_DCACHE_PRELOAD_SIZE_S)) -#define EXTMEM_DCACHE_PRELOAD_SIZE_V 0x3FFF -#define EXTMEM_DCACHE_PRELOAD_SIZE_S 0 - -#define EXTMEM_DCACHE_AUTOLOAD_CTRL_REG (DR_REG_EXTMEM_BASE + 0x134) -/* EXTMEM_DCACHE_AUTOLOAD_SCT1_ENA : R/W ;bitpos:[9] ;default: 1'h0 ; */ -/*description: The bit is used to enable the second section for autoload operation on L1-DCache -..*/ -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ENA (BIT(9)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ENA_M (BIT(9)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ENA_V 0x1 -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ENA_S 9 -/* EXTMEM_DCACHE_AUTOLOAD_SCT0_ENA : R/W ;bitpos:[8] ;default: 1'h0 ; */ -/*description: The bit is used to enable the first section for autoload operation on L1-DCache..*/ -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ENA (BIT(8)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ENA_M (BIT(8)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ENA_V 0x1 -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ENA_S 8 -/* EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE : R/W ;bitpos:[4:3] ;default: 2'h0 ; */ -/*description: The field is used to configure trigger mode of autoload operation on L1-DCache. -0/3: miss-trigger, 1: hit-trigger, 2: miss-hit-trigger..*/ -#define EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE 0x00000003 -#define EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE_M ((EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE_V)<<(EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE_S)) -#define EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE_V 0x3 -#define EXTMEM_DCACHE_AUTOLOAD_TRIGGER_MODE_S 3 -/* EXTMEM_DCACHE_AUTOLOAD_ORDER : R/W ;bitpos:[2] ;default: 1'h0 ; */ -/*description: The bit is used to configure the direction of autoload operation on L1-DCache. 0 -: ascending. 1: descending..*/ -#define EXTMEM_DCACHE_AUTOLOAD_ORDER (BIT(2)) -#define EXTMEM_DCACHE_AUTOLOAD_ORDER_M (BIT(2)) -#define EXTMEM_DCACHE_AUTOLOAD_ORDER_V 0x1 -#define EXTMEM_DCACHE_AUTOLOAD_ORDER_S 2 -/* EXTMEM_DCACHE_AUTOLOAD_DONE : RO ;bitpos:[1] ;default: 1'h1 ; */ -/*description: The bit is used to indicate whether autoload operation on L1-DCache is finished -or not. 0: not finished. 1: finished..*/ -#define EXTMEM_DCACHE_AUTOLOAD_DONE (BIT(1)) -#define EXTMEM_DCACHE_AUTOLOAD_DONE_M (BIT(1)) -#define EXTMEM_DCACHE_AUTOLOAD_DONE_V 0x1 -#define EXTMEM_DCACHE_AUTOLOAD_DONE_S 1 -/* EXTMEM_DCACHE_AUTOLOAD_ENA : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: The bit is used to enable and disable autoload operation on L1-DCache. 1: enabl -e, 0: disable..*/ -#define EXTMEM_DCACHE_AUTOLOAD_ENA (BIT(0)) -#define EXTMEM_DCACHE_AUTOLOAD_ENA_M (BIT(0)) -#define EXTMEM_DCACHE_AUTOLOAD_ENA_V 0x1 -#define EXTMEM_DCACHE_AUTOLOAD_ENA_S 0 - -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR_REG (DR_REG_EXTMEM_BASE + 0x138) -/* EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +Cache, which should be used together with L1_CACHE_PRELOAD_ADDR_REG.*/ +#define EXTMEM_L1_CACHE_PRELOAD_SIZE 0x00003FFF +#define EXTMEM_L1_CACHE_PRELOAD_SIZE_M ((EXTMEM_L1_CACHE_PRELOAD_SIZE_V)<<(EXTMEM_L1_CACHE_PRELOAD_SIZE_S)) +#define EXTMEM_L1_CACHE_PRELOAD_SIZE_V 0x3FFF +#define EXTMEM_L1_CACHE_PRELOAD_SIZE_S 0 + +#define EXTMEM_L1_CACHE_AUTOLOAD_CTRL_REG (DR_REG_EXTMEM_BASE + 0x134) +/* EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ENA : R/W ;bitpos:[9] ;default: 1'h0 ; */ +/*description: The bit is used to enable the second section for autoload operation on L1-Cache..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ENA (BIT(9)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ENA_M (BIT(9)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ENA_V 0x1 +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ENA_S 9 +/* EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ENA : R/W ;bitpos:[8] ;default: 1'h0 ; */ +/*description: The bit is used to enable the first section for autoload operation on L1-Cache..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ENA (BIT(8)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ENA_M (BIT(8)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ENA_V 0x1 +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ENA_S 8 +/* EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE : R/W ;bitpos:[4:3] ;default: 2'h0 ; */ +/*description: The field is used to configure trigger mode of autoload operation on L1-Cache. 0 +/3: miss-trigger, 1: hit-trigger, 2: miss-hit-trigger..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE 0x00000003 +#define EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE_M ((EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE_V)<<(EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE_S)) +#define EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE_V 0x3 +#define EXTMEM_L1_CACHE_AUTOLOAD_TRIGGER_MODE_S 3 +/* EXTMEM_L1_CACHE_AUTOLOAD_ORDER : R/W ;bitpos:[2] ;default: 1'h0 ; */ +/*description: The bit is used to configure the direction of autoload operation on L1-Cache. 0: + ascending. 1: descending..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_ORDER (BIT(2)) +#define EXTMEM_L1_CACHE_AUTOLOAD_ORDER_M (BIT(2)) +#define EXTMEM_L1_CACHE_AUTOLOAD_ORDER_V 0x1 +#define EXTMEM_L1_CACHE_AUTOLOAD_ORDER_S 2 +/* EXTMEM_L1_CACHE_AUTOLOAD_DONE : RO ;bitpos:[1] ;default: 1'h1 ; */ +/*description: The bit is used to indicate whether autoload operation on L1-Cache is finished o +r not. 0: not finished. 1: finished..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_DONE (BIT(1)) +#define EXTMEM_L1_CACHE_AUTOLOAD_DONE_M (BIT(1)) +#define EXTMEM_L1_CACHE_AUTOLOAD_DONE_V 0x1 +#define EXTMEM_L1_CACHE_AUTOLOAD_DONE_S 1 +/* EXTMEM_L1_CACHE_AUTOLOAD_ENA : R/W ;bitpos:[0] ;default: 1'h0 ; */ +/*description: The bit is used to enable and disable autoload operation on L1-Cache. 1: enable +, 0: disable..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_ENA (BIT(0)) +#define EXTMEM_L1_CACHE_AUTOLOAD_ENA_M (BIT(0)) +#define EXTMEM_L1_CACHE_AUTOLOAD_ENA_V 0x1 +#define EXTMEM_L1_CACHE_AUTOLOAD_ENA_S 0 + +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR_REG (DR_REG_EXTMEM_BASE + 0x138) +/* EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: Those bits are used to configure the start virtual address of the first section -for autoload operation on L1-DCache. Note that it should be used together with L -1_DCACHE_AUTOLOAD_SCT0_SIZE and L1_DCACHE_AUTOLOAD_SCT0_ENA..*/ -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR 0xFFFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR_M ((EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR_V)<<(EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR_S)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR_V 0xFFFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_ADDR_S 0 - -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE_REG (DR_REG_EXTMEM_BASE + 0x13C) -/* EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE : R/W ;bitpos:[27:0] ;default: 28'h0 ; */ +for autoload operation on L1-Cache. Note that it should be used together with L1 +_CACHE_AUTOLOAD_SCT0_SIZE and L1_CACHE_AUTOLOAD_SCT0_ENA..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR_M ((EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR_V)<<(EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR_S)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_ADDR_S 0 + +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE_REG (DR_REG_EXTMEM_BASE + 0x13C) +/* EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE : R/W ;bitpos:[27:0] ;default: 28'h0 ; */ /*description: Those bits are used to configure the size of the first section for autoload oper -ation on L1-DCache. Note that it should be used together with L1_DCACHE_AUTOLOAD -_SCT0_ADDR and L1_DCACHE_AUTOLOAD_SCT0_ENA..*/ -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE 0x0FFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE_M ((EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE_V)<<(EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE_S)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE_V 0xFFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT0_SIZE_S 0 - -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR_REG (DR_REG_EXTMEM_BASE + 0x140) -/* EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +ation on L1-Cache. Note that it should be used together with L1_CACHE_AUTOLOAD_S +CT0_ADDR and L1_CACHE_AUTOLOAD_SCT0_ENA..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE 0x0FFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE_M ((EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE_V)<<(EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE_S)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE_V 0xFFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT0_SIZE_S 0 + +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR_REG (DR_REG_EXTMEM_BASE + 0x140) +/* EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: Those bits are used to configure the start virtual address of the second section - for autoload operation on L1-DCache. Note that it should be used together with -L1_DCACHE_AUTOLOAD_SCT1_SIZE and L1_DCACHE_AUTOLOAD_SCT1_ENA..*/ -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR 0xFFFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR_M ((EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR_V)<<(EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR_S)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR_V 0xFFFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_ADDR_S 0 - -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE_REG (DR_REG_EXTMEM_BASE + 0x144) -/* EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE : R/W ;bitpos:[27:0] ;default: 28'h0 ; */ + for autoload operation on L1-Cache. Note that it should be used together with L +1_CACHE_AUTOLOAD_SCT1_SIZE and L1_CACHE_AUTOLOAD_SCT1_ENA..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR_M ((EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR_V)<<(EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR_S)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_ADDR_S 0 + +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE_REG (DR_REG_EXTMEM_BASE + 0x144) +/* EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE : R/W ;bitpos:[27:0] ;default: 28'h0 ; */ /*description: Those bits are used to configure the size of the second section for autoload ope -ration on L1-DCache. Note that it should be used together with L1_DCACHE_AUTOLOA -D_SCT1_ADDR and L1_DCACHE_AUTOLOAD_SCT1_ENA..*/ -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE 0x0FFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE_M ((EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE_V)<<(EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE_S)) -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE_V 0xFFFFFFF -#define EXTMEM_DCACHE_AUTOLOAD_SCT1_SIZE_S 0 - -#define EXTMEM_CACHE_ACS_CNT_INT_ENA_REG (DR_REG_EXTMEM_BASE + 0x158) -/* EXTMEM_DBUS1_OVF_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ; */ +ration on L1-Cache. Note that it should be used together with L1_CACHE_AUTOLOAD_ +SCT1_ADDR and L1_CACHE_AUTOLOAD_SCT1_ENA..*/ +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE 0x0FFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE_M ((EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE_V)<<(EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE_S)) +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE_V 0xFFFFFFF +#define EXTMEM_L1_CACHE_AUTOLOAD_SCT1_SIZE_S 0 + +#define EXTMEM_L1_CACHE_ACS_CNT_INT_ENA_REG (DR_REG_EXTMEM_BASE + 0x158) +/* EXTMEM_L1_DBUS_OVF_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ; */ /*description: The bit is used to enable interrupt of one of counters overflow that occurs in L 1-DCache due to bus1 accesses L1-DCache..*/ -#define EXTMEM_DBUS1_OVF_INT_ENA (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_ENA_M (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_ENA_V 0x1 -#define EXTMEM_DBUS1_OVF_INT_ENA_S 5 -/* EXTMEM_DBUS0_OVF_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_DBUS_OVF_INT_ENA (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_ENA_M (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_ENA_V 0x1 +#define EXTMEM_L1_DBUS_OVF_INT_ENA_S 5 +/* EXTMEM_L1_IBUS_OVF_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit is used to enable interrupt of one of counters overflow that occurs in L 1-DCache due to bus0 accesses L1-DCache..*/ -#define EXTMEM_DBUS0_OVF_INT_ENA (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_ENA_M (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_ENA_V 0x1 -#define EXTMEM_DBUS0_OVF_INT_ENA_S 4 +#define EXTMEM_L1_IBUS_OVF_INT_ENA (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_ENA_M (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_ENA_V 0x1 +#define EXTMEM_L1_IBUS_OVF_INT_ENA_S 4 -#define EXTMEM_CACHE_ACS_CNT_INT_CLR_REG (DR_REG_EXTMEM_BASE + 0x15C) -/* EXTMEM_DBUS1_OVF_INT_CLR : WT ;bitpos:[5] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_CNT_INT_CLR_REG (DR_REG_EXTMEM_BASE + 0x15C) +/* EXTMEM_L1_DBUS_OVF_INT_CLR : WT ;bitpos:[5] ;default: 1'b0 ; */ /*description: The bit is used to clear counters overflow interrupt and counters in L1-DCache d ue to bus1 accesses L1-DCache..*/ -#define EXTMEM_DBUS1_OVF_INT_CLR (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_CLR_M (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_CLR_V 0x1 -#define EXTMEM_DBUS1_OVF_INT_CLR_S 5 -/* EXTMEM_DBUS0_OVF_INT_CLR : WT ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_DBUS_OVF_INT_CLR (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_CLR_M (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_CLR_V 0x1 +#define EXTMEM_L1_DBUS_OVF_INT_CLR_S 5 +/* EXTMEM_L1_IBUS_OVF_INT_CLR : WT ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit is used to clear counters overflow interrupt and counters in L1-DCache d ue to bus0 accesses L1-DCache..*/ -#define EXTMEM_DBUS0_OVF_INT_CLR (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_CLR_M (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_CLR_V 0x1 -#define EXTMEM_DBUS0_OVF_INT_CLR_S 4 +#define EXTMEM_L1_IBUS_OVF_INT_CLR (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_CLR_M (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_CLR_V 0x1 +#define EXTMEM_L1_IBUS_OVF_INT_CLR_S 4 -#define EXTMEM_CACHE_ACS_CNT_INT_RAW_REG (DR_REG_EXTMEM_BASE + 0x160) -/* EXTMEM_DBUS1_OVF_INT_RAW : R/WTC/SS ;bitpos:[5] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_CNT_INT_RAW_REG (DR_REG_EXTMEM_BASE + 0x160) +/* EXTMEM_L1_DBUS_OVF_INT_RAW : R/WTC/SS ;bitpos:[5] ;default: 1'b0 ; */ /*description: The raw bit of the interrupt of one of counters overflow that occurs in L1-DCach e due to bus1 accesses L1-DCache..*/ -#define EXTMEM_DBUS1_OVF_INT_RAW (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_RAW_M (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_RAW_V 0x1 -#define EXTMEM_DBUS1_OVF_INT_RAW_S 5 -/* EXTMEM_DBUS0_OVF_INT_RAW : R/WTC/SS ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_DBUS_OVF_INT_RAW (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_RAW_M (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_RAW_V 0x1 +#define EXTMEM_L1_DBUS_OVF_INT_RAW_S 5 +/* EXTMEM_L1_IBUS_OVF_INT_RAW : R/WTC/SS ;bitpos:[4] ;default: 1'b0 ; */ /*description: The raw bit of the interrupt of one of counters overflow that occurs in L1-DCach e due to bus0 accesses L1-DCache..*/ -#define EXTMEM_DBUS0_OVF_INT_RAW (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_RAW_M (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_RAW_V 0x1 -#define EXTMEM_DBUS0_OVF_INT_RAW_S 4 +#define EXTMEM_L1_IBUS_OVF_INT_RAW (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_RAW_M (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_RAW_V 0x1 +#define EXTMEM_L1_IBUS_OVF_INT_RAW_S 4 -#define EXTMEM_CACHE_ACS_CNT_INT_ST_REG (DR_REG_EXTMEM_BASE + 0x164) -/* EXTMEM_DBUS1_OVF_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_CNT_INT_ST_REG (DR_REG_EXTMEM_BASE + 0x164) +/* EXTMEM_L1_DBUS_OVF_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ; */ /*description: The bit indicates the interrupt status of one of counters overflow that occurs i n L1-DCache due to bus1 accesses L1-DCache..*/ -#define EXTMEM_DBUS1_OVF_INT_ST (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_ST_M (BIT(5)) -#define EXTMEM_DBUS1_OVF_INT_ST_V 0x1 -#define EXTMEM_DBUS1_OVF_INT_ST_S 5 -/* EXTMEM_DBUS0_OVF_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_DBUS_OVF_INT_ST (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_ST_M (BIT(5)) +#define EXTMEM_L1_DBUS_OVF_INT_ST_V 0x1 +#define EXTMEM_L1_DBUS_OVF_INT_ST_S 5 +/* EXTMEM_L1_IBUS_OVF_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit indicates the interrupt status of one of counters overflow that occurs i n L1-DCache due to bus0 accesses L1-DCache..*/ -#define EXTMEM_DBUS0_OVF_INT_ST (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_ST_M (BIT(4)) -#define EXTMEM_DBUS0_OVF_INT_ST_V 0x1 -#define EXTMEM_DBUS0_OVF_INT_ST_S 4 +#define EXTMEM_L1_IBUS_OVF_INT_ST (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_ST_M (BIT(4)) +#define EXTMEM_L1_IBUS_OVF_INT_ST_V 0x1 +#define EXTMEM_L1_IBUS_OVF_INT_ST_S 4 -#define EXTMEM_CACHE_ACS_FAIL_INT_ENA_REG (DR_REG_EXTMEM_BASE + 0x168) -/* EXTMEM_DCACHE_FAIL_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_FAIL_INT_ENA_REG (DR_REG_EXTMEM_BASE + 0x168) +/* EXTMEM_L1_CACHE_FAIL_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit is used to enable interrupt of access fail that occurs in L1-DCache due to cpu accesses L1-DCache..*/ -#define EXTMEM_DCACHE_FAIL_INT_ENA (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_ENA_M (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_ENA_V 0x1 -#define EXTMEM_DCACHE_FAIL_INT_ENA_S 4 +#define EXTMEM_L1_CACHE_FAIL_INT_ENA (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_ENA_M (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_ENA_V 0x1 +#define EXTMEM_L1_CACHE_FAIL_INT_ENA_S 4 -#define EXTMEM_CACHE_ACS_FAIL_INT_CLR_REG (DR_REG_EXTMEM_BASE + 0x16C) -/* EXTMEM_DCACHE_FAIL_INT_CLR : WT ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_FAIL_INT_CLR_REG (DR_REG_EXTMEM_BASE + 0x16C) +/* EXTMEM_L1_CACHE_FAIL_INT_CLR : WT ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit is used to clear interrupt of access fail that occurs in L1-DCache due t o cpu accesses L1-DCache..*/ -#define EXTMEM_DCACHE_FAIL_INT_CLR (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_CLR_M (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_CLR_V 0x1 -#define EXTMEM_DCACHE_FAIL_INT_CLR_S 4 +#define EXTMEM_L1_CACHE_FAIL_INT_CLR (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_CLR_M (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_CLR_V 0x1 +#define EXTMEM_L1_CACHE_FAIL_INT_CLR_S 4 -#define EXTMEM_CACHE_ACS_FAIL_INT_RAW_REG (DR_REG_EXTMEM_BASE + 0x170) -/* EXTMEM_DCACHE_FAIL_INT_RAW : R/WTC/SS ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_FAIL_INT_RAW_REG (DR_REG_EXTMEM_BASE + 0x170) +/* EXTMEM_L1_CACHE_FAIL_INT_RAW : R/WTC/SS ;bitpos:[4] ;default: 1'b0 ; */ /*description: The raw bit of the interrupt of access fail that occurs in L1-DCache..*/ -#define EXTMEM_DCACHE_FAIL_INT_RAW (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_RAW_M (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_RAW_V 0x1 -#define EXTMEM_DCACHE_FAIL_INT_RAW_S 4 +#define EXTMEM_L1_CACHE_FAIL_INT_RAW (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_RAW_M (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_RAW_V 0x1 +#define EXTMEM_L1_CACHE_FAIL_INT_RAW_S 4 -#define EXTMEM_CACHE_ACS_FAIL_INT_ST_REG (DR_REG_EXTMEM_BASE + 0x174) -/* EXTMEM_DCACHE_FAIL_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_FAIL_INT_ST_REG (DR_REG_EXTMEM_BASE + 0x174) +/* EXTMEM_L1_CACHE_FAIL_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit indicates the interrupt status of access fail that occurs in L1-DCache d ue to cpu accesses L1-DCache..*/ -#define EXTMEM_DCACHE_FAIL_INT_ST (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_ST_M (BIT(4)) -#define EXTMEM_DCACHE_FAIL_INT_ST_V 0x1 -#define EXTMEM_DCACHE_FAIL_INT_ST_S 4 +#define EXTMEM_L1_CACHE_FAIL_INT_ST (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_ST_M (BIT(4)) +#define EXTMEM_L1_CACHE_FAIL_INT_ST_V 0x1 +#define EXTMEM_L1_CACHE_FAIL_INT_ST_S 4 -#define EXTMEM_CACHE_ACS_CNT_CTRL_REG (DR_REG_EXTMEM_BASE + 0x178) -/* EXTMEM_DBUS1_CNT_CLR : WT ;bitpos:[21] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_ACS_CNT_CTRL_REG (DR_REG_EXTMEM_BASE + 0x178) +/* EXTMEM_L1_DBUS_CNT_CLR : WT ;bitpos:[21] ;default: 1'b0 ; */ /*description: The bit is used to clear dbus1 counter in L1-DCache..*/ -#define EXTMEM_DBUS1_CNT_CLR (BIT(21)) -#define EXTMEM_DBUS1_CNT_CLR_M (BIT(21)) -#define EXTMEM_DBUS1_CNT_CLR_V 0x1 -#define EXTMEM_DBUS1_CNT_CLR_S 21 -/* EXTMEM_DBUS0_CNT_CLR : WT ;bitpos:[20] ;default: 1'b0 ; */ +#define EXTMEM_L1_DBUS_CNT_CLR (BIT(21)) +#define EXTMEM_L1_DBUS_CNT_CLR_M (BIT(21)) +#define EXTMEM_L1_DBUS_CNT_CLR_V 0x1 +#define EXTMEM_L1_DBUS_CNT_CLR_S 21 +/* EXTMEM_L1_IBUS_CNT_CLR : WT ;bitpos:[20] ;default: 1'b0 ; */ /*description: The bit is used to clear dbus0 counter in L1-DCache..*/ -#define EXTMEM_DBUS0_CNT_CLR (BIT(20)) -#define EXTMEM_DBUS0_CNT_CLR_M (BIT(20)) -#define EXTMEM_DBUS0_CNT_CLR_V 0x1 -#define EXTMEM_DBUS0_CNT_CLR_S 20 -/* EXTMEM_DBUS1_CNT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ; */ +#define EXTMEM_L1_IBUS_CNT_CLR (BIT(20)) +#define EXTMEM_L1_IBUS_CNT_CLR_M (BIT(20)) +#define EXTMEM_L1_IBUS_CNT_CLR_V 0x1 +#define EXTMEM_L1_IBUS_CNT_CLR_S 20 +/* EXTMEM_L1_DBUS_CNT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ; */ /*description: The bit is used to enable dbus1 counter in L1-DCache..*/ -#define EXTMEM_DBUS1_CNT_ENA (BIT(5)) -#define EXTMEM_DBUS1_CNT_ENA_M (BIT(5)) -#define EXTMEM_DBUS1_CNT_ENA_V 0x1 -#define EXTMEM_DBUS1_CNT_ENA_S 5 -/* EXTMEM_DBUS0_CNT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ +#define EXTMEM_L1_DBUS_CNT_ENA (BIT(5)) +#define EXTMEM_L1_DBUS_CNT_ENA_M (BIT(5)) +#define EXTMEM_L1_DBUS_CNT_ENA_V 0x1 +#define EXTMEM_L1_DBUS_CNT_ENA_S 5 +/* EXTMEM_L1_IBUS_CNT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ /*description: The bit is used to enable dbus0 counter in L1-DCache..*/ -#define EXTMEM_DBUS0_CNT_ENA (BIT(4)) -#define EXTMEM_DBUS0_CNT_ENA_M (BIT(4)) -#define EXTMEM_DBUS0_CNT_ENA_V 0x1 -#define EXTMEM_DBUS0_CNT_ENA_S 4 - -#define EXTMEM_DBUS0_ACS_HIT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1BC) -/* EXTMEM_DBUS0_HIT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of hits when bus0 accesses L1-DCache..*/ -#define EXTMEM_DBUS0_HIT_CNT 0xFFFFFFFF -#define EXTMEM_DBUS0_HIT_CNT_M ((EXTMEM_DBUS0_HIT_CNT_V)<<(EXTMEM_DBUS0_HIT_CNT_S)) -#define EXTMEM_DBUS0_HIT_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS0_HIT_CNT_S 0 - -#define EXTMEM_DBUS0_ACS_MISS_CNT_REG (DR_REG_EXTMEM_BASE + 0x1C0) -/* EXTMEM_DBUS0_MISS_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of missing when bus0 accesses L1-DCache..*/ -#define EXTMEM_DBUS0_MISS_CNT 0xFFFFFFFF -#define EXTMEM_DBUS0_MISS_CNT_M ((EXTMEM_DBUS0_MISS_CNT_V)<<(EXTMEM_DBUS0_MISS_CNT_S)) -#define EXTMEM_DBUS0_MISS_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS0_MISS_CNT_S 0 - -#define EXTMEM_DBUS0_ACS_CONFLICT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1C4) -/* EXTMEM_DBUS0_CONFLICT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of access-conflicts when bus0 accesses L1-DCache -..*/ -#define EXTMEM_DBUS0_CONFLICT_CNT 0xFFFFFFFF -#define EXTMEM_DBUS0_CONFLICT_CNT_M ((EXTMEM_DBUS0_CONFLICT_CNT_V)<<(EXTMEM_DBUS0_CONFLICT_CNT_S)) -#define EXTMEM_DBUS0_CONFLICT_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS0_CONFLICT_CNT_S 0 - -#define EXTMEM_DBUS0_ACS_NXTLVL_CNT_REG (DR_REG_EXTMEM_BASE + 0x1C8) -/* EXTMEM_DBUS0_NXTLVL_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of times that L1-DCache accesses L2-Cache due to - bus0 accessing L1-DCache..*/ -#define EXTMEM_DBUS0_NXTLVL_CNT 0xFFFFFFFF -#define EXTMEM_DBUS0_NXTLVL_CNT_M ((EXTMEM_DBUS0_NXTLVL_CNT_V)<<(EXTMEM_DBUS0_NXTLVL_CNT_S)) -#define EXTMEM_DBUS0_NXTLVL_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS0_NXTLVL_CNT_S 0 - -#define EXTMEM_DBUS1_ACS_HIT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1CC) -/* EXTMEM_DBUS1_HIT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of hits when bus1 accesses L1-DCache..*/ -#define EXTMEM_DBUS1_HIT_CNT 0xFFFFFFFF -#define EXTMEM_DBUS1_HIT_CNT_M ((EXTMEM_DBUS1_HIT_CNT_V)<<(EXTMEM_DBUS1_HIT_CNT_S)) -#define EXTMEM_DBUS1_HIT_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS1_HIT_CNT_S 0 - -#define EXTMEM_DBUS1_ACS_MISS_CNT_REG (DR_REG_EXTMEM_BASE + 0x1D0) -/* EXTMEM_DBUS1_MISS_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of missing when bus1 accesses L1-DCache..*/ -#define EXTMEM_DBUS1_MISS_CNT 0xFFFFFFFF -#define EXTMEM_DBUS1_MISS_CNT_M ((EXTMEM_DBUS1_MISS_CNT_V)<<(EXTMEM_DBUS1_MISS_CNT_S)) -#define EXTMEM_DBUS1_MISS_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS1_MISS_CNT_S 0 - -#define EXTMEM_DBUS1_ACS_CONFLICT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1D4) -/* EXTMEM_DBUS1_CONFLICT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of access-conflicts when bus1 accesses L1-DCache +#define EXTMEM_L1_IBUS_CNT_ENA (BIT(4)) +#define EXTMEM_L1_IBUS_CNT_ENA_M (BIT(4)) +#define EXTMEM_L1_IBUS_CNT_ENA_V 0x1 +#define EXTMEM_L1_IBUS_CNT_ENA_S 4 + +#define EXTMEM_L1_IBUS_ACS_HIT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1BC) +/* EXTMEM_L1_IBUS_HIT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of hits when bus0 accesses L1-Cache..*/ +#define EXTMEM_L1_IBUS_HIT_CNT 0xFFFFFFFF +#define EXTMEM_L1_IBUS_HIT_CNT_M ((EXTMEM_L1_IBUS_HIT_CNT_V)<<(EXTMEM_L1_IBUS_HIT_CNT_S)) +#define EXTMEM_L1_IBUS_HIT_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_IBUS_HIT_CNT_S 0 + +#define EXTMEM_L1_IBUS_ACS_MISS_CNT_REG (DR_REG_EXTMEM_BASE + 0x1C0) +/* EXTMEM_L1_IBUS_MISS_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of missing when bus0 accesses L1-Cache..*/ +#define EXTMEM_L1_IBUS_MISS_CNT 0xFFFFFFFF +#define EXTMEM_L1_IBUS_MISS_CNT_M ((EXTMEM_L1_IBUS_MISS_CNT_V)<<(EXTMEM_L1_IBUS_MISS_CNT_S)) +#define EXTMEM_L1_IBUS_MISS_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_IBUS_MISS_CNT_S 0 + +#define EXTMEM_L1_IBUS_ACS_CONFLICT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1C4) +/* EXTMEM_L1_IBUS_CONFLICT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of access-conflicts when bus0 accesses L1-Cache..*/ +#define EXTMEM_L1_IBUS_CONFLICT_CNT 0xFFFFFFFF +#define EXTMEM_L1_IBUS_CONFLICT_CNT_M ((EXTMEM_L1_IBUS_CONFLICT_CNT_V)<<(EXTMEM_L1_IBUS_CONFLICT_CNT_S)) +#define EXTMEM_L1_IBUS_CONFLICT_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_IBUS_CONFLICT_CNT_S 0 + +#define EXTMEM_L1_IBUS_ACS_NXTLVL_CNT_REG (DR_REG_EXTMEM_BASE + 0x1C8) +/* EXTMEM_L1_IBUS_NXTLVL_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of times that L1-Cache accesses L2-Cache due to +bus0 accessing L1-Cache..*/ +#define EXTMEM_L1_IBUS_NXTLVL_CNT 0xFFFFFFFF +#define EXTMEM_L1_IBUS_NXTLVL_CNT_M ((EXTMEM_L1_IBUS_NXTLVL_CNT_V)<<(EXTMEM_L1_IBUS_NXTLVL_CNT_S)) +#define EXTMEM_L1_IBUS_NXTLVL_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_IBUS_NXTLVL_CNT_S 0 + +#define EXTMEM_L1_DBUS_ACS_HIT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1CC) +/* EXTMEM_L1_DBUS_HIT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of hits when bus1 accesses L1-Cache..*/ +#define EXTMEM_L1_DBUS_HIT_CNT 0xFFFFFFFF +#define EXTMEM_L1_DBUS_HIT_CNT_M ((EXTMEM_L1_DBUS_HIT_CNT_V)<<(EXTMEM_L1_DBUS_HIT_CNT_S)) +#define EXTMEM_L1_DBUS_HIT_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_DBUS_HIT_CNT_S 0 + +#define EXTMEM_L1_DBUS_ACS_MISS_CNT_REG (DR_REG_EXTMEM_BASE + 0x1D0) +/* EXTMEM_L1_DBUS_MISS_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of missing when bus1 accesses L1-Cache..*/ +#define EXTMEM_L1_DBUS_MISS_CNT 0xFFFFFFFF +#define EXTMEM_L1_DBUS_MISS_CNT_M ((EXTMEM_L1_DBUS_MISS_CNT_V)<<(EXTMEM_L1_DBUS_MISS_CNT_S)) +#define EXTMEM_L1_DBUS_MISS_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_DBUS_MISS_CNT_S 0 + +#define EXTMEM_L1_DBUS_ACS_CONFLICT_CNT_REG (DR_REG_EXTMEM_BASE + 0x1D4) +/* EXTMEM_L1_DBUS_CONFLICT_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of access-conflicts when bus1 accesses L1-Cache..*/ +#define EXTMEM_L1_DBUS_CONFLICT_CNT 0xFFFFFFFF +#define EXTMEM_L1_DBUS_CONFLICT_CNT_M ((EXTMEM_L1_DBUS_CONFLICT_CNT_V)<<(EXTMEM_L1_DBUS_CONFLICT_CNT_S)) +#define EXTMEM_L1_DBUS_CONFLICT_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_DBUS_CONFLICT_CNT_S 0 + +#define EXTMEM_L1_DBUS_ACS_NXTLVL_CNT_REG (DR_REG_EXTMEM_BASE + 0x1D8) +/* EXTMEM_L1_DBUS_NXTLVL_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the number of times that L1-Cache accesses L2-Cache due to +bus1 accessing L1-Cache..*/ +#define EXTMEM_L1_DBUS_NXTLVL_CNT 0xFFFFFFFF +#define EXTMEM_L1_DBUS_NXTLVL_CNT_M ((EXTMEM_L1_DBUS_NXTLVL_CNT_V)<<(EXTMEM_L1_DBUS_NXTLVL_CNT_S)) +#define EXTMEM_L1_DBUS_NXTLVL_CNT_V 0xFFFFFFFF +#define EXTMEM_L1_DBUS_NXTLVL_CNT_S 0 + +#define EXTMEM_L1_CACHE_ACS_FAIL_ID_ATTR_REG (DR_REG_EXTMEM_BASE + 0x21C) +/* EXTMEM_L1_CACHE_FAIL_ATTR : RO ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: The register records the attribution of fail-access when cache accesses L1-Cache ..*/ -#define EXTMEM_DBUS1_CONFLICT_CNT 0xFFFFFFFF -#define EXTMEM_DBUS1_CONFLICT_CNT_M ((EXTMEM_DBUS1_CONFLICT_CNT_V)<<(EXTMEM_DBUS1_CONFLICT_CNT_S)) -#define EXTMEM_DBUS1_CONFLICT_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS1_CONFLICT_CNT_S 0 - -#define EXTMEM_DBUS1_ACS_NXTLVL_CNT_REG (DR_REG_EXTMEM_BASE + 0x1D8) -/* EXTMEM_DBUS1_NXTLVL_CNT : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the number of times that L1-DCache accesses L2-Cache due to - bus1 accessing L1-DCache..*/ -#define EXTMEM_DBUS1_NXTLVL_CNT 0xFFFFFFFF -#define EXTMEM_DBUS1_NXTLVL_CNT_M ((EXTMEM_DBUS1_NXTLVL_CNT_V)<<(EXTMEM_DBUS1_NXTLVL_CNT_S)) -#define EXTMEM_DBUS1_NXTLVL_CNT_V 0xFFFFFFFF -#define EXTMEM_DBUS1_NXTLVL_CNT_S 0 - -#define EXTMEM_ICACHE0_ACS_FAIL_ID_ATTR_REG (DR_REG_EXTMEM_BASE + 0x1FC) -/* EXTMEM_ICACHE0_FAIL_ATTR : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: The register records the attribution of fail-access when cache0 accesses L1-ICac -he..*/ -#define EXTMEM_ICACHE0_FAIL_ATTR 0x0000FFFF -#define EXTMEM_ICACHE0_FAIL_ATTR_M ((EXTMEM_ICACHE0_FAIL_ATTR_V)<<(EXTMEM_ICACHE0_FAIL_ATTR_S)) -#define EXTMEM_ICACHE0_FAIL_ATTR_V 0xFFFF -#define EXTMEM_ICACHE0_FAIL_ATTR_S 16 -/* EXTMEM_ICACHE0_FAIL_ID : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: The register records the ID of fail-access when cache0 accesses L1-ICache..*/ -#define EXTMEM_ICACHE0_FAIL_ID 0x0000FFFF -#define EXTMEM_ICACHE0_FAIL_ID_M ((EXTMEM_ICACHE0_FAIL_ID_V)<<(EXTMEM_ICACHE0_FAIL_ID_S)) -#define EXTMEM_ICACHE0_FAIL_ID_V 0xFFFF -#define EXTMEM_ICACHE0_FAIL_ID_S 0 - -#define EXTMEM_ICACHE0_ACS_FAIL_ADDR_REG (DR_REG_EXTMEM_BASE + 0x200) -/* EXTMEM_ICACHE0_FAIL_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the address of fail-access when cache0 accesses L1-ICache..*/ -#define EXTMEM_ICACHE0_FAIL_ADDR 0xFFFFFFFF -#define EXTMEM_ICACHE0_FAIL_ADDR_M ((EXTMEM_ICACHE0_FAIL_ADDR_V)<<(EXTMEM_ICACHE0_FAIL_ADDR_S)) -#define EXTMEM_ICACHE0_FAIL_ADDR_V 0xFFFFFFFF -#define EXTMEM_ICACHE0_FAIL_ADDR_S 0 - -#define EXTMEM_ICACHE1_ACS_FAIL_ID_ATTR_REG (DR_REG_EXTMEM_BASE + 0x204) -/* EXTMEM_ICACHE1_FAIL_ATTR : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: The register records the attribution of fail-access when cache1 accesses L1-ICac -he..*/ -#define EXTMEM_ICACHE1_FAIL_ATTR 0x0000FFFF -#define EXTMEM_ICACHE1_FAIL_ATTR_M ((EXTMEM_ICACHE1_FAIL_ATTR_V)<<(EXTMEM_ICACHE1_FAIL_ATTR_S)) -#define EXTMEM_ICACHE1_FAIL_ATTR_V 0xFFFF -#define EXTMEM_ICACHE1_FAIL_ATTR_S 16 -/* EXTMEM_ICACHE1_FAIL_ID : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: The register records the ID of fail-access when cache1 accesses L1-ICache..*/ -#define EXTMEM_ICACHE1_FAIL_ID 0x0000FFFF -#define EXTMEM_ICACHE1_FAIL_ID_M ((EXTMEM_ICACHE1_FAIL_ID_V)<<(EXTMEM_ICACHE1_FAIL_ID_S)) -#define EXTMEM_ICACHE1_FAIL_ID_V 0xFFFF -#define EXTMEM_ICACHE1_FAIL_ID_S 0 - -#define EXTMEM_ICACHE1_ACS_FAIL_ADDR_REG (DR_REG_EXTMEM_BASE + 0x208) -/* EXTMEM_ICACHE1_FAIL_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the address of fail-access when cache1 accesses L1-ICache..*/ -#define EXTMEM_ICACHE1_FAIL_ADDR 0xFFFFFFFF -#define EXTMEM_ICACHE1_FAIL_ADDR_M ((EXTMEM_ICACHE1_FAIL_ADDR_V)<<(EXTMEM_ICACHE1_FAIL_ADDR_S)) -#define EXTMEM_ICACHE1_FAIL_ADDR_V 0xFFFFFFFF -#define EXTMEM_ICACHE1_FAIL_ADDR_S 0 - -#define EXTMEM_DCACHE_ACS_FAIL_ID_ATTR_REG (DR_REG_EXTMEM_BASE + 0x21C) -/* EXTMEM_DCACHE_FAIL_ATTR : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: The register records the attribution of fail-access when cache accesses L1-DCach -e..*/ -#define EXTMEM_DCACHE_FAIL_ATTR 0x0000FFFF -#define EXTMEM_DCACHE_FAIL_ATTR_M ((EXTMEM_DCACHE_FAIL_ATTR_V)<<(EXTMEM_DCACHE_FAIL_ATTR_S)) -#define EXTMEM_DCACHE_FAIL_ATTR_V 0xFFFF -#define EXTMEM_DCACHE_FAIL_ATTR_S 16 -/* EXTMEM_DCACHE_FAIL_ID : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: The register records the ID of fail-access when cache accesses L1-DCache..*/ -#define EXTMEM_DCACHE_FAIL_ID 0x0000FFFF -#define EXTMEM_DCACHE_FAIL_ID_M ((EXTMEM_DCACHE_FAIL_ID_V)<<(EXTMEM_DCACHE_FAIL_ID_S)) -#define EXTMEM_DCACHE_FAIL_ID_V 0xFFFF -#define EXTMEM_DCACHE_FAIL_ID_S 0 - -#define EXTMEM_DCACHE_ACS_FAIL_ADDR_REG (DR_REG_EXTMEM_BASE + 0x220) -/* EXTMEM_DCACHE_FAIL_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: The register records the address of fail-access when cache accesses L1-DCache..*/ -#define EXTMEM_DCACHE_FAIL_ADDR 0xFFFFFFFF -#define EXTMEM_DCACHE_FAIL_ADDR_M ((EXTMEM_DCACHE_FAIL_ADDR_V)<<(EXTMEM_DCACHE_FAIL_ADDR_S)) -#define EXTMEM_DCACHE_FAIL_ADDR_V 0xFFFFFFFF -#define EXTMEM_DCACHE_FAIL_ADDR_S 0 - -#define EXTMEM_CACHE_SYNC_PRELOAD_INT_ENA_REG (DR_REG_EXTMEM_BASE + 0x224) -/* EXTMEM_CACHE_SYNC_ERR_INT_ENA : R/W ;bitpos:[13] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_FAIL_ATTR 0x0000FFFF +#define EXTMEM_L1_CACHE_FAIL_ATTR_M ((EXTMEM_L1_CACHE_FAIL_ATTR_V)<<(EXTMEM_L1_CACHE_FAIL_ATTR_S)) +#define EXTMEM_L1_CACHE_FAIL_ATTR_V 0xFFFF +#define EXTMEM_L1_CACHE_FAIL_ATTR_S 16 +/* EXTMEM_L1_CACHE_FAIL_ID : RO ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: The register records the ID of fail-access when cache accesses L1-Cache..*/ +#define EXTMEM_L1_CACHE_FAIL_ID 0x0000FFFF +#define EXTMEM_L1_CACHE_FAIL_ID_M ((EXTMEM_L1_CACHE_FAIL_ID_V)<<(EXTMEM_L1_CACHE_FAIL_ID_S)) +#define EXTMEM_L1_CACHE_FAIL_ID_V 0xFFFF +#define EXTMEM_L1_CACHE_FAIL_ID_S 0 + +#define EXTMEM_L1_CACHE_ACS_FAIL_ADDR_REG (DR_REG_EXTMEM_BASE + 0x220) +/* EXTMEM_L1_CACHE_FAIL_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: The register records the address of fail-access when cache accesses L1-Cache..*/ +#define EXTMEM_L1_CACHE_FAIL_ADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_FAIL_ADDR_M ((EXTMEM_L1_CACHE_FAIL_ADDR_V)<<(EXTMEM_L1_CACHE_FAIL_ADDR_S)) +#define EXTMEM_L1_CACHE_FAIL_ADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_FAIL_ADDR_S 0 + +#define EXTMEM_L1_CACHE_SYNC_PRELOAD_INT_ENA_REG (DR_REG_EXTMEM_BASE + 0x224) +/* EXTMEM_L1_CACHE_SYNC_ERR_INT_ENA : R/W ;bitpos:[13] ;default: 1'b0 ; */ /*description: The bit is used to enable interrupt of Cache sync-operation error..*/ -#define EXTMEM_CACHE_SYNC_ERR_INT_ENA (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_ENA_M (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_ENA_V 0x1 -#define EXTMEM_CACHE_SYNC_ERR_INT_ENA_S 13 -/* EXTMEM_DCACHE_PLD_ERR_INT_ENA : R/W ;bitpos:[11] ;default: 1'b0 ; */ -/*description: The bit is used to enable interrupt of L1-DCache preload-operation error..*/ -#define EXTMEM_DCACHE_PLD_ERR_INT_ENA (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_ENA_M (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_ENA_V 0x1 -#define EXTMEM_DCACHE_PLD_ERR_INT_ENA_S 11 -/* EXTMEM_CACHE_SYNC_DONE_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ENA (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ENA_M (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ENA_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ENA_S 13 +/* EXTMEM_L1_CACHE_PLD_ERR_INT_ENA : R/W ;bitpos:[11] ;default: 1'b0 ; */ +/*description: The bit is used to enable interrupt of L1-Cache preload-operation error..*/ +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ENA (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ENA_M (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ENA_V 0x1 +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ENA_S 11 +/* EXTMEM_L1_CACHE_SYNC_DONE_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ; */ /*description: The bit is used to enable interrupt of Cache sync-operation done..*/ -#define EXTMEM_CACHE_SYNC_DONE_INT_ENA (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_ENA_M (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_ENA_V 0x1 -#define EXTMEM_CACHE_SYNC_DONE_INT_ENA_S 6 -/* EXTMEM_DCACHE_PLD_DONE_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The bit is used to enable interrupt of L1-DCache preload-operation. If preload o -peration is done, interrupt occurs..*/ -#define EXTMEM_DCACHE_PLD_DONE_INT_ENA (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_ENA_M (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_ENA_V 0x1 -#define EXTMEM_DCACHE_PLD_DONE_INT_ENA_S 4 - -#define EXTMEM_CACHE_SYNC_PRELOAD_INT_CLR_REG (DR_REG_EXTMEM_BASE + 0x228) -/* EXTMEM_CACHE_SYNC_ERR_INT_CLR : WT ;bitpos:[13] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ENA (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ENA_M (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ENA_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ENA_S 6 +/* EXTMEM_L1_CACHE_PLD_DONE_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: The bit is used to enable interrupt of L1-Cache preload-operation. If preload op +eration is done, interrupt occurs..*/ +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ENA (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ENA_M (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ENA_V 0x1 +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ENA_S 4 + +#define EXTMEM_L1_CACHE_SYNC_PRELOAD_INT_CLR_REG (DR_REG_EXTMEM_BASE + 0x228) +/* EXTMEM_L1_CACHE_SYNC_ERR_INT_CLR : WT ;bitpos:[13] ;default: 1'b0 ; */ /*description: The bit is used to clear interrupt of Cache sync-operation error..*/ -#define EXTMEM_CACHE_SYNC_ERR_INT_CLR (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_CLR_M (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_CLR_V 0x1 -#define EXTMEM_CACHE_SYNC_ERR_INT_CLR_S 13 -/* EXTMEM_DCACHE_PLD_ERR_INT_CLR : WT ;bitpos:[11] ;default: 1'b0 ; */ -/*description: The bit is used to clear interrupt of L1-DCache preload-operation error..*/ -#define EXTMEM_DCACHE_PLD_ERR_INT_CLR (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_CLR_M (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_CLR_V 0x1 -#define EXTMEM_DCACHE_PLD_ERR_INT_CLR_S 11 -/* EXTMEM_CACHE_SYNC_DONE_INT_CLR : WT ;bitpos:[6] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_CLR (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_CLR_M (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_CLR_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_CLR_S 13 +/* EXTMEM_L1_CACHE_PLD_ERR_INT_CLR : WT ;bitpos:[11] ;default: 1'b0 ; */ +/*description: The bit is used to clear interrupt of L1-Cache preload-operation error..*/ +#define EXTMEM_L1_CACHE_PLD_ERR_INT_CLR (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_CLR_M (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_CLR_V 0x1 +#define EXTMEM_L1_CACHE_PLD_ERR_INT_CLR_S 11 +/* EXTMEM_L1_CACHE_SYNC_DONE_INT_CLR : WT ;bitpos:[6] ;default: 1'b0 ; */ /*description: The bit is used to clear interrupt that occurs only when Cache sync-operation is done..*/ -#define EXTMEM_CACHE_SYNC_DONE_INT_CLR (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_CLR_M (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_CLR_V 0x1 -#define EXTMEM_CACHE_SYNC_DONE_INT_CLR_S 6 -/* EXTMEM_DCACHE_PLD_DONE_INT_CLR : WT ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The bit is used to clear interrupt that occurs only when L1-DCache preload-opera -tion is done..*/ -#define EXTMEM_DCACHE_PLD_DONE_INT_CLR (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_CLR_M (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_CLR_V 0x1 -#define EXTMEM_DCACHE_PLD_DONE_INT_CLR_S 4 - -#define EXTMEM_CACHE_SYNC_PRELOAD_INT_RAW_REG (DR_REG_EXTMEM_BASE + 0x22C) -/* EXTMEM_CACHE_SYNC_ERR_INT_RAW : R/WTC/SS ;bitpos:[13] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_CLR (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_CLR_M (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_CLR_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_CLR_S 6 +/* EXTMEM_L1_CACHE_PLD_DONE_INT_CLR : WT ;bitpos:[4] ;default: 1'b0 ; */ +/*description: The bit is used to clear interrupt that occurs only when L1-Cache preload-operat +ion is done..*/ +#define EXTMEM_L1_CACHE_PLD_DONE_INT_CLR (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_CLR_M (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_CLR_V 0x1 +#define EXTMEM_L1_CACHE_PLD_DONE_INT_CLR_S 4 + +#define EXTMEM_L1_CACHE_SYNC_PRELOAD_INT_RAW_REG (DR_REG_EXTMEM_BASE + 0x22C) +/* EXTMEM_L1_CACHE_SYNC_ERR_INT_RAW : R/WTC/SS ;bitpos:[13] ;default: 1'b0 ; */ /*description: The raw bit of the interrupt that occurs only when Cache sync-operation error oc curs..*/ -#define EXTMEM_CACHE_SYNC_ERR_INT_RAW (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_RAW_M (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_RAW_V 0x1 -#define EXTMEM_CACHE_SYNC_ERR_INT_RAW_S 13 -/* EXTMEM_DCACHE_PLD_ERR_INT_RAW : R/WTC/SS ;bitpos:[11] ;default: 1'b0 ; */ -/*description: The raw bit of the interrupt that occurs only when L1-DCache preload-operation e -rror occurs..*/ -#define EXTMEM_DCACHE_PLD_ERR_INT_RAW (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_RAW_M (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_RAW_V 0x1 -#define EXTMEM_DCACHE_PLD_ERR_INT_RAW_S 11 -/* EXTMEM_CACHE_SYNC_DONE_INT_RAW : R/WTC/SS ;bitpos:[6] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_RAW (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_RAW_M (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_RAW_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_RAW_S 13 +/* EXTMEM_L1_CACHE_PLD_ERR_INT_RAW : R/WTC/SS ;bitpos:[11] ;default: 1'b0 ; */ +/*description: The raw bit of the interrupt that occurs only when L1-Cache preload-operation er +ror occurs..*/ +#define EXTMEM_L1_CACHE_PLD_ERR_INT_RAW (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_RAW_M (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_RAW_V 0x1 +#define EXTMEM_L1_CACHE_PLD_ERR_INT_RAW_S 11 +/* EXTMEM_L1_CACHE_SYNC_DONE_INT_RAW : R/WTC/SS ;bitpos:[6] ;default: 1'b0 ; */ /*description: The raw bit of the interrupt that occurs only when Cache sync-operation is done..*/ -#define EXTMEM_CACHE_SYNC_DONE_INT_RAW (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_RAW_M (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_RAW_V 0x1 -#define EXTMEM_CACHE_SYNC_DONE_INT_RAW_S 6 -/* EXTMEM_DCACHE_PLD_DONE_INT_RAW : R/WTC/SS ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The raw bit of the interrupt that occurs only when L1-DCache preload-operation i -s done..*/ -#define EXTMEM_DCACHE_PLD_DONE_INT_RAW (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_RAW_M (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_RAW_V 0x1 -#define EXTMEM_DCACHE_PLD_DONE_INT_RAW_S 4 - -#define EXTMEM_CACHE_SYNC_PRELOAD_INT_ST_REG (DR_REG_EXTMEM_BASE + 0x230) -/* EXTMEM_CACHE_SYNC_ERR_INT_ST : RO ;bitpos:[13] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_RAW (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_RAW_M (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_RAW_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_RAW_S 6 +/* EXTMEM_L1_CACHE_PLD_DONE_INT_RAW : R/WTC/SS ;bitpos:[4] ;default: 1'b0 ; */ +/*description: The raw bit of the interrupt that occurs only when L1-Cache preload-operation is + done..*/ +#define EXTMEM_L1_CACHE_PLD_DONE_INT_RAW (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_RAW_M (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_RAW_V 0x1 +#define EXTMEM_L1_CACHE_PLD_DONE_INT_RAW_S 4 + +#define EXTMEM_L1_CACHE_SYNC_PRELOAD_INT_ST_REG (DR_REG_EXTMEM_BASE + 0x230) +/* EXTMEM_L1_CACHE_SYNC_ERR_INT_ST : RO ;bitpos:[13] ;default: 1'b0 ; */ /*description: The bit indicates the status of the interrupt of Cache sync-operation error..*/ -#define EXTMEM_CACHE_SYNC_ERR_INT_ST (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_ST_M (BIT(13)) -#define EXTMEM_CACHE_SYNC_ERR_INT_ST_V 0x1 -#define EXTMEM_CACHE_SYNC_ERR_INT_ST_S 13 -/* EXTMEM_DCACHE_PLD_ERR_INT_ST : RO ;bitpos:[11] ;default: 1'b0 ; */ -/*description: The bit indicates the status of the interrupt of L1-DCache preload-operation err -or..*/ -#define EXTMEM_DCACHE_PLD_ERR_INT_ST (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_ST_M (BIT(11)) -#define EXTMEM_DCACHE_PLD_ERR_INT_ST_V 0x1 -#define EXTMEM_DCACHE_PLD_ERR_INT_ST_S 11 -/* EXTMEM_CACHE_SYNC_DONE_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ; */ +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ST (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ST_M (BIT(13)) +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ST_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_ERR_INT_ST_S 13 +/* EXTMEM_L1_CACHE_PLD_ERR_INT_ST : RO ;bitpos:[11] ;default: 1'b0 ; */ +/*description: The bit indicates the status of the interrupt of L1-Cache preload-operation erro +r..*/ +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ST (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ST_M (BIT(11)) +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ST_V 0x1 +#define EXTMEM_L1_CACHE_PLD_ERR_INT_ST_S 11 +/* EXTMEM_L1_CACHE_SYNC_DONE_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ; */ /*description: The bit indicates the status of the interrupt that occurs only when Cache sync-o peration is done..*/ -#define EXTMEM_CACHE_SYNC_DONE_INT_ST (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_ST_M (BIT(6)) -#define EXTMEM_CACHE_SYNC_DONE_INT_ST_V 0x1 -#define EXTMEM_CACHE_SYNC_DONE_INT_ST_S 6 -/* EXTMEM_DCACHE_PLD_DONE_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The bit indicates the status of the interrupt that occurs only when L1-DCache pr -eload-operation is done..*/ -#define EXTMEM_DCACHE_PLD_DONE_INT_ST (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_ST_M (BIT(4)) -#define EXTMEM_DCACHE_PLD_DONE_INT_ST_V 0x1 -#define EXTMEM_DCACHE_PLD_DONE_INT_ST_S 4 - -#define EXTMEM_CACHE_SYNC_PRELOAD_EXCEPTION_REG (DR_REG_EXTMEM_BASE + 0x234) -/* EXTMEM_CACHE_SYNC_ERR_CODE : RO ;bitpos:[13:12] ;default: 2'h0 ; */ +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ST (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ST_M (BIT(6)) +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ST_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_DONE_INT_ST_S 6 +/* EXTMEM_L1_CACHE_PLD_DONE_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ +/*description: The bit indicates the status of the interrupt that occurs only when L1-Cache pre +load-operation is done..*/ +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ST (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ST_M (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ST_V 0x1 +#define EXTMEM_L1_CACHE_PLD_DONE_INT_ST_S 4 + +#define EXTMEM_L1_CACHE_SYNC_PRELOAD_EXCEPTION_REG (DR_REG_EXTMEM_BASE + 0x234) +/* EXTMEM_L1_CACHE_SYNC_ERR_CODE : RO ;bitpos:[13:12] ;default: 2'h0 ; */ /*description: The values 0-2 are available which means sync map, command conflict and size are error in Cache System..*/ -#define EXTMEM_CACHE_SYNC_ERR_CODE 0x00000003 -#define EXTMEM_CACHE_SYNC_ERR_CODE_M ((EXTMEM_CACHE_SYNC_ERR_CODE_V)<<(EXTMEM_CACHE_SYNC_ERR_CODE_S)) -#define EXTMEM_CACHE_SYNC_ERR_CODE_V 0x3 -#define EXTMEM_CACHE_SYNC_ERR_CODE_S 12 -/* EXTMEM_DCACHE_PLD_ERR_CODE : RO ;bitpos:[9:8] ;default: 2'h0 ; */ -/*description: The value 2 is Only available which means preload size is error in L1-DCache..*/ -#define EXTMEM_DCACHE_PLD_ERR_CODE 0x00000003 -#define EXTMEM_DCACHE_PLD_ERR_CODE_M ((EXTMEM_DCACHE_PLD_ERR_CODE_V)<<(EXTMEM_DCACHE_PLD_ERR_CODE_S)) -#define EXTMEM_DCACHE_PLD_ERR_CODE_V 0x3 -#define EXTMEM_DCACHE_PLD_ERR_CODE_S 8 - -#define EXTMEM_CACHE_SYNC_RST_CTRL_REG (DR_REG_EXTMEM_BASE + 0x238) -/* EXTMEM_DCACHE_SYNC_RST : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: set this bit to reset sync-logic inside L1-DCache. Recommend that this should on -ly be used to initialize sync-logic when some fatal error of sync-logic occurs..*/ -#define EXTMEM_DCACHE_SYNC_RST (BIT(4)) -#define EXTMEM_DCACHE_SYNC_RST_M (BIT(4)) -#define EXTMEM_DCACHE_SYNC_RST_V 0x1 -#define EXTMEM_DCACHE_SYNC_RST_S 4 - -#define EXTMEM_CACHE_PRELOAD_RST_CTRL_REG (DR_REG_EXTMEM_BASE + 0x23C) -/* EXTMEM_DCACHE_PLD_RST : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: set this bit to reset preload-logic inside L1-DCache. Recommend that this should - only be used to initialize preload-logic when some fatal error of preload-logic - occurs..*/ -#define EXTMEM_DCACHE_PLD_RST (BIT(4)) -#define EXTMEM_DCACHE_PLD_RST_M (BIT(4)) -#define EXTMEM_DCACHE_PLD_RST_V 0x1 -#define EXTMEM_DCACHE_PLD_RST_S 4 - -#define EXTMEM_CACHE_AUTOLOAD_BUF_CLR_CTRL_REG (DR_REG_EXTMEM_BASE + 0x240) -/* EXTMEM_DCACHE_ALD_BUF_CLR : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: set this bit to clear autoload-buffer inside L1-DCache. If this bit is active, a -utoload will not work in L1-DCache. This bit should not be active when autoload -works in L1-DCache..*/ -#define EXTMEM_DCACHE_ALD_BUF_CLR (BIT(4)) -#define EXTMEM_DCACHE_ALD_BUF_CLR_M (BIT(4)) -#define EXTMEM_DCACHE_ALD_BUF_CLR_V 0x1 -#define EXTMEM_DCACHE_ALD_BUF_CLR_S 4 - -#define EXTMEM_UNALLOCATE_BUFFER_CLEAR_REG (DR_REG_EXTMEM_BASE + 0x244) -/* EXTMEM_DCACHE_UNALLOC_CLR : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The bit is used to clear the unallocate request buffer of l1 dcache where the un -allocate request is responsed but not completed..*/ -#define EXTMEM_DCACHE_UNALLOC_CLR (BIT(4)) -#define EXTMEM_DCACHE_UNALLOC_CLR_M (BIT(4)) -#define EXTMEM_DCACHE_UNALLOC_CLR_V 0x1 -#define EXTMEM_DCACHE_UNALLOC_CLR_S 4 - -#define EXTMEM_CACHE_OBJECT_CTRL_REG (DR_REG_EXTMEM_BASE + 0x248) -/* EXTMEM_DCACHE_MEM_OBJECT : R/W ;bitpos:[10] ;default: 1'b0 ; */ -/*description: Set this bit to set L1-DCache data memory as object. This bit should be onehot w -ith the others fields inside this register..*/ -#define EXTMEM_DCACHE_MEM_OBJECT (BIT(10)) -#define EXTMEM_DCACHE_MEM_OBJECT_M (BIT(10)) -#define EXTMEM_DCACHE_MEM_OBJECT_V 0x1 -#define EXTMEM_DCACHE_MEM_OBJECT_S 10 -/* EXTMEM_DCACHE_TAG_OBJECT : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: Set this bit to set L1-DCache tag memory as object. This bit should be onehot wi +#define EXTMEM_L1_CACHE_SYNC_ERR_CODE 0x00000003 +#define EXTMEM_L1_CACHE_SYNC_ERR_CODE_M ((EXTMEM_L1_CACHE_SYNC_ERR_CODE_V)<<(EXTMEM_L1_CACHE_SYNC_ERR_CODE_S)) +#define EXTMEM_L1_CACHE_SYNC_ERR_CODE_V 0x3 +#define EXTMEM_L1_CACHE_SYNC_ERR_CODE_S 12 +/* EXTMEM_L1_CACHE_PLD_ERR_CODE : RO ;bitpos:[9:8] ;default: 2'h0 ; */ +/*description: The value 2 is Only available which means preload size is error in L1-Cache..*/ +#define EXTMEM_L1_CACHE_PLD_ERR_CODE 0x00000003 +#define EXTMEM_L1_CACHE_PLD_ERR_CODE_M ((EXTMEM_L1_CACHE_PLD_ERR_CODE_V)<<(EXTMEM_L1_CACHE_PLD_ERR_CODE_S)) +#define EXTMEM_L1_CACHE_PLD_ERR_CODE_V 0x3 +#define EXTMEM_L1_CACHE_PLD_ERR_CODE_S 8 + +#define EXTMEM_L1_CACHE_SYNC_RST_CTRL_REG (DR_REG_EXTMEM_BASE + 0x238) +/* EXTMEM_L1_CACHE_SYNC_RST : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: set this bit to reset sync-logic inside L1-Cache. Recommend that this should onl +y be used to initialize sync-logic when some fatal error of sync-logic occurs..*/ +#define EXTMEM_L1_CACHE_SYNC_RST (BIT(4)) +#define EXTMEM_L1_CACHE_SYNC_RST_M (BIT(4)) +#define EXTMEM_L1_CACHE_SYNC_RST_V 0x1 +#define EXTMEM_L1_CACHE_SYNC_RST_S 4 + +#define EXTMEM_L1_CACHE_PRELOAD_RST_CTRL_REG (DR_REG_EXTMEM_BASE + 0x23C) +/* EXTMEM_L1_CACHE_PLD_RST : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: set this bit to reset preload-logic inside L1-Cache. Recommend that this should +only be used to initialize preload-logic when some fatal error of preload-logic +occurs..*/ +#define EXTMEM_L1_CACHE_PLD_RST (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_RST_M (BIT(4)) +#define EXTMEM_L1_CACHE_PLD_RST_V 0x1 +#define EXTMEM_L1_CACHE_PLD_RST_S 4 + +#define EXTMEM_L1_CACHE_AUTOLOAD_BUF_CLR_CTRL_REG (DR_REG_EXTMEM_BASE + 0x240) +/* EXTMEM_L1_CACHE_ALD_BUF_CLR : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: set this bit to clear autoload-buffer inside L1-Cache. If this bit is active, au +toload will not work in L1-Cache. This bit should not be active when autoload wo +rks in L1-Cache..*/ +#define EXTMEM_L1_CACHE_ALD_BUF_CLR (BIT(4)) +#define EXTMEM_L1_CACHE_ALD_BUF_CLR_M (BIT(4)) +#define EXTMEM_L1_CACHE_ALD_BUF_CLR_V 0x1 +#define EXTMEM_L1_CACHE_ALD_BUF_CLR_S 4 + +#define EXTMEM_L1_UNALLOCATE_BUFFER_CLEAR_REG (DR_REG_EXTMEM_BASE + 0x244) +/* EXTMEM_L1_CACHE_UNALLOC_CLR : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: The bit is used to clear the unallocate request buffer of l1 cache where the una +llocate request is responsed but not completed..*/ +#define EXTMEM_L1_CACHE_UNALLOC_CLR (BIT(4)) +#define EXTMEM_L1_CACHE_UNALLOC_CLR_M (BIT(4)) +#define EXTMEM_L1_CACHE_UNALLOC_CLR_V 0x1 +#define EXTMEM_L1_CACHE_UNALLOC_CLR_S 4 + +#define EXTMEM_L1_CACHE_OBJECT_CTRL_REG (DR_REG_EXTMEM_BASE + 0x248) +/* EXTMEM_L1_CACHE_MEM_OBJECT : R/W ;bitpos:[10] ;default: 1'b0 ; */ +/*description: Set this bit to set L1-Cache data memory as object. This bit should be onehot wi th the others fields inside this register..*/ -#define EXTMEM_DCACHE_TAG_OBJECT (BIT(4)) -#define EXTMEM_DCACHE_TAG_OBJECT_M (BIT(4)) -#define EXTMEM_DCACHE_TAG_OBJECT_V 0x1 -#define EXTMEM_DCACHE_TAG_OBJECT_S 4 - -#define EXTMEM_CACHE_WAY_OBJECT_REG (DR_REG_EXTMEM_BASE + 0x24C) -/* EXTMEM_CACHE_WAY_OBJECT : R/W ;bitpos:[2:0] ;default: 3'h0 ; */ +#define EXTMEM_L1_CACHE_MEM_OBJECT (BIT(10)) +#define EXTMEM_L1_CACHE_MEM_OBJECT_M (BIT(10)) +#define EXTMEM_L1_CACHE_MEM_OBJECT_V 0x1 +#define EXTMEM_L1_CACHE_MEM_OBJECT_S 10 +/* EXTMEM_L1_CACHE_TAG_OBJECT : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: Set this bit to set L1-Cache tag memory as object. This bit should be onehot wit +h the others fields inside this register..*/ +#define EXTMEM_L1_CACHE_TAG_OBJECT (BIT(4)) +#define EXTMEM_L1_CACHE_TAG_OBJECT_M (BIT(4)) +#define EXTMEM_L1_CACHE_TAG_OBJECT_V 0x1 +#define EXTMEM_L1_CACHE_TAG_OBJECT_S 4 + +#define EXTMEM_L1_CACHE_WAY_OBJECT_REG (DR_REG_EXTMEM_BASE + 0x24C) +/* EXTMEM_L1_CACHE_WAY_OBJECT : R/W ;bitpos:[2:0] ;default: 3'h0 ; */ /*description: Set this bits to select which way of the tag-object will be accessed. 0: way0, 1 : way1, 2: way2, 3: way3, ?, 7: way7..*/ -#define EXTMEM_CACHE_WAY_OBJECT 0x00000007 -#define EXTMEM_CACHE_WAY_OBJECT_M ((EXTMEM_CACHE_WAY_OBJECT_V)<<(EXTMEM_CACHE_WAY_OBJECT_S)) -#define EXTMEM_CACHE_WAY_OBJECT_V 0x7 -#define EXTMEM_CACHE_WAY_OBJECT_S 0 +#define EXTMEM_L1_CACHE_WAY_OBJECT 0x00000007 +#define EXTMEM_L1_CACHE_WAY_OBJECT_M ((EXTMEM_L1_CACHE_WAY_OBJECT_V)<<(EXTMEM_L1_CACHE_WAY_OBJECT_S)) +#define EXTMEM_L1_CACHE_WAY_OBJECT_V 0x7 +#define EXTMEM_L1_CACHE_WAY_OBJECT_S 0 -#define EXTMEM_CACHE_VADDR_REG (DR_REG_EXTMEM_BASE + 0x250) -/* EXTMEM_CACHE_VADDR : R/W ;bitpos:[31:0] ;default: 32'h40000000 ; */ +#define EXTMEM_L1_CACHE_VADDR_REG (DR_REG_EXTMEM_BASE + 0x250) +/* EXTMEM_L1_CACHE_VADDR : R/W ;bitpos:[31:0] ;default: 32'h40000000 ; */ /*description: Those bits stores the virtual address which will decide where inside the specifi ed tag memory object will be accessed..*/ -#define EXTMEM_CACHE_VADDR 0xFFFFFFFF -#define EXTMEM_CACHE_VADDR_M ((EXTMEM_CACHE_VADDR_V)<<(EXTMEM_CACHE_VADDR_S)) -#define EXTMEM_CACHE_VADDR_V 0xFFFFFFFF -#define EXTMEM_CACHE_VADDR_S 0 +#define EXTMEM_L1_CACHE_VADDR 0xFFFFFFFF +#define EXTMEM_L1_CACHE_VADDR_M ((EXTMEM_L1_CACHE_VADDR_V)<<(EXTMEM_L1_CACHE_VADDR_S)) +#define EXTMEM_L1_CACHE_VADDR_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_VADDR_S 0 -#define EXTMEM_CACHE_DEBUG_BUS_REG (DR_REG_EXTMEM_BASE + 0x254) -/* EXTMEM_CACHE_DEBUG_BUS : R/W ;bitpos:[31:0] ;default: 32'h254 ; */ +#define EXTMEM_L1_CACHE_DEBUG_BUS_REG (DR_REG_EXTMEM_BASE + 0x254) +/* EXTMEM_L1_CACHE_DEBUG_BUS : R/W ;bitpos:[31:0] ;default: 32'h254 ; */ /*description: This is a constant place where we can write data to or read data from the tag/da ta memory on the specified cache..*/ -#define EXTMEM_CACHE_DEBUG_BUS 0xFFFFFFFF -#define EXTMEM_CACHE_DEBUG_BUS_M ((EXTMEM_CACHE_DEBUG_BUS_V)<<(EXTMEM_CACHE_DEBUG_BUS_S)) -#define EXTMEM_CACHE_DEBUG_BUS_V 0xFFFFFFFF -#define EXTMEM_CACHE_DEBUG_BUS_S 0 +#define EXTMEM_L1_CACHE_DEBUG_BUS 0xFFFFFFFF +#define EXTMEM_L1_CACHE_DEBUG_BUS_M ((EXTMEM_L1_CACHE_DEBUG_BUS_V)<<(EXTMEM_L1_CACHE_DEBUG_BUS_S)) +#define EXTMEM_L1_CACHE_DEBUG_BUS_V 0xFFFFFFFF +#define EXTMEM_L1_CACHE_DEBUG_BUS_S 0 #define EXTMEM_DATE_REG (DR_REG_EXTMEM_BASE + 0x3FC) /* EXTMEM_DATE : R/W ;bitpos:[27:0] ;default: 28'h2202080 ; */ @@ -945,7 +866,6 @@ ta memory on the specified cache..*/ #define EXTMEM_DATE_V 0xFFFFFFF #define EXTMEM_DATE_S 0 - #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c6/include/soc/gdma_channel.h b/components/soc/esp32c6/include/soc/gdma_channel.h new file mode 100644 index 000000000000..785d9207852b --- /dev/null +++ b/components/soc/esp32c6/include/soc/gdma_channel.h @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +// The following macros have a format SOC_[periph][instance_id] to make it work with `GDMA_MAKE_TRIGGER` +#define SOC_GDMA_TRIG_PERIPH_M2M0 (-1) +#define SOC_GDMA_TRIG_PERIPH_SPI2 (0) +#define SOC_GDMA_TRIG_PERIPH_UHCI0 (2) +#define SOC_GDMA_TRIG_PERIPH_I2S0 (3) +#define SOC_GDMA_TRIG_PERIPH_AES0 (6) +#define SOC_GDMA_TRIG_PERIPH_SHA0 (7) +#define SOC_GDMA_TRIG_PERIPH_ADC0 (8) +#define SOC_GDMA_TRIG_PERIPH_PARLIO0 (9) diff --git a/components/soc/esp32c6/include/soc/gpio_ext_reg.h b/components/soc/esp32c6/include/soc/gpio_ext_reg.h index 7f6b4d6d01bb..6b7fb33f6fdf 100644 --- a/components/soc/esp32c6/include/soc/gpio_ext_reg.h +++ b/components/soc/esp32c6/include/soc/gpio_ext_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,58 +34,58 @@ extern "C" { * Duty Cycle Configure Register of SDM1 */ #define GPIO_SIGMADELTA1_REG (DR_REG_GPIO_EXT_BASE + 0x4) -/** GPIO_SD0_IN : R/W; bitpos: [7:0]; default: 0; +/** GPIO_SD1_IN : R/W; bitpos: [7:0]; default: 0; * This field is used to configure the duty cycle of sigma delta modulation output. */ -#define GPIO_SD0_IN 0x000000FFU -#define GPIO_SD0_IN_M (GPIO_SD0_IN_V << GPIO_SD0_IN_S) -#define GPIO_SD0_IN_V 0x000000FFU -#define GPIO_SD0_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +#define GPIO_SD1_IN 0x000000FFU +#define GPIO_SD1_IN_M (GPIO_SD1_IN_V << GPIO_SD1_IN_S) +#define GPIO_SD1_IN_V 0x000000FFU +#define GPIO_SD1_IN_S 0 +/** GPIO_SD1_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD1_PRESCALE 0x000000FFU +#define GPIO_SD1_PRESCALE_M (GPIO_SD1_PRESCALE_V << GPIO_SD1_PRESCALE_S) +#define GPIO_SD1_PRESCALE_V 0x000000FFU +#define GPIO_SD1_PRESCALE_S 8 /** GPIO_SIGMADELTA2_REG register * Duty Cycle Configure Register of SDM2 */ #define GPIO_SIGMADELTA2_REG (DR_REG_GPIO_EXT_BASE + 0x8) -/** GPIO_SD0_IN : R/W; bitpos: [7:0]; default: 0; +/** GPIO_SD2_IN : R/W; bitpos: [7:0]; default: 0; * This field is used to configure the duty cycle of sigma delta modulation output. */ -#define GPIO_SD0_IN 0x000000FFU -#define GPIO_SD0_IN_M (GPIO_SD0_IN_V << GPIO_SD0_IN_S) -#define GPIO_SD0_IN_V 0x000000FFU -#define GPIO_SD0_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +#define GPIO_SD2_IN 0x000000FFU +#define GPIO_SD2_IN_M (GPIO_SD2_IN_V << GPIO_SD2_IN_S) +#define GPIO_SD2_IN_V 0x000000FFU +#define GPIO_SD2_IN_S 0 +/** GPIO_SD2_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD2_PRESCALE 0x000000FFU +#define GPIO_SD2_PRESCALE_M (GPIO_SD2_PRESCALE_V << GPIO_SD2_PRESCALE_S) +#define GPIO_SD2_PRESCALE_V 0x000000FFU +#define GPIO_SD2_PRESCALE_S 8 /** GPIO_SIGMADELTA3_REG register * Duty Cycle Configure Register of SDM3 */ #define GPIO_SIGMADELTA3_REG (DR_REG_GPIO_EXT_BASE + 0xc) -/** GPIO_SD0_IN : R/W; bitpos: [7:0]; default: 0; +/** GPIO_SD3_IN : R/W; bitpos: [7:0]; default: 0; * This field is used to configure the duty cycle of sigma delta modulation output. */ -#define GPIO_SD0_IN 0x000000FFU -#define GPIO_SD0_IN_M (GPIO_SD0_IN_V << GPIO_SD0_IN_S) -#define GPIO_SD0_IN_V 0x000000FFU -#define GPIO_SD0_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +#define GPIO_SD3_IN 0x000000FFU +#define GPIO_SD3_IN_M (GPIO_SD3_IN_V << GPIO_SD3_IN_S) +#define GPIO_SD3_IN_V 0x000000FFU +#define GPIO_SD3_IN_S 0 +/** GPIO_SD3_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD3_PRESCALE 0x000000FFU +#define GPIO_SD3_PRESCALE_M (GPIO_SD3_PRESCALE_V << GPIO_SD3_PRESCALE_S) +#define GPIO_SD3_PRESCALE_V 0x000000FFU +#define GPIO_SD3_PRESCALE_S 8 /** GPIO_CLOCK_GATE_REG register * Clock Gating Configure Register diff --git a/components/soc/esp32c6/include/soc/gpio_ext_struct.h b/components/soc/esp32c6/include/soc/gpio_ext_struct.h index b06cd88027bf..1468d5ef2a18 100644 --- a/components/soc/esp32c6/include/soc/gpio_ext_struct.h +++ b/components/soc/esp32c6/include/soc/gpio_ext_struct.h @@ -70,22 +70,22 @@ typedef union { */ typedef union { struct { - /** filter_ch0_en : R/W; bitpos: [0]; default: 0; + /** filter_chn_en : R/W; bitpos: [0]; default: 0; * Glitch Filter channel enable bit. */ - uint32_t filter_ch0_en:1; - /** filter_ch0_input_io_num : R/W; bitpos: [6:1]; default: 0; + uint32_t filter_chn_en:1; + /** filter_chn_input_io_num : R/W; bitpos: [6:1]; default: 0; * Glitch Filter input io number. */ - uint32_t filter_ch0_input_io_num:6; - /** filter_ch0_window_thres : R/W; bitpos: [12:7]; default: 0; + uint32_t filter_chn_input_io_num:6; + /** filter_chn_window_thres : R/W; bitpos: [12:7]; default: 0; * Glitch Filter window threshold. */ - uint32_t filter_ch0_window_thres:6; - /** filter_ch0_window_width : R/W; bitpos: [18:13]; default: 0; + uint32_t filter_chn_window_thres:6; + /** filter_chn_window_width : R/W; bitpos: [18:13]; default: 0; * Glitch Filter window width. */ - uint32_t filter_ch0_window_width:6; + uint32_t filter_chn_window_width:6; uint32_t reserved_19:13; }; uint32_t val; @@ -155,314 +155,7 @@ typedef union { uint32_t reserved_28:4; }; uint32_t val; -} gpio_etm_task_p0_cfg_reg_t; - -/** Type of etm_task_p1_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio4_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio4_en:1; - /** etm_task_gpio4_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio4_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio5_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio5_en:1; - /** etm_task_gpio5_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio5_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio6_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio6_en:1; - /** etm_task_gpio6_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio6_sel:3; - uint32_t reserved_20:4; - /** etm_task_gpio7_en : R/W; bitpos: [24]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio7_en:1; - /** etm_task_gpio7_sel : R/W; bitpos: [27:25]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio7_sel:3; - uint32_t reserved_28:4; - }; - uint32_t val; -} gpio_etm_task_p1_cfg_reg_t; - -/** Type of etm_task_p2_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio8_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio8_en:1; - /** etm_task_gpio8_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio8_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio9_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio9_en:1; - /** etm_task_gpio9_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio9_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio10_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio10_en:1; - /** etm_task_gpio10_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio10_sel:3; - uint32_t reserved_20:4; - /** etm_task_gpio11_en : R/W; bitpos: [24]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio11_en:1; - /** etm_task_gpio11_sel : R/W; bitpos: [27:25]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio11_sel:3; - uint32_t reserved_28:4; - }; - uint32_t val; -} gpio_etm_task_p2_cfg_reg_t; - -/** Type of etm_task_p3_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio12_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio12_en:1; - /** etm_task_gpio12_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio12_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio13_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio13_en:1; - /** etm_task_gpio13_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio13_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio14_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio14_en:1; - /** etm_task_gpio14_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio14_sel:3; - uint32_t reserved_20:4; - /** etm_task_gpio15_en : R/W; bitpos: [24]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio15_en:1; - /** etm_task_gpio15_sel : R/W; bitpos: [27:25]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio15_sel:3; - uint32_t reserved_28:4; - }; - uint32_t val; -} gpio_etm_task_p3_cfg_reg_t; - -/** Type of etm_task_p4_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio16_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio16_en:1; - /** etm_task_gpio16_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio16_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio17_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio17_en:1; - /** etm_task_gpio17_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio17_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio18_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio18_en:1; - /** etm_task_gpio18_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio18_sel:3; - uint32_t reserved_20:4; - /** etm_task_gpio19_en : R/W; bitpos: [24]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio19_en:1; - /** etm_task_gpio19_sel : R/W; bitpos: [27:25]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio19_sel:3; - uint32_t reserved_28:4; - }; - uint32_t val; -} gpio_etm_task_p4_cfg_reg_t; - -/** Type of etm_task_p5_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio20_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio20_en:1; - /** etm_task_gpio20_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio20_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio21_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio21_en:1; - /** etm_task_gpio21_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio21_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio22_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio22_en:1; - /** etm_task_gpio22_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio22_sel:3; - uint32_t reserved_20:4; - /** etm_task_gpio23_en : R/W; bitpos: [24]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio23_en:1; - /** etm_task_gpio23_sel : R/W; bitpos: [27:25]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio23_sel:3; - uint32_t reserved_28:4; - }; - uint32_t val; -} gpio_etm_task_p5_cfg_reg_t; - -/** Type of etm_task_p6_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio24_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio24_en:1; - /** etm_task_gpio24_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio24_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio25_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio25_en:1; - /** etm_task_gpio25_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio25_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio26_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio26_en:1; - /** etm_task_gpio26_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio26_sel:3; - uint32_t reserved_20:4; - /** etm_task_gpio27_en : R/W; bitpos: [24]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio27_en:1; - /** etm_task_gpio27_sel : R/W; bitpos: [27:25]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio27_sel:3; - uint32_t reserved_28:4; - }; - uint32_t val; -} gpio_etm_task_p6_cfg_reg_t; - -/** Type of etm_task_p7_cfg register - * Etm Configure Register to decide which GPIO been chosen - */ -typedef union { - struct { - /** etm_task_gpio28_en : R/W; bitpos: [0]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio28_en:1; - /** etm_task_gpio28_sel : R/W; bitpos: [3:1]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio28_sel:3; - uint32_t reserved_4:4; - /** etm_task_gpio29_en : R/W; bitpos: [8]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio29_en:1; - /** etm_task_gpio29_sel : R/W; bitpos: [11:9]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio29_sel:3; - uint32_t reserved_12:4; - /** etm_task_gpio30_en : R/W; bitpos: [16]; default: 0; - * Enable bit of GPIO response etm task. - */ - uint32_t etm_task_gpio30_en:1; - /** etm_task_gpio30_sel : R/W; bitpos: [19:17]; default: 0; - * GPIO choose a etm task channel. - */ - uint32_t etm_task_gpio30_sel:3; - uint32_t reserved_20:12; - }; - uint32_t val; -} gpio_etm_task_p7_cfg_reg_t; - +} gpio_etm_task_pn_cfg_reg_t; /** Group: Version Register */ /** Type of version register @@ -491,17 +184,10 @@ typedef struct { volatile gpio_glitch_filter_chn_reg_t glitch_filter_chn[8]; } gpio_glitch_filter_dev_t; -typedef struct { +typedef struct gpio_etm_dev_t { volatile gpio_etm_event_chn_cfg_reg_t event_chn_cfg[8]; uint32_t reserved_080[8]; - volatile gpio_etm_task_p0_cfg_reg_t etm_task_p0_cfg; - volatile gpio_etm_task_p1_cfg_reg_t etm_task_p1_cfg; - volatile gpio_etm_task_p2_cfg_reg_t etm_task_p2_cfg; - volatile gpio_etm_task_p3_cfg_reg_t etm_task_p3_cfg; - volatile gpio_etm_task_p4_cfg_reg_t etm_task_p4_cfg; - volatile gpio_etm_task_p5_cfg_reg_t etm_task_p5_cfg; - volatile gpio_etm_task_p6_cfg_reg_t etm_task_p6_cfg; - volatile gpio_etm_task_p7_cfg_reg_t etm_task_p7_cfg; + volatile gpio_etm_task_pn_cfg_reg_t etm_task_pn_cfg[8]; } gpio_etm_dev_t; typedef struct gpio_ext_dev_t { @@ -517,6 +203,7 @@ typedef struct gpio_ext_dev_t { extern gpio_sd_dev_t SDM; extern gpio_glitch_filter_dev_t GLITCH_FILTER; extern gpio_etm_dev_t GPIO_ETM; +extern gpio_ext_dev_t GPIO_EXT; #ifndef __cplusplus _Static_assert(sizeof(gpio_ext_dev_t) == 0x100, "Invalid size of gpio_ext_dev_t structure"); diff --git a/components/soc/esp32c6/include/soc/gpio_pins.h b/components/soc/esp32c6/include/soc/gpio_pins.h new file mode 100644 index 000000000000..78af5a05dc4d --- /dev/null +++ b/components/soc/esp32c6/include/soc/gpio_pins.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIO_MATRIX_CONST_ONE_INPUT (0x38) +#define GPIO_MATRIX_CONST_ZERO_INPUT (0x3C) + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/gpio_struct.h b/components/soc/esp32c6/include/soc/gpio_struct.h index ed3e224ca91a..68a44048dc46 100644 --- a/components/soc/esp32c6/include/soc/gpio_struct.h +++ b/components/soc/esp32c6/include/soc/gpio_struct.h @@ -589,8 +589,8 @@ typedef struct gpio_dev_t { uint32_t reserved_100[19]; volatile gpio_status_next_reg_t status_next; volatile gpio_status_next1_reg_t status_next1; - volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[125]; - uint32_t reserved_348[131]; + volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[128]; + uint32_t reserved_34b[128]; volatile gpio_func_out_sel_cfg_reg_t func_out_sel_cfg[35]; uint32_t reserved_5e0[19]; volatile gpio_clock_gate_reg_t clock_gate; diff --git a/components/soc/esp32c6/include/soc/host_struct.h b/components/soc/esp32c6/include/soc/host_struct.h index 0462b842769e..275e30e72f67 100644 --- a/components/soc/esp32c6/include/soc/host_struct.h +++ b/components/soc/esp32c6/include/soc/host_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -2654,7 +2654,7 @@ typedef union { } slchost_inf_st_reg_t; -typedef struct slchost_dev_t { +typedef struct host_dev_t { uint32_t reserved_000[4]; volatile slchost_func2_0_reg_t func2_0; volatile slchost_func2_1_reg_t func2_1; @@ -2725,12 +2725,12 @@ typedef struct slchost_dev_t { uint32_t reserved_180[28]; volatile slchost_conf_reg_t conf; volatile slchost_inf_st_reg_t inf_st; -} slchost_dev_t; +} host_dev_t; -extern slchost_dev_t HOST; +extern host_dev_t HOST; #ifndef __cplusplus -_Static_assert(sizeof(slchost_dev_t) == 0x1f8, "Invalid size of slchost_dev_t structure"); +_Static_assert(sizeof(host_dev_t) == 0x1f8, "Invalid size of host_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32c6/include/soc/hwcrypto_reg.h b/components/soc/esp32c6/include/soc/hwcrypto_reg.h new file mode 100644 index 000000000000..71a680e4ce2b --- /dev/null +++ b/components/soc/esp32c6/include/soc/hwcrypto_reg.h @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __HWCRYPTO_REG_H__ +#define __HWCRYPTO_REG_H__ + +#include "soc/aes_reg.h" +#include "soc/ds_reg.h" +#include "soc/hmac_reg.h" +#include "soc/rsa_reg.h" +#include "soc/sha_reg.h" + +#endif diff --git a/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h b/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h new file mode 100644 index 000000000000..d0f6d4c84336 --- /dev/null +++ b/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h @@ -0,0 +1,220 @@ +/** + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2C_ANA_MST_I2C0_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x0) +/* I2C_MST_I2C0_BUSY : RO ;bitpos:[25] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_BUSY (BIT(25)) +#define I2C_ANA_MST_I2C0_BUSY_M (BIT(25)) +#define I2C_ANA_MST_I2C0_BUSY_V 0x1 +#define I2C_ANA_MST_I2C0_BUSY_S 25 +/* I2C_MST_I2C0_CTRL : R/W ;bitpos:[24:0] ;default: 25'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_CTRL 0x01FFFFFF +#define I2C_ANA_MST_I2C0_CTRL_M ((I2C_MST_I2C0_CTRL_V)<<(I2C_MST_I2C0_CTRL_S)) +#define I2C_ANA_MST_I2C0_CTRL_V 0x1FFFFFF +#define I2C_ANA_MST_I2C0_CTRL_S 0 + +#define I2C_ANA_MST_I2C1_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x4) +/* I2C_MST_I2C1_BUSY : RO ;bitpos:[25] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_BUSY (BIT(25)) +#define I2C_ANA_MST_I2C1_BUSY_M (BIT(25)) +#define I2C_ANA_MST_I2C1_BUSY_V 0x1 +#define I2C_ANA_MST_I2C1_BUSY_S 25 +/* I2C_MST_I2C1_CTRL : R/W ;bitpos:[24:0] ;default: 25'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_CTRL 0x01FFFFFF +#define I2C_ANA_MST_I2C1_CTRL_M ((I2C_MST_I2C1_CTRL_V)<<(I2C_MST_I2C1_CTRL_S)) +#define I2C_ANA_MST_I2C1_CTRL_V 0x1FFFFFF +#define I2C_ANA_MST_I2C1_CTRL_S 0 + +#define I2C_ANA_MST_I2C0_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x8) +/* I2C_MST_I2C0_STATUS : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_STATUS 0x000000FF +#define I2C_ANA_MST_I2C0_STATUS_M ((I2C_MST_I2C0_STATUS_V)<<(I2C_MST_I2C0_STATUS_S)) +#define I2C_ANA_MST_I2C0_STATUS_V 0xFF +#define I2C_ANA_MST_I2C0_STATUS_S 24 +/* I2C_MST_I2C0_CONF : R/W ;bitpos:[23:0] ;default: 24'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_CONF 0x00FFFFFF +#define I2C_ANA_MST_I2C0_CONF_M ((I2C_MST_I2C0_CONF_V)<<(I2C_MST_I2C0_CONF_S)) +#define I2C_ANA_MST_I2C0_CONF_V 0xFFFFFF +#define I2C_ANA_MST_I2C0_CONF_S 0 + +#define I2C_ANA_MST_I2C1_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0xC) +/* I2C_MST_I2C1_STATUS : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_STATUS 0x000000FF +#define I2C_ANA_MST_I2C1_STATUS_M ((I2C_MST_I2C1_STATUS_V)<<(I2C_MST_I2C1_STATUS_S)) +#define I2C_ANA_MST_I2C1_STATUS_V 0xFF +#define I2C_ANA_MST_I2C1_STATUS_S 24 +/* I2C_MST_I2C1_CONF : R/W ;bitpos:[23:0] ;default: 24'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_CONF 0x00FFFFFF +#define I2C_ANA_MST_I2C1_CONF_M ((I2C_MST_I2C1_CONF_V)<<(I2C_MST_I2C1_CONF_S)) +#define I2C_ANA_MST_I2C1_CONF_V 0xFFFFFF +#define I2C_ANA_MST_I2C1_CONF_S 0 + +#define I2C_ANA_MST_I2C_BURST_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x10) +/* I2C_MST_BURST_CTRL : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_BURST_CTRL 0xFFFFFFFF +#define I2C_ANA_MST_BURST_CTRL_M ((I2C_MST_BURST_CTRL_V)<<(I2C_MST_BURST_CTRL_S)) +#define I2C_ANA_MST_BURST_CTRL_V 0xFFFFFFFF +#define I2C_ANA_MST_BURST_CTRL_S 0 + +#define I2C_ANA_MST_I2C_BURST_STATUS_REG (DR_REG_I2C_ANA_MST_BASE + 0x14) +/* I2C_MST_BURST_TIMEOUT_CNT : R/W ;bitpos:[31:20] ;default: 12'h400 ; */ +/*description: .*/ +#define I2C_ANA_MST_BURST_TIMEOUT_CNT 0x00000FFF +#define I2C_ANA_MST_BURST_TIMEOUT_CNT_M ((I2C_MST_BURST_TIMEOUT_CNT_V)<<(I2C_MST_BURST_TIMEOUT_CNT_S)) +#define I2C_ANA_MST_BURST_TIMEOUT_CNT_V 0xFFF +#define I2C_ANA_MST_BURST_TIMEOUT_CNT_S 20 +/* I2C_MST1_BURST_ERR_FLAG : RO ;bitpos:[2] ;default: 1'b0 ; */ +/*description: .*/ +#define I2C_ANA_MST1_BURST_ERR_FLAG (BIT(2)) +#define I2C_ANA_MST1_BURST_ERR_FLAG_M (BIT(2)) +#define I2C_ANA_MST1_BURST_ERR_FLAG_V 0x1 +#define I2C_ANA_MST1_BURST_ERR_FLAG_S 2 +/* I2C_MST0_BURST_ERR_FLAG : RO ;bitpos:[1] ;default: 1'b0 ; */ +/*description: .*/ +#define I2C_ANA_MST0_BURST_ERR_FLAG (BIT(1)) +#define I2C_ANA_MST0_BURST_ERR_FLAG_M (BIT(1)) +#define I2C_ANA_MST0_BURST_ERR_FLAG_V 0x1 +#define I2C_ANA_MST0_BURST_ERR_FLAG_S 1 +/* I2C_MST_BURST_DONE : RO ;bitpos:[0] ;default: 1'b0 ; */ +/*description: .*/ +#define I2C_ANA_MST_BURST_DONE (BIT(0)) +#define I2C_ANA_MST_BURST_DONE_M (BIT(0)) +#define I2C_ANA_MST_BURST_DONE_V 0x1 +#define I2C_ANA_MST_BURST_DONE_S 0 + +#define I2C_ANA_MST_ANA_CONF0_REG (DR_REG_I2C_ANA_MST_BASE + 0x18) +/* I2C_ANA_MST_STATUS0 : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_STATUS0 0x000000FF +#define I2C_ANA_MST_ANA_STATUS0_M ((I2C_ANA_MST_STATUS0_V)<<(I2C_ANA_MST_STATUS0_S)) +#define I2C_ANA_MST_ANA_STATUS0_V 0xFF +#define I2C_ANA_MST_ANA_STATUS0_S 24 +/* I2C_ANA_MST_ANA_CONF0 : R/W ;bitpos:[23:0] ;default: 24'h00_e408 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_CONF0 0x00FFFFFF +#define I2C_ANA_MST_ANA_CONF0_M ((I2C_ANA_MST_ANA_CONF0_V)<<(I2C_ANA_MST_ANA_CONF0_S)) +#define I2C_ANA_MST_ANA_CONF0_V 0xFFFFFF +#define I2C_ANA_MST_ANA_CONF0_S 0 + +#define I2C_ANA_MST_ANA_CONF1_REG (DR_REG_I2C_ANA_MST_BASE + 0x1C) +/* I2C_ANA_MST_STATUS1 : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_STATUS1 0x000000FF +#define I2C_ANA_MST_ANA_STATUS1_M ((I2C_ANA_MST_STATUS1_V)<<(I2C_ANA_MST_STATUS1_S)) +#define I2C_ANA_MST_ANA_STATUS1_V 0xFF +#define I2C_ANA_MST_ANA_STATUS1_S 24 +/* I2C_MST_AANA_NA_CONF1 : R/W ;bitpos:[23:0] ;default: 24'h00_002d ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_CONF1 0x00FFFFFF +#define I2C_ANA_MST_ANA_CONF1_M ((I2C_ANA_MST_ANA_CONF1_V)<<(I2C_ANA_MST_ANA_CONF1_S)) +#define I2C_ANA_MST_ANA_CONF1_V 0xFFFFFF +#define I2C_ANA_MST_ANA_CONF1_S 0 + +#define I2C_ANA_MST_ANA_CONF2_REG (DR_REG_I2C_ANA_MST_BASE + 0x20) +/* I2C_ANA_MST_STATUS2 : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_STATUS2 0x000000FF +#define I2C_ANA_MST_ANA_STATUS2_M ((I2C_ANA_MST_STATUS2_V)<<(I2C_ANA_MST_STATUS2_S)) +#define I2C_ANA_MST_ANA_STATUS2_V 0xFF +#define I2C_ANA_MST_ANA_STATUS2_S 24 +/* I2C_ANA_MST_ANA_CONF2 : R/W ;bitpos:[23:0] ;default: 24'h00_0004 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_CONF2 0x00FFFFFF +#define I2C_ANA_MST_ANA_CONF2_M ((I2C_ANA_MST_ANA_CONF2_V)<<(I2C_ANA_MST_ANA_CONF2_S)) +#define I2C_ANA_MST_ANA_CONF2_V 0xFFFFFF +#define I2C_ANA_MST_ANA_CONF2_S 0 + +#define I2C_ANA_MST_I2C0_CTRL1_REG (DR_REG_I2C_ANA_MST_BASE + 0x24) +/* I2C_MST_I2C0_SDA_SIDE_GUARD : R/W ;bitpos:[10:6] ;default: 5'h1 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD 0x0000001F +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_M ((I2C_MST_I2C0_SDA_SIDE_GUARD_V)<<(I2C_MST_I2C0_SDA_SIDE_GUARD_S)) +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_V 0x1F +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_S 6 +/* I2C_MST_I2C0_SCL_PULSE_DUR : R/W ;bitpos:[5:0] ;default: 6'h2 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR 0x0000003F +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_M ((I2C_MST_I2C0_SCL_PULSE_DUR_V)<<(I2C_MST_I2C0_SCL_PULSE_DUR_S)) +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_V 0x3F +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_S 0 + +#define I2C_ANA_MST_I2C1_CTRL1_REG (DR_REG_I2C_ANA_MST_BASE + 0x28) +/* I2C_MST_I2C1_SDA_SIDE_GUARD : R/W ;bitpos:[10:6] ;default: 5'h1 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD 0x0000001F +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_M ((I2C_MST_I2C1_SDA_SIDE_GUARD_V)<<(I2C_MST_I2C1_SDA_SIDE_GUARD_S)) +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_V 0x1F +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_S 6 +/* I2C_MST_I2C1_SCL_PULSE_DUR : R/W ;bitpos:[5:0] ;default: 6'h2 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR 0x0000003F +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_M ((I2C_MST_I2C1_SCL_PULSE_DUR_V)<<(I2C_MST_I2C1_SCL_PULSE_DUR_S)) +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_V 0x3F +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_S 0 + +#define I2C_ANA_MST_HW_I2C_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x2C) +/* I2C_MST_ARBITER_DIS : R/W ;bitpos:[11] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ARBITER_DIS (BIT(11)) +#define I2C_ANA_MST_ARBITER_DIS_M (BIT(11)) +#define I2C_ANA_MST_ARBITER_DIS_V 0x1 +#define I2C_ANA_MST_ARBITER_DIS_S 11 +/* I2C_MST_HW_I2C_SDA_SIDE_GUARD : R/W ;bitpos:[10:6] ;default: 5'h1 ; */ +/*description: .*/ +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD 0x0000001F +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_M ((I2C_MST_HW_I2C_SDA_SIDE_GUARD_V)<<(I2C_MST_HW_I2C_SDA_SIDE_GUARD_S)) +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_V 0x1F +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_S 6 +/* I2C_MST_HW_I2C_SCL_PULSE_DUR : R/W ;bitpos:[5:0] ;default: 6'h2 ; */ +/*description: .*/ +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR 0x0000003F +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_M ((I2C_MST_HW_I2C_SCL_PULSE_DUR_V)<<(I2C_MST_HW_I2C_SCL_PULSE_DUR_S)) +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_V 0x3F +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_S 0 + +#define I2C_ANA_MST_NOUSE_REG (DR_REG_I2C_ANA_MST_BASE + 0x30) +/* I2C_MST_NOUSE : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_NOUSE 0xFFFFFFFF +#define I2C_ANA_MST_NOUSE_M ((I2C_MST_NOUSE_V)<<(I2C_MST_NOUSE_S)) +#define I2C_ANA_MST_NOUSE_V 0xFFFFFFFF +#define I2C_ANA_MST_NOUSE_S 0 + +#define I2C_ANA_MST_DATE_REG (DR_REG_I2C_ANA_MST_BASE + 0x34) +/* I2C_MST_CLK_EN : R/W ;bitpos:[28] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_CLK_EN (BIT(28)) +#define I2C_ANA_MST_CLK_EN_M (BIT(28)) +#define I2C_ANA_MST_CLK_EN_V 0x1 +#define I2C_ANA_MST_CLK_EN_S 28 +/* I2C_MST_DATE : R/W ;bitpos:[27:0] ;default: 28'h2201300 ; */ +/*description: .*/ +#define I2C_ANA_MST_DATE 0x0FFFFFFF +#define I2C_ANA_MST_DATE_M ((I2C_MST_DATE_V)<<(I2C_MST_DATE_S)) +#define I2C_ANA_MST_DATE_V 0xFFFFFFF +#define I2C_ANA_MST_DATE_S 0 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/i2c_struct.h b/components/soc/esp32c6/include/soc/i2c_struct.h index e1a03349f4ec..e6617dcf5e46 100644 --- a/components/soc/esp32c6/include/soc/i2c_struct.h +++ b/components/soc/esp32c6/include/soc/i2c_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1013,6 +1013,7 @@ typedef struct i2c_dev_t { } i2c_dev_t; extern i2c_dev_t I2C0; +extern i2c_dev_t LP_I2C; #ifndef __cplusplus _Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); diff --git a/components/soc/esp32c6/include/soc/i2s_struct.h b/components/soc/esp32c6/include/soc/i2s_struct.h index 6938b7540767..e2e4de298cf8 100644 --- a/components/soc/esp32c6/include/soc/i2s_struct.h +++ b/components/soc/esp32c6/include/soc/i2s_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -255,7 +255,7 @@ typedef union { */ uint32_t rx_clk_active:1; /** rx_clk_sel : R/W; bitpos: [28:27]; default: 0; - * Select I2S Rx module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in. + * Select I2S Rx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in. */ uint32_t rx_clk_sel:2; /** mclk_sel : R/W; bitpos: [29]; default: 0; @@ -448,7 +448,7 @@ typedef union { uint32_t val; } i2s_rx_tdm_ctrl_reg_t; -/** Type of rxeof_num register +/** Type of rx_eof_num register * I2S RX data number control register. */ typedef union { @@ -461,7 +461,7 @@ typedef union { uint32_t reserved_12:20; }; uint32_t val; -} i2s_rxeof_num_reg_t; +} i2s_rx_eof_num_reg_t; /** Group: TX Control and configuration registers */ @@ -627,7 +627,7 @@ typedef union { */ uint32_t tx_clk_active:1; /** tx_clk_sel : R/W; bitpos: [28:27]; default: 0; - * Select I2S Tx module source clock. 0: XTAL clock. 1: APLL. 2: CLK160. 3: + * Select I2S Tx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: * I2S_MCLK_in. */ uint32_t tx_clk_sel:2; @@ -914,7 +914,7 @@ typedef union { uint32_t val; } i2s_lc_hung_conf_reg_t; -/** Type of conf_sigle_data register +/** Type of conf_single_data register * I2S signal data register */ typedef union { @@ -925,7 +925,7 @@ typedef union { uint32_t single_data:32; }; uint32_t val; -} i2s_conf_sigle_data_reg_t; +} i2s_conf_single_data_reg_t; /** Group: TX status registers */ @@ -1005,8 +1005,8 @@ typedef struct i2s_dev_t { volatile i2s_rx_timing_reg_t rx_timing; volatile i2s_tx_timing_reg_t tx_timing; volatile i2s_lc_hung_conf_reg_t lc_hung_conf; - volatile i2s_rxeof_num_reg_t rxeof_num; - volatile i2s_conf_sigle_data_reg_t conf_sigle_data; + volatile i2s_rx_eof_num_reg_t rx_eof_num; + volatile i2s_conf_single_data_reg_t conf_single_data; volatile i2s_state_reg_t state; volatile i2s_etm_conf_reg_t etm_conf; uint32_t reserved_074[3]; diff --git a/components/soc/esp32c6/include/soc/ieee802154_reg.h b/components/soc/esp32c6/include/soc/ieee802154_reg.h new file mode 100644 index 000000000000..db8e6e12bfec --- /dev/null +++ b/components/soc/esp32c6/include/soc/ieee802154_reg.h @@ -0,0 +1,524 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif +// TODO: ZB-93, rewrite this file using regdesc tools when IEEE802154.csv is ready. +#define IEEE802154_REG_BASE 0x600A3000 + +#define IEEE802154_COMMAND_REG (IEEE802154_REG_BASE + 0x0000) +#define IEEE802154_OPCODE 0x000000FF +#define IEEE802154_OPCODE_S 0 + +#define IEEE802154_CTRL_CFG_REG (IEEE802154_REG_BASE + 0x0004) +#define IEEE802154_MAC_INF3_ENABLE (BIT(31)) +#define IEEE802154_MAC_INF3_ENABLE_S 31 +#define IEEE802154_MAC_INF2_ENABLE (BIT(30)) +#define IEEE802154_MAC_INF2_ENABLE_S 30 +#define IEEE802154_MAC_INF1_ENABLE (BIT(29)) +#define IEEE802154_MAC_INF1_ENABLE_S 29 +#define IEEE802154_MAC_INF0_ENABLE (BIT(28)) +#define IEEE802154_MAC_INF0_ENABLE_S 28 +#define IEEE802154_RX_DONE_TRIGGER_IDLE (BIT(27)) +#define IEEE802154_RX_DONE_TRIGGER_IDLE_S 27 +#define IEEE802154_FORCE_RX_ENB (BIT(26)) +#define IEEE802154_FORCE_RX_ENB_S 26 +#define IEEE802154_NO_RSS_TRK_ENB (BIT(25)) +#define IEEE802154_NO_RSS_TRK_ENB_S 25 +#define IEEE802154_BIT_ORDER (BIT(24)) +#define IEEE802154_BIT_ORDER_S 24 +#define IEEE802154_COEX_ARB_DELAY 0x000000FF +#define IEEE802154_COEX_ARB_DELAY_S 16 +#define IEEE802154_FILTER_ENHANCE (BIT(14)) +#define IEEE802154_FILTER_ENHANCE_S 14 +#define IEEE802154_AUTOPEND_ENHANCE (BIT(12)) +#define IEEE802154_AUTOPEND_ENHANCE_S 12 +#define IEEE802154_DIS_FRAME_VERSION_RSV_FILTER (BIT(11)) +#define IEEE802154_DIS_FRAME_VERSION_RSV_FILTER_S 11 +#define IEEE802154_PROMISCUOUS_MODE (BIT(7)) +#define IEEE802154_PROMISCUOUS_MODE_S 7 +#define IEEE802154_PAN_COORDINATOR (BIT(6)) +#define IEEE802154_PAN_COORDINATOR_S 6 +#define IEEE802154_DIS_IFS_CONTROL (BIT(5)) +#define IEEE802154_DIS_IFS_CONTROL_S 5 +#define IEEE802154_HW_AUTO_ACK_RX_EN (BIT(3)) +#define IEEE802154_HW_AUTO_ACK_RX_EN_S 3 +#define HW_ENHANCE_ACK_TX_EN (BIT(1)) +#define HW_ENHANCE_ACK_TX_EN_S 1 +#define IEEE802154_HW_AUTO_ACK_TX_EN (BIT(0)) +#define IEEE802154_HW_AUTO_ACK_TX_EN_S 0 + +#define IEEE802154_INF0_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0008) +#define IEEE802154_MAC_INF0_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF0_SHORT_ADDR_S 0 + +#define IEEE802154_INF0_PAN_ID_REG (IEEE802154_REG_BASE + 0x000C) +#define IEEE802154_MAC_INF0_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF0_PAN_ID_S 0 + +#define IEEE802154_INF0_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0010) +#define IEEE802154_MAC_INF0_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF0_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF0_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0014) +#define IEEE802154_MAC_INF0_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF0_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF1_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0018) +#define IEEE802154_MAC_INF1_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF1_SHORT_ADDR_S 0 + +#define IEEE802154_INF1_PAN_ID_REG (IEEE802154_REG_BASE + 0x001C) +#define IEEE802154_MAC_INF1_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF1_PAN_ID_S 0 + +#define IEEE802154_INF1_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0020) +#define IEEE802154_MAC_INF1_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF1_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF1_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0024) +#define IEEE802154_MAC_INF1_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF1_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF2_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0028) +#define IEEE802154_MAC_INF2_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF2_SHORT_ADDR_S 0 + +#define IEEE802154_INF2_PAN_ID_REG (IEEE802154_REG_BASE + 0x002C) +#define IEEE802154_MAC_INF2_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF2_PAN_ID_S 0 + +#define IEEE802154_INF2_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0030) +#define IEEE802154_MAC_INF2_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF2_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF2_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0034) +#define IEEE802154_MAC_INF2_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF2_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF3_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0038) +#define IEEE802154_MAC_INF3_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF3_SHORT_ADDR_S 0 + +#define IEEE802154_INF3_PAN_ID_REG (IEEE802154_REG_BASE + 0x003C) +#define IEEE802154_MAC_INF3_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF3_PAN_ID_S 0 + +#define IEEE802154_INF3_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0040) +#define IEEE802154_MAC_INF3_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF3_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF3_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0044) +#define IEEE802154_MAC_INF3_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF3_EXTEND_ADDR1_S 0 + +#define IEEE802154_CHANNEL_REG (IEEE802154_REG_BASE + 0x0048) +#define IEEE802154_HOP 0x0000007F +#define IEEE802154_HOP_S 0 + +#define IEEE802154_TX_POWER_REG (IEEE802154_REG_BASE + 0x004C) +#define IEEE802154_TX_POWER 0x0000001F +#define IEEE802154_TX_POWER_S 0 + +#define IEEE802154_ED_SCAN_DURATION_REG (IEEE802154_REG_BASE + 0x0050) +#define IEEE802154_ED_SCAN_WAIT_DLY 0x0000000F +#define IEEE802154_ED_SCAN_WAIT_DLY_S 24 +#define IEEE802154_ED_SCAN_DURATION 0x00FFFFFF +#define IEEE802154_ED_SCAN_DURATION_S 0 + +#define IEEE802154_ED_SCAN_CFG_REG (IEEE802154_REG_BASE + 0x0054) +#define IEEE802154_CCA_BUSY (BIT(24)) +#define IEEE802154_CCA_BUSY_S 24 +#define IEEE802154_ED_RSS 0x000000FF +#define IEEE802154_ED_RSS_S 16 +#define IEEE802154_CCA_MODE 0x00000003 +#define IEEE802154_CCA_MODE_S 14 +#define IEEE802154_DIS_ED_POWER_SEL (BIT(13)) +#define IEEE802154_DIS_ED_POWER_SEL_S 13 +#define IEEE802154_ED_SAMPLE_MODE 0x00000003 +#define IEEE802154_ED_SAMPLE_MODE_S 11 +#define IEEE802154_CCA_ED_THRESHOLD 0x000000FF +#define IEEE802154_CCA_ED_THRESHOLD_S 0 + +#define IEEE802154_IFS_REG (IEEE802154_REG_BASE + 0x0058) +#define IEEE802154_LIFS 0x000003FF +#define IEEE802154_LIFS_S 16 +#define IEEE802154_SIFS 0x000000FF +#define IEEE802154_SIFS_S 0 + +#define IEEE802154_ACK_TIMEOUT_REG (IEEE802154_REG_BASE + 0x005C) +#define IEEE802154_ACK_TIMEOUT 0x0000FFFF +#define IEEE802154_ACK_TIMEOUT_S 0 + +#define IEEE802154_EVENT_EN_REG (IEEE802154_REG_BASE + 0x0060) +#define IEEE802154_EVENT_EN 0x00001FFF +#define IEEE802154_EVENT_EN_S 0 + +#define IEEE802154_EVENT_STATUS_REG (IEEE802154_REG_BASE + 0x0064) +#define IEEE802154_EVENT_STATUS 0x00001FFF +#define IEEE802154_EVENT_STATUS_S 0 + +#define IEEE802154_RX_ABORT_INTR_CTRL_REG (IEEE802154_REG_BASE + 0x0068) +#define IEEE802154_RX_ABORT_INTR_CTRL 0x7FFFFFFF +#define IEEE802154_RX_ABORT_INTR_CTRL_S 0 + +#define IEEE802154_ACK_FRAME_PENDING_EN_REG (IEEE802154_REG_BASE + 0x006c) +#define IEEE802154_ACK_TX_ACK_TIMEOUT 0x0000FFFF +#define IEEE802154_ACK_TX_ACK_TIMEOUT_S 16 +#define IEEE802154_ACK_FRAME_PENDING_EN (BIT(0)) +#define IEEE802154_ACK_FRAME_PENDING_EN_S 0 + +#define IEEE802154_COEX_PTI_REG (IEEE802154_REG_BASE + 0x0070) +#define IEEE802154_CLOSE_RF_SEL (BIT(8)) +#define IEEE802154_CLOSE_RF_SEL_S 8 +#define IEEE802154_COEX_ACK_PTI 0x0000000F +#define IEEE802154_COEX_ACK_PTI_S 4 +#define IEEE802154_COEX_PTI 0x0000000F +#define IEEE802154_COEX_PTI_S 0 + +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL_REG (IEEE802154_REG_BASE + 0x0078) +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL 0x7FFFFFFF +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL_S 0 + +#define IEEE802154_ENHANCE_ACK_CFG_REG (IEEE802154_REG_BASE + 0x7C) +#define IEEE802154_TX_ENH_ACK_GENERATE_DONE_NOTIFY 0xFFFFFFFF +#define IEEE802154_TX_ENH_ACK_GENERATE_DONE_NOTIFY_S 0 + +#define IEEE802154_RX_STATUS_REG (IEEE802154_REG_BASE + 0x0080) +#define IEEE802154_SFD_MATCH (BIT(21)) +#define IEEE802154_SFD_MATCH_S 21 +#define IEEE802154_PREAMBLE_MATCH (BIT(20)) +#define IEEE802154_PREAMBLE_MATCH_S 20 +#define IEEE802154_RX_STATE 0x00000007 +#define IEEE802154_RX_STATE_S 16 +#define IEEE802154_RX_ABORT_STATUS 0x0000001F +#define IEEE802154_RX_ABORT_STATUS_S 4 +#define IEEE802154_FILTER_FAIL_STATUS 0x0000000F +#define IEEE802154_FILTER_FAIL_STATUS_S 0 + +#define IEEE802154_TX_STATUS_REG (IEEE802154_REG_BASE + 0x0084) +#define IEEE802154_TX_SEC_ERROR_CODE 0x0000000F +#define IEEE802154_TX_SEC_ERROR_CODE_S 16 +#define IEEE802154_TX_ABORT_STATUS 0x0000001F +#define IEEE802154_TX_ABORT_STATUS_S 4 +#define IEEE802154_TX_STATE 0x0000000F +#define IEEE802154_TX_STATE_S 0 + +#define IEEE802154_TXRX_STATUS_REG (IEEE802154_REG_BASE + 0x0088) +#define IEEE802154_RF_CTRL_STATE 0x0000000F +#define IEEE802154_RF_CTRL_STATE_S 16 +#define IEEE802154_ED_TRIGGER_TX_PROC (BIT(11)) +#define IEEE802154_ED_TRIGGER_TX_PROC_S 11 +#define IEEE802154_ED_PROC (BIT(10)) +#define IEEE802154_ED_PROC_S 10 +#define IEEE802154_RX_PROC (BIT(9)) +#define IEEE802154_RX_PROC_S 9 +#define IEEE802154_TX_PROC (BIT(8)) +#define IEEE802154_TX_PROC_S 8 +#define IEEE802154_TXRX_STATE 0x0000000F +#define IEEE802154_TXRX_STATE_S 0 + +#define IEEE802154_TX_CCM_SCHEDULE_STATUS_REG (IEEE802154_REG_BASE + 0x008c) +#define IEEE802154_TX_CCM_SCHEDULE_STATUS 0x7FFFFFFF +#define IEEE802154_TX_CCM_SCHEDULE_STATUS_S 0 + +#define IEEE802154_RX_LENGTH_REG (IEEE802154_REG_BASE + 0x00a4) +#define IEEE802154_RX_LENGTH 0x0000007F +#define IEEE802154_RX_LENGTH_S 0 + +#define IEEE802154_TIME0_THRESHOLD_REG (IEEE802154_REG_BASE + 0x00a8) +#define IEEE802154_TIMER0_THRESHOLD 0xFFFFFFFF +#define IEEE802154_TIMER0_THRESHOLD_S 0 + +#define IEEE802154_TIME0_VALUE_REG (IEEE802154_REG_BASE + 0x00ac) +#define IEEE802154_TIMER0_VALUE 0xFFFFFFFF +#define IEEE802154_TIMER0_VALUE_S 0 + +#define IEEE802154_TIME1_THRESHOLD_REG (IEEE802154_REG_BASE + 0x00b0) +#define IEEE802154_TIMER1_THRESHOLD 0xFFFFFFFF +#define IEEE802154_TIMER1_THRESHOLD_S 0 + +#define IEEE802154_TIME1_VALUE_REG (IEEE802154_REG_BASE + 0x00b4) +#define IEEE802154_TIMER1_VALUE 0xFFFFFFFF +#define IEEE802154_TIMER1_VALUE_S 0 + +#define IEEE802154_CLK_COUNTER_MATCH_VAL_REG (IEEE802154_REG_BASE + 0x00b8) +#define IEEE802154_CLK_COUNT_MATCH_VAL 0x0000FFFF +#define IEEE802154_CLK_COUNT_MATCH_VAL_S 0 + +#define IEEE802154_CLK_COUNTER_REG (IEEE802154_REG_BASE + 0x00bc) +#define IEEE802154_CLK_625US_CNT 0x0000FFFF +#define IEEE802154_CLK_625US_CNT_S 0 + +#define IEEE802154_IFS_COUNTER_REG (IEEE802154_REG_BASE + 0x00c0) +#define IEEE802154_IFS_COUNTER_EN (BIT(16)) +#define IEEE802154_IFS_COUNTER_EN_S 16 +#define IEEE802154_IFS_COUNTER 0x000003FF +#define IEEE802154_IFS_COUNTER_S 0 + +#define IEEE802154_SFD_WAIT_SYMBOL_REG (IEEE802154_REG_BASE + 0x00c4) +#define IEEE802154_SFD_WAIT_SYMBOL_NUM 0x0000000F +#define IEEE802154_SFD_WAIT_SYMBOL_NUM_S 0 + +#define IEEE802154_TXRX_PATH_DELAY_REG (IEEE802154_REG_BASE + 0x00c8) +#define IEEE802154_RX_PATH_DELAY 0x0000003F +#define IEEE802154_RX_PATH_DELAY_S 16 +#define IEEE802154_TX_PATH_DELAY 0x0000003F +#define IEEE802154_TX_PATH_DELAY_S 0 + +#define IEEE802154_BB_CLK_REG (IEEE802154_REG_BASE + 0x00cc) +#define IEEE802154_BB_CLK_FREQ_MINUS_1 0x0000001F +#define IEEE802154_BB_CLK_FREQ_MINUS_1_S 0 + +#define IEEE802154_TXDMA_ADDR_REG (IEEE802154_REG_BASE + 0x00D0) +#define IEEE802154_TXDMA_ADDR 0xFFFFFFFF +#define IEEE802154_TXDMA_ADDR_S 0 + +#define IEEE802154_TXDMA_CTRL_STATE_REG (IEEE802154_REG_BASE + 0x00D4) +#define IEEE802154_TXDMA_FETCH_BYTE_CNT 0x0000007F +#define IEEE802154_TXDMA_FETCH_BYTE_CNT_S 24 +#define IEEE802154_TXDMA_STATE 0x0000001F +#define IEEE802154_TXDMA_STATE_S 16 +#define IEEE802154_TXDMA_FILL_ENTRY 0x00000007 +#define IEEE802154_TXDMA_FILL_ENTRY_S 4 +#define IEEE802154_TXDMA_WATER_LEVEL 0x00000007 +#define IEEE802154_TXDMA_WATER_LEVEL_S 0 + +#define IEEE802154_TXDMA_ERR_REG (IEEE802154_REG_BASE + 0x00D8) +#define IEEE802154_TXDMA_ERR 0x0000000F +#define IEEE802154_TXDMA_ERR_S 0 + +#define IEEE802154_RXDMA_ADDR_REG (IEEE802154_REG_BASE + 0x00E0) +#define IEEE802154_RXDMA_ADDR 0xFFFFFFFF +#define IEEE802154_RXDMA_ADDR_S 0 + +#define IEEE802154_RXDMA_CTRL_STATE_REG (IEEE802154_REG_BASE + 0x00E4) +#define IEEE802154_RXDMA_APPEND_FREQ_OFFSET (BIT(25)) +#define IEEE802154_RXDMA_APPEND_FREQ_OFFSET_S 25 +#define IEEE802154_RXDMA_APPEND_LQI_OFFSET (BIT(24)) +#define IEEE802154_RXDMA_APPEND_LQI_OFFSET_S 24 +#define IEEE802154_RXDMA_STATE 0x0000001F +#define IEEE802154_RXDMA_STATE_S 16 +#define IEEE802154_RXDMA_WATER_LEVEL 0x00000007 +#define IEEE802154_RXDMA_WATER_LEVEL_S 0 + +#define IEEE802154_RXDMA_ERR_REG (IEEE802154_REG_BASE + 0x00E8) +#define IEEE802154_RXDMA_ERR 0x0000000F +#define IEEE802154_RXDMA_ERR_S 0 + +#define IEEE802154_DMA_GCK_CFG_REG (IEEE802154_REG_BASE + 0x00F0) +#define IEEE802154_DMA_GCK_CFG (BIT(0)) +#define IEEE802154_DMA_GCK_CFG_S 0 + +#define IEEE802154_DMA_DUMMY_REG (IEEE802154_REG_BASE + 0x00F4) +#define IEEE802154_DMA_DUMMY_DATA 0xFFFFFFFF +#define IEEE802154_DMA_DUMMY_DATA_S + +#define IEEE802154_PAON_DELAY_REG (IEEE802154_REG_BASE + 0x0100) +#define IEEE802154_PAON_DELAY 0x000003FF +#define IEEE802154_PAON_DELAY_S 0 + +#define IEEE802154_TXON_DELAY_REG (IEEE802154_REG_BASE + 0x0104) +#define IEEE802154_TXON_DELAY 0x000003FF +#define IEEE802154_TXON_DELAY_S 0 + +#define IEEE802154_TXEN_STOP_DELAY_REG (IEEE802154_REG_BASE + 0x0108) +#define IEEE802154_TXEN_STOP_DLY 0x0000003F +#define IEEE802154_TXEN_STOP_DLY_S 0 + +#define IEEE802154_TXOFF_DELAY_REG (IEEE802154_REG_BASE + 0x010c) +#define IEEE802154_TXOFF_DELAY 0x0000003F +#define IEEE802154_TXOFF_DELAY_S 0 + +#define IEEE802154_RXON_DELAY_REG (IEEE802154_REG_BASE + 0x0110) +#define IEEE802154_RXON_DELAY 0x000007FF +#define IEEE802154_RXON_DELAY_S 0 + +#define IEEE802154_TXRX_SWITCH_DELAY_REG (IEEE802154_REG_BASE + 0x0114) +#define IEEE802154_TXRX_SWITCH_DELAY 0x000003FF +#define IEEE802154_TXRX_SWITCH_DELAY_S 0 + +#define IEEE802154_CONT_RX_DELAY_REG (IEEE802154_REG_BASE + 0x0118) +#define IEEE802154_CONT_RX_DELAY 0x0000003F +#define IEEE802154_CONT_RX_DELAY_S 0 + +#define IEEE802154_DCDC_CTRL_REG (IEEE802154_REG_BASE + 0x011c) +#define IEEE802154_TX_DCDC_UP (BIT(31)) +#define IEEE802154_TX_DCDC_UP_S 31 +#define IEEE802154_DCDC_CTRL_EN (BIT(16)) +#define IEEE802154_DCDC_CTRL_EN_S 16 +#define IEEE802154_DCDC_DOWN_DELAY 0x000000FF +#define IEEE802154_DCDC_DOWN_DELAY_S 8 +#define IEEE802154_DCDC_PRE_UP_DELAY 0x000000FF +#define IEEE802154_DCDC_PRE_UP_DELAY_S 0 + +#define IEEE802154_DEBUG_CTRL_REG (IEEE802154_REG_BASE + 0x0120) +#define IEEE802154_DEBUG_TRIGGER_DUMP_EN (BIT(31)) +#define IEEE802154_DEBUG_TRIGGER_DUMP_EN_S 31 +#define IEEE802154_DEBUG_STATE_MATCH_DUMP_EN (BIT(30)) +#define IEEE802154_DEBUG_STATE_MATCH_DUMP_EN_S 30 +#define IEEE802154_DEBUG_TRIGGER_PULSE_SELECT 0x00000007 +#define IEEE802154_DEBUG_TRIGGER_PULSE_SELECT_S 24 +#define IEEE802154_DEBUG_TRIGGER_STATE_MATCH_VALUE 0x0000001F +#define IEEE802154_DEBUG_TRIGGER_STATE_MATCH_VALUE_S 16 +#define IEEE802154_DEBUG_SER_DEBUG_SEL 0x0000000F +#define IEEE802154_DEBUG_SER_DEBUG_SEL_S 12 +#define IEEE802154_DEBUG_TRIGGER_STATE_SELECT 0x0000000F +#define IEEE802154_DEBUG_TRIGGER_STATE_SELECT_S 8 +#define IEEE802154_DEBUG_SIGNAL_SEL 0x00000007 +#define IEEE802154_DEBUG_SIGNAL_SEL_S 0 + +#define IEEE802154_SEC_CTRL_REG (IEEE802154_REG_BASE + 0x0128) +#define IEEE802154_SEC_PAYLOAD_OFFSET 0x0000007F +#define IEEE802154_SEC_PAYLOAD_OFFSET_S 8 +#define IEEE802154_SEC_EN (BIT(0)) +#define IEEE802154_SEC_EN_S 0 + +#define IEEE802154_SEC_EXTEND_ADDRESS0_REG (IEEE802154_REG_BASE + 0x012c) +#define IEEE802154_SEC_EXTEND_ADDRESS0 0xFFFFFFFF +#define IEEE802154_SEC_EXTEND_ADDRESS0_S 0 + +#define IEEE802154_SEC_EXTEND_ADDRESS1_REG (IEEE802154_REG_BASE + 0x0130) +#define IEEE802154_SEC_EXTEND_ADDRESS1 0xFFFFFFFF +#define IEEE802154_SEC_EXTEND_ADDRESS1_S 0 + +#define IEEE802154_SEC_KEY0_REG (IEEE802154_REG_BASE + 0x0134) +#define IEEE802154_SEC_KEY0 0xFFFFFFFF +#define IEEE802154_SEC_KEY0_S 0 + +#define IEEE802154_SEC_KEY1_REG (IEEE802154_REG_BASE + 0x0138) +#define IEEE802154_SEC_KEY1 0xFFFFFFFF +#define IEEE802154_SEC_KEY1_S 0 + +#define IEEE802154_SEC_KEY2_REG (IEEE802154_REG_BASE + 0x013c) +#define IEEE802154_SEC_KEY2 0xFFFFFFFF +#define IEEE802154_SEC_KEY2_S 0 + +#define IEEE802154_SEC_KEY3_REG (IEEE802154_REG_BASE + 0x0140) +#define IEEE802154_SEC_KEY3 0xFFFFFFFF +#define IEEE802154_SEC_KEY3_S 0 + +#define IEEE802154_SFD_TIMEOUT_CNT_REG (IEEE802154_REG_BASE + 0x0144) +#define IEEE802154_SFD_TIMEOUT_CNT 0x0000FFFF +#define IEEE802154_SFD_TIMEOUT_CNT_S 0 + +#define IEEE802154_CRC_ERROR_CNT_REG (IEEE802154_REG_BASE + 0x0148) +#define IEEE802154_CRC_ERROR_CNT 0x0000FFFF +#define IEEE802154_CRC_ERROR_CNT_S 0 + +#define IEEE802154_ED_ABORT_CNT_REG (IEEE802154_REG_BASE + 0x014c) +#define IEEE802154_ED_ABORT_CNT 0x0000FFFF +#define IEEE802154_ED_ABORT_CNT_S 0 + +#define IEEE802154_CCA_FAIL_CNT_REG (IEEE802154_REG_BASE + 0x0150) +#define IEEE802154_CCA_FAIL_CNT 0x0000FFFF +#define IEEE802154_CCA_FAIL_CNT_S 0 + +#define IEEE802154_RX_FILTER_FAIL_CNT_REG (IEEE802154_REG_BASE + 0x0154) +#define IEEE802154_RX_FILTER_FAIL_CNT 0x0000FFFF +#define IEEE802154_RX_FILTER_FAIL_CNT_S 0 + +#define IEEE802154_NO_RSS_DETECT_CNT_REG (IEEE802154_REG_BASE + 0x0158) +#define IEEE802154_NO_RSS_DETECT_CNT 0x0000FFFF +#define IEEE802154_NO_RSS_DETECT_CNT_S 0 + +#define IEEE802154_RX_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x015c) +#define IEEE802154_RX_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_RX_ABORT_COEX_CNT_S 0 + +#define IEEE802154_RX_RESTART_CNT_REG (IEEE802154_REG_BASE + 0x0160) +#define IEEE802154_RX_RESTART_CNT 0x0000FFFF +#define IEEE802154_RX_RESTART_CNT_S 0 + +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0164) +#define IEEE802154_TX_ACK_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_S 0 + +#define IEEE802154_ED_SCAN_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0168) +#define IEEE802154_ED_SCAN_COEX_CNT 0x0000FFFF +#define IEEE802154_ED_SCAN_COEX_CNT_S 0 + +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x016c) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_S 0 + +#define IEEE802154_RX_ACK_TIMEOUT_CNT_REG (IEEE802154_REG_BASE + 0x0170) +#define IEEE802154_RX_ACK_TIMEOUT_CNT 0x0000FFFF +#define IEEE802154_RX_ACK_TIMEOUT_CNT_S 0 + +#define IEEE802154_TX_BREAK_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0174) +#define IEEE802154_TX_BREAK_COEX_CNT 0x0000FFFF +#define IEEE802154_TX_BREAK_COEX_CNT_S 0 + +#define IEEE802154_TX_SECURITY_ERROR_CNT_REG (IEEE802154_REG_BASE + 0x0178) +#define IEEE802154_TX_SECURITY_ERROR_CNT 0x0000FFFF +#define IEEE802154_TX_SECURITY_ERROR_CNT_S 0 + +#define IEEE802154_CCA_BUSY_CNT_REG (IEEE802154_REG_BASE + 0x017c) +#define IEEE802154_CCA_BUSY_CNT 0x0000FFFF +#define IEEE802154_CCA_BUSY_CNT_S 0 + +#define IEEE802154_ERROR_CNT_CLEAR_REG (IEEE802154_REG_BASE + 0x0180) +#define IEEE802154_SFD_TIMEOUT_CNT_CLEAR (BIT(14)) +#define IEEE802154_SFD_TIMEOUT_CNT_CLEAR_S 14 +#define IEEE802154_CRC_ERROR_CNT_CLEAR (BIT(13)) +#define IEEE802154_CRC_ERROR_CNT_CLEAR_S 13 +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR (BIT(12)) +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR_S 12 +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR (BIT(11)) +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR_S 11 +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR (BIT(10)) +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR_S 10 +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR (BIT(9)) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR_S 9 +#define IEEE802154_RX_RESTART_CNT_CLEAR (BIT(8)) +#define IEEE802154_RX_RESTART_CNT_CLEAR_S 8 +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR (BIT(7)) +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR_S 7 +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR (BIT(6)) +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR_S 6 +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR (BIT(5)) +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR_S 5 +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR (BIT(4)) +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR_S 4 +#define IEEE802154_ED_ABORT_CNT_CLEAR (BIT(3)) +#define IEEE802154_ED_ABORT_CNT_CLEAR_S 3 +#define IEEE802154_CCA_FAIL_CNT_CLEAR (BIT(2)) +#define IEEE802154_CCA_FAIL_CNT_CLEAR_S 2 +#define IEEE802154_CCA_BUSY_CNT_CLEAR (BIT(1)) +#define IEEE802154_CCA_BUSY_CNT_CLEAR_S 1 +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR (BIT(0)) +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR_S 0 + +#define IEEE802154_MAC_DATE_REG (IEEE802154_REG_BASE + 0x0184) +#define IEEE802154_MAC_DATE 0xFFFFFFFF +#define IEEE802154_MAC_DATE_S 0 +#define IEEE802154_MAC_DATE_VERSION 0x220622 + +// For ETM feature. +#define ETM_REG_BASE 0x600A8800 +#define ETM_CHEN_AD0_REG (ETM_REG_BASE + 0x0000) +#define ETM_CHENSET_AD0_REG (ETM_REG_BASE + 0x0004) +#define ETM_CHENCLR_AD0_REG (ETM_REG_BASE + 0x0008) +#define ETM_CH0_EVT_ID_REG (ETM_REG_BASE + 0x0018) +#define ETM_CH0_TASK_ID_REG (ETM_REG_BASE + 0x001C) + +#define ETM_CH_OFFSET 0x08 + +#define ETM_EVENT_TIMER1_OVERFLOW 58 +#define ETM_EVENT_TIMER0_OVERFLOW 59 +#define ETM_TASK_ED_TRIG_TX 64 +#define ETM_TASK_RX_START 65 +#define ETM_TASK_TX_START 68 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/ieee802154_struct.h b/components/soc/esp32c6/include/soc/ieee802154_struct.h new file mode 100644 index 000000000000..b28c7d9c84d3 --- /dev/null +++ b/components/soc/esp32c6/include/soc/ieee802154_struct.h @@ -0,0 +1,462 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: ZB-93, rewrite this file using regdesc tools when IEEE802154.csv is ready. +typedef volatile struct esp_ieee802154_s { + union { + struct { + uint32_t cmd: 8; + uint32_t reserved8: 24; + }; + uint32_t val; + } cmd; // 0x00 + + union { + struct { + uint32_t auto_ack_tx: 1; + uint32_t auto_enhack: 1; + uint32_t reserved2: 1; + uint32_t auto_ack_rx: 1; + uint32_t reserved4: 1; + uint32_t ifs_dis: 1; + uint32_t coordinator: 1; + uint32_t promiscuous: 1; + uint32_t reserved8: 3; + uint32_t version_filter_dis: 1; + uint32_t pending_enhance: 1; + uint32_t reserved13: 1; + uint32_t filter_enhance_dis: 1; + uint32_t reserved15: 1; + uint32_t coex_arb_delay: 8; + uint32_t bit_order: 1; + uint32_t no_rssi_trigger_break_en: 1; + uint32_t coex_force_rx: 1; + uint32_t rx_done_trig_idle: 1; + uint32_t multipan_mask: 4; + }; + uint32_t val; + } conf; // 0x04 + + struct { + union { + struct { + uint32_t addr: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } short_addr; // 0x08 + + union { + struct { + uint32_t id: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } panid; // 0x0c + + uint32_t ext_addr0; // 0x10 + uint32_t ext_addr1; // 0x14 + } multipan[4]; + + union { + struct { + uint32_t freq: 7; + uint32_t reserved7: 25; + }; + uint32_t val; + } channel; //0x48 + + union { + struct { + uint32_t power: 5; + uint32_t reserved5: 27; + }; + uint32_t val; + } txpower; //0x4c + + union { + struct { + uint32_t duration: 24; + uint32_t delay: 4; + uint32_t reserved28: 4; + }; + uint32_t val; + } ed_duration; //0x50 + + union { + struct { + uint32_t cca_threshold: 8; + uint32_t reserved8: 3; + uint32_t ed_sample_rate: 2; + uint32_t ed_sample_mode: 1; + uint32_t cca_mode: 2; + uint32_t ed_rss: 8; + uint32_t cca_busy: 1; + uint32_t reserved25: 7; + }; + uint32_t val; + } ed_cfg; //0x54 + + union { + struct { + uint32_t sifs: 8; + uint32_t reserved8: 8; + uint32_t lifs: 10; + uint32_t reserved26: 6; + }; + uint32_t val; + } ifs_cfg; //0x58 + + union { + struct { + uint32_t timeout: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } ack_timeout; //0x5c + + union { + struct { + uint32_t events: 13; + uint32_t reserved13: 19; + }; + uint32_t val; + } event_en; //0x60 + + union { + struct { + uint32_t events: 13; + uint32_t reserved13: 19; + }; + uint32_t val; + } event_status; //0x64 + + union { + struct { + uint32_t rx_abort_en: 31; + uint32_t reserved31: 1; + }; + uint32_t val; + } rx_abort_event_en; //0x68 + + union { + struct { + uint32_t pending: 1; + uint32_t reserved1: 15; + uint32_t pending_timeout: 16; + }; + uint32_t val; + } pending_cfg; //0x6c + + union { + struct { + uint32_t pti: 4; + uint32_t hw_ack_pti: 4; + uint32_t close_rf_sel: 1; + uint32_t reserved9: 23; + }; + uint32_t val; + } pti; //0x70 + + uint32_t reserved_74; //0x74 + + union { + struct { + uint32_t tx_abort_en: 31; + uint32_t reserved31: 1; + }; + uint32_t val; + } tx_abort_event_en; //0x78 + + uint32_t enhack_generate_done_notify; //0x7c + + union { + struct { + uint32_t filter_fail_reason: 4; + uint32_t rx_abort_reason: 5; + uint32_t reserved9: 7; + uint32_t rx_state: 3; + uint32_t reserved19: 1; + uint32_t preamble_match: 1; + uint32_t sfd_match: 1; + uint32_t reserved22: 10; + }; + uint32_t val; + } rx_status; // 0x80 + + union { + struct { + uint32_t tx_state: 4; + uint32_t tx_abort_reason: 5; + uint32_t reserved9: 7; + uint32_t tx_security_error: 4; + uint32_t reserved20: 12; + }; + uint32_t val; + } tx_status; //0x84 + + union { + struct { + uint32_t txrx_status: 4; + uint32_t reserved4: 4; + uint32_t tx_proc: 1; + uint32_t rx_proc: 1; + uint32_t ed_proc: 1; + uint32_t ed_trig_tx_proc: 1; + uint32_t reserved12: 4; + uint32_t rf_ctrl_state: 4; + uint32_t reserved20: 12; + }; + uint32_t val; + } txrx_status; //0x88 + + uint32_t tx_sec_schedule_state; //0x8c + + union { + struct { + uint32_t pkt_gck: 1; + uint32_t ctrl_gck: 1; + uint32_t reserved2: 30; + }; + uint32_t val; + } core_gck_cfg; //0x90 + + uint32_t reserved_94; //0x94 + uint32_t reserved_98; //0x98 + uint32_t reserved_9c; //0x9c + uint32_t reserved_a0; //0xa0 + + uint32_t rx_length; //0xa4 + + uint32_t timer0_threshold; //0xa8 + uint32_t timer0_value; //0xac + uint32_t timer1_threshold; //0xb0 + uint32_t timer1_value; //0xb4 + uint32_t clk_counter_threshold; //0xb8 + uint32_t clk_counter_value; //0xbc + + union { + struct { + uint32_t ifs_counter: 10; + uint32_t reserved10: 6; + uint32_t ifs_counter_en: 1; + uint32_t reserved17: 15; + }; + uint32_t val; + } ifs_counter_cfg; //0xc0 + + union { + struct { + uint32_t sfd_wait_symbol_num: 4; + uint32_t reserved4: 28; + }; + uint32_t val; + } sfd_wait; //0xc4 + + union { + struct { + uint32_t tx_path_delay: 6; + uint32_t reserved6: 10; + uint32_t rx_path_delay: 6; + uint32_t reserved624: 10; + }; + uint32_t val; + } txrx_path_delay; //0xc8 + + uint32_t bb_clk; //0xcc + uint32_t dma_tx_addr; //0xd0 + + union { + struct { + uint32_t txdma_water_level: 3; + uint32_t reserved3: 1; + uint32_t txdma_fill_entry: 3; + uint32_t reserved7: 9; + uint32_t txdma_ctrl_state: 5; + uint32_t reserved21: 3; + uint32_t txdma_fetch_byte_cnt: 7; + uint32_t reserved31: 1; + }; + uint32_t val; + } dma_tx_cfg; //0xd4 + + uint32_t dma_tx_err; //0xd8 + + uint32_t reserved_dc; //0xdc + + uint32_t dma_rx_addr; //0xe0 + + union { + struct { + uint32_t rxdma_water_level: 3; + uint32_t reserved3: 13; + uint32_t rxdma_ctrl_state: 5; + uint32_t reserved21: 3; + uint32_t rxdma_append_lqi: 1; + uint32_t rxdma_append_freq_offset: 1; + uint32_t reserved26: 6; + }; + uint32_t val; + } dma_rx_cfg; //0xe4 + + uint32_t dma_rx_err; //0xe8 + + uint32_t reserved_ec; //x0ec + + uint32_t dma_gck; //0xf0 + uint32_t dma_dummy_data; //0xf4 + uint32_t reserved_f8; //0xf8 + uint32_t reserved_fc; //0xfc + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } pa_on_delay; //0x100 + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } tx_on_delay; //0x104 + + union { + struct { + uint32_t delay: 6; + uint32_t reserved6: 26; + }; + uint32_t val; + } txen_stop_delay; //0x108 + + union { + struct { + uint32_t delay: 6; + uint32_t reserved6: 26; + }; + uint32_t val; + } tx_off_delay; //0x10c + + union { + struct { + uint32_t delay: 11; + uint32_t reserved11: 21; + }; + uint32_t val; + } rx_on_delay; //0x110 + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } txrx_switch_delay; //0x114 + + uint32_t cont_rx_delay; //0x118 + + union { + struct { + uint32_t dcdc_pre_up_delay: 8; + uint32_t dcdc_down_delay: 8; + uint32_t dcdc_ctrl_en: 1; + uint32_t reserved17: 14; + uint32_t tx_dcdc_up: 1; + }; + uint32_t val; + } dcdc_ctrl; //0x11c + + union { + struct { + uint32_t debug_sel: 3; + uint32_t reserved3: 5; + uint32_t trig_st_sel: 4; + uint32_t ser_debug_sel: 4; + uint32_t trig_st_match_val: 5; + uint32_t reserved21: 3; + uint32_t trig_pulse_sel: 3; + uint32_t reserved27: 3; + uint32_t trig_st_match_dump_en: 1; + uint32_t trig_pulse_dump_en: 1; + }; + uint32_t val; + } debug_ctrl; //0x120 + + uint32_t tx_dma_err_sts_reg; //0x124 + union { + struct { + uint32_t tx_security_en: 1; + uint32_t reserved1: 7; + uint32_t security_offset: 7; + uint32_t reserved15: 17; + }; + uint32_t val; + } security_ctrl; //0x128 + + uint32_t security_addr0; //0x12c + uint32_t security_addr1; //0x130 + uint32_t security_key0; //0x134 + uint32_t security_key1; //0x138 + uint32_t security_key2; //0x13c + uint32_t security_key3; //0x140 + + uint32_t debug_sfd_timeout_cnt; //0x144 + uint32_t debug_crc_error_cnt; //0x148 + uint32_t debug_ed_abort_cnt; //0x14c + uint32_t debug_cca_fail_cnt; //0x150 + uint32_t debug_rx_filter_fail_cnt; //0x154 + uint32_t debug_no_rss_detect_cnt; //0x158 + uint32_t debug_rx_abort_coex_cnt; //0x15c + uint32_t debug_rx_restart_cnt; //0x160 + uint32_t debug_tx_ack_abort_coex_cnt; //0x164 + uint32_t debug_ed_scan_break_coex_cnt; //0x168 + uint32_t debug_rx_ack_abort_coex_cnt; //0x16c + uint32_t debug_rx_ack_timeout_cnt; //0x170 + uint32_t debug_tx_break_coex_cnt; //0x174 + uint32_t debug_tx_security_error_cnt; //0x178 + uint32_t debug_cca_busy_cnt; //0x17c + + union { + struct { + uint32_t debug_ed_scan_break_coex_cnt: 1; + uint32_t debug_cca_busy_cnt: 1; + uint32_t debug_cca_fail_cnt: 1; + uint32_t debug_ed_abort_cnt: 1; + uint32_t debug_tx_security_error_cnt: 1; + uint32_t debug_tx_break_coex_cnt: 1; + uint32_t debug_tx_ack_abort_coex_cnt: 1; + uint32_t debug_rx_ack_timeout_cnt: 1; + uint32_t debug_rx_restart_cnt: 1; + uint32_t debug_rx_ack_abort_coex_cnt: 1; + uint32_t debug_rx_abort_coex_cnt: 1; + uint32_t debug_no_rss_detect_cnt: 1; + uint32_t debug_rx_filter_fail_cnt: 1; + uint32_t debug_crc_error_cnt: 1; + uint32_t debug_sfd_timeout_cnt: 1; + uint32_t reserved15: 17; + }; + uint32_t val; + } debug_cnt_clr; //0x180 + + uint32_t i154_version; //0x184 + +} esp_ieee802154_t; + +extern esp_ieee802154_t IEEE802154; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/interrupt_reg.h b/components/soc/esp32c6/include/soc/interrupt_reg.h new file mode 100644 index 000000000000..d59eb394af4b --- /dev/null +++ b/components/soc/esp32c6/include/soc/interrupt_reg.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/interrupt_matrix_reg.h" +#include "soc/intpri_reg.h" +#include "soc/plic_reg.h" +#include "soc/soc_caps.h" + +// ESP32C6 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y) +#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG +#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG +#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG +#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG +#define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) + +#define DR_REG_INTERRUPT_BASE DR_REG_INTERRUPT_MATRIX_BASE diff --git a/components/soc/esp32c6/include/soc/io_mux_reg.h b/components/soc/esp32c6/include/soc/io_mux_reg.h index 8a0a64acec50..304ed1c383bd 100644 --- a/components/soc/esp32c6/include/soc/io_mux_reg.h +++ b/components/soc/esp32c6/include/soc/io_mux_reg.h @@ -13,7 +13,7 @@ #define SLP_OE_M (BIT(0)) #define SLP_OE_V 1 #define SLP_OE_S 0 -/* Pin used for wakeup from sleep */ +/* Used to enable sleep mode pin functions */ #define SLP_SEL (BIT(1)) #define SLP_SEL_M (BIT(1)) #define SLP_SEL_V 1 @@ -63,15 +63,33 @@ #define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S) #define MCU_SEL_V 0x7 #define MCU_SEL_S 12 - -#define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE) -#define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE) -#define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv)); -#define PIN_PULLUP_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PU) -#define PIN_PULLUP_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PU) -#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD) -#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD) -#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC) +/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */ +#define FILTER_EN (BIT(15)) +#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S) +#define FILTER_EN_V 1 +#define FILTER_EN_S 15 + +#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE) +#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE) +#define PIN_SLP_OUTPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_OE) +#define PIN_SLP_OUTPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_OE) +#define PIN_SLP_PULLUP_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PU) +#define PIN_SLP_PULLUP_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PU) +#define PIN_SLP_PULLDOWN_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PD) +#define PIN_SLP_PULLDOWN_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PD) +#define PIN_SLP_SEL_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_SEL) +#define PIN_SLP_SEL_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_SEL) + +#define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE) +#define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE) +#define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv)); +#define PIN_PULLUP_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PU) +#define PIN_PULLUP_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PU) +#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD) +#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD) +#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC) +#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN) +#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN) #define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_XTAL_32K_P_U #define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_XTAL_32K_N_U @@ -125,7 +143,12 @@ #define SD_DATA2_GPIO_NUM 22 #define SD_DATA3_GPIO_NUM 23 -#define MAX_RTC_GPIO_NUM 5 +#define USB_DM_GPIO_NUM 12 +#define USB_DP_GPIO_NUM 13 + +#define EXT_OSC_SLOW_GPIO_NUM 0 + +#define MAX_RTC_GPIO_NUM 8 #define MAX_PAD_GPIO_NUM 30 #define MAX_GPIO_NUM 34 #define DIG_IO_HOLD_BIT_SHIFT 32 @@ -133,25 +156,16 @@ #define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE #define PIN_CTRL (REG_IO_MUX_BASE +0x00) -#define PAD_POWER_SEL BIT(15) -#define PAD_POWER_SEL_V 0x1 -#define PAD_POWER_SEL_M BIT(15) -#define PAD_POWER_SEL_S 15 - -#define PAD_POWER_SWITCH_DELAY 0x7 -#define PAD_POWER_SWITCH_DELAY_V 0x7 -#define PAD_POWER_SWITCH_DELAY_M (PAD_POWER_SWITCH_DELAY_V << PAD_POWER_SWITCH_DELAY_S) -#define PAD_POWER_SWITCH_DELAY_S 12 -#define CLK_OUT3 0xf +#define CLK_OUT3 0x1f #define CLK_OUT3_V CLK_OUT3 -#define CLK_OUT3_S 8 +#define CLK_OUT3_S 10 #define CLK_OUT3_M (CLK_OUT3_V << CLK_OUT3_S) -#define CLK_OUT2 0xf +#define CLK_OUT2 0x1f #define CLK_OUT2_V CLK_OUT2 -#define CLK_OUT2_S 4 +#define CLK_OUT2_S 5 #define CLK_OUT2_M (CLK_OUT2_V << CLK_OUT2_S) -#define CLK_OUT1 0xf +#define CLK_OUT1 0x1f #define CLK_OUT1_V CLK_OUT1 #define CLK_OUT1_S 0 #define CLK_OUT1_M (CLK_OUT1_V << CLK_OUT1_S) diff --git a/components/soc/esp32c6/include/soc/lp_analog_peri_reg.h b/components/soc/esp32c6/include/soc/lp_analog_peri_reg.h index 25848608d664..84f2f919e692 100644 --- a/components/soc/esp32c6/include/soc/lp_analog_peri_reg.h +++ b/components/soc/esp32c6/include/soc/lp_analog_peri_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -109,7 +109,7 @@ extern "C" { #define LP_ANALOG_PERI_LP_ANA_ANA_FIB_ENA_S 0 #define LP_ANALOG_PERI_LP_ANA_FIB_GLITCH_RST BIT(0) -#define LP_ANALOG_PERI_LP_ANA_FIB_BOR_RST BIT(1) +#define LP_ANALOG_PERI_LP_ANA_FIB_BOD_RST BIT(1) #define LP_ANALOG_PERI_LP_ANA_FIB_SUPER_WDT_RST BIT(2) /** LP_ANALOG_PERI_LP_ANA_INT_RAW_REG register diff --git a/components/soc/esp32c6/include/soc/lp_i2c_struct.h b/components/soc/esp32c6/include/soc/lp_i2c_struct.h index 5a0e4835adf0..73b5491287d1 100644 --- a/components/soc/esp32c6/include/soc/lp_i2c_struct.h +++ b/components/soc/esp32c6/include/soc/lp_i2c_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -775,194 +775,32 @@ typedef union { /** Group: Command registers */ -/** Type of comd0 register - * I2C command register 0 +/** Type of command register + * I2C command register */ typedef union { struct { - /** command0 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 0. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. + /** command : R/W; bitpos: [13:0]; default: 0; + * This is the content of a command. It consists of three parts: + * op_code is the command, 6: RSTART, 1: WRITE, 3: READ, 2: STOP, 4: END. * Byte_num represents the number of bytes that need to be sent or received. * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. + * structure for more information. */ - uint32_t command0:14; + uint32_t byte_num:8; + uint32_t ack_en:1; + uint32_t ack_exp:1; + uint32_t ack_val:1; + uint32_t op_code:3; uint32_t reserved_14:17; - /** command0_done : R/W/SS; bitpos: [31]; default: 0; - * When command 0 is done in I2C Master mode, this bit changes to high + /** command_done : R/W/SS; bitpos: [31]; default: 0; + * When command is done in I2C Master mode, this bit changes to high * level. */ - uint32_t command0_done:1; + uint32_t command_done:1; }; uint32_t val; -} lp_i2c_comd0_reg_t; - -/** Type of comd1 register - * I2C command register 1 - */ -typedef union { - struct { - /** command1 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 1. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command1:14; - uint32_t reserved_14:17; - /** command1_done : R/W/SS; bitpos: [31]; default: 0; - * When command 1 is done in I2C Master mode, this bit changes to high - * level. - */ - uint32_t command1_done:1; - }; - uint32_t val; -} lp_i2c_comd1_reg_t; - -/** Type of comd2 register - * I2C command register 2 - */ -typedef union { - struct { - /** command2 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 2. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command2:14; - uint32_t reserved_14:17; - /** command2_done : R/W/SS; bitpos: [31]; default: 0; - * When command 2 is done in I2C Master mode, this bit changes to high - * Level. - */ - uint32_t command2_done:1; - }; - uint32_t val; -} lp_i2c_comd2_reg_t; - -/** Type of comd3 register - * I2C command register 3 - */ -typedef union { - struct { - /** command3 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 3. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command3:14; - uint32_t reserved_14:17; - /** command3_done : R/W/SS; bitpos: [31]; default: 0; - * When command 3 is done in I2C Master mode, this bit changes to high - * level. - */ - uint32_t command3_done:1; - }; - uint32_t val; -} lp_i2c_comd3_reg_t; - -/** Type of comd4 register - * I2C command register 4 - */ -typedef union { - struct { - /** command4 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 4. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command4:14; - uint32_t reserved_14:17; - /** command4_done : R/W/SS; bitpos: [31]; default: 0; - * When command 4 is done in I2C Master mode, this bit changes to high - * level. - */ - uint32_t command4_done:1; - }; - uint32_t val; -} lp_i2c_comd4_reg_t; - -/** Type of comd5 register - * I2C command register 5 - */ -typedef union { - struct { - /** command5 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 5. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command5:14; - uint32_t reserved_14:17; - /** command5_done : R/W/SS; bitpos: [31]; default: 0; - * When command 5 is done in I2C Master mode, this bit changes to high level. - */ - uint32_t command5_done:1; - }; - uint32_t val; -} lp_i2c_comd5_reg_t; - -/** Type of comd6 register - * I2C command register 6 - */ -typedef union { - struct { - /** command6 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 6. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command6:14; - uint32_t reserved_14:17; - /** command6_done : R/W/SS; bitpos: [31]; default: 0; - * When command 6 is done in I2C Master mode, this bit changes to high level. - */ - uint32_t command6_done:1; - }; - uint32_t val; -} lp_i2c_comd6_reg_t; - -/** Type of comd7 register - * I2C command register 7 - */ -typedef union { - struct { - /** command7 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 7. It consists of three parts: - * op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END. - * Byte_num represents the number of bytes that need to be sent or received. - * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd - * structure for more - * Information. - */ - uint32_t command7:14; - uint32_t reserved_14:17; - /** command7_done : R/W/SS; bitpos: [31]; default: 0; - * When command 7 is done in I2C Master mode, this bit changes to high level. - */ - uint32_t command7_done:1; - }; - uint32_t val; -} lp_i2c_comd7_reg_t; +} lp_i2c_command_reg_t; /** Group: Version register */ @@ -1031,14 +869,7 @@ typedef struct lp_i2c_dev_t { volatile lp_i2c_scl_stop_setup_reg_t scl_stop_setup; volatile lp_i2c_filter_cfg_reg_t filter_cfg; volatile lp_i2c_clk_conf_reg_t clk_conf; - volatile lp_i2c_comd0_reg_t comd0; - volatile lp_i2c_comd1_reg_t comd1; - volatile lp_i2c_comd2_reg_t comd2; - volatile lp_i2c_comd3_reg_t comd3; - volatile lp_i2c_comd4_reg_t comd4; - volatile lp_i2c_comd5_reg_t comd5; - volatile lp_i2c_comd6_reg_t comd6; - volatile lp_i2c_comd7_reg_t comd7; + volatile lp_i2c_command_reg_t command[8]; volatile lp_i2c_scl_st_time_out_reg_t scl_st_time_out; volatile lp_i2c_scl_main_st_time_out_reg_t scl_main_st_time_out; volatile lp_i2c_scl_sp_conf_reg_t scl_sp_conf; @@ -1050,7 +881,8 @@ typedef struct lp_i2c_dev_t { volatile lp_i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; } lp_i2c_dev_t; -extern lp_i2c_dev_t LP_I2C; +// We map the LP_I2C instance to the i2c_dev_t struct for convinience of using the same HAL/LL. See soc/i2c_struct.h +//extern lp_i2c_dev_t LP_I2C; #ifndef __cplusplus _Static_assert(sizeof(lp_i2c_dev_t) == 0x184, "Invalid size of lp_i2c_dev_t structure"); diff --git a/components/soc/esp32c6/include/soc/lp_timer_struct.h b/components/soc/esp32c6/include/soc/lp_timer_struct.h index a45c0b407e96..9efef9b16927 100644 --- a/components/soc/esp32c6/include/soc/lp_timer_struct.h +++ b/components/soc/esp32c6/include/soc/lp_timer_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,346 +10,99 @@ extern "C" { #endif -/** Group: configure_register */ -/** Type of tar0_low register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_low0 : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_low0:32; - }; - uint32_t val; -} lp_timer_tar0_low_reg_t; - -/** Type of tar0_high register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_high0 : R/W; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_high0:16; - uint32_t reserved_16:15; - /** main_timer_tar_en0 : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_tar_en0:1; - }; - uint32_t val; -} lp_timer_tar0_high_reg_t; - -/** Type of tar1_low register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_low1 : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_low1:32; - }; - uint32_t val; -} lp_timer_tar1_low_reg_t; - -/** Type of tar1_high register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_high1 : R/W; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_high1:16; - uint32_t reserved_16:15; - /** main_timer_tar_en1 : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_tar_en1:1; - }; - uint32_t val; -} lp_timer_tar1_high_reg_t; +typedef struct { + union { + struct { + uint32_t target_lo: 32; + }; + uint32_t val; + } lo; + union { + struct { + uint32_t target_hi: 16; + uint32_t reserved0: 15; + uint32_t enable : 1; + }; + uint32_t val; + } hi; +} lp_timer_target_reg_t; -/** Type of update register - * need_des - */ typedef union { struct { - uint32_t reserved_0:28; - /** main_timer_update : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t main_timer_update:1; - /** main_timer_xtal_off : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t main_timer_xtal_off:1; - /** main_timer_sys_stall : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_sys_stall:1; - /** main_timer_sys_rst : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_sys_rst:1; + uint32_t reserved0: 28; + uint32_t update : 1; + uint32_t xtal_off : 1; + uint32_t sys_stall: 1; + uint32_t sys_rst : 1; }; uint32_t val; } lp_timer_update_reg_t; -/** Type of main_buf0_low register - * need_des - */ -typedef union { - struct { - /** main_timer_buf0_low : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf0_low:32; - }; - uint32_t val; -} lp_timer_main_buf0_low_reg_t; - -/** Type of main_buf0_high register - * need_des - */ -typedef union { - struct { - /** main_timer_buf0_high : RO; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf0_high:16; - uint32_t reserved_16:16; - }; - uint32_t val; -} lp_timer_main_buf0_high_reg_t; - -/** Type of main_buf1_low register - * need_des - */ -typedef union { - struct { - /** main_timer_buf1_low : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf1_low:32; - }; - uint32_t val; -} lp_timer_main_buf1_low_reg_t; - -/** Type of main_buf1_high register - * need_des - */ -typedef union { - struct { - /** main_timer_buf1_high : RO; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf1_high:16; - uint32_t reserved_16:16; - }; - uint32_t val; -} lp_timer_main_buf1_high_reg_t; - -/** Type of main_overflow register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** main_timer_alarm_load : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_alarm_load:1; - }; - uint32_t val; -} lp_timer_main_overflow_reg_t; - -/** Type of int_raw register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_raw:1; - /** soc_wakeup_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_raw:1; - }; - uint32_t val; -} lp_timer_int_raw_reg_t; - -/** Type of int_st register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_st:1; - /** soc_wakeup_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_st:1; - }; - uint32_t val; -} lp_timer_int_st_reg_t; - -/** Type of int_ena register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_ena:1; - /** soc_wakeup_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_ena:1; - }; - uint32_t val; -} lp_timer_int_ena_reg_t; - -/** Type of int_clr register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_clr:1; - /** soc_wakeup_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_clr:1; - }; - uint32_t val; -} lp_timer_int_clr_reg_t; +typedef struct { + union { + struct { + uint32_t counter_lo: 32; + }; + uint32_t val; + } lo; + union { + struct { + uint32_t counter_hi: 16; + uint32_t reserved0 : 16; + }; + uint32_t val; + } hi; +} lp_timer_counter_reg_t; -/** Type of lp_int_raw register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_raw:1; - /** main_timer_lp_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_raw:1; + uint32_t reserved0: 31; + uint32_t trigger : 1; }; uint32_t val; -} lp_timer_lp_int_raw_reg_t; +} lp_timer_overflow_reg_t; -/** Type of lp_int_st register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_st:1; - /** main_timer_lp_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_st:1; + uint32_t reserved0: 30; + uint32_t overflow : 1; + uint32_t alarm : 1; }; uint32_t val; -} lp_timer_lp_int_st_reg_t; +} lp_timer_intr_reg_t; -/** Type of lp_int_ena register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_ena:1; - /** main_timer_lp_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_ena:1; + uint32_t reserved0: 30; + uint32_t overflow : 1; + uint32_t alarm : 1; }; uint32_t val; -} lp_timer_lp_int_ena_reg_t; +} lp_timer_lp_intr_reg_t; -/** Type of lp_int_clr register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_clr:1; - /** main_timer_lp_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_clr:1; + uint32_t date : 31; + uint32_t clk_en: 1; }; uint32_t val; -} lp_timer_lp_int_clr_reg_t; - -/** Type of date register - * need_des - */ -typedef union { - struct { - /** date : R/W; bitpos: [30:0]; default: 34672976; - * need_des - */ - uint32_t date:31; - /** clk_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t clk_en:1; - }; - uint32_t val; -} lp_timer_date_reg_t; - +} lp_timer_date_clken_reg_t; -typedef struct lp_timer_dev_t { - volatile lp_timer_tar0_low_reg_t tar0_low; - volatile lp_timer_tar0_high_reg_t tar0_high; - volatile lp_timer_tar1_low_reg_t tar1_low; - volatile lp_timer_tar1_high_reg_t tar1_high; - volatile lp_timer_update_reg_t update; - volatile lp_timer_main_buf0_low_reg_t main_buf0_low; - volatile lp_timer_main_buf0_high_reg_t main_buf0_high; - volatile lp_timer_main_buf1_low_reg_t main_buf1_low; - volatile lp_timer_main_buf1_high_reg_t main_buf1_high; - volatile lp_timer_main_overflow_reg_t main_overflow; - volatile lp_timer_int_raw_reg_t int_raw; - volatile lp_timer_int_st_reg_t int_st; - volatile lp_timer_int_ena_reg_t int_ena; - volatile lp_timer_int_clr_reg_t int_clr; - volatile lp_timer_lp_int_raw_reg_t lp_int_raw; - volatile lp_timer_lp_int_st_reg_t lp_int_st; - volatile lp_timer_lp_int_ena_reg_t lp_int_ena; - volatile lp_timer_lp_int_clr_reg_t lp_int_clr; - uint32_t reserved_048[237]; - volatile lp_timer_date_reg_t date; +typedef struct lp_timer_dev_t{ + volatile lp_timer_target_reg_t target[2]; + volatile lp_timer_update_reg_t update; + volatile lp_timer_counter_reg_t counter[2]; + volatile lp_timer_overflow_reg_t overflow; + volatile lp_timer_intr_reg_t int_raw; + volatile lp_timer_intr_reg_t int_st; + volatile lp_timer_intr_reg_t int_en; + volatile lp_timer_intr_reg_t int_clr; + volatile lp_timer_lp_intr_reg_t lp_int_raw; + volatile lp_timer_lp_intr_reg_t lp_int_st; + volatile lp_timer_lp_intr_reg_t lp_int_en; + volatile lp_timer_lp_intr_reg_t lp_int_clr; + uint32_t reserved[237]; + volatile lp_timer_date_clken_reg_t date_clken; } lp_timer_dev_t; extern lp_timer_dev_t LP_TIMER; diff --git a/components/soc/esp32c6/include/soc/lp_wdt_reg.h b/components/soc/esp32c6/include/soc/lp_wdt_reg.h index 5c9a78dac9f7..4b0071c22351 100644 --- a/components/soc/esp32c6/include/soc/lp_wdt_reg.h +++ b/components/soc/esp32c6/include/soc/lp_wdt_reg.h @@ -11,11 +11,11 @@ extern "C" { #endif -// TODO: IDF-5730 (better to move to wdt_types.h?) -/* The value that needs to be written to RTC_CNTL_WDT_WKEY to write-enable the wdt registers */ +// TODO: IDF-5730 (better to rename and move to wdt_types.h?) +/* The value that needs to be written to LP_WDT_WPROTECT_REG to write-enable the wdt registers */ #define RTC_CNTL_WDT_WKEY_VALUE 0x50D83AA1 -/* The value that needs to be written to RTC_CNTL_SWD_WPROTECT_REG to write-enable the wdt registers */ -#define RTC_CNTL_SWD_WKEY_VALUE 0x8F1D312A +/* The value that needs to be written to LP_WDT_SWD_WPROTECT_REG to write-enable the swd registers */ +#define LP_WDT_SWD_WKEY_VALUE 0x50D83AA1 /* Possible values for RTC_CNTL_WDT_CPU_RESET_LENGTH and RTC_CNTL_WDT_SYS_RESET_LENGTH */ #define RTC_WDT_RESET_LENGTH_100_NS 0 diff --git a/components/soc/esp32c6/include/soc/lpperi_reg.h b/components/soc/esp32c6/include/soc/lpperi_reg.h index 80b4d32f8659..b39b2f353f6a 100644 --- a/components/soc/esp32c6/include/soc/lpperi_reg.h +++ b/components/soc/esp32c6/include/soc/lpperi_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -137,13 +137,13 @@ extern "C" { * need_des */ #define LPPERI_RNG_DATA_REG (DR_REG_LPPERI_BASE + 0x8) -/** LPPERI_RND_DATA : RO; bitpos: [31:0]; default: 0; +/** LPPERI_RNG_DATA : RO; bitpos: [31:0]; default: 0; * need_des */ -#define LPPERI_RND_DATA 0xFFFFFFFFU -#define LPPERI_RND_DATA_M (LPPERI_RND_DATA_V << LPPERI_RND_DATA_S) -#define LPPERI_RND_DATA_V 0xFFFFFFFFU -#define LPPERI_RND_DATA_S 0 +#define LPPERI_RNG_DATA 0xFFFFFFFFU +#define LPPERI_RNG_DATA_M (LPPERI_RNG_DATA_V << LPPERI_RNG_DATA_S) +#define LPPERI_RNG_DATA_V 0xFFFFFFFFU +#define LPPERI_RNG_DATA_S 0 /** LPPERI_CPU_REG register * need_des diff --git a/components/soc/esp32c6/include/soc/lpperi_struct.h b/components/soc/esp32c6/include/soc/lpperi_struct.h index 278301712c27..8dc3cde04fcc 100644 --- a/components/soc/esp32c6/include/soc/lpperi_struct.h +++ b/components/soc/esp32c6/include/soc/lpperi_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -101,10 +101,10 @@ typedef union { */ typedef union { struct { - /** rnd_data : RO; bitpos: [31:0]; default: 0; + /** rng_data : RO; bitpos: [31:0]; default: 0; * need_des */ - uint32_t rnd_data:32; + uint32_t rng_data:32; }; uint32_t val; } lpperi_rng_data_reg_t; diff --git a/components/soc/esp32c6/include/soc/mcpwm_struct.h b/components/soc/esp32c6/include/soc/mcpwm_struct.h index 2d98b4e26e41..1a91a623f6bc 100644 --- a/components/soc/esp32c6/include/soc/mcpwm_struct.h +++ b/components/soc/esp32c6/include/soc/mcpwm_struct.h @@ -1683,7 +1683,7 @@ typedef struct mcpwm_dev_t { volatile mcpwm_version_reg_t version; } mcpwm_dev_t; -extern mcpwm_dev_t MCPWM; +extern mcpwm_dev_t MCPWM0; #ifndef __cplusplus _Static_assert(sizeof(mcpwm_dev_t) == 0x130, "Invalid size of mcpwm_dev_t structure"); diff --git a/components/soc/esp32c6/include/soc/memprot_defs.h b/components/soc/esp32c6/include/soc/memprot_defs.h new file mode 100644 index 000000000000..6db06a8b2647 --- /dev/null +++ b/components/soc/esp32c6/include/soc/memprot_defs.h @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc.h" +#include "esp32c6/rom/cache.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { + struct { + uint32_t cat0 : 2; + uint32_t cat1 : 2; + uint32_t cat2 : 2; + uint32_t res0 : 8; + uint32_t splitaddr : 8; + uint32_t res1 : 10; + }; + uint32_t val; +} constrain_reg_fields_t; + +#ifndef I_D_SRAM_SEGMENT_SIZE +#define I_D_SRAM_SEGMENT_SIZE 0x20000 +#endif + +#define I_D_SPLIT_LINE_SHIFT 0x9 +#define I_D_FAULT_ADDR_SHIFT 0x2 + +#define DRAM_SRAM_START 0x3FC7C000 + +//IRAM0 + +//16kB (ICACHE) +#define IRAM0_SRAM_LEVEL_0_LOW SOC_IRAM_LOW //0x40370000 +#define IRAM0_SRAM_LEVEL_0_HIGH (IRAM0_SRAM_LEVEL_0_LOW + CACHE_MEMORY_IBANK_SIZE - 0x1) //0x4037FFFF + +//128kB (LEVEL 1) +#define IRAM0_SRAM_LEVEL_1_LOW (IRAM0_SRAM_LEVEL_0_HIGH + 0x1) //0x40380000 +#define IRAM0_SRAM_LEVEL_1_HIGH (IRAM0_SRAM_LEVEL_1_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x4039FFFF + +//128kB (LEVEL 2) +#define IRAM0_SRAM_LEVEL_2_LOW (IRAM0_SRAM_LEVEL_1_HIGH + 0x1) //0x403A0000 +#define IRAM0_SRAM_LEVEL_2_HIGH (IRAM0_SRAM_LEVEL_2_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x403BFFFF + +//128kB (LEVEL 3) +#define IRAM0_SRAM_LEVEL_3_LOW (IRAM0_SRAM_LEVEL_2_HIGH + 0x1) //0x403C0000 +#define IRAM0_SRAM_LEVEL_3_HIGH (IRAM0_SRAM_LEVEL_3_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x403DFFFF + +//permission bits +#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_R 0x1 +#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_W 0x2 +#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_F 0x4 + +//DRAM0 + +//16kB ICACHE not available from DRAM0 + +//128kB (LEVEL 1) +#define DRAM0_SRAM_LEVEL_1_LOW SOC_DRAM_LOW //0x3FC80000 +#define DRAM0_SRAM_LEVEL_1_HIGH (DRAM0_SRAM_LEVEL_1_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x3FC9FFFF + +//128kB (LEVEL 2) +#define DRAM0_SRAM_LEVEL_2_LOW (DRAM0_SRAM_LEVEL_1_HIGH + 0x1) //0x3FCA0000 +#define DRAM0_SRAM_LEVEL_2_HIGH (DRAM0_SRAM_LEVEL_2_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x3FCBFFFF + +//128kB (LEVEL 3) +#define DRAM0_SRAM_LEVEL_3_LOW (DRAM0_SRAM_LEVEL_2_HIGH + 0x1) //0x3FCC0000 +#define DRAM0_SRAM_LEVEL_3_HIGH (DRAM0_SRAM_LEVEL_3_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x3FCDFFFF + +#define SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_R 0x1 +#define SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_W 0x2 + +//RTC FAST + +//permission bits +#define SENSITIVE_CORE_0_PIF_PMS_CONSTRAIN_RTCFAST_WORLD_X_W 0x1 +#define SENSITIVE_CORE_0_PIF_PMS_CONSTRAIN_RTCFAST_WORLD_X_R 0x2 +#define SENSITIVE_CORE_0_PIF_PMS_CONSTRAIN_RTCFAST_WORLD_X_F 0x4 + +#define AREA_LOW 0 +#define AREA_HIGH 1 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/mmu.h b/components/soc/esp32c6/include/soc/mmu.h new file mode 100644 index 000000000000..e4b929414600 --- /dev/null +++ b/components/soc/esp32c6/include/soc/mmu.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "soc/ext_mem_defs.h" +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined for flash mmap */ +#define SOC_MMU_REGIONS_COUNT 1 +#define SOC_MMU_PAGES_PER_REGION 256 +#define SOC_MMU_IROM0_PAGES_START (CACHE_IROM_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL +#define SOC_MMU_ADDR_MASK (MMU_VALID - 1) +#define SOC_MMU_PAGE_IN_FLASH(page) (page) //Always in Flash +#define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW +#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START +#define SOC_MMU_VADDR0_START_ADDR (SOC_IROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE)) +#define SOC_MMU_VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/pcr_struct.h b/components/soc/esp32c6/include/soc/pcr_struct.h index a6e5d06edca9..f31e632d865b 100644 --- a/components/soc/esp32c6/include/soc/pcr_struct.h +++ b/components/soc/esp32c6/include/soc/pcr_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -607,7 +607,7 @@ typedef union { */ uint32_t i2s_tx_clkm_div_num:8; /** i2s_tx_clkm_sel : R/W; bitpos: [21:20]; default: 0; - * Select I2S Tx module source clock. 0: XTAL clock. 1: APLL. 2: CLK160. 3: + * Select I2S Tx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: * I2S_MCLK_in. */ uint32_t i2s_tx_clkm_sel:2; @@ -661,7 +661,7 @@ typedef union { */ uint32_t i2s_rx_clkm_div_num:8; /** i2s_rx_clkm_sel : R/W; bitpos: [21:20]; default: 0; - * Select I2S Rx module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in. + * Select I2S Rx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in. */ uint32_t i2s_rx_clkm_sel:2; /** i2s_rx_clkm_en : R/W; bitpos: [22]; default: 1; @@ -751,7 +751,7 @@ typedef union { */ uint32_t saradc_clkm_div_num:8; /** saradc_clkm_sel : R/W; bitpos: [21:20]; default: 0; - * set this field to select clock-source. 0(default): XTAL, 1: 240MHz, 2: FOSC, 3: + * set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3: * reserved. */ uint32_t saradc_clkm_sel:2; @@ -1699,8 +1699,8 @@ typedef union { typedef union { struct { /** clk_32k_sel : R/W; bitpos: [1:0]; default: 0; - * This field indicates which one 32KHz clock will be used by MODEM_SYSTEM and - * timergroup. 0: OSC32K(default), 1: XTAL32K, 2/3: 32KHz from pad GPIO0. + * This field indicates which one 32KHz clock will be used by timergroup. + * 0: OSC32K(default), 1: XTAL32K, 2/3: 32KHz from pad GPIO0. */ uint32_t clk_32k_sel:2; uint32_t reserved_2:30; diff --git a/components/soc/esp32c6/include/soc/periph_defs.h b/components/soc/esp32c6/include/soc/periph_defs.h index 822a9e52142b..e4c401a9ad5c 100644 --- a/components/soc/esp32c6/include/soc/periph_defs.h +++ b/components/soc/esp32c6/include/soc/periph_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,27 +21,46 @@ typedef enum { PERIPH_TIMG1_MODULE, PERIPH_UHCI0_MODULE, PERIPH_RMT_MODULE, + PERIPH_PCNT_MODULE, PERIPH_SPI_MODULE, //SPI1 PERIPH_SPI2_MODULE, //SPI2 PERIPH_TWAI0_MODULE, PERIPH_TWAI1_MODULE, PERIPH_RNG_MODULE, - PERIPH_WIFI_MODULE, - PERIPH_BT_MODULE, - PERIPH_WIFI_BT_COMMON_MODULE, - PERIPH_BT_BASEBAND_MODULE, - PERIPH_BT_LC_MODULE, PERIPH_RSA_MODULE, PERIPH_AES_MODULE, PERIPH_SHA_MODULE, + PERIPH_ECC_MODULE, PERIPH_HMAC_MODULE, PERIPH_DS_MODULE, + PERIPH_SDIO_SLAVE_MODULE, PERIPH_GDMA_MODULE, + PERIPH_MCPWM0_MODULE, + PERIPH_ETM_MODULE, + PERIPH_PARLIO_MODULE, PERIPH_SYSTIMER_MODULE, PERIPH_SARADC_MODULE, + PERIPH_TEMPSENSOR_MODULE, + PERIPH_REGDMA_MODULE, + PERIPH_LP_I2C0_MODULE, +/* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */ + PERIPH_WIFI_MODULE, + PERIPH_BT_MODULE, + PERIPH_IEEE802154_MODULE, + PERIPH_COEX_MODULE, + PERIPH_PHY_MODULE, + PERIPH_ANA_I2C_MASTER_MODULE, + PERIPH_MODEM_ETM_MODULE, + PERIPH_MODEM_ADC_COMMON_FE_MODULE, PERIPH_MODULE_MAX +/* !!! Don't append soc modules here !!! */ } periph_module_t; +#define PERIPH_MODEM_MODULE_MIN PERIPH_WIFI_MODULE +#define PERIPH_MODEM_MODULE_MAX PERIPH_MODEM_ADC_COMMON_FE_MODULE +#define PERIPH_MODEM_MODULE_NUM (PERIPH_MODEM_MODULE_MAX - PERIPH_MODEM_MODULE_MIN + 1) +#define IS_MODEM_MODULE(periph) ((periph>=PERIPH_MODEM_MODULE_MIN) && (periph<=PERIPH_MODEM_MODULE_MAX)) + typedef enum { ETS_WIFI_MAC_INTR_SOURCE = 0, /**< interrupt of WiFi MAC, level*/ ETS_WIFI_MAC_NMI_SOURCE, /**< interrupt of WiFi MAC, NMI, use if MAC have bug to fix in NMI*/ @@ -104,7 +123,7 @@ typedef enum { ETS_SYSTIMER_TARGET1_EDGE_INTR_SOURCE, /**< interrupt of system timer 1, EDGE*/ ETS_SYSTIMER_TARGET2_EDGE_INTR_SOURCE, /**< interrupt of system timer 2, EDGE*/ ETS_APB_ADC_INTR_SOURCE, /**< interrupt of APB ADC, LEVEL*/ - ETS_PWM_INTR_SOURCE, + ETS_MCPWM0_INTR_SOURCE, /**< interrupt of MCPWM0, LEVEL*/ ETS_PCNT_INTR_SOURCE, ETS_PARL_IO_INTR_SOURCE, ETS_SLC0_INTR_SOURCE, diff --git a/components/soc/esp32c6/include/soc/plic_reg.h b/components/soc/esp32c6/include/soc/plic_reg.h index 8d5accd75fea..dff45b960562 100644 --- a/components/soc/esp32c6/include/soc/plic_reg.h +++ b/components/soc/esp32c6/include/soc/plic_reg.h @@ -5,12 +5,11 @@ */ #pragma once +#include "soc/soc.h" #ifdef __cplusplus extern "C" { #endif -#define DR_REG_PLIC_MX_BASE ( 0x20001000 ) -#define DR_REG_PLIC_UX_BASE ( 0x20001400 ) #define PLIC_MXINT_CONF_REG ( 0x200013FC ) #define PLIC_UXINT_CONF_REG ( 0x200017FC ) diff --git a/components/soc/esp32c6/include/soc/pmu_struct.h b/components/soc/esp32c6/include/soc/pmu_struct.h index f265b8fd0063..5d0631189555 100644 --- a/components/soc/esp32c6/include/soc/pmu_struct.h +++ b/components/soc/esp32c6/include/soc/pmu_struct.h @@ -1,2816 +1,754 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include +#include #ifdef __cplusplus extern "C" { #endif -/** Group: configure_register */ -/** Type of hp_active_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** hp_active_vdd_spi_pd_en : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t hp_active_vdd_spi_pd_en:1; - /** hp_active_hp_mem_dslp : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t hp_active_hp_mem_dslp:1; - /** hp_active_pd_hp_mem_pd_en : R/W; bitpos: [26:23]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_mem_pd_en:4; - /** hp_active_pd_hp_wifi_pd_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_wifi_pd_en:1; - uint32_t reserved_28:1; - /** hp_active_pd_hp_cpu_pd_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_cpu_pd_en:1; - /** hp_active_pd_hp_aon_pd_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_aon_pd_en:1; - /** hp_active_pd_top_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_active_pd_top_pd_en:1; - }; - uint32_t val; -} pmu_hp_active_dig_power_reg_t; +#include "soc.h" +#include "soc/pmu_reg.h" -/** Type of hp_active_icg_hp_func register - * need_des - */ typedef union { struct { - /** hp_active_dig_icg_func_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_active_dig_icg_func_en:32; + uint32_t reserved0 : 21; + uint32_t vdd_spi_pd_en: 1; + uint32_t mem_dslp : 1; + uint32_t mem_pd_en : 4; + uint32_t wifi_pd_en : 1; + uint32_t reserved1 : 1; + uint32_t cpu_pd_en : 1; + uint32_t aon_pd_en : 1; + uint32_t top_pd_en : 1; }; uint32_t val; -} pmu_hp_active_icg_hp_func_reg_t; +} pmu_hp_dig_power_reg_t; -/** Type of hp_active_icg_hp_apb register - * need_des - */ typedef union { struct { - /** hp_active_dig_icg_apb_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_active_dig_icg_apb_en:32; + uint32_t reserved0: 30; + uint32_t code : 2; }; uint32_t val; -} pmu_hp_active_icg_hp_apb_reg_t; +} pmu_hp_icg_modem_reg_t; -/** Type of hp_active_icg_modem register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** hp_active_dig_icg_modem_code : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_active_dig_icg_modem_code:2; + uint32_t reserved0 : 24; + uint32_t uart_wakeup_en : 1; + uint32_t lp_pad_hold_all: 1; + uint32_t hp_pad_hold_all: 1; + uint32_t dig_pad_slp_sel: 1; + uint32_t dig_pause_wdt : 1; + uint32_t dig_cpu_stall : 1; + uint32_t reserved1 : 2; }; uint32_t val; -} pmu_hp_active_icg_modem_reg_t; +} pmu_hp_sys_cntl_reg_t; -/** Type of hp_active_hp_sys_cntl register - * need_des - */ typedef union { struct { - uint32_t reserved_0:24; - /** hp_active_uart_wakeup_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t hp_active_uart_wakeup_en:1; - /** hp_active_lp_pad_hold_all : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_active_lp_pad_hold_all:1; - /** hp_active_hp_pad_hold_all : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_active_hp_pad_hold_all:1; - /** hp_active_dig_pad_slp_sel : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_dig_pad_slp_sel:1; - /** hp_active_dig_pause_wdt : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_active_dig_pause_wdt:1; - /** hp_active_dig_cpu_stall : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_dig_cpu_stall:1; - uint32_t reserved_30:2; + uint32_t reserved0 : 26; + uint32_t i2c_iso_en : 1; + uint32_t i2c_retention: 1; + uint32_t xpd_bb_i2c : 1; + uint32_t xpd_bbpll_i2c: 1; + uint32_t xpd_bbpll : 1; + uint32_t reserved1 : 1; }; uint32_t val; -} pmu_hp_active_hp_sys_cntl_reg_t; +} pmu_hp_clk_power_reg_t; -/** Type of hp_active_hp_ck_power register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** hp_active_i2c_iso_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_active_i2c_iso_en:1; - /** hp_active_i2c_retention : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_i2c_retention:1; - /** hp_active_xpd_bb_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bb_i2c:1; - /** hp_active_xpd_bbpll_i2c : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bbpll_i2c:1; - /** hp_active_xpd_bbpll : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bbpll:1; - uint32_t reserved_31:1; + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; }; uint32_t val; -} pmu_hp_active_hp_ck_power_reg_t; +} pmu_hp_bias_reg_t; -/** Type of hp_active_bias register - * need_des - */ typedef union { - struct { - uint32_t reserved_0:25; - /** hp_active_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bias:1; - /** hp_active_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t hp_active_dbg_atten:4; - /** hp_active_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_active_pd_cur:1; - /** hp_active_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_active_bias_sleep:1; + struct { /* HP: Active State */ + uint32_t reserved0 : 4; + uint32_t hp_sleep2active_backup_modem_clk_code: 2; + uint32_t hp_modem2active_backup_modem_clk_code: 2; + uint32_t reserved1 : 2; + uint32_t hp_active_retention_mode : 1; + uint32_t hp_sleep2active_retention_en : 1; + uint32_t hp_modem2active_retention_en : 1; + uint32_t reserved2 : 1; + uint32_t hp_sleep2active_backup_clk_sel : 2; + uint32_t hp_modem2active_backup_clk_sel : 2; + uint32_t reserved3 : 2; + uint32_t hp_sleep2active_backup_mode : 3; + uint32_t hp_modem2active_backup_mode : 3; + uint32_t reserved4 : 3; + uint32_t hp_sleep2active_backup_en : 1; + uint32_t hp_modem2active_backup_en : 1; + uint32_t reserved5 : 1; }; - uint32_t val; -} pmu_hp_active_bias_reg_t; - -/** Type of hp_active_backup register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:4; - /** hp_sleep2active_backup_modem_clk_code : R/W; bitpos: [5:4]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_modem_clk_code:2; - /** hp_modem2active_backup_modem_clk_code : R/W; bitpos: [7:6]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_modem_clk_code:2; - uint32_t reserved_8:2; - /** hp_active_retention_mode : R/W; bitpos: [10]; default: 0; - * need_des - */ - uint32_t hp_active_retention_mode:1; - /** hp_sleep2active_retention_en : R/W; bitpos: [11]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_retention_en:1; - /** hp_modem2active_retention_en : R/W; bitpos: [12]; default: 0; - * need_des - */ - uint32_t hp_modem2active_retention_en:1; - uint32_t reserved_13:1; - /** hp_sleep2active_backup_clk_sel : R/W; bitpos: [15:14]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_clk_sel:2; - /** hp_modem2active_backup_clk_sel : R/W; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_clk_sel:2; - uint32_t reserved_18:2; - /** hp_sleep2active_backup_mode : R/W; bitpos: [22:20]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_mode:3; - /** hp_modem2active_backup_mode : R/W; bitpos: [25:23]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_mode:3; - uint32_t reserved_26:3; - /** hp_sleep2active_backup_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_en:1; - /** hp_modem2active_backup_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_en:1; - uint32_t reserved_31:1; + struct { /* HP: Modem State */ + uint32_t reserved6 : 4; + uint32_t hp_sleep2modem_backup_modem_clk_code : 2; + uint32_t reserved7 : 4; + uint32_t hp_modem_retention_mode : 1; + uint32_t hp_sleep2modem_retention_en : 1; + uint32_t reserved8 : 2; + uint32_t hp_sleep2modem_backup_clk_sel : 2; + uint32_t reserved9 : 4; + uint32_t hp_sleep2modem_backup_mode : 3; + uint32_t reserved10 : 6; + uint32_t hp_sleep2modem_backup_en : 1; + uint32_t reserved11 : 2; }; - uint32_t val; -} pmu_hp_active_backup_reg_t; - -/** Type of hp_active_backup_clk register - * need_des - */ -typedef union { - struct { - /** hp_active_backup_icg_func_en : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_active_backup_icg_func_en:32; + struct { /* HP: Sleep State */ + uint32_t reserved12 : 6; + uint32_t hp_modem2sleep_backup_modem_clk_code : 2; + uint32_t hp_active2sleep_backup_modem_clk_code: 2; + uint32_t hp_sleep_retention_mode : 1; + uint32_t reserved13 : 1; + uint32_t hp_modem2sleep_retention_en : 1; + uint32_t hp_active2sleep_retention_en : 1; + uint32_t reserved14 : 2; + uint32_t hp_modem2sleep_backup_clk_sel : 2; + uint32_t hp_active2sleep_backup_clk_sel : 2; + uint32_t reserved15 : 3; + uint32_t hp_modem2sleep_backup_mode : 3; + uint32_t hp_active2sleep_backup_mode : 3; + uint32_t reserved16 : 1; + uint32_t hp_modem2sleep_backup_en : 1; + uint32_t hp_active2sleep_backup_en : 1; }; uint32_t val; -} pmu_hp_active_backup_clk_reg_t; +} pmu_hp_backup_reg_t; -/** Type of hp_active_sysclk register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** hp_active_dig_sys_clk_no_div : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_active_dig_sys_clk_no_div:1; - /** hp_active_icg_sys_clock_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_icg_sys_clock_en:1; - /** hp_active_sys_clk_slp_sel : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_active_sys_clk_slp_sel:1; - /** hp_active_icg_slp_sel : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_icg_slp_sel:1; - /** hp_active_dig_sys_clk_sel : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_active_dig_sys_clk_sel:2; + uint32_t reserved0 : 26; + uint32_t dig_sysclk_nodiv: 1; + uint32_t icg_sysclk_en : 1; + uint32_t sysclk_slp_sel : 1; + uint32_t icg_slp_sel : 1; + uint32_t dig_sysclk_sel : 2; }; uint32_t val; -} pmu_hp_active_sysclk_reg_t; +} pmu_hp_sysclk_reg_t; -/** Type of hp_active_hp_regulator0 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:4; - /** lp_dbias_vol : RO; bitpos: [8:4]; default: 24; - * need_des - */ - uint32_t lp_dbias_vol:5; - /** hp_dbias_vol : RO; bitpos: [13:9]; default: 24; - * need_des - */ - uint32_t hp_dbias_vol:5; - /** dig_regulator0_dbias_sel : R/W; bitpos: [14]; default: 1; - * need_des - */ - uint32_t dig_regulator0_dbias_sel:1; - /** dig_dbias_init : WT; bitpos: [15]; default: 0; - * need_des - */ - uint32_t dig_dbias_init:1; - /** hp_active_hp_regulator_slp_mem_xpd : R/W; bitpos: [16]; default: 1; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_mem_xpd:1; - /** hp_active_hp_regulator_slp_logic_xpd : R/W; bitpos: [17]; default: 1; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_logic_xpd:1; - /** hp_active_hp_regulator_xpd : R/W; bitpos: [18]; default: 1; - * need_des - */ - uint32_t hp_active_hp_regulator_xpd:1; - /** hp_active_hp_regulator_slp_mem_dbias : R/W; bitpos: [22:19]; default: 12; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_mem_dbias:4; - /** hp_active_hp_regulator_slp_logic_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_logic_dbias:4; - /** hp_active_hp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_active_hp_regulator_dbias:5; + uint32_t reserved0 : 4; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t lp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t hp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_sel : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_init : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t slp_mem_xpd : 1; + uint32_t slp_logic_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_mem_dbias : 4; + uint32_t slp_logic_dbias: 4; + uint32_t dbias : 5; }; uint32_t val; -} pmu_hp_active_hp_regulator0_reg_t; +} pmu_hp_regulator0_reg_t; -/** Type of hp_active_hp_regulator1 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:8; - /** hp_active_hp_regulator_drv_b : R/W; bitpos: [31:8]; default: 0; - * need_des - */ - uint32_t hp_active_hp_regulator_drv_b:24; + uint32_t reserved0: 8; + uint32_t drv_b : 24; }; uint32_t val; -} pmu_hp_active_hp_regulator1_reg_t; +} pmu_hp_regulator1_reg_t; -/** Type of hp_active_xtal register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** hp_active_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t hp_active_xpd_xtal:1; + uint32_t reserved0: 31; + uint32_t xpd_xtal : 1; }; uint32_t val; -} pmu_hp_active_xtal_reg_t; +} pmu_hp_xtal_reg_t; -/** Type of hp_modem_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** hp_modem_vdd_spi_pd_en : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t hp_modem_vdd_spi_pd_en:1; - /** hp_modem_hp_mem_dslp : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t hp_modem_hp_mem_dslp:1; - /** hp_modem_pd_hp_mem_pd_en : R/W; bitpos: [26:23]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_mem_pd_en:4; - /** hp_modem_pd_hp_wifi_pd_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_wifi_pd_en:1; - uint32_t reserved_28:1; - /** hp_modem_pd_hp_cpu_pd_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_cpu_pd_en:1; - /** hp_modem_pd_hp_aon_pd_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_aon_pd_en:1; - /** hp_modem_pd_top_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_top_pd_en:1; - }; - uint32_t val; -} pmu_hp_modem_dig_power_reg_t; +typedef struct pmu_hp_hw_regmap_t{ + pmu_hp_dig_power_reg_t dig_power; + uint32_t icg_func; + uint32_t icg_apb; + pmu_hp_icg_modem_reg_t icg_modem; + pmu_hp_sys_cntl_reg_t syscntl; + pmu_hp_clk_power_reg_t clk_power; + pmu_hp_bias_reg_t bias; + pmu_hp_backup_reg_t backup; + uint32_t backup_clk; + pmu_hp_sysclk_reg_t sysclk; + pmu_hp_regulator0_reg_t regulator0; + pmu_hp_regulator1_reg_t regulator1; + pmu_hp_xtal_reg_t xtal; +} pmu_hp_hw_regmap_t; -/** Type of hp_modem_icg_hp_func register - * need_des - */ +/** */ typedef union { struct { - /** hp_modem_dig_icg_func_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_modem_dig_icg_func_en:32; + uint32_t reserved0: 21; + uint32_t slp_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_dbias: 4; + uint32_t dbias : 5; }; uint32_t val; -} pmu_hp_modem_icg_hp_func_reg_t; +} pmu_lp_regulator0_reg_t; -/** Type of hp_modem_icg_hp_apb register - * need_des - */ typedef union { struct { - /** hp_modem_dig_icg_apb_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_modem_dig_icg_apb_en:32; + uint32_t reserved0: 28; + uint32_t drv_b : 4; }; uint32_t val; -} pmu_hp_modem_icg_hp_apb_reg_t; +} pmu_lp_regulator1_reg_t; -/** Type of hp_modem_icg_modem register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** hp_modem_dig_icg_modem_code : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_icg_modem_code:2; + uint32_t reserved0: 31; + uint32_t xpd_xtal : 1; }; uint32_t val; -} pmu_hp_modem_icg_modem_reg_t; +} pmu_lp_xtal_reg_t; -/** Type of hp_modem_hp_sys_cntl register - * need_des - */ typedef union { struct { - uint32_t reserved_0:24; - /** hp_modem_uart_wakeup_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t hp_modem_uart_wakeup_en:1; - /** hp_modem_lp_pad_hold_all : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_modem_lp_pad_hold_all:1; - /** hp_modem_hp_pad_hold_all : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_modem_hp_pad_hold_all:1; - /** hp_modem_dig_pad_slp_sel : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_pad_slp_sel:1; - /** hp_modem_dig_pause_wdt : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_pause_wdt:1; - /** hp_modem_dig_cpu_stall : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_cpu_stall:1; - uint32_t reserved_30:2; + uint32_t reserved0 : 30; + uint32_t mem_dslp : 1; + uint32_t peri_pd_en: 1; }; uint32_t val; -} pmu_hp_modem_hp_sys_cntl_reg_t; +} pmu_lp_dig_power_reg_t; -/** Type of hp_modem_hp_ck_power register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** hp_modem_i2c_iso_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_modem_i2c_iso_en:1; - /** hp_modem_i2c_retention : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_i2c_retention:1; - /** hp_modem_xpd_bb_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bb_i2c:1; - /** hp_modem_xpd_bbpll_i2c : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bbpll_i2c:1; - /** hp_modem_xpd_bbpll : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bbpll:1; - uint32_t reserved_31:1; + uint32_t reserved0 : 28; + uint32_t xpd_xtal32k: 1; + uint32_t xpd_rc32k : 1; + uint32_t xpd_fosc : 1; + uint32_t pd_osc : 1; }; uint32_t val; -} pmu_hp_modem_hp_ck_power_reg_t; +} pmu_lp_clk_power_reg_t; -/** Type of hp_modem_bias register - * need_des - */ typedef union { struct { - uint32_t reserved_0:25; - /** hp_modem_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bias:1; - /** hp_modem_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t hp_modem_dbg_atten:4; - /** hp_modem_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_cur:1; - /** hp_modem_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_modem_bias_sleep:1; + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; }; uint32_t val; -} pmu_hp_modem_bias_reg_t; +} pmu_lp_bias_reg_t; -/** Type of hp_modem_backup register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:4; - /** hp_sleep2modem_backup_modem_clk_code : R/W; bitpos: [5:4]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_modem_clk_code:2; - uint32_t reserved_6:4; - /** hp_modem_retention_mode : R/W; bitpos: [10]; default: 0; - * need_des - */ - uint32_t hp_modem_retention_mode:1; - /** hp_sleep2modem_retention_en : R/W; bitpos: [11]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_retention_en:1; - uint32_t reserved_12:2; - /** hp_sleep2modem_backup_clk_sel : R/W; bitpos: [15:14]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_clk_sel:2; - uint32_t reserved_16:4; - /** hp_sleep2modem_backup_mode : R/W; bitpos: [22:20]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_mode:3; - uint32_t reserved_23:6; - /** hp_sleep2modem_backup_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_en:1; - uint32_t reserved_30:2; - }; - uint32_t val; -} pmu_hp_modem_backup_reg_t; +typedef struct pmu_lp_hw_regmap_t{ + pmu_lp_regulator0_reg_t regulator0; + pmu_lp_regulator1_reg_t regulator1; + pmu_lp_xtal_reg_t xtal; /* Only LP_SLEEP mode under lp system is valid */ + pmu_lp_dig_power_reg_t dig_power; + pmu_lp_clk_power_reg_t clk_power; + pmu_lp_bias_reg_t bias; /* Only LP_SLEEP mode under lp system is valid */ +} pmu_lp_hw_regmap_t; -/** Type of hp_modem_backup_clk register - * need_des - */ -typedef union { - struct { - /** hp_modem_backup_icg_func_en : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_modem_backup_icg_func_en:32; - }; - uint32_t val; -} pmu_hp_modem_backup_clk_reg_t; -/** Type of hp_modem_sysclk register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** hp_modem_dig_sys_clk_no_div : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_sys_clk_no_div:1; - /** hp_modem_icg_sys_clock_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_icg_sys_clock_en:1; - /** hp_modem_sys_clk_slp_sel : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_modem_sys_clk_slp_sel:1; - /** hp_modem_icg_slp_sel : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_icg_slp_sel:1; - /** hp_modem_dig_sys_clk_sel : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_sys_clk_sel:2; + uint32_t tie_low_global_bbpll_icg : 1; + uint32_t tie_low_global_xtal_icg : 1; + uint32_t tie_low_i2c_retention : 1; + uint32_t tie_low_xpd_bb_i2c : 1; + uint32_t tie_low_xpd_bbpll_i2c : 1; + uint32_t tie_low_xpd_bbpll : 1; + uint32_t tie_low_xpd_xtal : 1; + uint32_t reserved0 : 18; + uint32_t tie_high_global_bbpll_icg: 1; + uint32_t tie_high_global_xtal_icg : 1; + uint32_t tie_high_i2c_retention : 1; + uint32_t tie_high_xpd_bb_i2c : 1; + uint32_t tie_high_xpd_bbpll_i2c : 1; + uint32_t tie_high_xpd_bbpll : 1; + uint32_t tie_high_xpd_xtal : 1; }; uint32_t val; -} pmu_hp_modem_sysclk_reg_t; +} pmu_imm_hp_clk_power_reg_t; -/** Type of hp_modem_hp_regulator0 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:16; - /** hp_modem_hp_regulator_slp_mem_xpd : R/W; bitpos: [16]; default: 1; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_mem_xpd:1; - /** hp_modem_hp_regulator_slp_logic_xpd : R/W; bitpos: [17]; default: 1; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_logic_xpd:1; - /** hp_modem_hp_regulator_xpd : R/W; bitpos: [18]; default: 1; - * need_des - */ - uint32_t hp_modem_hp_regulator_xpd:1; - /** hp_modem_hp_regulator_slp_mem_dbias : R/W; bitpos: [22:19]; default: 12; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_mem_dbias:4; - /** hp_modem_hp_regulator_slp_logic_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_logic_dbias:4; - /** hp_modem_hp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_modem_hp_regulator_dbias:5; - }; - uint32_t val; -} pmu_hp_modem_hp_regulator0_reg_t; - -/** Type of hp_modem_hp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:8; - /** hp_modem_hp_regulator_drv_b : R/W; bitpos: [31:8]; default: 0; - * need_des - */ - uint32_t hp_modem_hp_regulator_drv_b:24; - }; - uint32_t val; -} pmu_hp_modem_hp_regulator1_reg_t; - -/** Type of hp_modem_xtal register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** hp_modem_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t hp_modem_xpd_xtal:1; - }; - uint32_t val; -} pmu_hp_modem_xtal_reg_t; - -/** Type of hp_sleep_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** hp_sleep_vdd_spi_pd_en : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t hp_sleep_vdd_spi_pd_en:1; - /** hp_sleep_hp_mem_dslp : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t hp_sleep_hp_mem_dslp:1; - /** hp_sleep_pd_hp_mem_pd_en : R/W; bitpos: [26:23]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_mem_pd_en:4; - /** hp_sleep_pd_hp_wifi_pd_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_wifi_pd_en:1; - uint32_t reserved_28:1; - /** hp_sleep_pd_hp_cpu_pd_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_cpu_pd_en:1; - /** hp_sleep_pd_hp_aon_pd_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_aon_pd_en:1; - /** hp_sleep_pd_top_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_top_pd_en:1; - }; - uint32_t val; -} pmu_hp_sleep_dig_power_reg_t; - -/** Type of hp_sleep_icg_hp_func register - * need_des - */ -typedef union { - struct { - /** hp_sleep_dig_icg_func_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_sleep_dig_icg_func_en:32; - }; - uint32_t val; -} pmu_hp_sleep_icg_hp_func_reg_t; - -/** Type of hp_sleep_icg_hp_apb register - * need_des - */ -typedef union { - struct { - /** hp_sleep_dig_icg_apb_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_sleep_dig_icg_apb_en:32; - }; - uint32_t val; -} pmu_hp_sleep_icg_hp_apb_reg_t; - -/** Type of hp_sleep_icg_modem register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** hp_sleep_dig_icg_modem_code : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_icg_modem_code:2; - }; - uint32_t val; -} pmu_hp_sleep_icg_modem_reg_t; - -/** Type of hp_sleep_hp_sys_cntl register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:24; - /** hp_sleep_uart_wakeup_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t hp_sleep_uart_wakeup_en:1; - /** hp_sleep_lp_pad_hold_all : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_pad_hold_all:1; - /** hp_sleep_hp_pad_hold_all : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_sleep_hp_pad_hold_all:1; - /** hp_sleep_dig_pad_slp_sel : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_pad_slp_sel:1; - /** hp_sleep_dig_pause_wdt : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_pause_wdt:1; - /** hp_sleep_dig_cpu_stall : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_cpu_stall:1; - uint32_t reserved_30:2; - }; - uint32_t val; -} pmu_hp_sleep_hp_sys_cntl_reg_t; - -/** Type of hp_sleep_hp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:26; - /** hp_sleep_i2c_iso_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_sleep_i2c_iso_en:1; - /** hp_sleep_i2c_retention : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_i2c_retention:1; - /** hp_sleep_xpd_bb_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bb_i2c:1; - /** hp_sleep_xpd_bbpll_i2c : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bbpll_i2c:1; - /** hp_sleep_xpd_bbpll : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bbpll:1; - uint32_t reserved_31:1; - }; - uint32_t val; -} pmu_hp_sleep_hp_ck_power_reg_t; - -/** Type of hp_sleep_bias register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:25; - /** hp_sleep_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bias:1; - /** hp_sleep_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t hp_sleep_dbg_atten:4; - /** hp_sleep_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_cur:1; - /** hp_sleep_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_bias_sleep:1; - }; - uint32_t val; -} pmu_hp_sleep_bias_reg_t; - -/** Type of hp_sleep_backup register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:6; - /** hp_modem2sleep_backup_modem_clk_code : R/W; bitpos: [7:6]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_modem_clk_code:2; - /** hp_active2sleep_backup_modem_clk_code : R/W; bitpos: [9:8]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_modem_clk_code:2; - /** hp_sleep_retention_mode : R/W; bitpos: [10]; default: 0; - * need_des - */ - uint32_t hp_sleep_retention_mode:1; - uint32_t reserved_11:1; - /** hp_modem2sleep_retention_en : R/W; bitpos: [12]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_retention_en:1; - /** hp_active2sleep_retention_en : R/W; bitpos: [13]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_retention_en:1; - uint32_t reserved_14:2; - /** hp_modem2sleep_backup_clk_sel : R/W; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_clk_sel:2; - /** hp_active2sleep_backup_clk_sel : R/W; bitpos: [19:18]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_clk_sel:2; - uint32_t reserved_20:3; - /** hp_modem2sleep_backup_mode : R/W; bitpos: [25:23]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_mode:3; - /** hp_active2sleep_backup_mode : R/W; bitpos: [28:26]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_mode:3; - uint32_t reserved_29:1; - /** hp_modem2sleep_backup_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_en:1; - /** hp_active2sleep_backup_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_en:1; - }; - uint32_t val; -} pmu_hp_sleep_backup_reg_t; - -/** Type of hp_sleep_backup_clk register - * need_des - */ -typedef union { - struct { - /** hp_sleep_backup_icg_func_en : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_sleep_backup_icg_func_en:32; - }; - uint32_t val; -} pmu_hp_sleep_backup_clk_reg_t; - -/** Type of hp_sleep_sysclk register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:26; - /** hp_sleep_dig_sys_clk_no_div : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_sys_clk_no_div:1; - /** hp_sleep_icg_sys_clock_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_icg_sys_clock_en:1; - /** hp_sleep_sys_clk_slp_sel : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_sys_clk_slp_sel:1; - /** hp_sleep_icg_slp_sel : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_icg_slp_sel:1; - /** hp_sleep_dig_sys_clk_sel : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_sys_clk_sel:2; - }; - uint32_t val; -} pmu_hp_sleep_sysclk_reg_t; - -/** Type of hp_sleep_hp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:16; - /** hp_sleep_hp_regulator_slp_mem_xpd : R/W; bitpos: [16]; default: 1; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_mem_xpd:1; - /** hp_sleep_hp_regulator_slp_logic_xpd : R/W; bitpos: [17]; default: 1; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_logic_xpd:1; - /** hp_sleep_hp_regulator_xpd : R/W; bitpos: [18]; default: 1; - * need_des - */ - uint32_t hp_sleep_hp_regulator_xpd:1; - /** hp_sleep_hp_regulator_slp_mem_dbias : R/W; bitpos: [22:19]; default: 12; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_mem_dbias:4; - /** hp_sleep_hp_regulator_slp_logic_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_logic_dbias:4; - /** hp_sleep_hp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_sleep_hp_regulator_dbias:5; - }; - uint32_t val; -} pmu_hp_sleep_hp_regulator0_reg_t; - -/** Type of hp_sleep_hp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:8; - /** hp_sleep_hp_regulator_drv_b : R/W; bitpos: [31:8]; default: 0; - * need_des - */ - uint32_t hp_sleep_hp_regulator_drv_b:24; - }; - uint32_t val; -} pmu_hp_sleep_hp_regulator1_reg_t; - -/** Type of hp_sleep_xtal register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** hp_sleep_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t hp_sleep_xpd_xtal:1; - }; - uint32_t val; -} pmu_hp_sleep_xtal_reg_t; - -/** Type of hp_sleep_lp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** hp_sleep_lp_regulator_slp_xpd : R/W; bitpos: [21]; default: 1; - * need_des - */ - uint32_t hp_sleep_lp_regulator_slp_xpd:1; - /** hp_sleep_lp_regulator_xpd : R/W; bitpos: [22]; default: 1; - * need_des - */ - uint32_t hp_sleep_lp_regulator_xpd:1; - /** hp_sleep_lp_regulator_slp_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_sleep_lp_regulator_slp_dbias:4; - /** hp_sleep_lp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_sleep_lp_regulator_dbias:5; - }; - uint32_t val; -} pmu_hp_sleep_lp_regulator0_reg_t; - -/** Type of hp_sleep_lp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** hp_sleep_lp_regulator_drv_b : R/W; bitpos: [31:28]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_regulator_drv_b:4; - }; - uint32_t val; -} pmu_hp_sleep_lp_regulator1_reg_t; - -/** Type of hp_sleep_lp_dcdc_reserve register - * need_des - */ -typedef union { - struct { - /** hp_sleep_lp_dcdc_reserve : WT; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_dcdc_reserve:32; - }; - uint32_t val; -} pmu_hp_sleep_lp_dcdc_reserve_reg_t; - -/** Type of hp_sleep_lp_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** hp_sleep_lp_mem_dslp : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_mem_dslp:1; - /** hp_sleep_pd_lp_peri_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_lp_peri_pd_en:1; - }; - uint32_t val; -} pmu_hp_sleep_lp_dig_power_reg_t; - -/** Type of hp_sleep_lp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** hp_sleep_xpd_xtal32k : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_xtal32k:1; - /** hp_sleep_xpd_rc32k : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_rc32k:1; - /** hp_sleep_xpd_fosc_clk : R/W; bitpos: [30]; default: 1; - * need_des - */ - uint32_t hp_sleep_xpd_fosc_clk:1; - /** hp_sleep_pd_osc_clk : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_osc_clk:1; - }; - uint32_t val; -} pmu_hp_sleep_lp_ck_power_reg_t; - -/** Type of lp_sleep_lp_bias_reserve register - * need_des - */ -typedef union { - struct { - /** lp_sleep_lp_bias_reserve : WT; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t lp_sleep_lp_bias_reserve:32; - }; - uint32_t val; -} pmu_lp_sleep_lp_bias_reserve_reg_t; - -/** Type of lp_sleep_lp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** lp_sleep_lp_regulator_slp_xpd : R/W; bitpos: [21]; default: 1; - * need_des - */ - uint32_t lp_sleep_lp_regulator_slp_xpd:1; - /** lp_sleep_lp_regulator_xpd : R/W; bitpos: [22]; default: 1; - * need_des - */ - uint32_t lp_sleep_lp_regulator_xpd:1; - /** lp_sleep_lp_regulator_slp_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t lp_sleep_lp_regulator_slp_dbias:4; - /** lp_sleep_lp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t lp_sleep_lp_regulator_dbias:5; - }; - uint32_t val; -} pmu_lp_sleep_lp_regulator0_reg_t; - -/** Type of lp_sleep_lp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** lp_sleep_lp_regulator_drv_b : R/W; bitpos: [31:28]; default: 0; - * need_des - */ - uint32_t lp_sleep_lp_regulator_drv_b:4; - }; - uint32_t val; -} pmu_lp_sleep_lp_regulator1_reg_t; - -/** Type of lp_sleep_xtal register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** lp_sleep_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t lp_sleep_xpd_xtal:1; - }; - uint32_t val; -} pmu_lp_sleep_xtal_reg_t; - -/** Type of lp_sleep_lp_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** lp_sleep_lp_mem_dslp : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_sleep_lp_mem_dslp:1; - /** lp_sleep_pd_lp_peri_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_sleep_pd_lp_peri_pd_en:1; - }; - uint32_t val; -} pmu_lp_sleep_lp_dig_power_reg_t; - -/** Type of lp_sleep_lp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** lp_sleep_xpd_xtal32k : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t lp_sleep_xpd_xtal32k:1; - /** lp_sleep_xpd_rc32k : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t lp_sleep_xpd_rc32k:1; - /** lp_sleep_xpd_fosc_clk : R/W; bitpos: [30]; default: 1; - * need_des - */ - uint32_t lp_sleep_xpd_fosc_clk:1; - /** lp_sleep_pd_osc_clk : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_sleep_pd_osc_clk:1; - }; - uint32_t val; -} pmu_lp_sleep_lp_ck_power_reg_t; - -/** Type of lp_sleep_bias register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:25; - /** lp_sleep_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t lp_sleep_xpd_bias:1; - /** lp_sleep_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t lp_sleep_dbg_atten:4; - /** lp_sleep_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_sleep_pd_cur:1; - /** lp_sleep_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_sleep_bias_sleep:1; - }; - uint32_t val; -} pmu_lp_sleep_bias_reg_t; - -/** Type of imm_hp_ck_power register - * need_des - */ -typedef union { - struct { - /** tie_low_global_bbpll_icg : WT; bitpos: [0]; default: 0; - * need_des - */ - uint32_t tie_low_global_bbpll_icg:1; - /** tie_low_global_xtal_icg : WT; bitpos: [1]; default: 0; - * need_des - */ - uint32_t tie_low_global_xtal_icg:1; - /** tie_low_i2c_retention : WT; bitpos: [2]; default: 0; - * need_des - */ - uint32_t tie_low_i2c_retention:1; - /** tie_low_xpd_bb_i2c : WT; bitpos: [3]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_bb_i2c:1; - /** tie_low_xpd_bbpll_i2c : WT; bitpos: [4]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_bbpll_i2c:1; - /** tie_low_xpd_bbpll : WT; bitpos: [5]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_bbpll:1; - /** tie_low_xpd_xtal : WT; bitpos: [6]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_xtal:1; - uint32_t reserved_7:18; - /** tie_high_global_bbpll_icg : WT; bitpos: [25]; default: 0; - * need_des - */ - uint32_t tie_high_global_bbpll_icg:1; - /** tie_high_global_xtal_icg : WT; bitpos: [26]; default: 0; - * need_des - */ - uint32_t tie_high_global_xtal_icg:1; - /** tie_high_i2c_retention : WT; bitpos: [27]; default: 0; - * need_des - */ - uint32_t tie_high_i2c_retention:1; - /** tie_high_xpd_bb_i2c : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_bb_i2c:1; - /** tie_high_xpd_bbpll_i2c : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_bbpll_i2c:1; - /** tie_high_xpd_bbpll : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_bbpll:1; - /** tie_high_xpd_xtal : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_xtal:1; - }; - uint32_t val; -} pmu_imm_hp_ck_power_reg_t; - -/** Type of imm_sleep_sysclk register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** update_dig_icg_switch : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t update_dig_icg_switch:1; - /** tie_low_icg_slp_sel : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t tie_low_icg_slp_sel:1; - /** tie_high_icg_slp_sel : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_icg_slp_sel:1; - /** update_dig_sys_clk_sel : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_sys_clk_sel:1; + uint32_t reserved0 : 28; + uint32_t update_dig_icg_switch: 1; + uint32_t tie_low_icg_slp_sel : 1; + uint32_t tie_high_icg_slp_sel : 1; + uint32_t update_dig_sysclk_sel: 1; }; uint32_t val; } pmu_imm_sleep_sysclk_reg_t; -/** Type of imm_hp_func_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** update_dig_icg_func_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_icg_func_en:1; + uint32_t reserved0 : 31; + uint32_t update_dig_icg_func_en: 1; }; uint32_t val; } pmu_imm_hp_func_icg_reg_t; -/** Type of imm_hp_apb_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** update_dig_icg_apb_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_icg_apb_en:1; + uint32_t reserved0 : 31; + uint32_t update_dig_icg_apb_en: 1; }; uint32_t val; } pmu_imm_hp_apb_icg_reg_t; -/** Type of imm_modem_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** update_dig_icg_modem_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_icg_modem_en:1; + uint32_t reserved0 : 31; + uint32_t update_dig_icg_modem_en: 1; }; uint32_t val; } pmu_imm_modem_icg_reg_t; -/** Type of imm_lp_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** tie_low_lp_rootclk_sel : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_low_lp_rootclk_sel:1; - /** tie_high_lp_rootclk_sel : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_high_lp_rootclk_sel:1; + uint32_t reserved0 : 30; + uint32_t tie_low_lp_rootclk_sel : 1; + uint32_t tie_high_lp_rootclk_sel: 1; }; uint32_t val; } pmu_imm_lp_icg_reg_t; -/** Type of imm_pad_hold_all register - * need_des - */ typedef union { struct { - uint32_t reserved_0:28; - /** tie_high_lp_pad_hold_all : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t tie_high_lp_pad_hold_all:1; - /** tie_low_lp_pad_hold_all : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t tie_low_lp_pad_hold_all:1; - /** tie_high_hp_pad_hold_all : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_hp_pad_hold_all:1; - /** tie_low_hp_pad_hold_all : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_low_hp_pad_hold_all:1; + uint32_t reserved0 : 28; + uint32_t tie_high_lp_pad_hold_all: 1; + uint32_t tie_low_lp_pad_hold_all : 1; + uint32_t tie_high_hp_pad_hold_all: 1; + uint32_t tie_low_hp_pad_hold_all : 1; }; uint32_t val; } pmu_imm_pad_hold_all_reg_t; -/** Type of imm_i2c_iso register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** tie_high_i2c_iso_en : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_i2c_iso_en:1; - /** tie_low_i2c_iso_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_low_i2c_iso_en:1; + uint32_t reserved0 : 30; + uint32_t tie_high_i2c_iso_en: 1; + uint32_t tie_low_i2c_iso_en : 1; }; uint32_t val; -} pmu_imm_i2c_iso_reg_t; +} pmu_imm_i2c_isolate_reg_t; + +typedef struct pmu_imm_hw_regmap_t{ + pmu_imm_hp_clk_power_reg_t clk_power; + pmu_imm_sleep_sysclk_reg_t sleep_sysclk; + pmu_imm_hp_func_icg_reg_t hp_func_icg; + pmu_imm_hp_apb_icg_reg_t hp_apb_icg; + pmu_imm_modem_icg_reg_t modem_icg; + pmu_imm_lp_icg_reg_t lp_icg; + pmu_imm_pad_hold_all_reg_t pad_hold_all; + pmu_imm_i2c_isolate_reg_t i2c_iso; +} pmu_imm_hw_regmap_t; -/** Type of power_wait_timer0 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:5; - /** dg_hp_powerdown_timer : R/W; bitpos: [13:5]; default: 255; - * need_des - */ - uint32_t dg_hp_powerdown_timer:9; - /** dg_hp_powerup_timer : R/W; bitpos: [22:14]; default: 255; - * need_des - */ - uint32_t dg_hp_powerup_timer:9; - /** dg_hp_wait_timer : R/W; bitpos: [31:23]; default: 255; - * need_des - */ - uint32_t dg_hp_wait_timer:9; + uint32_t reserved0 : 5; + uint32_t powerdown_timer: 9; + uint32_t powerup_timer : 9; + uint32_t wait_timer : 9; }; uint32_t val; } pmu_power_wait_timer0_reg_t; -/** Type of power_wait_timer1 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:9; - /** dg_lp_powerdown_timer : R/W; bitpos: [15:9]; default: 255; - * need_des - */ - uint32_t dg_lp_powerdown_timer:7; - /** dg_lp_powerup_timer : R/W; bitpos: [22:16]; default: 255; - * need_des - */ - uint32_t dg_lp_powerup_timer:7; - /** dg_lp_wait_timer : R/W; bitpos: [31:23]; default: 255; - * need_des - */ - uint32_t dg_lp_wait_timer:9; + uint32_t reserved0 : 9; + uint32_t powerdown_timer: 7; + uint32_t powerup_timer : 7; + uint32_t wait_timer : 9; }; uint32_t val; } pmu_power_wait_timer1_reg_t; -/** Type of power_pd_top_cntl register - * need_des - */ -typedef union { - struct { - /** force_top_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_top_reset:1; - /** force_top_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_top_iso:1; - /** force_top_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_top_pu:1; - /** force_top_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_top_no_reset:1; - /** force_top_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_top_no_iso:1; - /** force_top_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_top_pd:1; - /** pd_top_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_top_mask:5; - uint32_t reserved_11:16; - /** pd_top_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_top_pd_mask:5; - }; - uint32_t val; -} pmu_power_pd_top_cntl_reg_t; - -/** Type of power_pd_hpaon_cntl register - * need_des - */ -typedef union { - struct { - /** force_hp_aon_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_aon_reset:1; - /** force_hp_aon_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_aon_iso:1; - /** force_hp_aon_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_hp_aon_pu:1; - /** force_hp_aon_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_hp_aon_no_reset:1; - /** force_hp_aon_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_hp_aon_no_iso:1; - /** force_hp_aon_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_hp_aon_pd:1; - /** pd_hp_aon_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_hp_aon_mask:5; - uint32_t reserved_11:16; - /** pd_hp_aon_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_aon_pd_mask:5; - }; - uint32_t val; -} pmu_power_pd_hpaon_cntl_reg_t; - -/** Type of power_pd_hpcpu_cntl register - * need_des - */ -typedef union { - struct { - /** force_hp_cpu_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_cpu_reset:1; - /** force_hp_cpu_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_cpu_iso:1; - /** force_hp_cpu_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_hp_cpu_pu:1; - /** force_hp_cpu_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_hp_cpu_no_reset:1; - /** force_hp_cpu_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_hp_cpu_no_iso:1; - /** force_hp_cpu_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_hp_cpu_pd:1; - /** pd_hp_cpu_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_hp_cpu_mask:5; - uint32_t reserved_11:16; - /** pd_hp_cpu_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_cpu_pd_mask:5; - }; - uint32_t val; -} pmu_power_pd_hpcpu_cntl_reg_t; - -/** Type of power_pd_hpperi_reserve register - * need_des - */ typedef union { struct { - /** hp_peri_reserve : WT; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_peri_reserve:32; + uint32_t force_reset : 1; + uint32_t force_iso : 1; + uint32_t force_pu : 1; + uint32_t force_no_reset: 1; + uint32_t force_no_iso : 1; + uint32_t force_pd : 1; + uint32_t mask : 5; /* Invalid of lp peripherals */ + uint32_t reserved0 : 16; /* Invalid of lp peripherals */ + uint32_t pd_mask : 5; /* Invalid of lp peripherals */ }; uint32_t val; -} pmu_power_pd_hpperi_reserve_reg_t; +} pmu_power_domain_cntl_reg_t; -/** Type of power_pd_hpwifi_cntl register - * need_des - */ typedef union { struct { - /** force_hp_wifi_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_wifi_reset:1; - /** force_hp_wifi_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_wifi_iso:1; - /** force_hp_wifi_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_hp_wifi_pu:1; - /** force_hp_wifi_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_hp_wifi_no_reset:1; - /** force_hp_wifi_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_hp_wifi_no_iso:1; - /** force_hp_wifi_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_hp_wifi_pd:1; - /** pd_hp_wifi_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_hp_wifi_mask:5; - uint32_t reserved_11:16; - /** pd_hp_wifi_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_wifi_pd_mask:5; + uint32_t force_hp_mem_iso : 4; + uint32_t force_hp_mem_pd : 4; + uint32_t reserved0 : 16; + uint32_t force_hp_mem_no_iso: 4; + uint32_t force_hp_mem_pu : 4; }; uint32_t val; -} pmu_power_pd_hpwifi_cntl_reg_t; +} pmu_power_memory_cntl_reg_t; -/** Type of power_pd_lpperi_cntl register - * need_des - */ typedef union { struct { - /** force_lp_peri_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_lp_peri_reset:1; - /** force_lp_peri_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_lp_peri_iso:1; - /** force_lp_peri_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_lp_peri_pu:1; - /** force_lp_peri_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_lp_peri_no_reset:1; - /** force_lp_peri_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_lp_peri_no_iso:1; - /** force_lp_peri_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_lp_peri_pd:1; - uint32_t reserved_6:26; + uint32_t mem2_pd_mask: 5; + uint32_t mem1_pd_mask: 5; + uint32_t mem0_pd_mask: 5; + uint32_t reserved0 : 2; + uint32_t mem2_mask : 5; + uint32_t mem1_mask : 5; + uint32_t mem0_mask : 5; }; uint32_t val; -} pmu_power_pd_lpperi_cntl_reg_t; +} pmu_power_memory_mask_reg_t; -/** Type of power_pd_mem_cntl register - * need_des - */ typedef union { struct { - /** force_hp_mem_iso : R/W; bitpos: [3:0]; default: 0; - * need_des - */ - uint32_t force_hp_mem_iso:4; - /** force_hp_mem_pd : R/W; bitpos: [7:4]; default: 0; - * need_des - */ - uint32_t force_hp_mem_pd:4; - uint32_t reserved_8:16; - /** force_hp_mem_no_iso : R/W; bitpos: [27:24]; default: 15; - * need_des - */ - uint32_t force_hp_mem_no_iso:4; - /** force_hp_mem_pu : R/W; bitpos: [31:28]; default: 15; - * need_des - */ - uint32_t force_hp_mem_pu:4; - }; - uint32_t val; -} pmu_power_pd_mem_cntl_reg_t; - -/** Type of power_pd_mem_mask register - * need_des - */ -typedef union { - struct { - /** pd_hp_mem2_pd_mask : R/W; bitpos: [4:0]; default: 0; - * need_des - */ - uint32_t pd_hp_mem2_pd_mask:5; - /** pd_hp_mem1_pd_mask : R/W; bitpos: [9:5]; default: 0; - * need_des - */ - uint32_t pd_hp_mem1_pd_mask:5; - /** pd_hp_mem0_pd_mask : R/W; bitpos: [14:10]; default: 0; - * need_des - */ - uint32_t pd_hp_mem0_pd_mask:5; - uint32_t reserved_15:2; - /** pd_hp_mem2_mask : R/W; bitpos: [21:17]; default: 0; - * need_des - */ - uint32_t pd_hp_mem2_mask:5; - /** pd_hp_mem1_mask : R/W; bitpos: [26:22]; default: 0; - * need_des - */ - uint32_t pd_hp_mem1_mask:5; - /** pd_hp_mem0_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_mem0_mask:5; - }; - uint32_t val; -} pmu_power_pd_mem_mask_reg_t; - -/** Type of power_hp_pad register - * need_des - */ -typedef union { - struct { - /** force_hp_pad_no_iso_all : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_pad_no_iso_all:1; - /** force_hp_pad_iso_all : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_pad_iso_all:1; - uint32_t reserved_2:30; + uint32_t force_hp_pad_no_iso_all: 1; + uint32_t force_hp_pad_iso_all : 1; + uint32_t reserved0 : 30; }; uint32_t val; } pmu_power_hp_pad_reg_t; -/** Type of power_vdd_spi_cntl register - * need_des - */ typedef union { struct { - uint32_t reserved_0:18; - /** vdd_spi_pwr_wait : R/W; bitpos: [28:18]; default: 255; - * need_des - */ - uint32_t vdd_spi_pwr_wait:11; - /** vdd_spi_pwr_sw : R/W; bitpos: [30:29]; default: 3; - * need_des - */ - uint32_t vdd_spi_pwr_sw:2; - /** vdd_spi_pwr_sel_sw : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t vdd_spi_pwr_sel_sw:1; + uint32_t reserved0 : 18; + uint32_t pwr_wait : 11; + uint32_t pwr_sw : 2; + uint32_t pwr_sel_sw: 1; }; uint32_t val; } pmu_power_vdd_spi_cntl_reg_t; -/** Type of power_ck_wait_cntl register - * need_des - */ typedef union { struct { - /** wait_xtl_stable : R/W; bitpos: [15:0]; default: 256; - * need_des - */ - uint32_t wait_xtl_stable:16; - /** wait_pll_stable : R/W; bitpos: [31:16]; default: 256; - * need_des - */ - uint32_t wait_pll_stable:16; + uint32_t wait_xtal_stable: 16; + uint32_t wait_pll_stable : 16; }; uint32_t val; -} pmu_power_ck_wait_cntl_reg_t; +} pmu_power_clk_wait_cntl_reg_t; + +typedef struct pmu_power_hw_regmap_t{ + pmu_power_wait_timer0_reg_t wait_timer0; + pmu_power_wait_timer1_reg_t wait_timer1; + pmu_power_domain_cntl_reg_t hp_pd[5]; + pmu_power_domain_cntl_reg_t lp_peri; + pmu_power_memory_cntl_reg_t mem_cntl; + pmu_power_memory_mask_reg_t mem_mask; + pmu_power_hp_pad_reg_t hp_pad; + pmu_power_vdd_spi_cntl_reg_t vdd_spi; + pmu_power_clk_wait_cntl_reg_t clk_wait; +} pmu_power_hw_regmap_t; -/** Type of slp_wakeup_cntl0 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** sleep_req : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t sleep_req:1; + uint32_t reserved0: 31; + uint32_t sleep_req: 1; }; uint32_t val; } pmu_slp_wakeup_cntl0_reg_t; -/** Type of slp_wakeup_cntl1 register - * need_des - */ typedef union { struct { - /** sleep_reject_ena : R/W; bitpos: [30:0]; default: 0; - * need_des - */ - uint32_t sleep_reject_ena:31; - /** slp_reject_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t slp_reject_en:1; + uint32_t sleep_reject_ena: 31; + uint32_t slp_reject_en : 1; }; uint32_t val; } pmu_slp_wakeup_cntl1_reg_t; -/** Type of slp_wakeup_cntl2 register - * need_des - */ -typedef union { - struct { - /** wakeup_ena : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t wakeup_ena:32; - }; - uint32_t val; -} pmu_slp_wakeup_cntl2_reg_t; - -/** Type of slp_wakeup_cntl3 register - * need_des - */ typedef union { struct { - /** lp_min_slp_val : R/W; bitpos: [7:0]; default: 0; - * need_des - */ - uint32_t lp_min_slp_val:8; - /** hp_min_slp_val : R/W; bitpos: [15:8]; default: 0; - * need_des - */ - uint32_t hp_min_slp_val:8; - /** sleep_prt_sel : R/W; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t sleep_prt_sel:2; - uint32_t reserved_18:14; + uint32_t lp_min_slp_val: 8; + uint32_t hp_min_slp_val: 8; + uint32_t sleep_prt_sel : 2; + uint32_t reserved0 : 14; }; uint32_t val; } pmu_slp_wakeup_cntl3_reg_t; -/** Type of slp_wakeup_cntl4 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** slp_reject_cause_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t slp_reject_cause_clr:1; + uint32_t reserved0 : 31; + uint32_t slp_reject_cause_clr: 1; }; uint32_t val; } pmu_slp_wakeup_cntl4_reg_t; -/** Type of slp_wakeup_cntl5 register - * need_des - */ typedef union { struct { - /** modem_wait_target : R/W; bitpos: [19:0]; default: 128; - * need_des - */ - uint32_t modem_wait_target:20; - uint32_t reserved_20:4; - /** lp_ana_wait_target : R/W; bitpos: [31:24]; default: 1; - * need_des - */ - uint32_t lp_ana_wait_target:8; + uint32_t modem_wait_target : 20; + uint32_t reserved0 : 4; + uint32_t lp_ana_wait_target: 8; }; uint32_t val; } pmu_slp_wakeup_cntl5_reg_t; -/** Type of slp_wakeup_cntl6 register - * need_des - */ typedef union { struct { - /** soc_wakeup_wait : R/W; bitpos: [19:0]; default: 128; - * need_des - */ - uint32_t soc_wakeup_wait:20; - uint32_t reserved_20:10; - /** soc_wakeup_wait_cfg : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t soc_wakeup_wait_cfg:2; + uint32_t soc_wakeup_wait : 20; + uint32_t reserved0 : 10; + uint32_t soc_wakeup_wait_cfg: 2; }; uint32_t val; } pmu_slp_wakeup_cntl6_reg_t; -/** Type of slp_wakeup_cntl7 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:16; - /** ana_wait_target : R/W; bitpos: [31:16]; default: 1; - * need_des - */ - uint32_t ana_wait_target:16; + uint32_t reserved0 : 16; + uint32_t ana_wait_target: 16; }; uint32_t val; } pmu_slp_wakeup_cntl7_reg_t; -/** Type of slp_wakeup_status0 register - * need_des - */ -typedef union { - struct { - /** wakeup_cause : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t wakeup_cause:32; - }; - uint32_t val; -} pmu_slp_wakeup_status0_reg_t; - -/** Type of slp_wakeup_status1 register - * need_des - */ -typedef union { - struct { - /** reject_cause : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t reject_cause:32; - }; - uint32_t val; -} pmu_slp_wakeup_status1_reg_t; +typedef struct pmu_wakeup_hw_regmap_t{ + pmu_slp_wakeup_cntl0_reg_t cntl0; + pmu_slp_wakeup_cntl1_reg_t cntl1; + uint32_t cntl2; + pmu_slp_wakeup_cntl3_reg_t cntl3; + pmu_slp_wakeup_cntl4_reg_t cntl4; + pmu_slp_wakeup_cntl5_reg_t cntl5; + pmu_slp_wakeup_cntl6_reg_t cntl6; + pmu_slp_wakeup_cntl7_reg_t cntl7; + uint32_t status0; + uint32_t status1; +} pmu_wakeup_hw_regmap_t; -/** Type of hp_ck_poweron register - * need_des - */ typedef union { struct { - /** i2c_por_wait_target : R/W; bitpos: [7:0]; default: 50; - * need_des - */ - uint32_t i2c_por_wait_target:8; - uint32_t reserved_8:24; + uint32_t i2c_por_wait_target: 8; + uint32_t reserved0 : 24; }; uint32_t val; -} pmu_hp_ck_poweron_reg_t; +} pmu_hp_clk_poweron_reg_t; -/** Type of hp_ck_cntl register - * need_des - */ typedef union { struct { - /** modify_icg_cntl_wait : R/W; bitpos: [7:0]; default: 10; - * need_des - */ - uint32_t modify_icg_cntl_wait:8; - /** switch_icg_cntl_wait : R/W; bitpos: [15:8]; default: 10; - * need_des - */ - uint32_t switch_icg_cntl_wait:8; - uint32_t reserved_16:16; + uint32_t modify_icg_cntl_wait: 8; + uint32_t switch_icg_cntl_wait: 8; + uint32_t reserved0 : 16; }; uint32_t val; -} pmu_hp_ck_cntl_reg_t; +} pmu_hp_clk_cntl_reg_t; -/** Type of por_status register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** por_done : RO; bitpos: [31]; default: 1; - * need_des - */ - uint32_t por_done:1; + uint32_t reserved0: 31; + uint32_t por_done : 1; }; uint32_t val; } pmu_por_status_reg_t; -/** Type of rf_pwc register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** perif_i2c_rstb : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t perif_i2c_rstb:1; - /** xpd_perif_i2c : R/W; bitpos: [27]; default: 1; - * need_des - */ - uint32_t xpd_perif_i2c:1; - /** xpd_txrf_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t xpd_txrf_i2c:1; - /** xpd_rfrx_pbus : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t xpd_rfrx_pbus:1; - /** xpd_ckgen_i2c : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t xpd_ckgen_i2c:1; - /** xpd_pll_i2c : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t xpd_pll_i2c:1; + uint32_t reserved0 : 26; + uint32_t perif_i2c_rstb: 1; + uint32_t xpd_perif_i2c : 1; + uint32_t xpd_txrf_i2c : 1; + uint32_t xpd_rfrx_pbus : 1; + uint32_t xpd_ckgen_i2c : 1; + uint32_t xpd_pll_i2c : 1; }; uint32_t val; } pmu_rf_pwc_reg_t; -/** Type of backup_cfg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** backup_sys_clk_no_div : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t backup_sys_clk_no_div:1; + uint32_t reserved0 : 31; + uint32_t backup_sysclk_nodiv: 1; }; uint32_t val; } pmu_backup_cfg_reg_t; -/** Type of int_raw register - * need_des - */ typedef union { struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_raw : R/WTC/SS; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_raw:1; - /** sdio_idle_int_raw : R/WTC/SS; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_raw:1; - /** sw_int_raw : R/WTC/SS; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_raw:1; - /** soc_sleep_reject_int_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_raw:1; - /** soc_wakeup_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_raw:1; + uint32_t reserved0 : 27; + uint32_t lp_cpu_exc: 1; + uint32_t sdio_idle : 1; + uint32_t sw : 1; + uint32_t reject : 1; + uint32_t wakeup : 1; }; uint32_t val; -} pmu_int_raw_reg_t; +} pmu_hp_intr_reg_t; -/** Type of hp_int_st register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_st : RO; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_st:1; - /** sdio_idle_int_st : RO; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_st:1; - /** sw_int_st : RO; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_st:1; - /** soc_sleep_reject_int_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_st:1; - /** soc_wakeup_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_st:1; - }; - uint32_t val; -} pmu_hp_int_st_reg_t; +typedef struct pmu_hp_ext_hw_regmap_t{ + pmu_hp_clk_poweron_reg_t clk_poweron; + pmu_hp_clk_cntl_reg_t clk_cntl; + pmu_por_status_reg_t por_status; + pmu_rf_pwc_reg_t rf_pwc; + pmu_backup_cfg_reg_t backup_cfg; + pmu_hp_intr_reg_t int_raw; + pmu_hp_intr_reg_t int_st; + pmu_hp_intr_reg_t int_ena; + pmu_hp_intr_reg_t int_clr; +} pmu_hp_ext_hw_regmap_t; -/** Type of hp_int_ena register - * need_des - */ typedef union { struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_ena : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_ena:1; - /** sdio_idle_int_ena : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_ena:1; - /** sw_int_ena : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_ena:1; - /** soc_sleep_reject_int_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_ena:1; - /** soc_wakeup_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_ena:1; + uint32_t reserved0 : 20; + uint32_t lp_cpu_wakeup : 1; + uint32_t modem_switch_active_end : 1; + uint32_t sleep_switch_active_end : 1; + uint32_t sleep_switch_modem_end : 1; + uint32_t modem_switch_sleep_end : 1; + uint32_t active_swtich_sleep_end : 1; + uint32_t modem_switch_active_start: 1; + uint32_t sleep_switch_active_start: 1; + uint32_t sleep_switch_modem_start : 1; + uint32_t modem_switch_sleep_start : 1; + uint32_t active_switch_sleep_start: 1; + uint32_t sw_trigger : 1; }; uint32_t val; -} pmu_hp_int_ena_reg_t; +} pmu_lp_intr_reg_t; -/** Type of hp_int_clr register - * need_des - */ typedef union { struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_clr : WT; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_clr:1; - /** sdio_idle_int_clr : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_clr:1; - /** sw_int_clr : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_clr:1; - /** soc_sleep_reject_int_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_clr:1; - /** soc_wakeup_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_clr:1; - }; - uint32_t val; -} pmu_hp_int_clr_reg_t; - -/** Type of lp_int_raw register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_raw : R/WTC/SS; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_raw:1; - /** modem_switch_active_end_int_raw : R/WTC/SS; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_raw:1; - /** sleep_switch_active_end_int_raw : R/WTC/SS; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_raw:1; - /** sleep_switch_modem_end_int_raw : R/WTC/SS; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_raw:1; - /** modem_switch_sleep_end_int_raw : R/WTC/SS; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_raw:1; - /** active_switch_sleep_end_int_raw : R/WTC/SS; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_raw:1; - /** modem_switch_active_start_int_raw : R/WTC/SS; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_raw:1; - /** sleep_switch_active_start_int_raw : R/WTC/SS; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_raw:1; - /** sleep_switch_modem_start_int_raw : R/WTC/SS; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_raw:1; - /** modem_switch_sleep_start_int_raw : R/WTC/SS; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_raw:1; - /** active_switch_sleep_start_int_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_raw:1; - /** hp_sw_trigger_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_raw:1; - }; - uint32_t val; -} pmu_lp_int_raw_reg_t; - -/** Type of lp_int_st register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_st : RO; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_st:1; - /** modem_switch_active_end_int_st : RO; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_st:1; - /** sleep_switch_active_end_int_st : RO; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_st:1; - /** sleep_switch_modem_end_int_st : RO; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_st:1; - /** modem_switch_sleep_end_int_st : RO; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_st:1; - /** active_switch_sleep_end_int_st : RO; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_st:1; - /** modem_switch_active_start_int_st : RO; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_st:1; - /** sleep_switch_active_start_int_st : RO; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_st:1; - /** sleep_switch_modem_start_int_st : RO; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_st:1; - /** modem_switch_sleep_start_int_st : RO; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_st:1; - /** active_switch_sleep_start_int_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_st:1; - /** hp_sw_trigger_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_st:1; - }; - uint32_t val; -} pmu_lp_int_st_reg_t; - -/** Type of lp_int_ena register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_ena : R/W; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_ena:1; - /** modem_switch_active_end_int_ena : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_ena:1; - /** sleep_switch_active_end_int_ena : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_ena:1; - /** sleep_switch_modem_end_int_ena : R/W; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_ena:1; - /** modem_switch_sleep_end_int_ena : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_ena:1; - /** active_switch_sleep_end_int_ena : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_ena:1; - /** modem_switch_active_start_int_ena : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_ena:1; - /** sleep_switch_active_start_int_ena : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_ena:1; - /** sleep_switch_modem_start_int_ena : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_ena:1; - /** modem_switch_sleep_start_int_ena : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_ena:1; - /** active_switch_sleep_start_int_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_ena:1; - /** hp_sw_trigger_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_ena:1; - }; - uint32_t val; -} pmu_lp_int_ena_reg_t; - -/** Type of lp_int_clr register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_clr : WT; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_clr:1; - /** modem_switch_active_end_int_clr : WT; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_clr:1; - /** sleep_switch_active_end_int_clr : WT; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_clr:1; - /** sleep_switch_modem_end_int_clr : WT; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_clr:1; - /** modem_switch_sleep_end_int_clr : WT; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_clr:1; - /** active_switch_sleep_end_int_clr : WT; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_clr:1; - /** modem_switch_active_start_int_clr : WT; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_clr:1; - /** sleep_switch_active_start_int_clr : WT; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_clr:1; - /** sleep_switch_modem_start_int_clr : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_clr:1; - /** modem_switch_sleep_start_int_clr : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_clr:1; - /** active_switch_sleep_start_int_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_clr:1; - /** hp_sw_trigger_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_clr:1; - }; - uint32_t val; -} pmu_lp_int_clr_reg_t; - -/** Type of lp_cpu_pwr0 register - * need_des - */ -typedef union { - struct { - /** lp_cpu_waiti_rdy : RO; bitpos: [0]; default: 0; - * need_des - */ - uint32_t lp_cpu_waiti_rdy:1; - /** lp_cpu_stall_rdy : RO; bitpos: [1]; default: 0; - * need_des - */ - uint32_t lp_cpu_stall_rdy:1; - uint32_t reserved_2:16; - /** lp_cpu_force_stall : R/W; bitpos: [18]; default: 0; - * need_des - */ - uint32_t lp_cpu_force_stall:1; - /** lp_cpu_slp_waiti_flag_en : R/W; bitpos: [19]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_waiti_flag_en:1; - /** lp_cpu_slp_stall_flag_en : R/W; bitpos: [20]; default: 1; - * need_des - */ - uint32_t lp_cpu_slp_stall_flag_en:1; - /** lp_cpu_slp_stall_wait : R/W; bitpos: [28:21]; default: 255; - * need_des - */ - uint32_t lp_cpu_slp_stall_wait:8; - /** lp_cpu_slp_stall_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_stall_en:1; - /** lp_cpu_slp_reset_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_reset_en:1; - /** lp_cpu_slp_bypass_intr_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_bypass_intr_en:1; + uint32_t waiti_rdy : 1; + uint32_t stall_rdy : 1; + uint32_t reserved0 : 16; + uint32_t force_stall : 1; + uint32_t slp_waiti_flag_en : 1; + uint32_t slp_stall_flag_en : 1; + uint32_t slp_stall_wait : 8; + uint32_t slp_stall_en : 1; + uint32_t slp_reset_en : 1; + uint32_t slp_bypass_intr_en: 1; }; uint32_t val; } pmu_lp_cpu_pwr0_reg_t; -/** Type of lp_cpu_pwr1 register - * need_des - */ typedef union { struct { - /** lp_cpu_wakeup_en : R/W; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_en:16; - uint32_t reserved_16:15; - /** lp_cpu_sleep_req : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_cpu_sleep_req:1; + uint32_t wakeup_en: 16; + uint32_t reserved0: 15; + uint32_t sleep_req: 1; }; uint32_t val; } pmu_lp_cpu_pwr1_reg_t; -/** Type of hp_lp_cpu_comm register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** lp_trigger_hp : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_trigger_hp:1; - /** hp_trigger_lp : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_trigger_lp:1; - }; - uint32_t val; -} pmu_hp_lp_cpu_comm_reg_t; - -/** Type of hp_regulator_cfg register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** dig_regulator_en_cal : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t dig_regulator_en_cal:1; - }; - uint32_t val; -} pmu_hp_regulator_cfg_reg_t; - -/** Type of main_state register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:11; - /** main_last_st_state : RO; bitpos: [17:11]; default: 1; - * need_des - */ - uint32_t main_last_st_state:7; - /** main_tar_st_state : RO; bitpos: [24:18]; default: 4; - * need_des - */ - uint32_t main_tar_st_state:7; - /** main_cur_st_state : RO; bitpos: [31:25]; default: 4; - * need_des - */ - uint32_t main_cur_st_state:7; - }; - uint32_t val; -} pmu_main_state_reg_t; - -/** Type of pwr_state register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:13; - /** backup_st_state : RO; bitpos: [17:13]; default: 1; - * need_des - */ - uint32_t backup_st_state:5; - /** lp_pwr_st_state : RO; bitpos: [22:18]; default: 0; - * need_des - */ - uint32_t lp_pwr_st_state:5; - /** hp_pwr_st_state : RO; bitpos: [31:23]; default: 1; - * need_des - */ - uint32_t hp_pwr_st_state:9; - }; - uint32_t val; -} pmu_pwr_state_reg_t; - -/** Type of date register - * need_des - */ -typedef union { - struct { - /** pmu_date : R/W; bitpos: [30:0]; default: 35676752; - * need_des - */ - uint32_t pmu_date:31; - /** clk_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t clk_en:1; - }; - uint32_t val; -} pmu_date_reg_t; - - -/** Group: status_register */ -/** Type of clk_state0 register - * need_des - */ -typedef union { - struct { - /** stable_xpd_bbpll_state : RO; bitpos: [0]; default: 1; - * need_des - */ - uint32_t stable_xpd_bbpll_state:1; - /** stable_xpd_xtal_state : RO; bitpos: [1]; default: 1; - * need_des - */ - uint32_t stable_xpd_xtal_state:1; - uint32_t reserved_2:13; - /** sys_clk_slp_sel_state : RO; bitpos: [15]; default: 0; - * need_des - */ - uint32_t sys_clk_slp_sel_state:1; - /** sys_clk_sel_state : RO; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t sys_clk_sel_state:2; - /** sys_clk_no_div_state : RO; bitpos: [18]; default: 0; - * need_des - */ - uint32_t sys_clk_no_div_state:1; - /** icg_sys_clk_en_state : RO; bitpos: [19]; default: 0; - * need_des - */ - uint32_t icg_sys_clk_en_state:1; - /** icg_modem_switch_state : RO; bitpos: [20]; default: 0; - * need_des - */ - uint32_t icg_modem_switch_state:1; - /** icg_modem_code_state : RO; bitpos: [22:21]; default: 0; - * need_des - */ - uint32_t icg_modem_code_state:2; - /** icg_slp_sel_state : RO; bitpos: [23]; default: 0; - * need_des - */ - uint32_t icg_slp_sel_state:1; - /** icg_global_xtal_state : RO; bitpos: [24]; default: 0; - * need_des - */ - uint32_t icg_global_xtal_state:1; - /** icg_global_pll_state : RO; bitpos: [25]; default: 0; - * need_des - */ - uint32_t icg_global_pll_state:1; - /** ana_i2c_iso_en_state : RO; bitpos: [26]; default: 0; - * need_des - */ - uint32_t ana_i2c_iso_en_state:1; - /** ana_i2c_retention_state : RO; bitpos: [27]; default: 0; - * need_des - */ - uint32_t ana_i2c_retention_state:1; - /** ana_xpd_bb_i2c_state : RO; bitpos: [28]; default: 0; - * need_des - */ - uint32_t ana_xpd_bb_i2c_state:1; - /** ana_xpd_bbpll_i2c_state : RO; bitpos: [29]; default: 0; - * need_des - */ - uint32_t ana_xpd_bbpll_i2c_state:1; - /** ana_xpd_bbpll_state : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t ana_xpd_bbpll_state:1; - /** ana_xpd_xtal_state : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t ana_xpd_xtal_state:1; - }; - uint32_t val; -} pmu_clk_state0_reg_t; - -/** Type of clk_state1 register - * need_des - */ -typedef union { - struct { - /** icg_func_en_state : RO; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t icg_func_en_state:32; - }; - uint32_t val; -} pmu_clk_state1_reg_t; - -/** Type of clk_state2 register - * need_des - */ -typedef union { - struct { - /** icg_apb_en_state : RO; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t icg_apb_en_state:32; - }; - uint32_t val; -} pmu_clk_state2_reg_t; - -/** Type of vdd_spi_status register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** stable_vdd_spi_pwr_drv : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t stable_vdd_spi_pwr_drv:1; - }; - uint32_t val; -} pmu_vdd_spi_status_reg_t; - - -typedef struct pmu_dev_t { - volatile pmu_hp_active_dig_power_reg_t hp_active_dig_power; - volatile pmu_hp_active_icg_hp_func_reg_t hp_active_icg_hp_func; - volatile pmu_hp_active_icg_hp_apb_reg_t hp_active_icg_hp_apb; - volatile pmu_hp_active_icg_modem_reg_t hp_active_icg_modem; - volatile pmu_hp_active_hp_sys_cntl_reg_t hp_active_hp_sys_cntl; - volatile pmu_hp_active_hp_ck_power_reg_t hp_active_hp_ck_power; - volatile pmu_hp_active_bias_reg_t hp_active_bias; - volatile pmu_hp_active_backup_reg_t hp_active_backup; - volatile pmu_hp_active_backup_clk_reg_t hp_active_backup_clk; - volatile pmu_hp_active_sysclk_reg_t hp_active_sysclk; - volatile pmu_hp_active_hp_regulator0_reg_t hp_active_hp_regulator0; - volatile pmu_hp_active_hp_regulator1_reg_t hp_active_hp_regulator1; - volatile pmu_hp_active_xtal_reg_t hp_active_xtal; - volatile pmu_hp_modem_dig_power_reg_t hp_modem_dig_power; - volatile pmu_hp_modem_icg_hp_func_reg_t hp_modem_icg_hp_func; - volatile pmu_hp_modem_icg_hp_apb_reg_t hp_modem_icg_hp_apb; - volatile pmu_hp_modem_icg_modem_reg_t hp_modem_icg_modem; - volatile pmu_hp_modem_hp_sys_cntl_reg_t hp_modem_hp_sys_cntl; - volatile pmu_hp_modem_hp_ck_power_reg_t hp_modem_hp_ck_power; - volatile pmu_hp_modem_bias_reg_t hp_modem_bias; - volatile pmu_hp_modem_backup_reg_t hp_modem_backup; - volatile pmu_hp_modem_backup_clk_reg_t hp_modem_backup_clk; - volatile pmu_hp_modem_sysclk_reg_t hp_modem_sysclk; - volatile pmu_hp_modem_hp_regulator0_reg_t hp_modem_hp_regulator0; - volatile pmu_hp_modem_hp_regulator1_reg_t hp_modem_hp_regulator1; - volatile pmu_hp_modem_xtal_reg_t hp_modem_xtal; - volatile pmu_hp_sleep_dig_power_reg_t hp_sleep_dig_power; - volatile pmu_hp_sleep_icg_hp_func_reg_t hp_sleep_icg_hp_func; - volatile pmu_hp_sleep_icg_hp_apb_reg_t hp_sleep_icg_hp_apb; - volatile pmu_hp_sleep_icg_modem_reg_t hp_sleep_icg_modem; - volatile pmu_hp_sleep_hp_sys_cntl_reg_t hp_sleep_hp_sys_cntl; - volatile pmu_hp_sleep_hp_ck_power_reg_t hp_sleep_hp_ck_power; - volatile pmu_hp_sleep_bias_reg_t hp_sleep_bias; - volatile pmu_hp_sleep_backup_reg_t hp_sleep_backup; - volatile pmu_hp_sleep_backup_clk_reg_t hp_sleep_backup_clk; - volatile pmu_hp_sleep_sysclk_reg_t hp_sleep_sysclk; - volatile pmu_hp_sleep_hp_regulator0_reg_t hp_sleep_hp_regulator0; - volatile pmu_hp_sleep_hp_regulator1_reg_t hp_sleep_hp_regulator1; - volatile pmu_hp_sleep_xtal_reg_t hp_sleep_xtal; - volatile pmu_hp_sleep_lp_regulator0_reg_t hp_sleep_lp_regulator0; - volatile pmu_hp_sleep_lp_regulator1_reg_t hp_sleep_lp_regulator1; - volatile pmu_hp_sleep_lp_dcdc_reserve_reg_t hp_sleep_lp_dcdc_reserve; - volatile pmu_hp_sleep_lp_dig_power_reg_t hp_sleep_lp_dig_power; - volatile pmu_hp_sleep_lp_ck_power_reg_t hp_sleep_lp_ck_power; - volatile pmu_lp_sleep_lp_bias_reserve_reg_t lp_sleep_lp_bias_reserve; - volatile pmu_lp_sleep_lp_regulator0_reg_t lp_sleep_lp_regulator0; - volatile pmu_lp_sleep_lp_regulator1_reg_t lp_sleep_lp_regulator1; - volatile pmu_lp_sleep_xtal_reg_t lp_sleep_xtal; - volatile pmu_lp_sleep_lp_dig_power_reg_t lp_sleep_lp_dig_power; - volatile pmu_lp_sleep_lp_ck_power_reg_t lp_sleep_lp_ck_power; - volatile pmu_lp_sleep_bias_reg_t lp_sleep_bias; - volatile pmu_imm_hp_ck_power_reg_t imm_hp_ck_power; - volatile pmu_imm_sleep_sysclk_reg_t imm_sleep_sysclk; - volatile pmu_imm_hp_func_icg_reg_t imm_hp_func_icg; - volatile pmu_imm_hp_apb_icg_reg_t imm_hp_apb_icg; - volatile pmu_imm_modem_icg_reg_t imm_modem_icg; - volatile pmu_imm_lp_icg_reg_t imm_lp_icg; - volatile pmu_imm_pad_hold_all_reg_t imm_pad_hold_all; - volatile pmu_imm_i2c_iso_reg_t imm_i2c_iso; - volatile pmu_power_wait_timer0_reg_t power_wait_timer0; - volatile pmu_power_wait_timer1_reg_t power_wait_timer1; - volatile pmu_power_pd_top_cntl_reg_t power_pd_top_cntl; - volatile pmu_power_pd_hpaon_cntl_reg_t power_pd_hpaon_cntl; - volatile pmu_power_pd_hpcpu_cntl_reg_t power_pd_hpcpu_cntl; - volatile pmu_power_pd_hpperi_reserve_reg_t power_pd_hpperi_reserve; - volatile pmu_power_pd_hpwifi_cntl_reg_t power_pd_hpwifi_cntl; - volatile pmu_power_pd_lpperi_cntl_reg_t power_pd_lpperi_cntl; - volatile pmu_power_pd_mem_cntl_reg_t power_pd_mem_cntl; - volatile pmu_power_pd_mem_mask_reg_t power_pd_mem_mask; - volatile pmu_power_hp_pad_reg_t power_hp_pad; - volatile pmu_power_vdd_spi_cntl_reg_t power_vdd_spi_cntl; - volatile pmu_power_ck_wait_cntl_reg_t power_ck_wait_cntl; - volatile pmu_slp_wakeup_cntl0_reg_t slp_wakeup_cntl0; - volatile pmu_slp_wakeup_cntl1_reg_t slp_wakeup_cntl1; - volatile pmu_slp_wakeup_cntl2_reg_t slp_wakeup_cntl2; - volatile pmu_slp_wakeup_cntl3_reg_t slp_wakeup_cntl3; - volatile pmu_slp_wakeup_cntl4_reg_t slp_wakeup_cntl4; - volatile pmu_slp_wakeup_cntl5_reg_t slp_wakeup_cntl5; - volatile pmu_slp_wakeup_cntl6_reg_t slp_wakeup_cntl6; - volatile pmu_slp_wakeup_cntl7_reg_t slp_wakeup_cntl7; - volatile pmu_slp_wakeup_status0_reg_t slp_wakeup_status0; - volatile pmu_slp_wakeup_status1_reg_t slp_wakeup_status1; - volatile pmu_hp_ck_poweron_reg_t hp_ck_poweron; - volatile pmu_hp_ck_cntl_reg_t hp_ck_cntl; - volatile pmu_por_status_reg_t por_status; - volatile pmu_rf_pwc_reg_t rf_pwc; - volatile pmu_backup_cfg_reg_t backup_cfg; - volatile pmu_int_raw_reg_t int_raw; - volatile pmu_hp_int_st_reg_t hp_int_st; - volatile pmu_hp_int_ena_reg_t hp_int_ena; - volatile pmu_hp_int_clr_reg_t hp_int_clr; - volatile pmu_lp_int_raw_reg_t lp_int_raw; - volatile pmu_lp_int_st_reg_t lp_int_st; - volatile pmu_lp_int_ena_reg_t lp_int_ena; - volatile pmu_lp_int_clr_reg_t lp_int_clr; - volatile pmu_lp_cpu_pwr0_reg_t lp_cpu_pwr0; - volatile pmu_lp_cpu_pwr1_reg_t lp_cpu_pwr1; - volatile pmu_hp_lp_cpu_comm_reg_t hp_lp_cpu_comm; - volatile pmu_hp_regulator_cfg_reg_t hp_regulator_cfg; - volatile pmu_main_state_reg_t main_state; - volatile pmu_pwr_state_reg_t pwr_state; - volatile pmu_clk_state0_reg_t clk_state0; - volatile pmu_clk_state1_reg_t clk_state1; - volatile pmu_clk_state2_reg_t clk_state2; - volatile pmu_vdd_spi_status_reg_t vdd_spi_status; - uint32_t reserved_1a4[150]; - volatile pmu_date_reg_t date; +typedef struct pmu_lp_ext_hw_regmap_t{ + pmu_lp_intr_reg_t int_raw; + pmu_lp_intr_reg_t int_st; + pmu_lp_intr_reg_t int_ena; + pmu_lp_intr_reg_t int_clr; + pmu_lp_cpu_pwr0_reg_t pwr0; + pmu_lp_cpu_pwr1_reg_t pwr1; +} pmu_lp_ext_hw_regmap_t; + +typedef struct pmu_dev_t{ + volatile pmu_hp_hw_regmap_t hp_sys[3]; + volatile pmu_lp_hw_regmap_t lp_sys[2]; + volatile pmu_imm_hw_regmap_t imm; + volatile pmu_power_hw_regmap_t power; + volatile pmu_wakeup_hw_regmap_t wakeup; + volatile pmu_hp_ext_hw_regmap_t hp_ext; + volatile pmu_lp_ext_hw_regmap_t lp_ext; + + union { + struct { + uint32_t reserved0 : 30; + volatile uint32_t lp_trigger_hp: 1; + volatile uint32_t hp_trigger_lp: 1; + }; + volatile uint32_t val; + } hp_lp_cpu_comm; + + union { + struct { + uint32_t reserved0 : 31; + volatile uint32_t dig_regulator_en_cal: 1; + }; + volatile uint32_t val; + } hp_regulator_cfg; + + union { + struct { + uint32_t reserved0 : 11; + volatile uint32_t last_st : 7; + volatile uint32_t target_st : 7; + volatile uint32_t current_st: 7; + }; + volatile uint32_t val; + } main_state; + + union { + struct { + uint32_t reserved0: 13; + volatile uint32_t backup_st: 5; + volatile uint32_t lp_pwr_st: 5; + volatile uint32_t hp_pwr_st: 9; + }; + volatile uint32_t val; + } pwr_state; + + union { + struct { + volatile uint32_t stable_xpd_bbpll : 1; + volatile uint32_t stable_xpd_xtal : 1; + volatile uint32_t reserved0 : 13; + volatile uint32_t sysclk_slp_sel : 1; + volatile uint32_t sysclk_sel : 2; + volatile uint32_t sysclk_nodiv : 1; + volatile uint32_t icg_sysclk_en : 1; + volatile uint32_t icg_modem_switch : 1; + volatile uint32_t icg_modem_code : 2; + volatile uint32_t icg_slp_sel : 1; + volatile uint32_t icg_global_xtal : 1; + volatile uint32_t icg_global_pll : 1; + volatile uint32_t ana_i2c_iso_en : 1; + volatile uint32_t ana_i2c_retention: 1; + volatile uint32_t ana_xpd_bb_i2c : 1; + volatile uint32_t ana_xpd_bbpll_i2c: 1; + volatile uint32_t ana_xpd_bbpll : 1; + volatile uint32_t ana_xpd_xtal : 1; + }; + volatile uint32_t val; + } clk_state0; + + volatile uint32_t clk_state1; + volatile uint32_t clk_state2; + + union { + struct { + uint32_t reserved0 : 31; + volatile uint32_t stable_vdd_spi_pwr_drv: 1; + }; + volatile uint32_t val; + } vdd_spi_status; + + uint32_t reserved[150]; + + union { + struct { + volatile uint32_t pmu_date: 31; + volatile uint32_t clk_en : 1; + }; + volatile uint32_t val; + } date; } pmu_dev_t; extern pmu_dev_t PMU; #ifndef __cplusplus _Static_assert(sizeof(pmu_dev_t) == 0x400, "Invalid size of pmu_dev_t structure"); + +_Static_assert(offsetof(pmu_dev_t, reserved) == (PMU_VDD_SPI_STATUS_REG - DR_REG_PMU_BASE) + 4, "Invalid size of pmu_dev_t structure"); + #endif #ifdef __cplusplus diff --git a/components/soc/esp32c6/include/soc/reg_base.h b/components/soc/esp32c6/include/soc/reg_base.h index 4fb5d2304ab4..7d8339605edb 100644 --- a/components/soc/esp32c6/include/soc/reg_base.h +++ b/components/soc/esp32c6/include/soc/reg_base.h @@ -1,9 +1,11 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#define DR_REG_PLIC_MX_BASE 0x20001000 +#define DR_REG_PLIC_UX_BASE 0x20001400 #define DR_REG_CLINT_M_BASE 0x20001800 #define DR_REG_CLINT_U_BASE 0x20001C00 @@ -53,6 +55,8 @@ #define DR_REG_LP_APM0_BASE 0x60099800 #define DR_REG_MISC_BASE 0x6009F000 +#define DR_REG_I2C_ANA_MST_BASE 0x600AF800 + #define DR_REG_PMU_BASE 0x600B0000 #define DR_REG_LP_CLKRST_BASE 0x600B0400 #define DR_REG_EFUSE_BASE 0x600B0800 @@ -74,3 +78,5 @@ #define DR_REG_CPU_BUS_MONITOR_BASE 0x600C2000 #define DR_REG_INTPRI_BASE 0x600C5000 #define DR_REG_EXTMEM_BASE 0x600C8000 + +#define PWDET_CONF_REG 0x600A0810 diff --git a/components/soc/esp32c6/include/soc/regi2c_bias.h b/components/soc/esp32c6/include/soc/regi2c_bias.h index 512cb54989b7..9a85b28fb580 100644 --- a/components/soc/esp32c6/include/soc/regi2c_bias.h +++ b/components/soc/esp32c6/include/soc/regi2c_bias.h @@ -11,7 +11,7 @@ * @brief Register definitions for bias * * This file lists register fields of BIAS. These definitions are used via macros defined in regi2c_ctrl.h, by - * bootloader_hardware_init function in bootloader_esp32c3.c. + * bootloader_hardware_init function in bootloader_esp32c6.c. */ #define I2C_BIAS 0X6A diff --git a/components/soc/esp32c6/include/soc/regi2c_defs.h b/components/soc/esp32c6/include/soc/regi2c_defs.h index 9ff42a0da668..38db4f159567 100644 --- a/components/soc/esp32c6/include/soc/regi2c_defs.h +++ b/components/soc/esp32c6/include/soc/regi2c_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,11 +9,13 @@ #include "esp_bit_defs.h" /* Analog function control register */ -#define I2C_MST_ANA_CONF0_REG 0x6000E040 +#define I2C_MST_ANA_CONF0_REG 0x600AF818 #define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2)) -#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3)) +#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3)) +#define I2C_MST_BBPLL_CAL_DONE (BIT(24)) -#define ANA_CONFIG_REG 0x6000E044 + +#define ANA_CONFIG_REG 0x600AF81C #define ANA_CONFIG_S (8) #define ANA_CONFIG_M (0x3FF) @@ -21,14 +23,7 @@ #define ANA_I2C_BBPLL_M BIT(17) /* Clear to enable BBPLL */ -#define ANA_CONFIG2_REG 0x6000E048 +#define ANA_CONFIG2_REG 0x600AF820 #define ANA_CONFIG2_M BIT(18) #define ANA_I2C_SAR_FORCE_PU BIT(16) - -/** - * Restore regi2c analog calibration related configuration registers. - * This is a workaround, and is fixed on later chips - */ -#define REGI2C_ANA_CALI_PD_WORKAROUND 1 -#define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/soc/esp32c6/include/soc/regi2c_dig_reg.h b/components/soc/esp32c6/include/soc/regi2c_dig_reg.h new file mode 100644 index 000000000000..b71845476ed0 --- /dev/null +++ b/components/soc/esp32c6/include/soc/regi2c_dig_reg.h @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/** + * @file regi2c_dig_reg.h + * @brief Register definitions for digital to get rtc voltage & digital voltage + * by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration. + */ + +#define I2C_DIG_REG 0x6D +#define I2C_DIG_REG_HOSTID 0 + +#define I2C_DIG_REG_EXT_RTC_DREG 4 +#define I2C_DIG_REG_EXT_RTC_DREG_MSB 4 +#define I2C_DIG_REG_EXT_RTC_DREG_LSB 0 + +#define I2C_DIG_REG_ENX_RTC_DREG 4 +#define I2C_DIG_REG_ENX_RTC_DREG_MSB 7 +#define I2C_DIG_REG_ENX_RTC_DREG_LSB 7 + +#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP 5 +#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB 4 +#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB 0 + +#define I2C_DIG_REG_ENIF_RTC_DREG 5 +#define I2C_DIG_REG_ENIF_RTC_DREG_MSB 7 +#define I2C_DIG_REG_ENIF_RTC_DREG_LSB 7 + +#define I2C_DIG_REG_EXT_DIG_DREG 6 +#define I2C_DIG_REG_EXT_DIG_DREG_MSB 4 +#define I2C_DIG_REG_EXT_DIG_DREG_LSB 0 + +#define I2C_DIG_REG_ENX_DIG_DREG 6 +#define I2C_DIG_REG_ENX_DIG_DREG_MSB 7 +#define I2C_DIG_REG_ENX_DIG_DREG_LSB 7 + +#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP 7 +#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB 4 +#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB 0 + +#define I2C_DIG_REG_ENIF_DIG_DREG 7 +#define I2C_DIG_REG_ENIF_DIG_DREG_MSB 7 +#define I2C_DIG_REG_ENIF_DIG_DREG_LSB 7 + +#define I2C_DIG_REG_OR_EN_CONT_CAL 9 +#define I2C_DIG_REG_OR_EN_CONT_CAL_MSB 7 +#define I2C_DIG_REG_OR_EN_CONT_CAL_LSB 7 + +#define I2C_DIG_REG_XPD_RTC_REG 13 +#define I2C_DIG_REG_XPD_RTC_REG_MSB 2 +#define I2C_DIG_REG_XPD_RTC_REG_LSB 2 + +#define I2C_DIG_REG_XPD_DIG_REG 13 +#define I2C_DIG_REG_XPD_DIG_REG_MSB 3 +#define I2C_DIG_REG_XPD_DIG_REG_LSB 3 + +#define I2C_DIG_REG_SCK_DCAP 14 +#define I2C_DIG_REG_SCK_DCAP_MSB 7 +#define I2C_DIG_REG_SCK_DCAP_LSB 0 diff --git a/components/soc/esp32c6/include/soc/reset_reasons.h b/components/soc/esp32c6/include/soc/reset_reasons.h new file mode 100644 index 000000000000..b6b0e33ae397 --- /dev/null +++ b/components/soc/esp32c6/include/soc/reset_reasons.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +//+-----------------------------------------------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 | +//| | +//+-------------------------------------------------------------------------------------------------------+ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Naming conventions: RESET_REASON_{reset level}_{reset reason} + * @note refer to TRM: chapter + */ +typedef enum { + RESET_REASON_CHIP_POWER_ON = 0x01, // Power on reset + RESET_REASON_CHIP_BROWN_OUT = 0x01, // VDD voltage is not stable and resets the chip + RESET_REASON_CORE_SW = 0x03, // Software resets the digital core (hp system) by LP_AON_HPSYS_SW_RESET + RESET_REASON_CORE_DEEP_SLEEP = 0x05, // Deep sleep reset the digital core (hp system) + RESET_REASON_CORE_SDIO = 0x06, // SDIO module resets the digital core (hp system) + RESET_REASON_CORE_MWDT0 = 0x07, // Main watch dog 0 resets digital core (hp system) + RESET_REASON_CORE_MWDT1 = 0x08, // Main watch dog 1 resets digital core (hp system) + RESET_REASON_CORE_RTC_WDT = 0x09, // RTC watch dog resets digital core (hp system) + RESET_REASON_CPU0_MWDT0 = 0x0B, // Main watch dog 0 resets CPU 0 + RESET_REASON_CPU0_SW = 0x0C, // Software resets CPU 0 by LP_AON_CPU_CORE0_SW_RESET + RESET_REASON_CPU0_RTC_WDT = 0x0D, // RTC watch dog resets CPU 0 + RESET_REASON_SYS_BROWN_OUT = 0x0F, // VDD voltage is not stable and resets the digital core + RESET_REASON_SYS_RTC_WDT = 0x10, // RTC watch dog resets digital core and rtc module + RESET_REASON_CPU0_MWDT1 = 0x11, // Main watch dog 1 resets CPU 0 + RESET_REASON_SYS_SUPER_WDT = 0x12, // Super watch dog resets the digital core and rtc module + RESET_REASON_CORE_EFUSE_CRC = 0x14, // eFuse CRC error resets the digital core (hp system) + RESET_REASON_CORE_USB_UART = 0x15, // USB UART resets the digital core (hp system) + RESET_REASON_CORE_USB_JTAG = 0x16, // USB JTAG resets the digital core (hp system) + RESET_REASON_CPU0_JTAG = 0x18, // JTAG resets the CPU 0 +} soc_reset_reason_t; + + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/rmt_reg.h b/components/soc/esp32c6/include/soc/rmt_reg.h index 6d409a9c8ed5..0bc75f17fc2c 100644 --- a/components/soc/esp32c6/include/soc/rmt_reg.h +++ b/components/soc/esp32c6/include/soc/rmt_reg.h @@ -1,7 +1,7 @@ /** * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 + * SPDX-License-Identifier: Apache-2.0 */ #pragma once @@ -183,121 +183,121 @@ extern "C" { * Channel 1 configure register 0 */ #define RMT_CH1CONF0_REG (DR_REG_RMT_BASE + 0x14) -/** RMT_TX_START_CH0 : WT; bitpos: [0]; default: 0; +/** RMT_TX_START_CH1 : WT; bitpos: [0]; default: 0; * Set this bit to start sending data on CHANNEL1. */ -#define RMT_TX_START_CH0 (BIT(0)) -#define RMT_TX_START_CH0_M (RMT_TX_START_CH0_V << RMT_TX_START_CH0_S) -#define RMT_TX_START_CH0_V 0x00000001U -#define RMT_TX_START_CH0_S 0 -/** RMT_MEM_RD_RST_CH0 : WT; bitpos: [1]; default: 0; +#define RMT_TX_START_CH1 (BIT(0)) +#define RMT_TX_START_CH1_M (RMT_TX_START_CH1_V << RMT_TX_START_CH1_S) +#define RMT_TX_START_CH1_V 0x00000001U +#define RMT_TX_START_CH1_S 0 +/** RMT_MEM_RD_RST_CH1 : WT; bitpos: [1]; default: 0; * Set this bit to reset read ram address for CHANNEL1 by accessing transmitter. */ -#define RMT_MEM_RD_RST_CH0 (BIT(1)) -#define RMT_MEM_RD_RST_CH0_M (RMT_MEM_RD_RST_CH0_V << RMT_MEM_RD_RST_CH0_S) -#define RMT_MEM_RD_RST_CH0_V 0x00000001U -#define RMT_MEM_RD_RST_CH0_S 1 -/** RMT_APB_MEM_RST_CH0 : WT; bitpos: [2]; default: 0; +#define RMT_MEM_RD_RST_CH1 (BIT(1)) +#define RMT_MEM_RD_RST_CH1_M (RMT_MEM_RD_RST_CH1_V << RMT_MEM_RD_RST_CH1_S) +#define RMT_MEM_RD_RST_CH1_V 0x00000001U +#define RMT_MEM_RD_RST_CH1_S 1 +/** RMT_APB_MEM_RST_CH1 : WT; bitpos: [2]; default: 0; * Set this bit to reset W/R ram address for CHANNEL1 by accessing apb fifo. */ -#define RMT_APB_MEM_RST_CH0 (BIT(2)) -#define RMT_APB_MEM_RST_CH0_M (RMT_APB_MEM_RST_CH0_V << RMT_APB_MEM_RST_CH0_S) -#define RMT_APB_MEM_RST_CH0_V 0x00000001U -#define RMT_APB_MEM_RST_CH0_S 2 -/** RMT_TX_CONTI_MODE_CH0 : R/W; bitpos: [3]; default: 0; +#define RMT_APB_MEM_RST_CH1 (BIT(2)) +#define RMT_APB_MEM_RST_CH1_M (RMT_APB_MEM_RST_CH1_V << RMT_APB_MEM_RST_CH1_S) +#define RMT_APB_MEM_RST_CH1_V 0x00000001U +#define RMT_APB_MEM_RST_CH1_S 2 +/** RMT_TX_CONTI_MODE_CH1 : R/W; bitpos: [3]; default: 0; * Set this bit to restart transmission from the first data to the last data in * CHANNEL1. */ -#define RMT_TX_CONTI_MODE_CH0 (BIT(3)) -#define RMT_TX_CONTI_MODE_CH0_M (RMT_TX_CONTI_MODE_CH0_V << RMT_TX_CONTI_MODE_CH0_S) -#define RMT_TX_CONTI_MODE_CH0_V 0x00000001U -#define RMT_TX_CONTI_MODE_CH0_S 3 -/** RMT_MEM_TX_WRAP_EN_CH0 : R/W; bitpos: [4]; default: 0; +#define RMT_TX_CONTI_MODE_CH1 (BIT(3)) +#define RMT_TX_CONTI_MODE_CH1_M (RMT_TX_CONTI_MODE_CH1_V << RMT_TX_CONTI_MODE_CH1_S) +#define RMT_TX_CONTI_MODE_CH1_V 0x00000001U +#define RMT_TX_CONTI_MODE_CH1_S 3 +/** RMT_MEM_TX_WRAP_EN_CH1 : R/W; bitpos: [4]; default: 0; * This is the channel 1 enable bit for wraparound mode: it will resume sending at the * start when the data to be sent is more than its memory size. */ -#define RMT_MEM_TX_WRAP_EN_CH0 (BIT(4)) -#define RMT_MEM_TX_WRAP_EN_CH0_M (RMT_MEM_TX_WRAP_EN_CH0_V << RMT_MEM_TX_WRAP_EN_CH0_S) -#define RMT_MEM_TX_WRAP_EN_CH0_V 0x00000001U -#define RMT_MEM_TX_WRAP_EN_CH0_S 4 -/** RMT_IDLE_OUT_LV_CH0 : R/W; bitpos: [5]; default: 0; +#define RMT_MEM_TX_WRAP_EN_CH1 (BIT(4)) +#define RMT_MEM_TX_WRAP_EN_CH1_M (RMT_MEM_TX_WRAP_EN_CH1_V << RMT_MEM_TX_WRAP_EN_CH1_S) +#define RMT_MEM_TX_WRAP_EN_CH1_V 0x00000001U +#define RMT_MEM_TX_WRAP_EN_CH1_S 4 +/** RMT_IDLE_OUT_LV_CH1 : R/W; bitpos: [5]; default: 0; * This bit configures the level of output signal in CHANNEL1 when the latter is in * IDLE state. */ -#define RMT_IDLE_OUT_LV_CH0 (BIT(5)) -#define RMT_IDLE_OUT_LV_CH0_M (RMT_IDLE_OUT_LV_CH0_V << RMT_IDLE_OUT_LV_CH0_S) -#define RMT_IDLE_OUT_LV_CH0_V 0x00000001U -#define RMT_IDLE_OUT_LV_CH0_S 5 -/** RMT_IDLE_OUT_EN_CH0 : R/W; bitpos: [6]; default: 0; +#define RMT_IDLE_OUT_LV_CH1 (BIT(5)) +#define RMT_IDLE_OUT_LV_CH1_M (RMT_IDLE_OUT_LV_CH1_V << RMT_IDLE_OUT_LV_CH1_S) +#define RMT_IDLE_OUT_LV_CH1_V 0x00000001U +#define RMT_IDLE_OUT_LV_CH1_S 5 +/** RMT_IDLE_OUT_EN_CH1 : R/W; bitpos: [6]; default: 0; * This is the output enable-control bit for CHANNEL1 in IDLE state. */ -#define RMT_IDLE_OUT_EN_CH0 (BIT(6)) -#define RMT_IDLE_OUT_EN_CH0_M (RMT_IDLE_OUT_EN_CH0_V << RMT_IDLE_OUT_EN_CH0_S) -#define RMT_IDLE_OUT_EN_CH0_V 0x00000001U -#define RMT_IDLE_OUT_EN_CH0_S 6 -/** RMT_TX_STOP_CH0 : R/W/SC; bitpos: [7]; default: 0; +#define RMT_IDLE_OUT_EN_CH1 (BIT(6)) +#define RMT_IDLE_OUT_EN_CH1_M (RMT_IDLE_OUT_EN_CH1_V << RMT_IDLE_OUT_EN_CH1_S) +#define RMT_IDLE_OUT_EN_CH1_V 0x00000001U +#define RMT_IDLE_OUT_EN_CH1_S 6 +/** RMT_TX_STOP_CH1 : R/W/SC; bitpos: [7]; default: 0; * Set this bit to stop the transmitter of CHANNEL1 sending data out. */ -#define RMT_TX_STOP_CH0 (BIT(7)) -#define RMT_TX_STOP_CH0_M (RMT_TX_STOP_CH0_V << RMT_TX_STOP_CH0_S) -#define RMT_TX_STOP_CH0_V 0x00000001U -#define RMT_TX_STOP_CH0_S 7 -/** RMT_DIV_CNT_CH0 : R/W; bitpos: [15:8]; default: 2; +#define RMT_TX_STOP_CH1 (BIT(7)) +#define RMT_TX_STOP_CH1_M (RMT_TX_STOP_CH1_V << RMT_TX_STOP_CH1_S) +#define RMT_TX_STOP_CH1_V 0x00000001U +#define RMT_TX_STOP_CH1_S 7 +/** RMT_DIV_CNT_CH1 : R/W; bitpos: [15:8]; default: 2; * This register is used to configure the divider for clock of CHANNEL1. */ -#define RMT_DIV_CNT_CH0 0x000000FFU -#define RMT_DIV_CNT_CH0_M (RMT_DIV_CNT_CH0_V << RMT_DIV_CNT_CH0_S) -#define RMT_DIV_CNT_CH0_V 0x000000FFU -#define RMT_DIV_CNT_CH0_S 8 -/** RMT_MEM_SIZE_CH0 : R/W; bitpos: [18:16]; default: 1; +#define RMT_DIV_CNT_CH1 0x000000FFU +#define RMT_DIV_CNT_CH1_M (RMT_DIV_CNT_CH1_V << RMT_DIV_CNT_CH1_S) +#define RMT_DIV_CNT_CH1_V 0x000000FFU +#define RMT_DIV_CNT_CH1_S 8 +/** RMT_MEM_SIZE_CH1 : R/W; bitpos: [18:16]; default: 1; * This register is used to configure the maximum size of memory allocated to CHANNEL1. */ -#define RMT_MEM_SIZE_CH0 0x00000007U -#define RMT_MEM_SIZE_CH0_M (RMT_MEM_SIZE_CH0_V << RMT_MEM_SIZE_CH0_S) -#define RMT_MEM_SIZE_CH0_V 0x00000007U -#define RMT_MEM_SIZE_CH0_S 16 -/** RMT_CARRIER_EFF_EN_CH0 : R/W; bitpos: [20]; default: 1; +#define RMT_MEM_SIZE_CH1 0x00000007U +#define RMT_MEM_SIZE_CH1_M (RMT_MEM_SIZE_CH1_V << RMT_MEM_SIZE_CH1_S) +#define RMT_MEM_SIZE_CH1_V 0x00000007U +#define RMT_MEM_SIZE_CH1_S 16 +/** RMT_CARRIER_EFF_EN_CH1 : R/W; bitpos: [20]; default: 1; * 1: Add carrier modulation on the output signal only at the send data state for * CHANNEL1. 0: Add carrier modulation on the output signal at all state for CHANNEL1. * Only valid when RMT_CARRIER_EN_CH1 is 1. */ -#define RMT_CARRIER_EFF_EN_CH0 (BIT(20)) -#define RMT_CARRIER_EFF_EN_CH0_M (RMT_CARRIER_EFF_EN_CH0_V << RMT_CARRIER_EFF_EN_CH0_S) -#define RMT_CARRIER_EFF_EN_CH0_V 0x00000001U -#define RMT_CARRIER_EFF_EN_CH0_S 20 -/** RMT_CARRIER_EN_CH0 : R/W; bitpos: [21]; default: 1; +#define RMT_CARRIER_EFF_EN_CH1 (BIT(20)) +#define RMT_CARRIER_EFF_EN_CH1_M (RMT_CARRIER_EFF_EN_CH1_V << RMT_CARRIER_EFF_EN_CH1_S) +#define RMT_CARRIER_EFF_EN_CH1_V 0x00000001U +#define RMT_CARRIER_EFF_EN_CH1_S 20 +/** RMT_CARRIER_EN_CH1 : R/W; bitpos: [21]; default: 1; * This is the carrier modulation enable-control bit for CHANNEL1. 1: Add carrier * modulation in the output signal. 0: No carrier modulation in sig_out. */ -#define RMT_CARRIER_EN_CH0 (BIT(21)) -#define RMT_CARRIER_EN_CH0_M (RMT_CARRIER_EN_CH0_V << RMT_CARRIER_EN_CH0_S) -#define RMT_CARRIER_EN_CH0_V 0x00000001U -#define RMT_CARRIER_EN_CH0_S 21 -/** RMT_CARRIER_OUT_LV_CH0 : R/W; bitpos: [22]; default: 1; +#define RMT_CARRIER_EN_CH1 (BIT(21)) +#define RMT_CARRIER_EN_CH1_M (RMT_CARRIER_EN_CH1_V << RMT_CARRIER_EN_CH1_S) +#define RMT_CARRIER_EN_CH1_V 0x00000001U +#define RMT_CARRIER_EN_CH1_S 21 +/** RMT_CARRIER_OUT_LV_CH1 : R/W; bitpos: [22]; default: 1; * This bit is used to configure the position of carrier wave for CHANNEL1. * * 1'h0: add carrier wave on low level. * * 1'h1: add carrier wave on high level. */ -#define RMT_CARRIER_OUT_LV_CH0 (BIT(22)) -#define RMT_CARRIER_OUT_LV_CH0_M (RMT_CARRIER_OUT_LV_CH0_V << RMT_CARRIER_OUT_LV_CH0_S) -#define RMT_CARRIER_OUT_LV_CH0_V 0x00000001U -#define RMT_CARRIER_OUT_LV_CH0_S 22 -/** RMT_AFIFO_RST_CH0 : WT; bitpos: [23]; default: 0; +#define RMT_CARRIER_OUT_LV_CH1 (BIT(22)) +#define RMT_CARRIER_OUT_LV_CH1_M (RMT_CARRIER_OUT_LV_CH1_V << RMT_CARRIER_OUT_LV_CH1_S) +#define RMT_CARRIER_OUT_LV_CH1_V 0x00000001U +#define RMT_CARRIER_OUT_LV_CH1_S 22 +/** RMT_AFIFO_RST_CH1 : WT; bitpos: [23]; default: 0; * Reserved */ -#define RMT_AFIFO_RST_CH0 (BIT(23)) -#define RMT_AFIFO_RST_CH0_M (RMT_AFIFO_RST_CH0_V << RMT_AFIFO_RST_CH0_S) -#define RMT_AFIFO_RST_CH0_V 0x00000001U -#define RMT_AFIFO_RST_CH0_S 23 -/** RMT_CONF_UPDATE_CH0 : WT; bitpos: [24]; default: 0; +#define RMT_AFIFO_RST_CH1 (BIT(23)) +#define RMT_AFIFO_RST_CH1_M (RMT_AFIFO_RST_CH1_V << RMT_AFIFO_RST_CH1_S) +#define RMT_AFIFO_RST_CH1_V 0x00000001U +#define RMT_AFIFO_RST_CH1_S 23 +/** RMT_CONF_UPDATE_CH1 : WT; bitpos: [24]; default: 0; * synchronization bit for CHANNEL1 */ -#define RMT_CONF_UPDATE_CH0 (BIT(24)) -#define RMT_CONF_UPDATE_CH0_M (RMT_CONF_UPDATE_CH0_V << RMT_CONF_UPDATE_CH0_S) -#define RMT_CONF_UPDATE_CH0_V 0x00000001U -#define RMT_CONF_UPDATE_CH0_S 24 +#define RMT_CONF_UPDATE_CH1 (BIT(24)) +#define RMT_CONF_UPDATE_CH1_M (RMT_CONF_UPDATE_CH1_V << RMT_CONF_UPDATE_CH1_S) +#define RMT_CONF_UPDATE_CH1_V 0x00000001U +#define RMT_CONF_UPDATE_CH1_S 24 /** RMT_CH2CONF0_REG register * Channel 2 configure register 0 @@ -423,121 +423,121 @@ extern "C" { * Channel 3 configure register 0 */ #define RMT_CH3CONF0_REG (DR_REG_RMT_BASE + 0x20) -/** RMT_DIV_CNT_CH2 : R/W; bitpos: [7:0]; default: 2; +/** RMT_DIV_CNT_CH3 : R/W; bitpos: [7:0]; default: 2; * This register is used to configure the divider for clock of CHANNEL3. */ -#define RMT_DIV_CNT_CH2 0x000000FFU -#define RMT_DIV_CNT_CH2_M (RMT_DIV_CNT_CH2_V << RMT_DIV_CNT_CH2_S) -#define RMT_DIV_CNT_CH2_V 0x000000FFU -#define RMT_DIV_CNT_CH2_S 0 -/** RMT_IDLE_THRES_CH2 : R/W; bitpos: [22:8]; default: 32767; +#define RMT_DIV_CNT_CH3 0x000000FFU +#define RMT_DIV_CNT_CH3_M (RMT_DIV_CNT_CH3_V << RMT_DIV_CNT_CH3_S) +#define RMT_DIV_CNT_CH3_V 0x000000FFU +#define RMT_DIV_CNT_CH3_S 0 +/** RMT_IDLE_THRES_CH3 : R/W; bitpos: [22:8]; default: 32767; * When no edge is detected on the input signal and continuous clock cycles is longer * than this register value, received process is finished. */ -#define RMT_IDLE_THRES_CH2 0x00007FFFU -#define RMT_IDLE_THRES_CH2_M (RMT_IDLE_THRES_CH2_V << RMT_IDLE_THRES_CH2_S) -#define RMT_IDLE_THRES_CH2_V 0x00007FFFU -#define RMT_IDLE_THRES_CH2_S 8 -/** RMT_MEM_SIZE_CH2 : R/W; bitpos: [25:23]; default: 1; +#define RMT_IDLE_THRES_CH3 0x00007FFFU +#define RMT_IDLE_THRES_CH3_M (RMT_IDLE_THRES_CH3_V << RMT_IDLE_THRES_CH3_S) +#define RMT_IDLE_THRES_CH3_V 0x00007FFFU +#define RMT_IDLE_THRES_CH3_S 8 +/** RMT_MEM_SIZE_CH3 : R/W; bitpos: [25:23]; default: 1; * This register is used to configure the maximum size of memory allocated to CHANNEL3. */ -#define RMT_MEM_SIZE_CH2 0x00000007U -#define RMT_MEM_SIZE_CH2_M (RMT_MEM_SIZE_CH2_V << RMT_MEM_SIZE_CH2_S) -#define RMT_MEM_SIZE_CH2_V 0x00000007U -#define RMT_MEM_SIZE_CH2_S 23 -/** RMT_CARRIER_EN_CH2 : R/W; bitpos: [28]; default: 1; +#define RMT_MEM_SIZE_CH3 0x00000007U +#define RMT_MEM_SIZE_CH3_M (RMT_MEM_SIZE_CH3_V << RMT_MEM_SIZE_CH3_S) +#define RMT_MEM_SIZE_CH3_V 0x00000007U +#define RMT_MEM_SIZE_CH3_S 23 +/** RMT_CARRIER_EN_CH3 : R/W; bitpos: [28]; default: 1; * This is the carrier modulation enable-control bit for CHANNEL3. 1: Add carrier * modulation in the output signal. 0: No carrier modulation in sig_out. */ -#define RMT_CARRIER_EN_CH2 (BIT(28)) -#define RMT_CARRIER_EN_CH2_M (RMT_CARRIER_EN_CH2_V << RMT_CARRIER_EN_CH2_S) -#define RMT_CARRIER_EN_CH2_V 0x00000001U -#define RMT_CARRIER_EN_CH2_S 28 -/** RMT_CARRIER_OUT_LV_CH2 : R/W; bitpos: [29]; default: 1; +#define RMT_CARRIER_EN_CH3 (BIT(28)) +#define RMT_CARRIER_EN_CH3_M (RMT_CARRIER_EN_CH3_V << RMT_CARRIER_EN_CH3_S) +#define RMT_CARRIER_EN_CH3_V 0x00000001U +#define RMT_CARRIER_EN_CH3_S 28 +/** RMT_CARRIER_OUT_LV_CH3 : R/W; bitpos: [29]; default: 1; * This bit is used to configure the position of carrier wave for CHANNEL3. * * 1'h0: add carrier wave on low level. * * 1'h1: add carrier wave on high level. */ -#define RMT_CARRIER_OUT_LV_CH2 (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH2_M (RMT_CARRIER_OUT_LV_CH2_V << RMT_CARRIER_OUT_LV_CH2_S) -#define RMT_CARRIER_OUT_LV_CH2_V 0x00000001U -#define RMT_CARRIER_OUT_LV_CH2_S 29 +#define RMT_CARRIER_OUT_LV_CH3 (BIT(29)) +#define RMT_CARRIER_OUT_LV_CH3_M (RMT_CARRIER_OUT_LV_CH3_V << RMT_CARRIER_OUT_LV_CH3_S) +#define RMT_CARRIER_OUT_LV_CH3_V 0x00000001U +#define RMT_CARRIER_OUT_LV_CH3_S 29 /** RMT_CH3CONF1_REG register * Channel 3 configure register 1 */ #define RMT_CH3CONF1_REG (DR_REG_RMT_BASE + 0x24) -/** RMT_RX_EN_CH2 : R/W; bitpos: [0]; default: 0; +/** RMT_RX_EN_CH3 : R/W; bitpos: [0]; default: 0; * Set this bit to enable receiver to receive data on CHANNEL3. */ -#define RMT_RX_EN_CH2 (BIT(0)) -#define RMT_RX_EN_CH2_M (RMT_RX_EN_CH2_V << RMT_RX_EN_CH2_S) -#define RMT_RX_EN_CH2_V 0x00000001U -#define RMT_RX_EN_CH2_S 0 -/** RMT_MEM_WR_RST_CH2 : WT; bitpos: [1]; default: 0; +#define RMT_RX_EN_CH3 (BIT(0)) +#define RMT_RX_EN_CH3_M (RMT_RX_EN_CH3_V << RMT_RX_EN_CH3_S) +#define RMT_RX_EN_CH3_V 0x00000001U +#define RMT_RX_EN_CH3_S 0 +/** RMT_MEM_WR_RST_CH3 : WT; bitpos: [1]; default: 0; * Set this bit to reset write ram address for CHANNEL3 by accessing receiver. */ -#define RMT_MEM_WR_RST_CH2 (BIT(1)) -#define RMT_MEM_WR_RST_CH2_M (RMT_MEM_WR_RST_CH2_V << RMT_MEM_WR_RST_CH2_S) -#define RMT_MEM_WR_RST_CH2_V 0x00000001U -#define RMT_MEM_WR_RST_CH2_S 1 -/** RMT_APB_MEM_RST_CH2 : WT; bitpos: [2]; default: 0; +#define RMT_MEM_WR_RST_CH3 (BIT(1)) +#define RMT_MEM_WR_RST_CH3_M (RMT_MEM_WR_RST_CH3_V << RMT_MEM_WR_RST_CH3_S) +#define RMT_MEM_WR_RST_CH3_V 0x00000001U +#define RMT_MEM_WR_RST_CH3_S 1 +/** RMT_APB_MEM_RST_CH3 : WT; bitpos: [2]; default: 0; * Set this bit to reset W/R ram address for CHANNEL3 by accessing apb fifo. */ -#define RMT_APB_MEM_RST_CH2 (BIT(2)) -#define RMT_APB_MEM_RST_CH2_M (RMT_APB_MEM_RST_CH2_V << RMT_APB_MEM_RST_CH2_S) -#define RMT_APB_MEM_RST_CH2_V 0x00000001U -#define RMT_APB_MEM_RST_CH2_S 2 -/** RMT_MEM_OWNER_CH2 : R/W/SC; bitpos: [3]; default: 1; +#define RMT_APB_MEM_RST_CH3 (BIT(2)) +#define RMT_APB_MEM_RST_CH3_M (RMT_APB_MEM_RST_CH3_V << RMT_APB_MEM_RST_CH3_S) +#define RMT_APB_MEM_RST_CH3_V 0x00000001U +#define RMT_APB_MEM_RST_CH3_S 2 +/** RMT_MEM_OWNER_CH3 : R/W/SC; bitpos: [3]; default: 1; * This register marks the ownership of CHANNEL3's ram block. * * 1'h1: Receiver is using the ram. * * 1'h0: APB bus is using the ram. */ -#define RMT_MEM_OWNER_CH2 (BIT(3)) -#define RMT_MEM_OWNER_CH2_M (RMT_MEM_OWNER_CH2_V << RMT_MEM_OWNER_CH2_S) -#define RMT_MEM_OWNER_CH2_V 0x00000001U -#define RMT_MEM_OWNER_CH2_S 3 -/** RMT_RX_FILTER_EN_CH2 : R/W; bitpos: [4]; default: 0; +#define RMT_MEM_OWNER_CH3 (BIT(3)) +#define RMT_MEM_OWNER_CH3_M (RMT_MEM_OWNER_CH3_V << RMT_MEM_OWNER_CH3_S) +#define RMT_MEM_OWNER_CH3_V 0x00000001U +#define RMT_MEM_OWNER_CH3_S 3 +/** RMT_RX_FILTER_EN_CH3 : R/W; bitpos: [4]; default: 0; * This is the receive filter's enable bit for CHANNEL3. */ -#define RMT_RX_FILTER_EN_CH2 (BIT(4)) -#define RMT_RX_FILTER_EN_CH2_M (RMT_RX_FILTER_EN_CH2_V << RMT_RX_FILTER_EN_CH2_S) -#define RMT_RX_FILTER_EN_CH2_V 0x00000001U -#define RMT_RX_FILTER_EN_CH2_S 4 -/** RMT_RX_FILTER_THRES_CH2 : R/W; bitpos: [12:5]; default: 15; +#define RMT_RX_FILTER_EN_CH3 (BIT(4)) +#define RMT_RX_FILTER_EN_CH3_M (RMT_RX_FILTER_EN_CH3_V << RMT_RX_FILTER_EN_CH3_S) +#define RMT_RX_FILTER_EN_CH3_V 0x00000001U +#define RMT_RX_FILTER_EN_CH3_S 4 +/** RMT_RX_FILTER_THRES_CH3 : R/W; bitpos: [12:5]; default: 15; * Ignores the input pulse when its width is smaller than this register value in APB * clock periods (in receive mode). */ -#define RMT_RX_FILTER_THRES_CH2 0x000000FFU -#define RMT_RX_FILTER_THRES_CH2_M (RMT_RX_FILTER_THRES_CH2_V << RMT_RX_FILTER_THRES_CH2_S) -#define RMT_RX_FILTER_THRES_CH2_V 0x000000FFU -#define RMT_RX_FILTER_THRES_CH2_S 5 -/** RMT_MEM_RX_WRAP_EN_CH2 : R/W; bitpos: [13]; default: 0; +#define RMT_RX_FILTER_THRES_CH3 0x000000FFU +#define RMT_RX_FILTER_THRES_CH3_M (RMT_RX_FILTER_THRES_CH3_V << RMT_RX_FILTER_THRES_CH3_S) +#define RMT_RX_FILTER_THRES_CH3_V 0x000000FFU +#define RMT_RX_FILTER_THRES_CH3_S 5 +/** RMT_MEM_RX_WRAP_EN_CH3 : R/W; bitpos: [13]; default: 0; * This is the channel 3 enable bit for wraparound mode: it will resume receiving at * the start when the data to be received is more than its memory size. */ -#define RMT_MEM_RX_WRAP_EN_CH2 (BIT(13)) -#define RMT_MEM_RX_WRAP_EN_CH2_M (RMT_MEM_RX_WRAP_EN_CH2_V << RMT_MEM_RX_WRAP_EN_CH2_S) -#define RMT_MEM_RX_WRAP_EN_CH2_V 0x00000001U -#define RMT_MEM_RX_WRAP_EN_CH2_S 13 -/** RMT_AFIFO_RST_CH2 : WT; bitpos: [14]; default: 0; +#define RMT_MEM_RX_WRAP_EN_CH3 (BIT(13)) +#define RMT_MEM_RX_WRAP_EN_CH3_M (RMT_MEM_RX_WRAP_EN_CH3_V << RMT_MEM_RX_WRAP_EN_CH3_S) +#define RMT_MEM_RX_WRAP_EN_CH3_V 0x00000001U +#define RMT_MEM_RX_WRAP_EN_CH3_S 13 +/** RMT_AFIFO_RST_CH3 : WT; bitpos: [14]; default: 0; * Reserved */ -#define RMT_AFIFO_RST_CH2 (BIT(14)) -#define RMT_AFIFO_RST_CH2_M (RMT_AFIFO_RST_CH2_V << RMT_AFIFO_RST_CH2_S) -#define RMT_AFIFO_RST_CH2_V 0x00000001U -#define RMT_AFIFO_RST_CH2_S 14 -/** RMT_CONF_UPDATE_CH2 : WT; bitpos: [15]; default: 0; +#define RMT_AFIFO_RST_CH3 (BIT(14)) +#define RMT_AFIFO_RST_CH3_M (RMT_AFIFO_RST_CH3_V << RMT_AFIFO_RST_CH3_S) +#define RMT_AFIFO_RST_CH3_V 0x00000001U +#define RMT_AFIFO_RST_CH3_S 14 +/** RMT_CONF_UPDATE_CH3 : WT; bitpos: [15]; default: 0; * synchronization bit for CHANNEL3 */ -#define RMT_CONF_UPDATE_CH2 (BIT(15)) -#define RMT_CONF_UPDATE_CH2_M (RMT_CONF_UPDATE_CH2_V << RMT_CONF_UPDATE_CH2_S) -#define RMT_CONF_UPDATE_CH2_V 0x00000001U -#define RMT_CONF_UPDATE_CH2_S 15 +#define RMT_CONF_UPDATE_CH3 (BIT(15)) +#define RMT_CONF_UPDATE_CH3_M (RMT_CONF_UPDATE_CH3_V << RMT_CONF_UPDATE_CH3_S) +#define RMT_CONF_UPDATE_CH3_V 0x00000001U +#define RMT_CONF_UPDATE_CH3_S 15 /** RMT_CH0STATUS_REG register * Channel 0 status register @@ -601,59 +601,59 @@ extern "C" { * Channel 1 status register */ #define RMT_CH1STATUS_REG (DR_REG_RMT_BASE + 0x2c) -/** RMT_MEM_RADDR_EX_CH0 : RO; bitpos: [8:0]; default: 0; +/** RMT_MEM_RADDR_EX_CH1 : RO; bitpos: [8:0]; default: 0; * This register records the memory address offset when transmitter of CHANNEL1 is * using the RAM. */ -#define RMT_MEM_RADDR_EX_CH0 0x000001FFU -#define RMT_MEM_RADDR_EX_CH0_M (RMT_MEM_RADDR_EX_CH0_V << RMT_MEM_RADDR_EX_CH0_S) -#define RMT_MEM_RADDR_EX_CH0_V 0x000001FFU -#define RMT_MEM_RADDR_EX_CH0_S 0 -/** RMT_STATE_CH0 : RO; bitpos: [11:9]; default: 0; +#define RMT_MEM_RADDR_EX_CH1 0x000001FFU +#define RMT_MEM_RADDR_EX_CH1_M (RMT_MEM_RADDR_EX_CH1_V << RMT_MEM_RADDR_EX_CH1_S) +#define RMT_MEM_RADDR_EX_CH1_V 0x000001FFU +#define RMT_MEM_RADDR_EX_CH1_S 0 +/** RMT_STATE_CH1 : RO; bitpos: [11:9]; default: 0; * This register records the FSM status of CHANNEL1. */ -#define RMT_STATE_CH0 0x00000007U -#define RMT_STATE_CH0_M (RMT_STATE_CH0_V << RMT_STATE_CH0_S) -#define RMT_STATE_CH0_V 0x00000007U -#define RMT_STATE_CH0_S 9 -/** RMT_APB_MEM_WADDR_CH0 : RO; bitpos: [20:12]; default: 0; +#define RMT_STATE_CH1 0x00000007U +#define RMT_STATE_CH1_M (RMT_STATE_CH1_V << RMT_STATE_CH1_S) +#define RMT_STATE_CH1_V 0x00000007U +#define RMT_STATE_CH1_S 9 +/** RMT_APB_MEM_WADDR_CH1 : RO; bitpos: [20:12]; default: 0; * This register records the memory address offset when writes RAM over APB bus. */ -#define RMT_APB_MEM_WADDR_CH0 0x000001FFU -#define RMT_APB_MEM_WADDR_CH0_M (RMT_APB_MEM_WADDR_CH0_V << RMT_APB_MEM_WADDR_CH0_S) -#define RMT_APB_MEM_WADDR_CH0_V 0x000001FFU -#define RMT_APB_MEM_WADDR_CH0_S 12 -/** RMT_APB_MEM_RD_ERR_CH0 : RO; bitpos: [21]; default: 0; +#define RMT_APB_MEM_WADDR_CH1 0x000001FFU +#define RMT_APB_MEM_WADDR_CH1_M (RMT_APB_MEM_WADDR_CH1_V << RMT_APB_MEM_WADDR_CH1_S) +#define RMT_APB_MEM_WADDR_CH1_V 0x000001FFU +#define RMT_APB_MEM_WADDR_CH1_S 12 +/** RMT_APB_MEM_RD_ERR_CH1 : RO; bitpos: [21]; default: 0; * This status bit will be set if the offset address out of memory size when reading * via APB bus. */ -#define RMT_APB_MEM_RD_ERR_CH0 (BIT(21)) -#define RMT_APB_MEM_RD_ERR_CH0_M (RMT_APB_MEM_RD_ERR_CH0_V << RMT_APB_MEM_RD_ERR_CH0_S) -#define RMT_APB_MEM_RD_ERR_CH0_V 0x00000001U -#define RMT_APB_MEM_RD_ERR_CH0_S 21 -/** RMT_MEM_EMPTY_CH0 : RO; bitpos: [22]; default: 0; +#define RMT_APB_MEM_RD_ERR_CH1 (BIT(21)) +#define RMT_APB_MEM_RD_ERR_CH1_M (RMT_APB_MEM_RD_ERR_CH1_V << RMT_APB_MEM_RD_ERR_CH1_S) +#define RMT_APB_MEM_RD_ERR_CH1_V 0x00000001U +#define RMT_APB_MEM_RD_ERR_CH1_S 21 +/** RMT_MEM_EMPTY_CH1 : RO; bitpos: [22]; default: 0; * This status bit will be set when the data to be set is more than memory size and * the wraparound mode is disabled. */ -#define RMT_MEM_EMPTY_CH0 (BIT(22)) -#define RMT_MEM_EMPTY_CH0_M (RMT_MEM_EMPTY_CH0_V << RMT_MEM_EMPTY_CH0_S) -#define RMT_MEM_EMPTY_CH0_V 0x00000001U -#define RMT_MEM_EMPTY_CH0_S 22 -/** RMT_APB_MEM_WR_ERR_CH0 : RO; bitpos: [23]; default: 0; +#define RMT_MEM_EMPTY_CH1 (BIT(22)) +#define RMT_MEM_EMPTY_CH1_M (RMT_MEM_EMPTY_CH1_V << RMT_MEM_EMPTY_CH1_S) +#define RMT_MEM_EMPTY_CH1_V 0x00000001U +#define RMT_MEM_EMPTY_CH1_S 22 +/** RMT_APB_MEM_WR_ERR_CH1 : RO; bitpos: [23]; default: 0; * This status bit will be set if the offset address out of memory size when writes * via APB bus. */ -#define RMT_APB_MEM_WR_ERR_CH0 (BIT(23)) -#define RMT_APB_MEM_WR_ERR_CH0_M (RMT_APB_MEM_WR_ERR_CH0_V << RMT_APB_MEM_WR_ERR_CH0_S) -#define RMT_APB_MEM_WR_ERR_CH0_V 0x00000001U -#define RMT_APB_MEM_WR_ERR_CH0_S 23 -/** RMT_APB_MEM_RADDR_CH0 : RO; bitpos: [31:24]; default: 0; +#define RMT_APB_MEM_WR_ERR_CH1 (BIT(23)) +#define RMT_APB_MEM_WR_ERR_CH1_M (RMT_APB_MEM_WR_ERR_CH1_V << RMT_APB_MEM_WR_ERR_CH1_S) +#define RMT_APB_MEM_WR_ERR_CH1_V 0x00000001U +#define RMT_APB_MEM_WR_ERR_CH1_S 23 +/** RMT_APB_MEM_RADDR_CH1 : RO; bitpos: [31:24]; default: 0; * This register records the memory address offset when reading RAM over APB bus. */ -#define RMT_APB_MEM_RADDR_CH0 0x000000FFU -#define RMT_APB_MEM_RADDR_CH0_M (RMT_APB_MEM_RADDR_CH0_V << RMT_APB_MEM_RADDR_CH0_S) -#define RMT_APB_MEM_RADDR_CH0_V 0x000000FFU -#define RMT_APB_MEM_RADDR_CH0_S 24 +#define RMT_APB_MEM_RADDR_CH1 0x000000FFU +#define RMT_APB_MEM_RADDR_CH1_M (RMT_APB_MEM_RADDR_CH1_V << RMT_APB_MEM_RADDR_CH1_S) +#define RMT_APB_MEM_RADDR_CH1_V 0x000000FFU +#define RMT_APB_MEM_RADDR_CH1_S 24 /** RMT_CH2STATUS_REG register * Channel 2 status register @@ -708,50 +708,50 @@ extern "C" { * Channel 3 status register */ #define RMT_CH3STATUS_REG (DR_REG_RMT_BASE + 0x34) -/** RMT_MEM_WADDR_EX_CH2 : RO; bitpos: [8:0]; default: 0; +/** RMT_MEM_WADDR_EX_CH3 : RO; bitpos: [8:0]; default: 0; * This register records the memory address offset when receiver of CHANNEL3 is using * the RAM. */ -#define RMT_MEM_WADDR_EX_CH2 0x000001FFU -#define RMT_MEM_WADDR_EX_CH2_M (RMT_MEM_WADDR_EX_CH2_V << RMT_MEM_WADDR_EX_CH2_S) -#define RMT_MEM_WADDR_EX_CH2_V 0x000001FFU -#define RMT_MEM_WADDR_EX_CH2_S 0 -/** RMT_APB_MEM_RADDR_CH2 : RO; bitpos: [20:12]; default: 0; +#define RMT_MEM_WADDR_EX_CH3 0x000001FFU +#define RMT_MEM_WADDR_EX_CH3_M (RMT_MEM_WADDR_EX_CH3_V << RMT_MEM_WADDR_EX_CH3_S) +#define RMT_MEM_WADDR_EX_CH3_V 0x000001FFU +#define RMT_MEM_WADDR_EX_CH3_S 0 +/** RMT_APB_MEM_RADDR_CH3 : RO; bitpos: [20:12]; default: 0; * This register records the memory address offset when reads RAM over APB bus. */ -#define RMT_APB_MEM_RADDR_CH2 0x000001FFU -#define RMT_APB_MEM_RADDR_CH2_M (RMT_APB_MEM_RADDR_CH2_V << RMT_APB_MEM_RADDR_CH2_S) -#define RMT_APB_MEM_RADDR_CH2_V 0x000001FFU -#define RMT_APB_MEM_RADDR_CH2_S 12 -/** RMT_STATE_CH2 : RO; bitpos: [24:22]; default: 0; +#define RMT_APB_MEM_RADDR_CH3 0x000001FFU +#define RMT_APB_MEM_RADDR_CH3_M (RMT_APB_MEM_RADDR_CH3_V << RMT_APB_MEM_RADDR_CH3_S) +#define RMT_APB_MEM_RADDR_CH3_V 0x000001FFU +#define RMT_APB_MEM_RADDR_CH3_S 12 +/** RMT_STATE_CH3 : RO; bitpos: [24:22]; default: 0; * This register records the FSM status of CHANNEL3. */ -#define RMT_STATE_CH2 0x00000007U -#define RMT_STATE_CH2_M (RMT_STATE_CH2_V << RMT_STATE_CH2_S) -#define RMT_STATE_CH2_V 0x00000007U -#define RMT_STATE_CH2_S 22 -/** RMT_MEM_OWNER_ERR_CH2 : RO; bitpos: [25]; default: 0; +#define RMT_STATE_CH3 0x00000007U +#define RMT_STATE_CH3_M (RMT_STATE_CH3_V << RMT_STATE_CH3_S) +#define RMT_STATE_CH3_V 0x00000007U +#define RMT_STATE_CH3_S 22 +/** RMT_MEM_OWNER_ERR_CH3 : RO; bitpos: [25]; default: 0; * This status bit will be set when the ownership of memory block is wrong. */ -#define RMT_MEM_OWNER_ERR_CH2 (BIT(25)) -#define RMT_MEM_OWNER_ERR_CH2_M (RMT_MEM_OWNER_ERR_CH2_V << RMT_MEM_OWNER_ERR_CH2_S) -#define RMT_MEM_OWNER_ERR_CH2_V 0x00000001U -#define RMT_MEM_OWNER_ERR_CH2_S 25 -/** RMT_MEM_FULL_CH2 : RO; bitpos: [26]; default: 0; +#define RMT_MEM_OWNER_ERR_CH3 (BIT(25)) +#define RMT_MEM_OWNER_ERR_CH3_M (RMT_MEM_OWNER_ERR_CH3_V << RMT_MEM_OWNER_ERR_CH3_S) +#define RMT_MEM_OWNER_ERR_CH3_V 0x00000001U +#define RMT_MEM_OWNER_ERR_CH3_S 25 +/** RMT_MEM_FULL_CH3 : RO; bitpos: [26]; default: 0; * This status bit will be set if the receiver receives more data than the memory size. */ -#define RMT_MEM_FULL_CH2 (BIT(26)) -#define RMT_MEM_FULL_CH2_M (RMT_MEM_FULL_CH2_V << RMT_MEM_FULL_CH2_S) -#define RMT_MEM_FULL_CH2_V 0x00000001U -#define RMT_MEM_FULL_CH2_S 26 -/** RMT_APB_MEM_RD_ERR_CH2 : RO; bitpos: [27]; default: 0; +#define RMT_MEM_FULL_CH3 (BIT(26)) +#define RMT_MEM_FULL_CH3_M (RMT_MEM_FULL_CH3_V << RMT_MEM_FULL_CH3_S) +#define RMT_MEM_FULL_CH3_V 0x00000001U +#define RMT_MEM_FULL_CH3_S 26 +/** RMT_APB_MEM_RD_ERR_CH3 : RO; bitpos: [27]; default: 0; * This status bit will be set if the offset address out of memory size when reads via * APB bus. */ -#define RMT_APB_MEM_RD_ERR_CH2 (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH2_M (RMT_APB_MEM_RD_ERR_CH2_V << RMT_APB_MEM_RD_ERR_CH2_S) -#define RMT_APB_MEM_RD_ERR_CH2_V 0x00000001U -#define RMT_APB_MEM_RD_ERR_CH2_S 27 +#define RMT_APB_MEM_RD_ERR_CH3 (BIT(27)) +#define RMT_APB_MEM_RD_ERR_CH3_M (RMT_APB_MEM_RD_ERR_CH3_V << RMT_APB_MEM_RD_ERR_CH3_S) +#define RMT_APB_MEM_RD_ERR_CH3_V 0x00000001U +#define RMT_APB_MEM_RD_ERR_CH3_S 27 /** RMT_INT_RAW_REG register * Raw interrupt status @@ -786,28 +786,28 @@ extern "C" { #define RMT_CH3_RX_END_INT_RAW_V 0x00000001U #define RMT_CH3_RX_END_INT_RAW_S 3 /** RMT_CH0_ERR_INT_RAW : R/WTC/SS; bitpos: [4]; default: 0; - * The interrupt raw bit for CHANNEL$m. Triggered when error occurs. + * The interrupt raw bit for CHANNEL0. Triggered when error occurs. */ #define RMT_CH0_ERR_INT_RAW (BIT(4)) #define RMT_CH0_ERR_INT_RAW_M (RMT_CH0_ERR_INT_RAW_V << RMT_CH0_ERR_INT_RAW_S) #define RMT_CH0_ERR_INT_RAW_V 0x00000001U #define RMT_CH0_ERR_INT_RAW_S 4 /** RMT_CH1_ERR_INT_RAW : R/WTC/SS; bitpos: [5]; default: 0; - * The interrupt raw bit for CHANNEL$m. Triggered when error occurs. + * The interrupt raw bit for CHANNEL1. Triggered when error occurs. */ #define RMT_CH1_ERR_INT_RAW (BIT(5)) #define RMT_CH1_ERR_INT_RAW_M (RMT_CH1_ERR_INT_RAW_V << RMT_CH1_ERR_INT_RAW_S) #define RMT_CH1_ERR_INT_RAW_V 0x00000001U #define RMT_CH1_ERR_INT_RAW_S 5 /** RMT_CH2_ERR_INT_RAW : R/WTC/SS; bitpos: [6]; default: 0; - * The interrupt raw bit for CHANNEL$m. Triggered when error occurs. + * The interrupt raw bit for CHANNEL2. Triggered when error occurs. */ #define RMT_CH2_ERR_INT_RAW (BIT(6)) #define RMT_CH2_ERR_INT_RAW_M (RMT_CH2_ERR_INT_RAW_V << RMT_CH2_ERR_INT_RAW_S) #define RMT_CH2_ERR_INT_RAW_V 0x00000001U #define RMT_CH2_ERR_INT_RAW_S 6 /** RMT_CH3_ERR_INT_RAW : R/WTC/SS; bitpos: [7]; default: 0; - * The interrupt raw bit for CHANNEL$m. Triggered when error occurs. + * The interrupt raw bit for CHANNEL3. Triggered when error occurs. */ #define RMT_CH3_ERR_INT_RAW (BIT(7)) #define RMT_CH3_ERR_INT_RAW_M (RMT_CH3_ERR_INT_RAW_V << RMT_CH3_ERR_INT_RAW_S) @@ -1196,22 +1196,22 @@ extern "C" { * Channel 1 duty cycle configuration register */ #define RMT_CH1CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x4c) -/** RMT_CARRIER_LOW_CH0 : R/W; bitpos: [15:0]; default: 64; +/** RMT_CARRIER_LOW_CH1 : R/W; bitpos: [15:0]; default: 64; * This register is used to configure carrier wave 's low level clock period for * CHANNEL1. */ -#define RMT_CARRIER_LOW_CH0 0x0000FFFFU -#define RMT_CARRIER_LOW_CH0_M (RMT_CARRIER_LOW_CH0_V << RMT_CARRIER_LOW_CH0_S) -#define RMT_CARRIER_LOW_CH0_V 0x0000FFFFU -#define RMT_CARRIER_LOW_CH0_S 0 -/** RMT_CARRIER_HIGH_CH0 : R/W; bitpos: [31:16]; default: 64; +#define RMT_CARRIER_LOW_CH1 0x0000FFFFU +#define RMT_CARRIER_LOW_CH1_M (RMT_CARRIER_LOW_CH1_V << RMT_CARRIER_LOW_CH1_S) +#define RMT_CARRIER_LOW_CH1_V 0x0000FFFFU +#define RMT_CARRIER_LOW_CH1_S 0 +/** RMT_CARRIER_HIGH_CH1 : R/W; bitpos: [31:16]; default: 64; * This register is used to configure carrier wave 's high level clock period for * CHANNEL1. */ -#define RMT_CARRIER_HIGH_CH0 0x0000FFFFU -#define RMT_CARRIER_HIGH_CH0_M (RMT_CARRIER_HIGH_CH0_V << RMT_CARRIER_HIGH_CH0_S) -#define RMT_CARRIER_HIGH_CH0_V 0x0000FFFFU -#define RMT_CARRIER_HIGH_CH0_S 16 +#define RMT_CARRIER_HIGH_CH1 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH1_M (RMT_CARRIER_HIGH_CH1_V << RMT_CARRIER_HIGH_CH1_S) +#define RMT_CARRIER_HIGH_CH1_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH1_S 16 /** RMT_CH2_RX_CARRIER_RM_REG register * Channel 2 carrier remove register @@ -1238,22 +1238,22 @@ extern "C" { * Channel 3 carrier remove register */ #define RMT_CH3_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x54) -/** RMT_CARRIER_LOW_THRES_CH2 : R/W; bitpos: [15:0]; default: 0; +/** RMT_CARRIER_LOW_THRES_CH3 : R/W; bitpos: [15:0]; default: 0; * The low level period in a carrier modulation mode is * (REG_RMT_REG_CARRIER_LOW_THRES_CH3 + 1) for channel 3. */ -#define RMT_CARRIER_LOW_THRES_CH2 0x0000FFFFU -#define RMT_CARRIER_LOW_THRES_CH2_M (RMT_CARRIER_LOW_THRES_CH2_V << RMT_CARRIER_LOW_THRES_CH2_S) -#define RMT_CARRIER_LOW_THRES_CH2_V 0x0000FFFFU -#define RMT_CARRIER_LOW_THRES_CH2_S 0 -/** RMT_CARRIER_HIGH_THRES_CH2 : R/W; bitpos: [31:16]; default: 0; +#define RMT_CARRIER_LOW_THRES_CH3 0x0000FFFFU +#define RMT_CARRIER_LOW_THRES_CH3_M (RMT_CARRIER_LOW_THRES_CH3_V << RMT_CARRIER_LOW_THRES_CH3_S) +#define RMT_CARRIER_LOW_THRES_CH3_V 0x0000FFFFU +#define RMT_CARRIER_LOW_THRES_CH3_S 0 +/** RMT_CARRIER_HIGH_THRES_CH3 : R/W; bitpos: [31:16]; default: 0; * The high level period in a carrier modulation mode is * (REG_RMT_REG_CARRIER_HIGH_THRES_CH3 + 1) for channel 3. */ -#define RMT_CARRIER_HIGH_THRES_CH2 0x0000FFFFU -#define RMT_CARRIER_HIGH_THRES_CH2_M (RMT_CARRIER_HIGH_THRES_CH2_V << RMT_CARRIER_HIGH_THRES_CH2_S) -#define RMT_CARRIER_HIGH_THRES_CH2_V 0x0000FFFFU -#define RMT_CARRIER_HIGH_THRES_CH2_S 16 +#define RMT_CARRIER_HIGH_THRES_CH3 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH3_M (RMT_CARRIER_HIGH_THRES_CH3_V << RMT_CARRIER_HIGH_THRES_CH3_S) +#define RMT_CARRIER_HIGH_THRES_CH3_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH3_S 16 /** RMT_CH0_TX_LIM_REG register * Channel 0 Tx event configuration register @@ -1301,43 +1301,43 @@ extern "C" { * Channel 1 Tx event configuration register */ #define RMT_CH1_TX_LIM_REG (DR_REG_RMT_BASE + 0x5c) -/** RMT_TX_LIM_CH0 : R/W; bitpos: [8:0]; default: 128; +/** RMT_TX_LIM_CH1 : R/W; bitpos: [8:0]; default: 128; * This register is used to configure the maximum entries that CHANNEL1 can send out. */ -#define RMT_TX_LIM_CH0 0x000001FFU -#define RMT_TX_LIM_CH0_M (RMT_TX_LIM_CH0_V << RMT_TX_LIM_CH0_S) -#define RMT_TX_LIM_CH0_V 0x000001FFU -#define RMT_TX_LIM_CH0_S 0 -/** RMT_TX_LOOP_NUM_CH0 : R/W; bitpos: [18:9]; default: 0; +#define RMT_TX_LIM_CH1 0x000001FFU +#define RMT_TX_LIM_CH1_M (RMT_TX_LIM_CH1_V << RMT_TX_LIM_CH1_S) +#define RMT_TX_LIM_CH1_V 0x000001FFU +#define RMT_TX_LIM_CH1_S 0 +/** RMT_TX_LOOP_NUM_CH1 : R/W; bitpos: [18:9]; default: 0; * This register is used to configure the maximum loop count when tx_conti_mode is * valid. */ -#define RMT_TX_LOOP_NUM_CH0 0x000003FFU -#define RMT_TX_LOOP_NUM_CH0_M (RMT_TX_LOOP_NUM_CH0_V << RMT_TX_LOOP_NUM_CH0_S) -#define RMT_TX_LOOP_NUM_CH0_V 0x000003FFU -#define RMT_TX_LOOP_NUM_CH0_S 9 -/** RMT_TX_LOOP_CNT_EN_CH0 : R/W; bitpos: [19]; default: 0; +#define RMT_TX_LOOP_NUM_CH1 0x000003FFU +#define RMT_TX_LOOP_NUM_CH1_M (RMT_TX_LOOP_NUM_CH1_V << RMT_TX_LOOP_NUM_CH1_S) +#define RMT_TX_LOOP_NUM_CH1_V 0x000003FFU +#define RMT_TX_LOOP_NUM_CH1_S 9 +/** RMT_TX_LOOP_CNT_EN_CH1 : R/W; bitpos: [19]; default: 0; * This register is the enabled bit for loop count. */ -#define RMT_TX_LOOP_CNT_EN_CH0 (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH0_M (RMT_TX_LOOP_CNT_EN_CH0_V << RMT_TX_LOOP_CNT_EN_CH0_S) -#define RMT_TX_LOOP_CNT_EN_CH0_V 0x00000001U -#define RMT_TX_LOOP_CNT_EN_CH0_S 19 -/** RMT_LOOP_COUNT_RESET_CH0 : WT; bitpos: [20]; default: 0; +#define RMT_TX_LOOP_CNT_EN_CH1 (BIT(19)) +#define RMT_TX_LOOP_CNT_EN_CH1_M (RMT_TX_LOOP_CNT_EN_CH1_V << RMT_TX_LOOP_CNT_EN_CH1_S) +#define RMT_TX_LOOP_CNT_EN_CH1_V 0x00000001U +#define RMT_TX_LOOP_CNT_EN_CH1_S 19 +/** RMT_LOOP_COUNT_RESET_CH1 : WT; bitpos: [20]; default: 0; * This register is used to reset the loop count when tx_conti_mode is valid. */ -#define RMT_LOOP_COUNT_RESET_CH0 (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH0_M (RMT_LOOP_COUNT_RESET_CH0_V << RMT_LOOP_COUNT_RESET_CH0_S) -#define RMT_LOOP_COUNT_RESET_CH0_V 0x00000001U -#define RMT_LOOP_COUNT_RESET_CH0_S 20 -/** RMT_LOOP_STOP_EN_CH0 : R/W; bitpos: [21]; default: 0; +#define RMT_LOOP_COUNT_RESET_CH1 (BIT(20)) +#define RMT_LOOP_COUNT_RESET_CH1_M (RMT_LOOP_COUNT_RESET_CH1_V << RMT_LOOP_COUNT_RESET_CH1_S) +#define RMT_LOOP_COUNT_RESET_CH1_V 0x00000001U +#define RMT_LOOP_COUNT_RESET_CH1_S 20 +/** RMT_LOOP_STOP_EN_CH1 : R/W; bitpos: [21]; default: 0; * This bit is used to enable the loop send stop function after the loop counter * counts to loop number for CHANNEL1. */ -#define RMT_LOOP_STOP_EN_CH0 (BIT(21)) -#define RMT_LOOP_STOP_EN_CH0_M (RMT_LOOP_STOP_EN_CH0_V << RMT_LOOP_STOP_EN_CH0_S) -#define RMT_LOOP_STOP_EN_CH0_V 0x00000001U -#define RMT_LOOP_STOP_EN_CH0_S 21 +#define RMT_LOOP_STOP_EN_CH1 (BIT(21)) +#define RMT_LOOP_STOP_EN_CH1_M (RMT_LOOP_STOP_EN_CH1_V << RMT_LOOP_STOP_EN_CH1_S) +#define RMT_LOOP_STOP_EN_CH1_V 0x00000001U +#define RMT_LOOP_STOP_EN_CH1_S 21 /** RMT_CH2_RX_LIM_REG register * Channel 2 Rx event configuration register diff --git a/components/soc/esp32c6/include/soc/rtc.h b/components/soc/esp32c6/include/soc/rtc.h new file mode 100644 index 000000000000..f34531218a7c --- /dev/null +++ b/components/soc/esp32c6/include/soc/rtc.h @@ -0,0 +1,522 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include +#include "soc/soc.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file rtc.h + * @brief Low-level RTC power, clock functions. + * + * Functions in this file facilitate configuration of ESP32's RTC_CNTL peripheral. + * RTC_CNTL peripheral handles many functions: + * - enables/disables clocks and power to various parts of the chip; this is + * done using direct register access (forcing power up or power down) or by + * allowing state machines to control power and clocks automatically + * - handles sleep and wakeup functions + * - maintains a 48-bit counter which can be used for timekeeping + * + * These functions are not thread safe, and should not be viewed as high level + * APIs. For example, while this file provides a function which can switch + * CPU frequency, this function is on its own is not sufficient to implement + * frequency switching in ESP-IDF context: some coordination with RTOS, + * peripheral drivers, and WiFi/BT stacks is also required. + * + * These functions will normally not be used in applications directly. + * ESP-IDF provides, or will provide, drivers and other facilities to use + * RTC subsystem functionality. + * + * The functions are loosely split into the following groups: + * - rtc_clk: clock switching, calibration + * - rtc_time: reading RTC counter, conversion between counter values and time + */ + +#define MHZ (1000000) + +#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10) +#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12) +#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value + +#define OTHER_BLOCKS_POWERUP 1 +#define OTHER_BLOCKS_WAIT 1 + +// TODO: IDF-5781 +/* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP, + * RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values. + */ +#define RTC_CNTL_DBIAS_SLP 5 //sleep dig_dbias & rtc_dbias +#define RTC_CNTL_DBIAS_0V90 13 //digital voltage +#define RTC_CNTL_DBIAS_0V95 16 +#define RTC_CNTL_DBIAS_1V00 18 +#define RTC_CNTL_DBIAS_1V05 20 +#define RTC_CNTL_DBIAS_1V10 23 +#define RTC_CNTL_DBIAS_1V15 25 +#define RTC_CNTL_DBIAS_1V20 28 +#define RTC_CNTL_DBIAS_1V25 30 +#define RTC_CNTL_DBIAS_1V30 31 //voltage is about 1.34v in fact + +/* Delays for various clock sources to be enabled/switched. + * All values are in microseconds. + */ +#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3 +#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300 +#define SOC_DELAY_RC_FAST_ENABLE 50 +#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5 +#define SOC_DELAY_RC32K_ENABLE 300 + +/* Core voltage: // TODO: IDF-5781 + * Currently, ESP32C6 never adjust its wake voltage in runtime + * Only sets dig/rtc voltage dbias at startup time + */ +#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20 +#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20 +#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10 +#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00 + +#define RTC_CNTL_PLL_BUF_WAIT_DEFAULT 20 +#define RTC_CNTL_XTL_BUF_WAIT_DEFAULT 100 +#define RTC_CNTL_CK8M_WAIT_DEFAULT 20 +#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5 + +#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100 +#define RTC_CNTL_SCK_DCAP_DEFAULT 128 +#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700 + +/* Various delays to be programmed into power control state machines */ +#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250) +#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1) +#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4) +#define RTC_CNTL_WAKEUP_DELAY_CYCLES (5) +#define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1) +#define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) + +/* +set sleep_init default param +*/ +#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5 +#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0 +#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15 +#define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0 +#define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0 +#define RTC_CNTL_BIASSLP_SLEEP_ON 0 +#define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1 +#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0 +#define RTC_CNTL_PD_CUR_SLEEP_ON 0 +#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1 +#define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254 + +/* +The follow value is used to get a reasonable rtc voltage dbias value according to digital dbias & some other value +storing in efuse (based on ATE 5k ECO3 chips) +*/ +#define K_RTC_MID_MUL10000 215 +#define K_DIG_MID_MUL10000 213 +#define V_RTC_MID_MUL10000 10800 +#define V_DIG_MID_MUL10000 10860 + +/** + * @brief Possible main XTAL frequency values. + * + * Enum values should be equal to frequency in MHz. + */ +typedef enum { + RTC_XTAL_FREQ_40M = 40, //!< 40 MHz XTAL +} rtc_xtal_freq_t; + +/** + * @brief CPU clock configuration structure + */ +typedef struct rtc_cpu_freq_config_s { + soc_cpu_clk_src_t source; //!< The clock from which CPU clock is derived + uint32_t source_freq_mhz; //!< Source clock frequency + uint32_t div; //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div + uint32_t freq_mhz; //!< CPU clock frequency +} rtc_cpu_freq_config_t; + +#define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal + +#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO +#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO + +/** + * @brief Clock source to be calibrated using rtc_clk_cal function + * + * @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL + * However, this is not true on ESP32C6. The conversion to register field values is explicitly done in + * rtc_clk_cal_internal + */ +typedef enum { + RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK + RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator + RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock + RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock + RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock + RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator +} rtc_cal_sel_t; + +/** + * Initialization parameters for rtc_clk_init + */ +typedef struct { + rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency + uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz + soc_rtc_fast_clk_src_t fast_clk_src : 2; //!< RTC_FAST_CLK clock source to choose + soc_rtc_slow_clk_src_t slow_clk_src : 3; //!< RTC_SLOW_CLK clock source to choose + uint32_t clk_rtc_clk_div : 8; + uint32_t clk_8m_clk_div : 3; //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency) + uint32_t slow_clk_dcap : 8; //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency) + uint32_t clk_8m_dfreq : 10; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency) + uint32_t rc32k_dfreq : 10; //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency) +} rtc_clk_config_t; + +/** + * Default initializer for rtc_clk_config_t + */ +#define RTC_CLK_CONFIG_DEFAULT() { \ + .xtal_freq = CONFIG_XTAL_FREQ, \ + .cpu_freq_mhz = 80, \ + .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ + .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ + .clk_rtc_clk_div = 0, \ + .clk_8m_clk_div = 0, \ + .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \ + .clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \ + .rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \ +} + +/** + * Initialize clocks and set CPU frequency + * + * @param cfg clock configuration as rtc_clk_config_t + */ +void rtc_clk_init(rtc_clk_config_t cfg); + +/** + * @brief Get main XTAL frequency + * + * This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader. As passed to + * rtc_clk_init function + * + * @return XTAL frequency, one of rtc_xtal_freq_t + */ +rtc_xtal_freq_t rtc_clk_xtal_freq_get(void); + +/** + * @brief Update XTAL frequency + * + * Updates the XTAL value stored in RTC_XTAL_FREQ_REG. Usually this value is ignored + * after startup. + * + * @param xtal_freq New frequency value + */ +void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq); + +/** + * @brief Enable or disable 32 kHz XTAL oscillator + * @param en true to enable, false to disable + */ +void rtc_clk_32k_enable(bool en); + +/** + * @brief Configure 32 kHz XTAL oscillator to accept external clock signal + */ +void rtc_clk_32k_enable_external(void); + +/** + * @brief Get the state of 32k XTAL oscillator + * @return true if 32k XTAL oscillator has been enabled + */ +bool rtc_clk_32k_enabled(void); + +/** + * @brief Enable 32k oscillator, configuring it for fast startup time. + * Note: to achieve higher frequency stability, rtc_clk_32k_enable function + * must be called one the 32k XTAL oscillator has started up. This function + * will initially disable the 32k XTAL oscillator, so it should not be called + * when the system is using 32k XTAL as RTC_SLOW_CLK. + * + * @param cycle Number of 32kHz cycles to bootstrap external crystal. + * If 0, no square wave will be used to bootstrap crystal oscillation. + */ +void rtc_clk_32k_bootstrap(uint32_t cycle); + +/** + * @brief Enable or disable 32 kHz internal rc oscillator + * @param en true to enable, false to disable + */ +void rtc_clk_rc32k_enable(bool enable); + +/** + * @brief Enable or disable 8 MHz internal oscillator + * + * @param clk_8m_en true to enable 8MHz generator + */ +void rtc_clk_8m_enable(bool clk_8m_en); + +/** + * @brief Get the state of 8 MHz internal oscillator + * @return true if the oscillator is enabled + */ +bool rtc_clk_8m_enabled(void); + +/** + * @brief Select source for RTC_SLOW_CLK + * @param clk_src clock source (one of soc_rtc_slow_clk_src_t values) + */ +void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src); + +/** + * @brief Get the RTC_SLOW_CLK source + * @return currently selected clock source (one of soc_rtc_slow_clk_src_t values) + */ +soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void); + +/** + * @brief Get the approximate frequency of RTC_SLOW_CLK, in Hz + * + * - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW is selected, returns 136000 + * - if SOC_RTC_SLOW_CLK_SRC_XTAL32K is selected, returns 32768 + * - if SOC_RTC_SLOW_CLK_SRC_RC32K is selected, returns 32768 + * - if SOC_RTC_SLOW_CLK_SRC_OSC_SLOW is selected, returns 32768 + * + * rtc_clk_cal function can be used to get more precise value by comparing + * RTC_SLOW_CLK frequency to the frequency of main XTAL. + * + * @return RTC_SLOW_CLK frequency, in Hz + */ +uint32_t rtc_clk_slow_freq_get_hz(void); + +/** + * @brief Select source for RTC_FAST_CLK + * @param clk_src clock source (one of soc_rtc_fast_clk_src_t values) + */ +void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src); + +/** + * @brief Get the RTC_FAST_CLK source + * @return currently selected clock source (one of soc_rtc_fast_clk_src_t values) + */ +soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void); + +/** + * @brief Get CPU frequency config for a given frequency + * @param freq_mhz Frequency in MHz + * @param[out] out_config Output, CPU frequency configuration structure + * @return true if frequency can be obtained, false otherwise + */ +bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config); + +/** + * @brief Switch CPU frequency + * + * This function sets CPU frequency according to the given configuration + * structure. It enables PLLs, if necessary. + * + * @note This function in not intended to be called by applications in FreeRTOS + * environment. This is because it does not adjust various timers based on the + * new CPU frequency. + * + * @param config CPU frequency configuration structure + */ +void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config); + +/** + * @brief Switch CPU frequency (optimized for speed) + * + * This function is a faster equivalent of rtc_clk_cpu_freq_set_config. + * It works faster because it does not disable PLLs when switching from PLL to + * XTAL and does not enabled them when switching back. If PLL is not already + * enabled when this function is called to switch from XTAL to PLL frequency, + * or the PLL which is enabled is the wrong one, this function will fall back + * to calling rtc_clk_cpu_freq_set_config. + * + * Unlike rtc_clk_cpu_freq_set_config, this function relies on static data, + * so it is less safe to use it e.g. from a panic handler (when memory might + * be corrupted). + * + * @note This function in not intended to be called by applications in FreeRTOS + * environment. This is because it does not adjust various timers based on the + * new CPU frequency. + * + * @param config CPU frequency configuration structure + */ +void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config); + +/** + * @brief Get the currently used CPU frequency configuration + * @param[out] out_config Output, CPU frequency configuration structure + */ +void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); + +/** + * @brief Switch CPU clock source to XTAL + * + * Short form for filling in rtc_cpu_freq_config_t structure and calling + * rtc_clk_cpu_freq_set_config when a switch to XTAL is needed. + * Assumes that XTAL frequency has been determined — don't call in startup code. + * + * @note On ESP32C6, this function will check whether BBPLL can be disabled. If there is no consumer, then BBPLL will be + * turned off. The behaviour is the same as using rtc_clk_cpu_freq_set_config to switch cpu clock source to XTAL. + */ +void rtc_clk_cpu_freq_set_xtal(void); + +/** + * @brief Switch root clock source to PLL (only used by sleep) release root clock source locked by PMU + * + * wifi receiving beacon frame in PMU modem state strongly depends on the BBPLL + * clock, PMU will forcibly lock the root clock source as PLL, when the root + * clock source of the software system is selected as PLL, we need to release + * the root clock source locking and switch the root clock source to PLL in the + * sleep process (a critical section). + * + * @param[in] Maximum CPU frequency, in MHz + */ +void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz); + +/** + * @brief Get the current APB frequency. + * @return The calculated APB frequency value, in Hz. + */ +uint32_t rtc_clk_apb_freq_get(void); + +/** + * @brief Measure RTC slow clock's period, based on main XTAL frequency + * + * This function will time out and return 0 if the time for the given number + * of cycles to be counted exceeds the expected time twice. This may happen if + * 32k XTAL is being calibrated, but the oscillator has not started up (due to + * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board). + * + * @note When 32k CLK is being calibrated, this function will check the accuracy + * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if + * the check fails, then consider this an invalid 32k clock and return 0. This + * check can filter some jamming signal. + * + * @param cal_clk clock to be measured + * @param slow_clk_cycles number of slow clock cycles to average + * @return average slow clock period in microseconds, Q13.19 fixed point format, + * or 0 if calibration has timed out + */ +uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles); + +/** + * @brief Convert time interval from microseconds to RTC_SLOW_CLK cycles + * @param time_in_us Time interval in microseconds + * @param slow_clk_period Period of slow clock in microseconds, Q13.19 + * fixed point format (as returned by rtc_slowck_cali). + * @return number of slow clock cycles + */ +uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period); + +/** + * @brief Convert time interval from RTC_SLOW_CLK to microseconds + * @param time_in_us Time interval in RTC_SLOW_CLK cycles + * @param slow_clk_period Period of slow clock in microseconds, Q13.19 + * fixed point format (as returned by rtc_slowck_cali). + * @return time interval in microseconds + */ +uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period); + +/** + * @brief Get current value of RTC counter + * + * RTC has a 48-bit counter which is incremented by 2 every 2 RTC_SLOW_CLK + * cycles. Counter value is not writable by software. The value is not adjusted + * when switching to a different RTC_SLOW_CLK source. + * + * Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute + * + * @return current value of RTC counter + */ +uint64_t rtc_time_get(void); + +/** + * @brief Busy loop until next RTC_SLOW_CLK cycle + * + * This function returns not earlier than the next RTC_SLOW_CLK clock cycle. + * In some cases (e.g. when RTC_SLOW_CLK cycle is very close), it may return + * one RTC_SLOW_CLK cycle later. + */ +void rtc_clk_wait_for_slow_cycle(void); + +/** + * @brief Enable the rtc digital 8M clock + * + * This function is used to enable the digital rtc 8M clock to support peripherals. + * For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above. + */ +void rtc_dig_clk8m_enable(void); + +/** + * @brief Disable the rtc digital 8M clock + * + * This function is used to disable the digital rtc 8M clock, which is only used to support peripherals. + */ +void rtc_dig_clk8m_disable(void); + +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + +/** + * @brief Calculate the real clock value after the clock calibration + * + * @param cal_val Average slow clock period in microseconds, fixed point value as returned from `rtc_clk_cal` + * @return Frequency of the clock in Hz + */ +uint32_t rtc_clk_freq_cal(uint32_t cal_val); + + +// -------------------------- CLOCK TREE DEFS ALIAS ---------------------------- +// **WARNING**: The following are only for backwards compatibility. +// Please use the declarations in soc/clk_tree_defs.h instead. +/** + * @brief CPU clock source + */ +typedef soc_cpu_clk_src_t rtc_cpu_freq_src_t; +#define RTC_CPU_FREQ_SRC_XTAL SOC_CPU_CLK_SRC_XTAL //!< XTAL +#define RTC_CPU_FREQ_SRC_PLL SOC_CPU_CLK_SRC_PLL //!< PLL (480M) +#define RTC_CPU_FREQ_SRC_8M SOC_CPU_CLK_SRC_RC_FAST //!< Internal 17.5M RTC oscillator + +/** + * @brief RTC SLOW_CLK frequency values + */ +typedef soc_rtc_slow_clk_src_t rtc_slow_freq_t; +#define RTC_SLOW_FREQ_RTC SOC_RTC_SLOW_CLK_SRC_RC_SLOW //!< Internal 150 kHz RC oscillator +#define RTC_SLOW_FREQ_32K_XTAL SOC_RTC_SLOW_CLK_SRC_XTAL32K //!< External 32 kHz XTAL + +/** + * @brief RTC FAST_CLK frequency values + */ +typedef soc_rtc_fast_clk_src_t rtc_fast_freq_t; +#define RTC_FAST_FREQ_XTALD4 SOC_RTC_FAST_CLK_SRC_XTAL_DIV //!< Main XTAL, divided by 2 +#define RTC_FAST_FREQ_8M SOC_RTC_FAST_CLK_SRC_RC_FAST //!< Internal 17.5 MHz RC oscillator + +/* Alias of frequency related macros */ +#define RTC_FAST_CLK_FREQ_APPROX SOC_CLK_RC_FAST_FREQ_APPROX +#define RTC_FAST_CLK_FREQ_8M SOC_CLK_RC_FAST_FREQ_APPROX +#define RTC_SLOW_CLK_FREQ_150K SOC_CLK_RC_SLOW_FREQ_APPROX +#define RTC_SLOW_CLK_FREQ_32K SOC_CLK_XTAL32K_FREQ_APPROX + +/* Alias of deprecated function names */ +#define rtc_clk_slow_freq_set(slow_freq) rtc_clk_slow_src_set(slow_freq) +#define rtc_clk_slow_freq_get() rtc_clk_slow_src_get() +#define rtc_clk_fast_freq_set(fast_freq) rtc_clk_fast_src_set(fast_freq) +#define rtc_clk_fast_freq_get() rtc_clk_fast_src_get() + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/rtc_io_channel.h b/components/soc/esp32c6/include/soc/rtc_io_channel.h new file mode 100644 index 000000000000..6571d4c28e84 --- /dev/null +++ b/components/soc/esp32c6/include/soc/rtc_io_channel.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +//RTC GPIO channels +#define RTCIO_GPIO0_CHANNEL 0 //RTCIO_CHANNEL_0 +#define RTCIO_CHANNEL_0_GPIO_NUM 0 + +#define RTCIO_GPIO1_CHANNEL 1 //RTCIO_CHANNEL_1 +#define RTCIO_CHANNEL_1_GPIO_NUM 1 + +#define RTCIO_GPIO2_CHANNEL 2 //RTCIO_CHANNEL_2 +#define RTCIO_CHANNEL_2_GPIO_NUM 2 + +#define RTCIO_GPIO3_CHANNEL 3 //RTCIO_CHANNEL_3 +#define RTCIO_CHANNEL_3_GPIO_NUM 3 + +#define RTCIO_GPIO4_CHANNEL 4 //RTCIO_CHANNEL_4 +#define RTCIO_CHANNEL_4_GPIO_NUM 4 + +#define RTCIO_GPIO5_CHANNEL 5 //RTCIO_CHANNEL_5 +#define RTCIO_CHANNEL_5_GPIO_NUM 5 + +#define RTCIO_GPIO6_CHANNEL 6 //RTCIO_CHANNEL_6 +#define RTCIO_CHANNEL_6_GPIO_NUM 6 + +#define RTCIO_GPIO7_CHANNEL 7 //RTCIO_CHANNEL_7 +#define RTCIO_CHANNEL_7_GPIO_NUM 7 diff --git a/components/soc/esp32c6/include/soc/rtc_io_reg.h b/components/soc/esp32c6/include/soc/rtc_io_reg.h new file mode 100644 index 000000000000..8a1b7e522f1f --- /dev/null +++ b/components/soc/esp32c6/include/soc/rtc_io_reg.h @@ -0,0 +1,8 @@ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "soc/lp_io_reg.h" diff --git a/components/soc/esp32c6/include/soc/rtc_io_struct.h b/components/soc/esp32c6/include/soc/rtc_io_struct.h new file mode 100644 index 000000000000..a17f927c65a7 --- /dev/null +++ b/components/soc/esp32c6/include/soc/rtc_io_struct.h @@ -0,0 +1,19 @@ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "soc/lp_io_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef lp_io_dev_t rtc_io_dev_t; +#define RTCIO LP_IO + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/sdio_slave_pins.h b/components/soc/esp32c6/include/soc/sdio_slave_pins.h new file mode 100644 index 000000000000..e7f4d11db269 --- /dev/null +++ b/components/soc/esp32c6/include/soc/sdio_slave_pins.h @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 18 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 19 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 20 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 21 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 22 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 23 +#define SDIO_SLAVE_SLOT0_FUNC 0 diff --git a/components/soc/esp32c6/include/soc/soc.h b/components/soc/esp32c6/include/soc/soc.h new file mode 100644 index 000000000000..3212e9647be1 --- /dev/null +++ b/components/soc/esp32c6/include/soc/soc.h @@ -0,0 +1,241 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifndef __ASSEMBLER__ +#include +#include "esp_assert.h" +#endif + +#include "esp_bit_defs.h" +#include "reg_base.h" + +#define PRO_CPU_NUM (0) + +#define REG_UHCI_BASE(i) (DR_REG_UHCI0_BASE) // only one UHCI on C6 +#define REG_UART_BASE(i) (DR_REG_UART_BASE + (i) * 0x1000) // UART0 and UART1 +#define REG_UART_AHB_BASE(i) (0x60000000 + (i) * 0x10000) +#define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) +#define REG_I2S_BASE(i) (DR_REG_I2S_BASE) // only one I2S on C6 +#define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i) * 0x1000) // TIMERG0 and TIMERG1 +#define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE + (i) * 0x1000) // SPIMEM0 and SPIMEM1 +#define REG_SPI_BASE(i) (((i)==2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI on C6 +#define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE) // only one I2C on C6 +#define REG_MCPWM_BASE(i) (DR_REG_MCPWM_BASE) // only one MCPWM on C6 +#define REG_TWAI_BASE(i) (DR_REG_TWAI0_BASE + (i) * 0x2000) // TWAI0 and TWAI1 + +//Registers Operation {{ +#define ETS_UNCACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) + +#ifndef __ASSEMBLER__ + +//write value to register +#define REG_WRITE(_r, _v) do { \ + (*(volatile uint32_t *)(_r)) = (_v); \ + } while(0) + +//read value from register +#define REG_READ(_r) ({ \ + (*(volatile uint32_t *)(_r)); \ + }) + +//get bit or get bits from register +#define REG_GET_BIT(_r, _b) ({ \ + (*(volatile uint32_t*)(_r) & (_b)); \ + }) + +//set bit or set bits to register +#define REG_SET_BIT(_r, _b) do { \ + *(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) | (_b); \ + } while(0) + +//clear bit or clear bits of register +#define REG_CLR_BIT(_r, _b) do { \ + *(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) & (~(_b)); \ + } while(0) + +//set bits of register controlled by mask +#define REG_SET_BITS(_r, _b, _m) do { \ + *(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m)); \ + } while(0) + +//get field from register, uses field _S & _V to determine mask +#define REG_GET_FIELD(_r, _f) ({ \ + ((REG_READ(_r) >> (_f##_S)) & (_f##_V)); \ + }) + +//set field of a register from variable, uses field _S & _V to determine mask +#define REG_SET_FIELD(_r, _f, _v) do { \ + REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S)))); \ + } while(0) + +//get field value from a variable, used when _f is not left shifted by _f##_S +#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f)) + +//get field value from a variable, used when _f is left shifted by _f##_S +#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S)) + +//set field value to a variable, used when _f is not left shifted by _f##_S +#define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S)))) + +//set field value to a variable, used when _f is left shifted by _f##_S +#define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S)))) + +//generate a value from a field value, used when _f is not left shifted by _f##_S +#define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S) + +//generate a value from a field value, used when _f is left shifted by _f##_S +#define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f)) + +//read value from register +#define READ_PERI_REG(addr) ({ \ + (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))); \ + }) + +//write value to register +#define WRITE_PERI_REG(addr, val) do { \ + (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val); \ + } while(0) + +//clear bits of register controlled by mask +#define CLEAR_PERI_REG_MASK(reg, mask) do { \ + WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask)))); \ + } while(0) + +//set bits of register controlled by mask +#define SET_PERI_REG_MASK(reg, mask) do { \ + WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask))); \ + } while(0) + +//get bits of register controlled by mask +#define GET_PERI_REG_MASK(reg, mask) ({ \ + (READ_PERI_REG(reg) & (mask)); \ + }) + +//get bits of register controlled by highest bit and lowest bit +#define GET_PERI_REG_BITS(reg, hipos,lowpos) ({ \ + ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)); \ + }) + +//set bits of register controlled by mask and shift +#define SET_PERI_REG_BITS(reg,bit_map,value,shift) do { \ + WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & (bit_map))<<(shift)) ); \ + } while(0) + +//get field of register +#define GET_PERI_REG_BITS2(reg, mask,shift) ({ \ + ((READ_PERI_REG(reg)>>(shift))&(mask)); \ + }) + +#endif /* !__ASSEMBLER__ */ +//}} + +//Periheral Clock {{ +#define APB_CLK_FREQ_ROM ( 40*1000000 ) +#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM +#define EFUSE_CLK_FREQ_ROM ( 20*1000000) +#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration +#define CPU_CLK_FREQ APB_CLK_FREQ +#define APB_CLK_FREQ ( 40*1000000 ) +#define MODEM_APB_CLK_FREQ ( 80*1000000 ) +#define REF_CLK_FREQ ( 1000000 ) +#define XTAL_CLK_FREQ (40*1000000) +#define GPIO_MATRIX_DELAY_NS 0 +//}} + +/* Overall memory map */ +/* Note: We should not use MACROs similar in cache_memory.h + * those are defined during run-time. But the MACROs here + * should be defined statically! + */ + +#define SOC_IROM_LOW 0x42000000 +#define SOC_IROM_HIGH (SOC_IROM_LOW + (SOC_MMU_PAGE_SIZE<<8)) +#define SOC_DROM_LOW SOC_IROM_LOW +#define SOC_DROM_HIGH SOC_IROM_HIGH +#define SOC_IROM_MASK_LOW 0x40000000 +#define SOC_IROM_MASK_HIGH 0x40050000 +#define SOC_DROM_MASK_LOW 0x40000000 +#define SOC_DROM_MASK_HIGH 0x40050000 +#define SOC_IRAM_LOW 0x40800000 +#define SOC_IRAM_HIGH 0x40880000 +#define SOC_DRAM_LOW 0x40800000 +#define SOC_DRAM_HIGH 0x40880000 +#define SOC_RTC_IRAM_LOW 0x50000000 // ESP32-C6 only has 16k LP memory +#define SOC_RTC_IRAM_HIGH 0x50004000 +#define SOC_RTC_DRAM_LOW 0x50000000 +#define SOC_RTC_DRAM_HIGH 0x50004000 +#define SOC_RTC_DATA_LOW 0x50000000 +#define SOC_RTC_DATA_HIGH 0x50004000 + +//First and last words of the D/IRAM region, for both the DRAM address as well as the IRAM alias. +#define SOC_DIRAM_IRAM_LOW 0x40800000 +#define SOC_DIRAM_IRAM_HIGH 0x40880000 +#define SOC_DIRAM_DRAM_LOW 0x40800000 +#define SOC_DIRAM_DRAM_HIGH 0x40880000 + +#define MAP_DRAM_TO_IRAM(addr) (addr) +#define MAP_IRAM_TO_DRAM(addr) (addr) + +// Region of memory accessible via DMA. See esp_ptr_dma_capable(). +#define SOC_DMA_LOW 0x40800000 +#define SOC_DMA_HIGH 0x40880000 + +// Region of RAM that is byte-accessible. See esp_ptr_byte_accessible(). +#define SOC_BYTE_ACCESSIBLE_LOW 0x40800000 +#define SOC_BYTE_ACCESSIBLE_HIGH 0x40880000 + +//Region of memory that is internal, as in on the same silicon die as the ESP32 CPUs +//(excluding RTC data region, that's checked separately.) See esp_ptr_internal(). +#define SOC_MEM_INTERNAL_LOW 0x40800000 +#define SOC_MEM_INTERNAL_HIGH 0x40880000 +#define SOC_MEM_INTERNAL_LOW1 0x40800000 +#define SOC_MEM_INTERNAL_HIGH1 0x40880000 + +#define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_IRAM_HIGH - SOC_IRAM_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space + +// Region of address space that holds peripherals +#define SOC_PERIPHERAL_LOW 0x60000000 +#define SOC_PERIPHERAL_HIGH 0x60100000 + +// CPU sub-system region, contains interrupt config registers +#define SOC_CPU_SUBSYSTEM_LOW 0x20000000 +#define SOC_CPU_SUBSYSTEM_HIGH 0x30000000 + +// Start (highest address) of ROM boot stack, only relevant during early boot +#define SOC_ROM_STACK_START 0x4087e610 +#define SOC_ROM_STACK_SIZE 0x2000 + +//On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW. +//There is no HW NMI conception. SW should controlled the masked levels through INT_THRESH_REG. + +//CPU0 Interrupt number reserved in riscv/vector.S, not touch this. +#define ETS_T1_WDT_INUM 24 +#define ETS_CACHEERR_INUM 25 +#define ETS_MEMPROT_ERR_INUM 26 +//CPU0 Max valid interrupt number +#define ETS_MAX_INUM 31 + +//CPU0 Interrupt number used in ROM, should be cancelled in SDK +#define ETS_SLC_INUM 1 +#define ETS_UART0_INUM 5 +#define ETS_UART1_INUM 5 +#define ETS_SPI2_INUM 1 +//CPU0 Interrupt number used in ROM code only when module init function called, should pay attention here. +#define ETS_GPIO_INUM 4 + +//Other interrupt number should be managed by the user + +//Invalid interrupt for number interrupt matrix +#define ETS_INVALID_INUM 0 + +//Interrupt medium level, used for INT WDT for example +#define SOC_INTERRUPT_LEVEL_MEDIUM 4 + +// Interrupt number for the Interrupt watchdog +#define ETS_INT_WDT_INUM (ETS_T1_WDT_INUM) diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h new file mode 100644 index 000000000000..56ef2fdafa2c --- /dev/null +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -0,0 +1,538 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The long term plan is to have a single soc_caps.h for each peripheral. +// During the refactoring and multichip support development process, we +// seperate these information into periph_caps.h for each peripheral and +// include them here. + +/* + * These defines are parsed and imported as kconfig variables via the script + * `tools/gen_soc_caps_kconfig/gen_soc_caps_kconfig.py` + * + * If this file is changed the script will automatically run the script + * and generate the kconfig variables as part of the pre-commit hooks. + * + * It can also be ran manually with `./tools/gen_soc_caps_kconfig/gen_soc_caps_kconfig.py 'components/soc/esp32c6/include/soc/'` + * + * For more information see `tools/gen_soc_caps_kconfig/README.md` + * +*/ + +#pragma once + +/*-------------------------- COMMON CAPS ---------------------------------------*/ +#define SOC_ADC_SUPPORTED 1 +#define SOC_DEDICATED_GPIO_SUPPORTED 1 +#define SOC_UART_SUPPORTED 1 +#define SOC_GDMA_SUPPORTED 1 +#define SOC_GPTIMER_SUPPORTED 1 +#define SOC_PCNT_SUPPORTED 1 +#define SOC_MCPWM_SUPPORTED 1 +#define SOC_TWAI_SUPPORTED 1 +#define SOC_ETM_SUPPORTED 1 +#define SOC_PARLIO_SUPPORTED 1 +#define SOC_BT_SUPPORTED 1 +#define SOC_IEEE802154_SUPPORTED 1 +#define SOC_ASYNC_MEMCPY_SUPPORTED 1 +#define SOC_USB_SERIAL_JTAG_SUPPORTED 1 +#define SOC_TEMP_SENSOR_SUPPORTED 1 +#define SOC_WIFI_SUPPORTED 1 +#define SOC_SUPPORTS_SECURE_DL_MODE 1 +#define SOC_ULP_SUPPORTED 1 +#define SOC_LP_CORE_SUPPORTED 1 +#define SOC_EFUSE_KEY_PURPOSE_FIELD 1 +#define SOC_RTC_FAST_MEM_SUPPORTED 1 +#define SOC_RTC_MEM_SUPPORTED 1 +#define SOC_I2S_SUPPORTED 1 +#define SOC_RMT_SUPPORTED 1 +#define SOC_SDM_SUPPORTED 1 +#define SOC_GPSPI_SUPPORTED 1 +#define SOC_LEDC_SUPPORTED 1 +#define SOC_I2C_SUPPORTED 1 +#define SOC_SYSTIMER_SUPPORTED 1 +#define SOC_SUPPORT_COEXISTENCE 1 +#define SOC_AES_SUPPORTED 1 +#define SOC_MPI_SUPPORTED 1 +#define SOC_SHA_SUPPORTED 1 +#define SOC_HMAC_SUPPORTED 1 +#define SOC_DIG_SIGN_SUPPORTED 1 +#define SOC_ECC_SUPPORTED 1 +#define SOC_FLASH_ENC_SUPPORTED 1 +#define SOC_SECURE_BOOT_SUPPORTED 1 +#define SOC_SDIO_SLAVE_SUPPORTED 1 +#define SOC_BOD_SUPPORTED 1 +#define SOC_APM_SUPPORTED 1 +#define SOC_PMU_SUPPORTED 1 +#define SOC_PAU_SUPPORTED 1 +#define SOC_LP_TIMER_SUPPORTED 1 +#define SOC_LP_AON_SUPPORTED 1 +#define SOC_LP_I2C_SUPPORTED 1 + +/*-------------------------- XTAL CAPS ---------------------------------------*/ +#define SOC_XTAL_SUPPORT_40M 1 + +/*-------------------------- AES CAPS -----------------------------------------*/ +#define SOC_AES_SUPPORT_DMA (1) + +/* Has a centralized DMA, which is shared with all peripherals */ +#define SOC_AES_GDMA (1) + +#define SOC_AES_SUPPORT_AES_128 (1) +#define SOC_AES_SUPPORT_AES_256 (1) + +/*-------------------------- ADC CAPS -------------------------------*/ +/*!< SAR ADC Module*/ +#define SOC_ADC_DIG_CTRL_SUPPORTED 1 +#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED 1 +#define SOC_ADC_MONITOR_SUPPORTED 1 +#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) 1 //Digital controller supported ADC unit +#define SOC_ADC_DMA_SUPPORTED 1 +#define SOC_ADC_PERIPH_NUM (1U) +#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (7) +#define SOC_ADC_MAX_CHANNEL_NUM (7) +#define SOC_ADC_ATTEN_NUM (4) + +/*!< Digital */ +#define SOC_ADC_DIGI_CONTROLLER_NUM (1U) +#define SOC_ADC_PATT_LEN_MAX (8) /*!< Two pattern tables, each contains 4 items. Each item takes 1 byte */ +#define SOC_ADC_DIGI_MAX_BITWIDTH (12) +#define SOC_ADC_DIGI_MIN_BITWIDTH (12) +#define SOC_ADC_DIGI_IIR_FILTER_NUM (2) +#define SOC_ADC_DIGI_MONITOR_NUM (2) +#define SOC_ADC_DIGI_RESULT_BYTES (4) +#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4) +/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval <= 4095 */ +#define SOC_ADC_SAMPLE_FREQ_THRES_HIGH 83333 +#define SOC_ADC_SAMPLE_FREQ_THRES_LOW 611 + +/*!< RTC */ +#define SOC_ADC_RTC_MIN_BITWIDTH (12) +#define SOC_ADC_RTC_MAX_BITWIDTH (12) + +/*!< Calibration */ +#define SOC_ADC_CALIBRATION_V1_SUPPORTED (1) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_SELF_HW_CALI_SUPPORTED (1) /*!< support HW offset self calibration */ +#define SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED (1) /*!< support channel compensation to the HW offset calibration */ + +/*!< Interrupt */ +#define SOC_ADC_TEMPERATURE_SHARE_INTR (1) + +// ESP32C6-TODO: Copy from esp32c6, need check +/*-------------------------- APB BACKUP DMA CAPS -------------------------------*/ +#define SOC_APB_BACKUP_DMA (0) + +/*-------------------------- BROWNOUT CAPS -----------------------------------*/ +#define SOC_BROWNOUT_RESET_SUPPORTED 1 + +/*-------------------------- CACHE CAPS --------------------------------------*/ +#define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data +#define SOC_CACHE_FREEZE_SUPPORTED 1 + +/*-------------------------- CPU CAPS ----------------------------------------*/ +#define SOC_CPU_CORES_NUM (1U) +#define SOC_CPU_INTR_NUM 32 +#define SOC_CPU_HAS_FLEXIBLE_INTC 1 +#define SOC_INT_PLIC_SUPPORTED 1 //riscv platform-level interrupt controller + +#define SOC_CPU_BREAKPOINTS_NUM 4 +#define SOC_CPU_WATCHPOINTS_NUM 4 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x80000000 // bytes + +#define SOC_CPU_HAS_PMA 1 +#define SOC_CPU_IDRAM_SPLIT_USING_PMP 1 + +// TODO: IDF-5360 (Copy from esp32c3, need check) +/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ +/** The maximum length of a Digital Signature in bits. */ +#define SOC_DS_SIGNATURE_MAX_BIT_LEN (3072) + +/** Initialization vector (IV) length for the RSA key parameter message digest (MD) in bytes. */ +#define SOC_DS_KEY_PARAM_MD_IV_LENGTH (16) + +/** Maximum wait time for DS parameter decryption key. If overdue, then key error. + See TRM DS chapter for more details */ +#define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100) + +/*-------------------------- GDMA CAPS -------------------------------------*/ +#define SOC_GDMA_GROUPS (1U) // Number of GDMA groups +#define SOC_GDMA_PAIRS_PER_GROUP (3) // Number of GDMA pairs in each group +#define SOC_GDMA_SUPPORT_ETM (1) // Support ETM submodule + +/*-------------------------- ETM CAPS --------------------------------------*/ +#define SOC_ETM_GROUPS 1U // Number of ETM groups +#define SOC_ETM_CHANNELS_PER_GROUP 50 // Number of ETM channels in the group + +/*-------------------------- GPIO CAPS ---------------------------------------*/ +// ESP32-C6 has 1 GPIO peripheral +#define SOC_GPIO_PORT 1U +#define SOC_GPIO_PIN_COUNT 31 +#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_FLEX_GLITCH_FILTER_NUM 8 + +// GPIO peripheral has the ETM extension +#define SOC_GPIO_SUPPORT_ETM 1 +#define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 +#define SOC_GPIO_ETM_TASKS_PER_GROUP 8 + +// Target has the full LP IO subsystem +// On ESP32-C6, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. +#define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) +// GPIO0~7 on ESP32C6 can support chip deep sleep wakeup +#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) + +#define SOC_GPIO_VALID_GPIO_MASK ((1U< SPI0/SPI1, host_id = 1 -> SPI2, +#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(host_id) ({(void)host_id; 1;}) + +#define SOC_MEMSPI_IS_INDEPENDENT 1 +#define SOC_SPI_MAX_PRE_DIVIDER 16 + +/*-------------------------- SPI MEM CAPS ---------------------------------------*/ +#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1) +#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) +#define SOC_SPI_MEM_SUPPORT_AUTO_RESUME (1) +#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) +#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) +#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) + +#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 +#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 +#define SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED 1 + +/*-------------------------- SYSTIMER CAPS ----------------------------------*/ +#define SOC_SYSTIMER_COUNTER_NUM 2 // Number of counter units +#define SOC_SYSTIMER_ALARM_NUM 3 // Number of alarm units +#define SOC_SYSTIMER_BIT_WIDTH_LO 32 // Bit width of systimer low part +#define SOC_SYSTIMER_BIT_WIDTH_HI 20 // Bit width of systimer high part +#define SOC_SYSTIMER_FIXED_DIVIDER 1 // Clock source divider is fixed: 2.5 +#define SOC_SYSTIMER_SUPPORT_RC_FAST 1 // Systimer can use RC_FAST clock source +#define SOC_SYSTIMER_INT_LEVEL 1 // Systimer peripheral uses level interrupt +#define SOC_SYSTIMER_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current) +#define SOC_SYSTIMER_SUPPORT_ETM 1 // Systimer comparator can generate ETM event + +/*-------------------------- LP_TIMER CAPS ----------------------------------*/ +#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part +#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part + +/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/ +#define SOC_TIMER_GROUPS (2) +#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U) +#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54) +#define SOC_TIMER_GROUP_SUPPORT_XTAL (1) +#define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1) +#define SOC_TIMER_GROUP_TOTAL_TIMERS (2) +#define SOC_TIMER_SUPPORT_ETM (1) + +/*--------------------------- WATCHDOG CAPS ---------------------------------------*/ +#define SOC_MWDT_SUPPORT_XTAL (1) + +/*-------------------------- TWAI CAPS ---------------------------------------*/ +#define SOC_TWAI_CONTROLLER_NUM 2 +#define SOC_TWAI_CLK_SUPPORT_XTAL 1 +#define SOC_TWAI_BRP_MIN 2 +#define SOC_TWAI_BRP_MAX 32768 +#define SOC_TWAI_SUPPORTS_RX_STATUS 1 + +/*-------------------------- eFuse CAPS----------------------------*/ +#define SOC_EFUSE_DIS_DOWNLOAD_ICACHE 1 +#define SOC_EFUSE_DIS_PAD_JTAG 1 +#define SOC_EFUSE_DIS_USB_JTAG 1 +#define SOC_EFUSE_DIS_DIRECT_BOOT 1 +#define SOC_EFUSE_SOFT_DIS_JTAG 1 +#define SOC_EFUSE_DIS_ICACHE 1 +#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS key purpose not supported for this block + +/*-------------------------- Secure Boot CAPS----------------------------*/ +#define SOC_SECURE_BOOT_V2_RSA 1 +#define SOC_SECURE_BOOT_V2_ECC 1 +#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 +#define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1 +#define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 + +/*-------------------------- Flash Encryption CAPS----------------------------*/ +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTION_XTS_AES 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 + +/*------------------------ Anti DPA (Security) CAPS --------------------------*/ +#define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1 + +/*-------------------------- UART CAPS ---------------------------------------*/ +// ESP32-C6 has 2 UARTs +#define SOC_UART_NUM (2) +#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ +#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ +#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */ +#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ +#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ +#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ + +// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled +#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) + +// TODO: IDF-5679 (Copy from esp32c3, need check) +/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ +#define SOC_COEX_HW_PTI (1) + +/*-------------------------- EXTERNAL COEXISTENCE CAPS -------------------------------------*/ +#define SOC_EXTERNAL_COEX_ADVANCE (1) /*!< HARDWARE ADVANCED EXTERNAL COEXISTENCE CAPS */ +#define SOC_EXTERNAL_COEX_LEADER_TX_LINE (0) /*!< EXTERNAL COEXISTENCE TX LINE CAPS */ + +/*--------------- PHY REGISTER AND MEMORY SIZE CAPS --------------------------*/ +#define SOC_PHY_DIG_REGS_MEM_SIZE (21*4) + +// TODO: IDF-5679 (Copy from esp32c3, need check) +/*--------------- WIFI LIGHT SLEEP CLOCK WIDTH CAPS --------------------------*/ +#define SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH (12) + +// TODO: IDF-5351 (Copy from esp32c3, need check) +/*-------------------------- Power Management CAPS ----------------------------*/ +#define SOC_PM_SUPPORT_WIFI_WAKEUP (1) +#define SOC_PM_SUPPORT_BEACON_WAKEUP (1) +#define SOC_PM_SUPPORT_BT_WAKEUP (1) +#define SOC_PM_SUPPORT_EXT1_WAKEUP (1) +#define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*! #include "soc/soc.h" + #ifdef __cplusplus extern "C" { #endif @@ -2998,94 +2999,6 @@ isable..*/ #define SPI_MEM_CLK_EN_V 0x1 #define SPI_MEM_CLK_EN_S 0 -#define SPI_MEM_XTS_PLAIN_BASE_REG(i) (REG_SPI_MEM_BASE(i) + 0x300) -/* SPI_MEM_XTS_PLAIN : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: This field is only used to generate include file in c case. This field is useles -s. Please do not use this field..*/ -#define SPI_MEM_XTS_PLAIN 0xFFFFFFFF -#define SPI_MEM_XTS_PLAIN_M ((SPI_MEM_XTS_PLAIN_V)<<(SPI_MEM_XTS_PLAIN_S)) -#define SPI_MEM_XTS_PLAIN_V 0xFFFFFFFF -#define SPI_MEM_XTS_PLAIN_S 0 - -#define SPI_MEM_XTS_LINESIZE_REG(i) (REG_SPI_MEM_BASE(i) + 0x340) -/* SPI_MEM_XTS_LINESIZE : R/W ;bitpos:[1:0] ;default: 2'h0 ; */ -/*description: This bits stores the line-size parameter which will be used in manual encryption - calculation. It decides how many bytes will be encrypted one time. 0: 16-bytes, - 1: 32-bytes, 2: 64-bytes, 3:reserved..*/ -#define SPI_MEM_XTS_LINESIZE 0x00000003 -#define SPI_MEM_XTS_LINESIZE_M ((SPI_MEM_XTS_LINESIZE_V)<<(SPI_MEM_XTS_LINESIZE_S)) -#define SPI_MEM_XTS_LINESIZE_V 0x3 -#define SPI_MEM_XTS_LINESIZE_S 0 - -#define SPI_MEM_XTS_DESTINATION_REG(i) (REG_SPI_MEM_BASE(i) + 0x344) -/* SPI_MEM_XTS_DESTINATION : R/W ;bitpos:[0] ;default: 1'b0 ; */ -/*description: This bit stores the destination parameter which will be used in manual encryptio -n calculation. 0: flash(default), 1: psram(reserved). Only default value can be -used..*/ -#define SPI_MEM_XTS_DESTINATION (BIT(0)) -#define SPI_MEM_XTS_DESTINATION_M (BIT(0)) -#define SPI_MEM_XTS_DESTINATION_V 0x1 -#define SPI_MEM_XTS_DESTINATION_S 0 - -#define SPI_MEM_XTS_PHYSICAL_ADDRESS_REG(i) (REG_SPI_MEM_BASE(i) + 0x348) -/* SPI_MEM_XTS_PHYSICAL_ADDRESS : R/W ;bitpos:[25:0] ;default: 26'h0 ; */ -/*description: This bits stores the physical-address parameter which will be used in manual enc -ryption calculation. This value should aligned with byte number decided by line- -size parameter..*/ -#define SPI_MEM_XTS_PHYSICAL_ADDRESS 0x03FFFFFF -#define SPI_MEM_XTS_PHYSICAL_ADDRESS_M ((SPI_MEM_XTS_PHYSICAL_ADDRESS_V)<<(SPI_MEM_XTS_PHYSICAL_ADDRESS_S)) -#define SPI_MEM_XTS_PHYSICAL_ADDRESS_V 0x3FFFFFF -#define SPI_MEM_XTS_PHYSICAL_ADDRESS_S 0 - -#define SPI_MEM_XTS_TRIGGER_REG(i) (REG_SPI_MEM_BASE(i) + 0x34C) -/* SPI_MEM_XTS_TRIGGER : WT ;bitpos:[0] ;default: 1'b0 ; */ -/*description: Set this bit to trigger the process of manual encryption calculation. This actio -n should only be asserted when manual encryption status is 0. After this action, - manual encryption status becomes 1. After calculation is done, manual encryptio -n status becomes 2..*/ -#define SPI_MEM_XTS_TRIGGER (BIT(0)) -#define SPI_MEM_XTS_TRIGGER_M (BIT(0)) -#define SPI_MEM_XTS_TRIGGER_V 0x1 -#define SPI_MEM_XTS_TRIGGER_S 0 - -#define SPI_MEM_XTS_RELEASE_REG(i) (REG_SPI_MEM_BASE(i) + 0x350) -/* SPI_MEM_XTS_RELEASE : WT ;bitpos:[0] ;default: 1'b0 ; */ -/*description: Set this bit to release encrypted result to mspi. This action should only be ass -erted when manual encryption status is 2. After this action, manual encryption s -tatus will become 3..*/ -#define SPI_MEM_XTS_RELEASE (BIT(0)) -#define SPI_MEM_XTS_RELEASE_M (BIT(0)) -#define SPI_MEM_XTS_RELEASE_V 0x1 -#define SPI_MEM_XTS_RELEASE_S 0 - -#define SPI_MEM_XTS_DESTROY_REG(i) (REG_SPI_MEM_BASE(i) + 0x354) -/* SPI_MEM_XTS_DESTROY : WT ;bitpos:[0] ;default: 1'b0 ; */ -/*description: Set this bit to destroy encrypted result. This action should be asserted only wh -en manual encryption status is 3. After this action, manual encryption status wi -ll become 0..*/ -#define SPI_MEM_XTS_DESTROY (BIT(0)) -#define SPI_MEM_XTS_DESTROY_M (BIT(0)) -#define SPI_MEM_XTS_DESTROY_V 0x1 -#define SPI_MEM_XTS_DESTROY_S 0 - -#define SPI_MEM_XTS_STATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x358) -/* SPI_MEM_XTS_STATE : RO ;bitpos:[1:0] ;default: 2'h0 ; */ -/*description: This bits stores the status of manual encryption. 0: idle, 1: busy of encryption - calculation, 2: encryption calculation is done but the encrypted result is invi -sible to mspi, 3: the encrypted result is visible to mspi..*/ -#define SPI_MEM_XTS_STATE 0x00000003 -#define SPI_MEM_XTS_STATE_M ((SPI_MEM_XTS_STATE_V)<<(SPI_MEM_XTS_STATE_S)) -#define SPI_MEM_XTS_STATE_V 0x3 -#define SPI_MEM_XTS_STATE_S 0 - -#define SPI_MEM_XTS_DATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x35C) -/* SPI_MEM_XTS_DATE : R/W ;bitpos:[29:0] ;default: 30'h20201010 ; */ -/*description: This bits stores the last modified-time of manual encryption feature..*/ -#define SPI_MEM_XTS_DATE 0x3FFFFFFF -#define SPI_MEM_XTS_DATE_M ((SPI_MEM_XTS_DATE_V)<<(SPI_MEM_XTS_DATE_S)) -#define SPI_MEM_XTS_DATE_V 0x3FFFFFFF -#define SPI_MEM_XTS_DATE_S 0 - #define SPI_MEM_MMU_ITEM_CONTENT_REG(i) (REG_SPI_MEM_BASE(i) + 0x37C) /* SPI_MEM_MMU_ITEM_CONTENT : R/W ;bitpos:[31:0] ;default: 32'h037c ; */ /*description: MSPI-MMU item content.*/ @@ -3147,31 +3060,6 @@ sible to mspi, 3: the encrypted result is visible to mspi..*/ #define SPI_MEM_MMU_MEM_FORCE_ON_V 0x1 #define SPI_MEM_MMU_MEM_FORCE_ON_S 0 -#define SPI_MEM_DPA_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x388) -/* SPI_MEM_CRYPT_DPA_SELECT_REGISTER : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: 1: MSPI XTS DPA clock gate is controlled by SPI_CRYPT_CALC_D_DPA_EN and SPI_CRYP -T_SECURITY_LEVEL. 0: Controlled by efuse bits..*/ -#define SPI_MEM_CRYPT_DPA_SELECT_REGISTER (BIT(4)) -#define SPI_MEM_CRYPT_DPA_SELECT_REGISTER_M (BIT(4)) -#define SPI_MEM_CRYPT_DPA_SELECT_REGISTER_V 0x1 -#define SPI_MEM_CRYPT_DPA_SELECT_REGISTER_S 4 -/* SPI_MEM_CRYPT_CALC_D_DPA_EN : R/W ;bitpos:[3] ;default: 1'b1 ; */ -/*description: Only available when SPI_CRYPT_SECURITY_LEVEL is not 0. 1: Enable DPA in the calc -ulation that using key 1 or key 2. 0: Enable DPA only in the calculation that us -ing key 1..*/ -#define SPI_MEM_CRYPT_CALC_D_DPA_EN (BIT(3)) -#define SPI_MEM_CRYPT_CALC_D_DPA_EN_M (BIT(3)) -#define SPI_MEM_CRYPT_CALC_D_DPA_EN_V 0x1 -#define SPI_MEM_CRYPT_CALC_D_DPA_EN_S 3 -/* SPI_MEM_CRYPT_SECURITY_LEVEL : R/W ;bitpos:[2:0] ;default: 3'd7 ; */ -/*description: Set the security level of spi mem cryption. 0: Shut off cryption DPA funtion. 1- -7: The bigger the number is, the more secure the cryption is. (Note that the per -formance of cryption will decrease together with this number increasing).*/ -#define SPI_MEM_CRYPT_SECURITY_LEVEL 0x00000007 -#define SPI_MEM_CRYPT_SECURITY_LEVEL_M ((SPI_MEM_CRYPT_SECURITY_LEVEL_V)<<(SPI_MEM_CRYPT_SECURITY_LEVEL_S)) -#define SPI_MEM_CRYPT_SECURITY_LEVEL_V 0x7 -#define SPI_MEM_CRYPT_SECURITY_LEVEL_S 0 - #define SPI_MEM_REGISTERRND_ECO_HIGH_REG(i) (REG_SPI_MEM_BASE(i) + 0x3F0) /* SPI_MEM_REGISTERRND_ECO_HIGH : RO ;bitpos:[31:0] ;default: 32'h037c ; */ /*description: ECO high register.*/ diff --git a/components/soc/esp32c6/include/soc/spi_pins.h b/components/soc/esp32c6/include/soc/spi_pins.h new file mode 100644 index 000000000000..2cb3b76fbfee --- /dev/null +++ b/components/soc/esp32c6/include/soc/spi_pins.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_SPI_PINS_H_ +#define _SOC_SPI_PINS_H_ + +#define SPI_FUNC_NUM 0 +#define SPI_IOMUX_PIN_NUM_CS 24 +#define SPI_IOMUX_PIN_NUM_CLK 29 +#define SPI_IOMUX_PIN_NUM_MOSI 30 +#define SPI_IOMUX_PIN_NUM_MISO 25 +#define SPI_IOMUX_PIN_NUM_WP 26 +#define SPI_IOMUX_PIN_NUM_HD 28 + +#define SPI2_FUNC_NUM 2 +#define SPI2_IOMUX_PIN_NUM_MISO 2 +#define SPI2_IOMUX_PIN_NUM_HD 4 +#define SPI2_IOMUX_PIN_NUM_WP 5 +#define SPI2_IOMUX_PIN_NUM_CLK 6 +#define SPI2_IOMUX_PIN_NUM_MOSI 7 +#define SPI2_IOMUX_PIN_NUM_CS 16 + +#endif diff --git a/components/soc/esp32c6/include/soc/system_reg.h b/components/soc/esp32c6/include/soc/system_reg.h new file mode 100644 index 000000000000..4ed6ac2ac25c --- /dev/null +++ b/components/soc/esp32c6/include/soc/system_reg.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/hp_system_reg.h" + +// TODO: IDF-5720 +#include "intpri_reg.h" +#define SYSTEM_CPU_INTR_FROM_CPU_0_REG INTPRI_CPU_INTR_FROM_CPU_0_REG +#define SYSTEM_CPU_INTR_FROM_CPU_0 INTPRI_CPU_INTR_FROM_CPU_0 diff --git a/components/soc/esp32c6/include/soc/tee_reg.h b/components/soc/esp32c6/include/soc/tee_reg.h index fd340089ee6a..b2839c4c3a2b 100644 --- a/components/soc/esp32c6/include/soc/tee_reg.h +++ b/components/soc/esp32c6/include/soc/tee_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -446,10 +446,10 @@ extern "C" { /** TEE_DATE_REG : R/W; bitpos: [27:0]; default: 35672706; * reg_tee_date */ -#define TEE_DATE_REG 0x0FFFFFFFU -#define TEE_DATE_REG_M (TEE_DATE_REG_V << TEE_DATE_REG_S) -#define TEE_DATE_REG_V 0x0FFFFFFFU -#define TEE_DATE_REG_S 0 +#define TEE_DATE 0x0FFFFFFFU +#define TEE_DATE_M (TEE_DATE_V << TEE_DATE_S) +#define TEE_DATE_V 0x0FFFFFFFU +#define TEE_DATE_S 0 #ifdef __cplusplus } diff --git a/components/soc/esp32c6/include/soc/twai_struct.h b/components/soc/esp32c6/include/soc/twai_struct.h index 11220fc1f29d..1f67feaa99be 100644 --- a/components/soc/esp32c6/include/soc/twai_struct.h +++ b/components/soc/esp32c6/include/soc/twai_struct.h @@ -502,6 +502,28 @@ typedef union { uint32_t val; } twai_tx_rx_buffer_reg_t; +typedef struct { + union { + struct { + uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */ + uint32_t reserved8: 24; /* Internal Reserved */ + }; + uint32_t val; + } acr[4]; + union { + struct { + uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */ + uint32_t reserved8: 24; /* Internal Reserved */ + }; + uint32_t val; + } amr[4]; + uint32_t reserved_60; + uint32_t reserved_64; + uint32_t reserved_68; + uint32_t reserved_6c; + uint32_t reserved_70; +} acceptance_filter_reg_t; + typedef struct twai_dev_s { volatile twai_mode_reg_t mode; @@ -518,7 +540,10 @@ typedef struct twai_dev_s { volatile twai_err_warning_limit_reg_t err_warning_limit; volatile twai_rx_err_cnt_reg_t rx_err_cnt; volatile twai_tx_err_cnt_reg_t tx_err_cnt; - volatile twai_tx_rx_buffer_reg_t tx_rx_buffer[13]; + volatile union { + acceptance_filter_reg_t acceptance_filter; + twai_tx_rx_buffer_reg_t tx_rx_buffer[13]; + }; volatile twai_rx_message_counter_reg_t rx_message_counter; uint32_t reserved_078; volatile twai_clock_divider_reg_t clock_divider; diff --git a/components/soc/esp32c6/include/soc/uart_channel.h b/components/soc/esp32c6/include/soc/uart_channel.h new file mode 100644 index 000000000000..9d9fb454fd25 --- /dev/null +++ b/components/soc/esp32c6/include/soc/uart_channel.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// This file defines GPIO lookup macros for available UART IO_MUX pins on ESP32C6. + +#pragma once + +//UART channels +#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 16 +#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 17 + +#define UART_TXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL +#define UART_RXD_GPIO17_DIRECT_CHANNEL UART_GPIO17_DIRECT_CHANNEL diff --git a/components/soc/esp32c6/include/soc/uart_pins.h b/components/soc/esp32c6/include/soc/uart_pins.h new file mode 100644 index 000000000000..cafc2c73801d --- /dev/null +++ b/components/soc/esp32c6/include/soc/uart_pins.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/io_mux_reg.h" + +/* Specify the number of pins for UART */ +#define SOC_UART_PINS_COUNT (4) + +/* Specify the GPIO pin number for each UART signal in the IOMUX */ +#define U0RXD_GPIO_NUM 17 +#define U0TXD_GPIO_NUM 16 +#define U0RTS_GPIO_NUM (-1) +#define U0CTS_GPIO_NUM (-1) + +#define U1RXD_GPIO_NUM (-1) +#define U1TXD_GPIO_NUM (-1) +#define U1RTS_GPIO_NUM (-1) +#define U1CTS_GPIO_NUM (-1) + +/* The following defines are necessary for reconfiguring the UART + * to use IOMUX, at runtime. */ +#define U0TXD_MUX_FUNC (FUNC_U0TXD_U0TXD) +#define U0RXD_MUX_FUNC (FUNC_U0RXD_U0RXD) +/* No func for the following pins, they shall not be used */ +#define U0RTS_MUX_FUNC (-1) +#define U0CTS_MUX_FUNC (-1) +/* Same goes for UART1 */ +#define U1TXD_MUX_FUNC (-1) +#define U1RXD_MUX_FUNC (-1) +#define U1RTS_MUX_FUNC (-1) +#define U1CTS_MUX_FUNC (-1) diff --git a/components/soc/esp32c6/include/soc/uart_reg.h b/components/soc/esp32c6/include/soc/uart_reg.h index 958b2e51dfb3..abac8d92b197 100644 --- a/components/soc/esp32c6/include/soc/uart_reg.h +++ b/components/soc/esp32c6/include/soc/uart_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1471,81 +1471,6 @@ extern "C" { #define UART_RXD_EDGE_CNT_V 0x000003FFU #define UART_RXD_EDGE_CNT_S 0 -/** UART_CLK_CONF_REG register - * UART core clock configuration - */ -#define UART_CLK_CONF_REG(i) (REG_UART_BASE(i) + 0x88) -/** UART_SCLK_DIV_B : R/W; bitpos: [5:0]; default: 0; - * The denominator of the frequency divider factor. - */ -#define UART_SCLK_DIV_B 0x0000003FU -#define UART_SCLK_DIV_B_M (UART_SCLK_DIV_B_V << UART_SCLK_DIV_B_S) -#define UART_SCLK_DIV_B_V 0x0000003FU -#define UART_SCLK_DIV_B_S 0 -/** UART_SCLK_DIV_A : R/W; bitpos: [11:6]; default: 0; - * The numerator of the frequency divider factor. - */ -#define UART_SCLK_DIV_A 0x0000003FU -#define UART_SCLK_DIV_A_M (UART_SCLK_DIV_A_V << UART_SCLK_DIV_A_S) -#define UART_SCLK_DIV_A_V 0x0000003FU -#define UART_SCLK_DIV_A_S 6 -/** UART_SCLK_DIV_NUM : R/W; bitpos: [19:12]; default: 1; - * The integral part of the frequency divider factor. - */ -#define UART_SCLK_DIV_NUM 0x000000FFU -#define UART_SCLK_DIV_NUM_M (UART_SCLK_DIV_NUM_V << UART_SCLK_DIV_NUM_S) -#define UART_SCLK_DIV_NUM_V 0x000000FFU -#define UART_SCLK_DIV_NUM_S 12 -/** UART_SCLK_SEL : R/W; bitpos: [21:20]; default: 3; - * UART clock source select. 1: 80Mhz. 2: 8Mhz. 3: XTAL. - */ -#define UART_SCLK_SEL 0x00000003U -#define UART_SCLK_SEL_M (UART_SCLK_SEL_V << UART_SCLK_SEL_S) -#define UART_SCLK_SEL_V 0x00000003U -#define UART_SCLK_SEL_S 20 -/** UART_SCLK_EN : R/W; bitpos: [22]; default: 1; - * Set this bit to enable UART Tx/Rx clock. - */ -#define UART_SCLK_EN (BIT(22)) -#define UART_SCLK_EN_M (UART_SCLK_EN_V << UART_SCLK_EN_S) -#define UART_SCLK_EN_V 0x00000001U -#define UART_SCLK_EN_S 22 -/** UART_RST_CORE : R/W; bitpos: [23]; default: 0; - * Write 1 then write 0 to this bit to reset UART Tx/Rx. - */ -#define UART_RST_CORE (BIT(23)) -#define UART_RST_CORE_M (UART_RST_CORE_V << UART_RST_CORE_S) -#define UART_RST_CORE_V 0x00000001U -#define UART_RST_CORE_S 23 -/** UART_TX_SCLK_EN : R/W; bitpos: [24]; default: 1; - * Set this bit to enable UART Tx clock. - */ -#define UART_TX_SCLK_EN (BIT(24)) -#define UART_TX_SCLK_EN_M (UART_TX_SCLK_EN_V << UART_TX_SCLK_EN_S) -#define UART_TX_SCLK_EN_V 0x00000001U -#define UART_TX_SCLK_EN_S 24 -/** UART_RX_SCLK_EN : R/W; bitpos: [25]; default: 1; - * Set this bit to enable UART Rx clock. - */ -#define UART_RX_SCLK_EN (BIT(25)) -#define UART_RX_SCLK_EN_M (UART_RX_SCLK_EN_V << UART_RX_SCLK_EN_S) -#define UART_RX_SCLK_EN_V 0x00000001U -#define UART_RX_SCLK_EN_S 25 -/** UART_TX_RST_CORE : R/W; bitpos: [26]; default: 0; - * Write 1 then write 0 to this bit to reset UART Tx. - */ -#define UART_TX_RST_CORE (BIT(26)) -#define UART_TX_RST_CORE_M (UART_TX_RST_CORE_V << UART_TX_RST_CORE_S) -#define UART_TX_RST_CORE_V 0x00000001U -#define UART_TX_RST_CORE_S 26 -/** UART_RX_RST_CORE : R/W; bitpos: [27]; default: 0; - * Write 1 then write 0 to this bit to reset UART Rx. - */ -#define UART_RX_RST_CORE (BIT(27)) -#define UART_RX_RST_CORE_M (UART_RX_RST_CORE_V << UART_RX_RST_CORE_S) -#define UART_RX_RST_CORE_V 0x00000001U -#define UART_RX_RST_CORE_S 27 - /** UART_DATE_REG register * UART Version register */ diff --git a/components/soc/esp32c6/include/soc/uart_struct.h b/components/soc/esp32c6/include/soc/uart_struct.h index 487c05b90a6c..467f86ff5a44 100644 --- a/components/soc/esp32c6/include/soc/uart_struct.h +++ b/components/soc/esp32c6/include/soc/uart_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,11 +16,10 @@ extern "C" { */ typedef union { struct { - /** rxfifo_rd_byte : RO; bitpos: [7:0]; default: 0; + /** rxfifo_rd_byte : RO; bitpos: [31:0]; default: 0; * UART $n accesses FIFO via this register. */ - uint32_t rxfifo_rd_byte:8; - uint32_t reserved_8:24; + uint32_t rxfifo_rd_byte:32; }; uint32_t val; } uart_fifo_reg_t; @@ -876,56 +875,6 @@ typedef union { uint32_t val; } uart_rs485_conf_sync_reg_t; -/** Type of clk_conf register - * UART core clock configuration - */ -typedef union { - struct { - /** sclk_div_b : R/W; bitpos: [5:0]; default: 0; - * The denominator of the frequency divider factor. - */ - uint32_t sclk_div_b:6; - /** sclk_div_a : R/W; bitpos: [11:6]; default: 0; - * The numerator of the frequency divider factor. - */ - uint32_t sclk_div_a:6; - /** sclk_div_num : R/W; bitpos: [19:12]; default: 1; - * The integral part of the frequency divider factor. - */ - uint32_t sclk_div_num:8; - /** sclk_sel : R/W; bitpos: [21:20]; default: 3; - * UART clock source select. 1: 80Mhz. 2: 8Mhz. 3: XTAL. - */ - uint32_t sclk_sel:2; - /** sclk_en : R/W; bitpos: [22]; default: 1; - * Set this bit to enable UART Tx/Rx clock. - */ - uint32_t sclk_en:1; - /** rst_core : R/W; bitpos: [23]; default: 0; - * Write 1 then write 0 to this bit to reset UART Tx/Rx. - */ - uint32_t rst_core:1; - /** tx_sclk_en : R/W; bitpos: [24]; default: 1; - * Set this bit to enable UART Tx clock. - */ - uint32_t tx_sclk_en:1; - /** rx_sclk_en : R/W; bitpos: [25]; default: 1; - * Set this bit to enable UART Rx clock. - */ - uint32_t rx_sclk_en:1; - /** tx_rst_core : R/W; bitpos: [26]; default: 0; - * Write 1 then write 0 to this bit to reset UART Tx. - */ - uint32_t tx_rst_core:1; - /** rx_rst_core : R/W; bitpos: [27]; default: 0; - * Write 1 then write 0 to this bit to reset UART Rx. - */ - uint32_t rx_rst_core:1; - uint32_t reserved_28:4; - }; - uint32_t val; -} uart_clk_conf_reg_t; - /** Group: Status Register */ /** Type of status register @@ -1274,7 +1223,7 @@ typedef struct uart_dev_s { volatile uart_lowpulse_reg_t lowpulse; volatile uart_highpulse_reg_t highpulse; volatile uart_rxd_cnt_reg_t rxd_cnt; - volatile uart_clk_conf_reg_t clk_conf; + uint32_t reserved_088; volatile uart_date_reg_t date; volatile uart_afifo_status_reg_t afifo_status; uint32_t reserved_094; diff --git a/components/soc/esp32c6/include/soc/wdev_reg.h b/components/soc/esp32c6/include/soc/wdev_reg.h new file mode 100644 index 000000000000..d4207e5c8835 --- /dev/null +++ b/components/soc/esp32c6/include/soc/wdev_reg.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc.h" +#include "soc/lpperi_reg.h" + +/* Hardware random number generator register */ +#define WDEV_RND_REG LPPERI_RNG_DATA_REG diff --git a/components/soc/esp32c6/include/soc/xts_aes_reg.h b/components/soc/esp32c6/include/soc/xts_aes_reg.h new file mode 100644 index 000000000000..5d7d7e0b8186 --- /dev/null +++ b/components/soc/esp32c6/include/soc/xts_aes_reg.h @@ -0,0 +1,128 @@ +/** + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "soc/soc.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define XTS_AES_PLAIN_MEM(i) (REG_SPI_MEM_BASE(i) + 0x300) +/* XTS_AES_PLAIN : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: This field is only used to generate include file in c case. This field is useles +s. Please do not use this field..*/ +#define XTS_AES_PLAIN 0xFFFFFFFF +#define XTS_AES_PLAIN_M ((XTS_AES_PLAIN_V)<<(XTS_AES_PLAIN_S)) +#define XTS_AES_PLAIN_V 0xFFFFFFFF +#define XTS_AES_PLAIN_S 0 + +#define XTS_AES_LINESIZE_REG(i) (REG_SPI_MEM_BASE(i) + 0x340) +/* XTS_AES_LINESIZE : R/W ;bitpos:[1:0] ;default: 2'h0 ; */ +/*description: This bits stores the line-size parameter which will be used in manual encryption + calculation. It decides how many bytes will be encrypted one time. 0: 16-bytes, + 1: 32-bytes, 2: 64-bytes, 3:reserved..*/ +#define XTS_AES_LINESIZE 0x00000003 +#define XTS_AES_LINESIZE_M ((XTS_AES_LINESIZE_V)<<(XTS_AES_LINESIZE_S)) +#define XTS_AES_LINESIZE_V 0x3 +#define XTS_AES_LINESIZE_S 0 + +#define XTS_AES_DESTINATION_REG(i) (REG_SPI_MEM_BASE(i) + 0x344) +/* XTS_AES_DESTINATION : R/W ;bitpos:[0] ;default: 1'b0 ; */ +/*description: This bit stores the destination parameter which will be used in manual encryptio +n calculation. 0: flash(default), 1: psram(reserved). Only default value can be +used..*/ +#define XTS_AES_DESTINATION (BIT(0)) +#define XTS_AES_DESTINATION_M (BIT(0)) +#define XTS_AES_DESTINATION_V 0x1 +#define XTS_AES_DESTINATION_S 0 + +#define XTS_AES_PHYSICAL_ADDRESS_REG(i) (REG_SPI_MEM_BASE(i) + 0x348) +/* XTS_AES_PHYSICAL_ADDRESS : R/W ;bitpos:[25:0] ;default: 26'h0 ; */ +/*description: This bits stores the physical-address parameter which will be used in manual enc +ryption calculation. This value should aligned with byte number decided by line- +size parameter..*/ +#define XTS_AES_PHYSICAL_ADDRESS 0x03FFFFFF +#define XTS_AES_PHYSICAL_ADDRESS_M ((XTS_AES_PHYSICAL_ADDRESS_V)<<(XTS_AES_PHYSICAL_ADDRESS_S)) +#define XTS_AES_PHYSICAL_ADDRESS_V 0x3FFFFFF +#define XTS_AES_PHYSICAL_ADDRESS_S 0 + +#define XTS_AES_TRIGGER_REG(i) (REG_SPI_MEM_BASE(i) + 0x34C) +/* XTS_AES_TRIGGER : WT ;bitpos:[0] ;default: 1'b0 ; */ +/*description: Set this bit to trigger the process of manual encryption calculation. This actio +n should only be asserted when manual encryption status is 0. After this action, + manual encryption status becomes 1. After calculation is done, manual encryptio +n status becomes 2..*/ +#define XTS_AES_TRIGGER (BIT(0)) +#define XTS_AES_TRIGGER_M (BIT(0)) +#define XTS_AES_TRIGGER_V 0x1 +#define XTS_AES_TRIGGER_S 0 + +#define XTS_AES_RELEASE_REG(i) (REG_SPI_MEM_BASE(i) + 0x350) +/* XTS_AES_RELEASE : WT ;bitpos:[0] ;default: 1'b0 ; */ +/*description: Set this bit to release encrypted result to mspi. This action should only be ass +erted when manual encryption status is 2. After this action, manual encryption s +tatus will become 3..*/ +#define XTS_AES_RELEASE (BIT(0)) +#define XTS_AES_RELEASE_M (BIT(0)) +#define XTS_AES_RELEASE_V 0x1 +#define XTS_AES_RELEASE_S 0 + +#define XTS_AES_DESTROY_REG(i) (REG_SPI_MEM_BASE(i) + 0x354) +/* XTS_AES_DESTROY : WT ;bitpos:[0] ;default: 1'b0 ; */ +/*description: Set this bit to destroy encrypted result. This action should be asserted only wh +en manual encryption status is 3. After this action, manual encryption status wi +ll become 0..*/ +#define XTS_AES_DESTROY (BIT(0)) +#define XTS_AES_DESTROY_M (BIT(0)) +#define XTS_AES_DESTROY_V 0x1 +#define XTS_AES_DESTROY_S 0 + +#define XTS_AES_STATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x358) +/* XTS_AES_STATE : RO ;bitpos:[1:0] ;default: 2'h0 ; */ +/*description: This bits stores the status of manual encryption. 0: idle, 1: busy of encryption + calculation, 2: encryption calculation is done but the encrypted result is invi +sible to mspi, 3: the encrypted result is visible to mspi..*/ +#define XTS_AES_STATE 0x00000003 +#define XTS_AES_STATE_M ((XTS_AES_STATE_V)<<(XTS_AES_STATE_S)) +#define XTS_AES_STATE_V 0x3 +#define XTS_AES_STATE_S 0 + +#define XTS_AES_DATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x35C) +/* XTS_AES_DATE : R/W ;bitpos:[29:0] ;default: 30'h20201010 ; */ +/*description: This bits stores the last modified-time of manual encryption feature..*/ +#define XTS_AES_DATE 0x3FFFFFFF +#define XTS_AES_DATE_M ((XTS_AES_DATE_V)<<(XTS_AES_DATE_S)) +#define XTS_AES_DATE_V 0x3FFFFFFF + +#define XTS_AES_DPA_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x388) +/* XTS_AES_CRYPT_DPA_SELECT_REGISTER : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: 1: MSPI XTS DPA clock gate is controlled by SPI_CRYPT_CALC_D_DPA_EN and SPI_CRYP +T_SECURITY_LEVEL. 0: Controlled by efuse bits..*/ +#define XTS_AES_CRYPT_DPA_SELECT_REGISTER (BIT(4)) +#define XTS_AES_CRYPT_DPA_SELECT_REGISTER_M (BIT(4)) +#define XTS_AES_CRYPT_DPA_SELECT_REGISTER_V 0x1 +#define XTS_AES_CRYPT_DPA_SELECT_REGISTER_S 4 +/* XTS_AES_CRYPT_CALC_D_DPA_EN : R/W ;bitpos:[3] ;default: 1'b1 ; */ +/*description: Only available when SPI_CRYPT_SECURITY_LEVEL is not 0. 1: Enable DPA in the calc +ulation that using key 1 or key 2. 0: Enable DPA only in the calculation that us +ing key 1..*/ +#define XTS_AES_CRYPT_CALC_D_DPA_EN (BIT(3)) +#define XTS_AES_CRYPT_CALC_D_DPA_EN_M (BIT(3)) +#define XTS_AES_CRYPT_CALC_D_DPA_EN_V 0x1 +#define XTS_AES_CRYPT_CALC_D_DPA_EN_S 3 +/* XTS_AES_CRYPT_SECURITY_LEVEL : R/W ;bitpos:[2:0] ;default: 3'd7 ; */ +/*description: Set the security level of spi mem cryption. 0: Shut off cryption DPA funtion. 1- +7: The bigger the number is, the more secure the cryption is. (Note that the per +formance of cryption will decrease together with this number increasing).*/ +#define XTS_AES_CRYPT_SECURITY_LEVEL 0x00000007 +#define XTS_AES_CRYPT_SECURITY_LEVEL_M ((XTS_AES_CRYPT_SECURITY_LEVEL_V)<<(XTS_AES_CRYPT_SECURITY_LEVEL_S)) +#define XTS_AES_CRYPT_SECURITY_LEVEL_V 0x7 +#define XTS_AES_CRYPT_SECURITY_LEVEL_S 0 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/ld/esp32c6.peripherals.ld b/components/soc/esp32c6/ld/esp32c6.peripherals.ld index 55f47792d2d0..86b9384b8986 100644 --- a/components/soc/esp32c6/ld/esp32c6.peripherals.ld +++ b/components/soc/esp32c6/ld/esp32c6.peripherals.ld @@ -27,7 +27,7 @@ PROVIDE ( INTMTX = 0x60010000 ); PROVIDE ( ATOMIC_LOCKER = 0x60011000 ); PROVIDE ( PCNT = 0x60012000 ); PROVIDE ( SOC_ETM = 0x60013000 ); -PROVIDE ( MCPWM = 0x60014000 ); +PROVIDE ( MCPWM0 = 0x60014000 ); PROVIDE ( PARL_IO = 0x60015000 ); PROVIDE ( HINF = 0x60016000 ); PROVIDE ( SLC = 0x60017000 ); @@ -46,7 +46,7 @@ PROVIDE ( HMAC = 0x6008D000 ); PROVIDE ( IO_MUX = 0x60090000 ); PROVIDE ( GPIO = 0x60091000 ); -PROVIDE ( GPIO_EXT = 0x60091f00 ); /*ESP32C6-TODO*/ +PROVIDE ( GPIO_EXT = 0x60091f00 ); PROVIDE ( SDM = 0x60091f00 ); PROVIDE ( GLITCH_FILTER = 0x60091f30 ); PROVIDE ( GPIO_ETM = 0x60091f60 ); @@ -58,6 +58,10 @@ PROVIDE ( PCR = 0x60096000 ); PROVIDE ( TEE = 0x60098000 ); PROVIDE ( HP_APM = 0x60099000 ); +PROVIDE ( IEEE802154 = 0x600A3000 ); +PROVIDE ( MODEM_SYSCON = 0x600A9800 ); +PROVIDE ( MODEM_LPCON = 0x600AF000 ); + PROVIDE ( PMU = 0x600B0000 ); PROVIDE ( LP_CLKRST = 0x600B0400 ); PROVIDE ( EFUSE = 0x600B0800 ); diff --git a/components/soc/esp32c6/ledc_periph.c b/components/soc/esp32c6/ledc_periph.c new file mode 100644 index 000000000000..b150f9bc991e --- /dev/null +++ b/components/soc/esp32c6/ledc_periph.c @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/ledc_periph.h" +#include "soc/gpio_sig_map.h" + +/* + Bunch of constants for every LEDC peripheral: GPIO signals +*/ +const ledc_signal_conn_t ledc_periph_signal[1] = { + { + .sig_out0_idx = LEDC_LS_SIG_OUT0_IDX, + } +}; diff --git a/components/soc/esp32c6/mcpwm_periph.c b/components/soc/esp32c6/mcpwm_periph.c new file mode 100644 index 000000000000..25e1b86cc15c --- /dev/null +++ b/components/soc/esp32c6/mcpwm_periph.c @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/mcpwm_periph.h" +#include "soc/gpio_sig_map.h" + +const mcpwm_signal_conn_t mcpwm_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_MCPWM0_MODULE, + .irq_id = ETS_MCPWM0_INTR_SOURCE, + .operators = { + [0] = { + .generators = { + [0] = { + .pwm_sig = PWM0_OUT0A_IDX + }, + [1] = { + .pwm_sig = PWM0_OUT0B_IDX + } + } + }, + [1] = { + .generators = { + [0] = { + .pwm_sig = PWM0_OUT1A_IDX + }, + [1] = { + .pwm_sig = PWM0_OUT1B_IDX + } + } + }, + [2] = { + .generators = { + [0] = { + .pwm_sig = PWM0_OUT2A_IDX + }, + [1] = { + .pwm_sig = PWM0_OUT2B_IDX + } + } + } + }, + .gpio_faults = { + [0] = { + .fault_sig = PWM0_F0_IN_IDX + }, + [1] = { + .fault_sig = PWM0_F1_IN_IDX + }, + [2] = { + .fault_sig = PWM0_F2_IN_IDX + } + }, + .captures = { + [0] = { + .cap_sig = PWM0_CAP0_IN_IDX + }, + [1] = { + .cap_sig = PWM0_CAP1_IN_IDX + }, + [2] = { + .cap_sig = PWM0_CAP2_IN_IDX + } + }, + .gpio_synchros = { + [0] = { + .sync_sig = PWM0_SYNC0_IN_IDX + }, + [1] = { + .sync_sig = PWM0_SYNC1_IN_IDX + }, + [2] = { + .sync_sig = PWM0_SYNC2_IN_IDX + } + } + }, + } +}; diff --git a/components/soc/esp32c6/parlio_periph.c b/components/soc/esp32c6/parlio_periph.c new file mode 100644 index 000000000000..40ac06320c27 --- /dev/null +++ b/components/soc/esp32c6/parlio_periph.c @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/parlio_periph.h" +#include "soc/gpio_sig_map.h" + +const parlio_signal_conn_t parlio_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_PARLIO_MODULE, + .tx_irq_id = ETS_PARL_IO_INTR_SOURCE, + .rx_irq_id = ETS_PARL_IO_INTR_SOURCE, + .tx_units = { + [0] = { + .data_sigs = { + PARL_TX_DATA0_IDX, + PARL_TX_DATA1_IDX, + PARL_TX_DATA2_IDX, + PARL_TX_DATA3_IDX, + PARL_TX_DATA4_IDX, + PARL_TX_DATA5_IDX, + PARL_TX_DATA6_IDX, + PARL_TX_DATA7_IDX, + PARL_TX_DATA8_IDX, + PARL_TX_DATA9_IDX, + PARL_TX_DATA10_IDX, + PARL_TX_DATA11_IDX, + PARL_TX_DATA12_IDX, + PARL_TX_DATA13_IDX, + PARL_TX_DATA14_IDX, + PARL_TX_DATA15_IDX, + }, + .clk_out_sig = PARL_TX_CLK_OUT_IDX, + .clk_in_sig = PARL_TX_CLK_IN_IDX, + } + }, + .rx_units = { + [0] = { + .data_sigs = { + PARL_RX_DATA0_IDX, + PARL_RX_DATA1_IDX, + PARL_RX_DATA2_IDX, + PARL_RX_DATA3_IDX, + PARL_RX_DATA4_IDX, + PARL_RX_DATA5_IDX, + PARL_RX_DATA6_IDX, + PARL_RX_DATA7_IDX, + PARL_RX_DATA8_IDX, + PARL_RX_DATA9_IDX, + PARL_RX_DATA10_IDX, + PARL_RX_DATA11_IDX, + PARL_RX_DATA12_IDX, + PARL_RX_DATA13_IDX, + PARL_RX_DATA14_IDX, + PARL_RX_DATA15_IDX, + }, + .clk_out_sig = -1, + .clk_in_sig = PARL_RX_CLK_IN_IDX, + } + } + }, + }, +}; diff --git a/components/soc/esp32c6/pcnt_periph.c b/components/soc/esp32c6/pcnt_periph.c new file mode 100644 index 000000000000..83c3424a0f8b --- /dev/null +++ b/components/soc/esp32c6/pcnt_periph.c @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/pcnt_periph.h" +#include "soc/gpio_sig_map.h" + +const pcnt_signal_conn_t pcnt_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_PCNT_MODULE, + .irq = ETS_PCNT_INTR_SOURCE, + .units = { + [0] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN0_IDX, + .pulse_sig = PCNT_SIG_CH0_IN0_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN0_IDX, + .pulse_sig = PCNT_SIG_CH1_IN0_IDX + } + } + }, + [1] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN1_IDX, + .pulse_sig = PCNT_SIG_CH0_IN1_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN1_IDX, + .pulse_sig = PCNT_SIG_CH1_IN1_IDX + } + } + }, + [2] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN2_IDX, + .pulse_sig = PCNT_SIG_CH0_IN2_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN2_IDX, + .pulse_sig = PCNT_SIG_CH1_IN2_IDX + } + } + }, + [3] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN3_IDX, + .pulse_sig = PCNT_SIG_CH0_IN3_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN3_IDX, + .pulse_sig = PCNT_SIG_CH1_IN3_IDX + } + } + } + } + } + } +}; diff --git a/components/soc/esp32c6/rmt_periph.c b/components/soc/esp32c6/rmt_periph.c new file mode 100644 index 000000000000..0c5a55871e40 --- /dev/null +++ b/components/soc/esp32c6/rmt_periph.c @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/rmt_periph.h" +#include "soc/gpio_sig_map.h" + +const rmt_signal_conn_t rmt_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_RMT_MODULE, + .irq = ETS_RMT_INTR_SOURCE, + .channels = { + [0] = { + .tx_sig = RMT_SIG_OUT0_IDX, + .rx_sig = -1 + }, + [1] = { + .tx_sig = RMT_SIG_OUT1_IDX, + .rx_sig = -1 + }, + [2] = { + .tx_sig = -1, + .rx_sig = RMT_SIG_IN0_IDX + }, + [3] = { + .tx_sig = -1, + .rx_sig = RMT_SIG_IN1_IDX + }, + } + } + } +}; diff --git a/components/soc/esp32c6/rtc_io_periph.c b/components/soc/esp32c6/rtc_io_periph.c new file mode 100644 index 000000000000..a55e1f530380 --- /dev/null +++ b/components/soc/esp32c6/rtc_io_periph.c @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/rtc_io_periph.h" + +const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = { + RTCIO_GPIO0_CHANNEL, //GPIO0 + RTCIO_GPIO1_CHANNEL, //GPIO1 + RTCIO_GPIO2_CHANNEL, //GPIO2 + RTCIO_GPIO3_CHANNEL, //GPIO3 + RTCIO_GPIO4_CHANNEL, //GPIO4 + RTCIO_GPIO5_CHANNEL, //GPIO5 + RTCIO_GPIO6_CHANNEL, //GPIO6 + RTCIO_GPIO7_CHANNEL, //GPIO7 + -1,//GPIO8 + -1,//GPIO9 + -1,//GPIO10 + -1,//GPIO11 + -1,//GPIO12 + -1,//GPIO13 + -1,//GPIO14 + -1,//GPIO15 + -1,//GPIO16 + -1,//GPIO17 + -1,//GPIO18 + -1,//GPIO19 + -1,//GPIO20 + -1,//GPIO21 + -1,//GPIO22 + -1,//GPIO23 + -1,//GPIO24 + -1,//GPIO25 + -1,//GPIO26 + -1,//GPIO27 + -1,//GPIO28 + -1,//GPIO29 + -1,//GPIO30 +}; diff --git a/components/soc/esp32c6/sdio_slave_periph.c b/components/soc/esp32c6/sdio_slave_periph.c new file mode 100644 index 000000000000..21d95011083b --- /dev/null +++ b/components/soc/esp32c6/sdio_slave_periph.c @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "soc/sdio_slave_periph.h" +#include "soc/sdio_slave_pins.h" + +const sdio_slave_slot_info_t sdio_slave_slot_info[1] = { + { + .clk_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK, + .cmd_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD, + .d0_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0, + .d1_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1, + .d2_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2, + .d3_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3, + .func = SDIO_SLAVE_SLOT0_FUNC, + }, +}; diff --git a/components/soc/esp32c6/sdm_periph.c b/components/soc/esp32c6/sdm_periph.c new file mode 100644 index 000000000000..6d41dc98f104 --- /dev/null +++ b/components/soc/esp32c6/sdm_periph.c @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/sdm_periph.h" +#include "soc/gpio_sig_map.h" + +const sigma_delta_signal_conn_t sigma_delta_periph_signals = { + .channels = { + [0] = { + GPIO_SD0_OUT_IDX + }, + [1] = { + GPIO_SD1_OUT_IDX + }, + [2] = { + GPIO_SD2_OUT_IDX + }, + [3] = { + GPIO_SD3_OUT_IDX + } + } +}; diff --git a/components/soc/esp32c6/spi_periph.c b/components/soc/esp32c6/spi_periph.c new file mode 100644 index 000000000000..4969841aec39 --- /dev/null +++ b/components/soc/esp32c6/spi_periph.c @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/spi_periph.h" +#include "stddef.h" + +/* + Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = { + { + // MSPI has dedicated iomux pins + .spiclk_out = -1, + .spiclk_in = -1, + .spid_out = -1, + .spiq_out = -1, + .spiwp_out = -1, + .spihd_out = -1, + .spid_in = -1, + .spiq_in = -1, + .spiwp_in = -1, + .spihd_in = -1, + .spics_out = {-1}, + .spics_in = -1, + .spiclk_iomux_pin = -1, + .spid_iomux_pin = -1, + .spiq_iomux_pin = -1, + .spiwp_iomux_pin = -1, + .spihd_iomux_pin = -1, + .spics0_iomux_pin = -1, + .irq = -1, + .irq_dma = -1, + .module = -1, + .hw = NULL, + .func = -1, + }, { + .spiclk_out = FSPICLK_OUT_IDX, + .spiclk_in = FSPICLK_IN_IDX, + .spid_out = FSPID_OUT_IDX, + .spiq_out = FSPIQ_OUT_IDX, + .spiwp_out = FSPIWP_OUT_IDX, + .spihd_out = FSPIHD_OUT_IDX, + .spid_in = FSPID_IN_IDX, + .spiq_in = FSPIQ_IN_IDX, + .spiwp_in = FSPIWP_IN_IDX, + .spihd_in = FSPIHD_IN_IDX, + .spics_out = {FSPICS0_OUT_IDX, FSPICS1_OUT_IDX, FSPICS2_OUT_IDX, FSPICS3_OUT_IDX, FSPICS4_OUT_IDX, FSPICS5_OUT_IDX}, + .spics_in = FSPICS0_IN_IDX, + .spiclk_iomux_pin = SPI2_IOMUX_PIN_NUM_CLK, + .spid_iomux_pin = SPI2_IOMUX_PIN_NUM_MOSI, + .spiq_iomux_pin = SPI2_IOMUX_PIN_NUM_MISO, + .spiwp_iomux_pin = SPI2_IOMUX_PIN_NUM_WP, + .spihd_iomux_pin = SPI2_IOMUX_PIN_NUM_HD, + .spics0_iomux_pin = SPI2_IOMUX_PIN_NUM_CS, + .irq = ETS_GSPI2_INTR_SOURCE, + .irq_dma = -1, + .module = PERIPH_SPI2_MODULE, + .hw = &GPSPI2, + .func = SPI2_FUNC_NUM, + } +}; diff --git a/components/soc/esp32c6/temperature_sensor_periph.c b/components/soc/esp32c6/temperature_sensor_periph.c new file mode 100644 index 000000000000..f5ad36f5a9f1 --- /dev/null +++ b/components/soc/esp32c6/temperature_sensor_periph.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/temperature_sensor_periph.h" + +const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_SENSOR_ATTR_RANGE_NUM] = { + /*Offset reg_val min max error */ + {-2, 5, 50, 125, 3}, + {-1, 7, 20, 100, 2}, + { 0, 15, -10, 80, 1}, + { 1, 11, -30, 50, 2}, + { 2, 10, -40, 20, 3}, +}; diff --git a/components/soc/esp32c6/timer_periph.c b/components/soc/esp32c6/timer_periph.c new file mode 100644 index 000000000000..089c80958fb0 --- /dev/null +++ b/components/soc/esp32c6/timer_periph.c @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/timer_periph.h" + +const timer_group_signal_conn_t timer_group_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_TIMG0_MODULE, + .timer_irq_id = { + [0] = ETS_TG0_T0_LEVEL_INTR_SOURCE, + } + }, + [1] = { + .module = PERIPH_TIMG1_MODULE, + .timer_irq_id = { + [0] = ETS_TG1_T0_LEVEL_INTR_SOURCE, + } + } + } +}; diff --git a/components/soc/esp32c6/twai_periph.c b/components/soc/esp32c6/twai_periph.c new file mode 100644 index 000000000000..712102bf145f --- /dev/null +++ b/components/soc/esp32c6/twai_periph.c @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/twai_periph.h" +#include "soc/gpio_sig_map.h" + +const twai_controller_signal_conn_t twai_controller_periph_signals = { + .controllers = { + [0] = { + .module = PERIPH_TWAI0_MODULE, + .irq_id = ETS_TWAI0_INTR_SOURCE, + .tx_sig = TWAI0_TX_IDX, + .rx_sig = TWAI0_RX_IDX, + .bus_off_sig = TWAI0_BUS_OFF_ON_IDX, + .clk_out_sig = TWAI0_CLKOUT_IDX, + .stand_by_sig = TWAI0_STANDBY_IDX, + }, + [1] = { + .module = PERIPH_TWAI1_MODULE, + .irq_id = ETS_TWAI1_INTR_SOURCE, + .tx_sig = TWAI1_TX_IDX, + .rx_sig = TWAI1_RX_IDX, + .bus_off_sig = TWAI1_BUS_OFF_ON_IDX, + .clk_out_sig = TWAI1_CLKOUT_IDX, + .stand_by_sig = TWAI1_STANDBY_IDX, + } + } +}; diff --git a/components/soc/esp32c6/uart_periph.c b/components/soc/esp32c6/uart_periph.c new file mode 100644 index 000000000000..ca2adc3e1f4b --- /dev/null +++ b/components/soc/esp32c6/uart_periph.c @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/uart_periph.h" + +/* + Bunch of constants for every UART peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { + { + .pins = { + [SOC_UART_TX_PIN_IDX] = { + .default_gpio = U0TXD_GPIO_NUM, + .iomux_func = U0TXD_MUX_FUNC, + .input = 0, + .signal = U0TXD_OUT_IDX, + }, + + [SOC_UART_RX_PIN_IDX] = { + .default_gpio = U0RXD_GPIO_NUM, + .iomux_func = U0RXD_MUX_FUNC, + .input = 1, + .signal = U0RXD_IN_IDX, + }, + + [SOC_UART_RTS_PIN_IDX] = { + .default_gpio = U0RTS_GPIO_NUM, + .iomux_func = U0RTS_MUX_FUNC, + .input = 0, + .signal = U0RTS_OUT_IDX, + }, + + [SOC_UART_CTS_PIN_IDX] = { + .default_gpio = U0CTS_GPIO_NUM, + .iomux_func = U0CTS_MUX_FUNC, + .input = 1, + .signal = U0CTS_IN_IDX, + } + }, + .irq = ETS_UART0_INTR_SOURCE, + .module = PERIPH_UART0_MODULE, + }, + + { + .pins = { + [SOC_UART_TX_PIN_IDX] = { + .default_gpio = U1TXD_GPIO_NUM, + .iomux_func = U1TXD_MUX_FUNC, + .input = 0, + .signal = U1TXD_OUT_IDX, + }, + + [SOC_UART_RX_PIN_IDX] = { + .default_gpio = U1RXD_GPIO_NUM, + .iomux_func = U1RXD_MUX_FUNC, + .input = 1, + .signal = U1RXD_IN_IDX, + }, + + [SOC_UART_RTS_PIN_IDX] = { + .default_gpio = U1RTS_GPIO_NUM, + .iomux_func = U1RTS_MUX_FUNC, + .input = 0, + .signal = U1RTS_OUT_IDX, + }, + + [SOC_UART_CTS_PIN_IDX] = { + .default_gpio = U1CTS_GPIO_NUM, + .iomux_func = U1CTS_MUX_FUNC, + .input = 1, + .signal = U1CTS_IN_IDX, + }, + }, + .irq = ETS_UART1_INTR_SOURCE, + .module = PERIPH_UART1_MODULE, + }, +}; diff --git a/components/soc/include/soc/adc_periph.h b/components/soc/include/soc/adc_periph.h index 437d8ad6e6ae..17aef77c1499 100644 --- a/components/soc/include/soc/adc_periph.h +++ b/components/soc/include/soc/adc_periph.h @@ -16,7 +16,9 @@ #include "soc/soc.h" #include "soc/soc_caps.h" +#if !defined(CONFIG_IDF_TARGET_ESP32C6) #include "soc/syscon_struct.h" +#endif #if SOC_ADC_RTC_CTRL_SUPPORTED #include "soc/sens_reg.h" @@ -26,7 +28,9 @@ #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #include "soc/rtc_io_struct.h" #endif +#if !defined(CONFIG_IDF_TARGET_ESP32C6) #include "soc/rtc_cntl_struct.h" +#endif #include "soc/adc_channel.h" #include "soc/soc_caps.h" diff --git a/components/soc/include/soc/chip_revision.h b/components/soc/include/soc/chip_revision.h new file mode 100644 index 000000000000..fbdc94a02c54 --- /dev/null +++ b/components/soc/include/soc/chip_revision.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Convenient macros to check current wafer version against a version where some changes are introduced. + * Use `ESP_CHIP_REV_ABOVE` for a change introduced before any major versions. + * Use `ESP_CHIP_REV_MAJOR_AND_ABOVE` for changes introduced after a major version is added. + * For example, on ESP32 we have wafer versions: + * + * 0.0 -> 1.0 -> 2.0 -> 3.0 -> 3.1 -> N.A. + * |->1.1 + * + * - If we are adding code for a change on 1.1, we should use `ESP_CHIP_REV_MAJOR_AND_ABOVE` + * because there is already major version 2 existing. The condition will be met from 1.1 to 1.99, + * while not inherited by 2.0 and above. + * + * - If we are adding code for a change on 3.1, we should use `ESP_CHIP_REV_ABOVE` + * because there is no major version 4. The condition will be met from 3.1 to 3.99 and 4.0 and above. + * Even if we add revision 4.0 on this version, the logic will be inherited. + */ + +#define ESP_CHIP_REV_ABOVE(rev, min_rev) ((min_rev) <= (rev)) +#define ESP_CHIP_REV_MAJOR_AND_ABOVE(rev, min_rev) (((rev) / 100 == (min_rev) / 100) && ((rev) >= (min_rev))) + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/include/soc/rtc_cntl_periph.h b/components/soc/include/soc/rtc_cntl_periph.h index 60e3d3216d7d..0b8cd74c0ded 100644 --- a/components/soc/include/soc/rtc_cntl_periph.h +++ b/components/soc/include/soc/rtc_cntl_periph.h @@ -1,18 +1,29 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once +#include "sdkconfig.h" + +#if CONFIG_IDF_TARGET_ESP32C6 +#include "soc/lp_aon_reg.h" +#include "soc/lp_analog_peri_reg.h" +#include "soc/lp_clkrst_reg.h" +#include "soc/lp_clkrst_struct.h" +#include "soc/lp_i2c_reg.h" +#include "soc/lp_i2c_struct.h" +#include "soc/lp_io_reg.h" +#include "soc/lp_io_struct.h" +#include "soc/lp_timer_reg.h" +#include "soc/lp_timer_struct.h" +#include "soc/lp_uart_reg.h" +#include "soc/lp_uart_struct.h" +#include "soc/lp_wdt_reg.h" +#include "soc/lp_wdt_struct.h" +#else #include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_struct.h" +#endif diff --git a/components/soc/include/soc/rtc_io_periph.h b/components/soc/include/soc/rtc_io_periph.h index 106d879dfbfd..3a1603d48068 100644 --- a/components/soc/include/soc/rtc_io_periph.h +++ b/components/soc/include/soc/rtc_io_periph.h @@ -6,7 +6,7 @@ #pragma once - +#include "sdkconfig.h" #include "soc/soc.h" //include soc related (generated) definitions #include "soc/soc_caps.h" @@ -17,8 +17,10 @@ #include "soc/rtc_io_struct.h" #endif +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_struct.h" +#endif #if SOC_ADC_RTC_CTRL_SUPPORTED #include "soc/sens_struct.h" diff --git a/components/soc/include/soc/rtc_periph.h b/components/soc/include/soc/rtc_periph.h index 433f5cc42ebe..591bc6d4b6b2 100644 --- a/components/soc/include/soc/rtc_periph.h +++ b/components/soc/include/soc/rtc_periph.h @@ -15,7 +15,7 @@ #pragma once #include #include "rtc_io_periph.h" -#include "soc/rtc_cntl_reg.h" +#include "rtc_cntl_periph.h" #include "soc/soc_caps.h" #ifdef __cplusplus diff --git a/components/soc/include/soc/spi_periph.h b/components/soc/include/soc/spi_periph.h index 5f91beb605e3..b969e82a110e 100644 --- a/components/soc/include/soc/spi_periph.h +++ b/components/soc/include/soc/spi_periph.h @@ -34,6 +34,10 @@ extern "C" { #define SPI_FWRITE_QIO 0 #endif +#ifndef SOC_SPI_MAX_CS_NUM +#define SOC_SPI_MAX_CS_NUM 3 +#endif + /* Stores a bunch of per-spi-peripheral data. */ @@ -60,7 +64,7 @@ typedef struct { const uint8_t spid6_in; const uint8_t spid7_in; #endif // SOC_SPI_SUPPORT_OCT - const uint8_t spics_out[3]; // /CS GPIO output mux signals + const uint8_t spics_out[SOC_SPI_MAX_CS_NUM]; // /CS GPIO output mux signals const uint8_t spics_in; const uint8_t spidqs_out; const uint8_t spicd_out; diff --git a/components/soc/include/soc/touch_sensor_periph.h b/components/soc/include/soc/touch_sensor_periph.h index 2b27b97d2016..c054d97ac1e3 100644 --- a/components/soc/include/soc/touch_sensor_periph.h +++ b/components/soc/include/soc/touch_sensor_periph.h @@ -6,12 +6,15 @@ #pragma once +#include "sdkconfig.h" #include "soc/soc_caps.h" #include "soc/touch_sensor_channel.h" +#if !CONFIG_IDF_TARGET_ESP32C6 #include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/sens_reg.h" #include "soc/sens_struct.h" +#endif #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #include "soc/rtc_io_struct.h" #endif diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 89bb53e8fc98..8e20e7c1f4f1 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -8,6 +8,7 @@ #include #include #include +#include "esp_attr.h" #include #include @@ -35,6 +36,10 @@ #include "esp32c2/rom/cache.h" #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/cache.h" +#include "soc/extmem_reg.h" +#include "soc/ext_mem_defs.h" #endif #include "esp_rom_spiflash.h" #include @@ -366,7 +371,7 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_st icache_state = Cache_Suspend_ICache() << 16; dcache_state = Cache_Suspend_DCache(); *saved_state = icache_state | dcache_state; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 uint32_t icache_state; icache_state = Cache_Suspend_ICache() << 16; *saved_state = icache_state; @@ -392,7 +397,7 @@ static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_sta #elif CONFIG_IDF_TARGET_ESP32S3 Cache_Resume_DCache(saved_state & 0xffff); Cache_Resume_ICache(saved_state >> 16); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 Cache_Resume_ICache(saved_state >> 16); #endif } @@ -408,6 +413,8 @@ IRAM_ATTR bool spi_flash_cache_enabled(void) bool result = (REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE) != 0); #elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 bool result = (REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE) != 0); +#elif CONFIG_IDF_TARGET_ESP32C6 + bool result = (REG_GET_BIT(EXTMEM_L1_CACHE_CTRL_REG, EXTMEM_L1_CACHE_SHUT_IBUS) == 0); #endif return result; } diff --git a/components/spi_flash/esp32c6/Kconfig.soc_caps.in b/components/spi_flash/esp32c6/Kconfig.soc_caps.in new file mode 100644 index 000000000000..87accd576f89 --- /dev/null +++ b/components/spi_flash/esp32c6/Kconfig.soc_caps.in @@ -0,0 +1,8 @@ +##################################################### +# This file is auto-generated from SoC caps +# using gen_soc_caps_kconfig.py, do not edit manually +##################################################### + +config SPI_FLASH_VENDOR_XMC_SUPPORTED + bool + default y diff --git a/components/spi_flash/esp32c6/flash_vendor_caps.h b/components/spi_flash/esp32c6/flash_vendor_caps.h new file mode 100644 index 000000000000..ffa84babf788 --- /dev/null +++ b/components/spi_flash/esp32c6/flash_vendor_caps.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#define SPI_FLASH_VENDOR_XMC_SUPPORTED (1) diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index a7bed139b2ac..8386b106fc18 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -169,6 +169,7 @@ static IRAM_ATTR esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t er /* Top-level API functions, calling into chip_drv functions via chip->drv */ static esp_err_t detect_spi_flash_chip(esp_flash_t *chip); +static esp_err_t read_id_core(esp_flash_t *chip, uint32_t *out_id, bool sanity_check); bool esp_flash_chip_driver_initialized(const esp_flash_t *chip) { @@ -193,7 +194,7 @@ esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip) uint32_t flash_id; int retries = 10; do { - err = esp_flash_read_chip_id(chip, &flash_id); + err = read_id_core(chip, &flash_id, true); } while (err == ESP_ERR_FLASH_NOT_INITIALISED && retries-- > 0); if (err != ESP_OK) { @@ -263,6 +264,13 @@ esp_err_t IRAM_ATTR esp_flash_init_main(esp_flash_t *chip) } octal_mode = (chip->read_mode >= SPI_FLASH_OPI_FLAG); + /* Bootloader already probed the main flash. A second RDID from the app + * suspends the cache and does not return on this C6 bring-up. */ + chip->chip_id = g_rom_flashchip.device_id; + chip->size = g_rom_flashchip.chip_size; + if (chip->chip_id != 0 && chip->size != 0) { + return ESP_OK; + } //read chip id // This can indicate the MSPI support OPI, if the flash works on MSPI in OPI mode, we directly bypass read id. uint32_t flash_id = 0; @@ -272,7 +280,7 @@ esp_err_t IRAM_ATTR esp_flash_init_main(esp_flash_t *chip) } else { int retries = 10; do { - err = esp_flash_read_chip_id(chip, &flash_id); + err = read_id_core(chip, &flash_id, true); } while (err == ESP_ERR_FLASH_NOT_INITIALISED && retries-- > 0); } diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 23ec3763fdee..984ac87e0173 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -104,7 +104,7 @@ esp_flash_t *esp_flash_default_chip = NULL; .input_delay_ns = 0,\ .cs_setup = 1,\ } -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 #if !CONFIG_SPI_FLASH_AUTO_SUSPEND #define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ .host_id = SPI1_HOST,\ @@ -332,7 +332,7 @@ esp_err_t esp_flash_init_default_chip(void) const esp_rom_spiflash_chip_t *legacy_chip = &g_rom_flashchip; memspi_host_config_t cfg = ESP_FLASH_HOST_CONFIG_DEFAULT(); - #if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32C2 + #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 // For esp32s2 spi IOs are configured as from IO MUX by default cfg.iomux = esp_rom_efuse_get_flash_gpio_info() == 0 ? true : false; #endif diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index fd4a5e17e502..086d08c8f6b5 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -36,6 +36,8 @@ #include "esp32c3/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/cache.h" #endif diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index f1ce890d3dd8..c0e15d12e827 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -26,6 +26,9 @@ #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/ets_sys.h" #include "esp32c2/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/ets_sys.h" +#include "esp32c6/rom/cache.h" #endif #include "esp_attr.h" @@ -37,7 +40,7 @@ typedef struct { } spi_noos_arg_t; static DRAM_ATTR spi_noos_arg_t spi_arg = { 0 }; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 typedef struct { uint32_t icache_autoload; } spi_noos_arg_t; @@ -54,7 +57,7 @@ static IRAM_ATTR esp_err_t start(void *arg) spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); spi_arg->dcache_autoload = Cache_Suspend_DCache(); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); #endif @@ -73,7 +76,7 @@ static IRAM_ATTR esp_err_t end(void *arg) Cache_Invalidate_ICache_All(); Cache_Resume_ICache(spi_arg->icache_autoload); Cache_Resume_DCache(spi_arg->dcache_autoload); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 spi_noos_arg_t *spi_arg = arg; Cache_Invalidate_ICache_All(); Cache_Resume_ICache(spi_arg->icache_autoload);