Merge branch 'feature/support_esp8684_cmake' into 'master'

ESP8684: Introduce new chip target esp8684

Closes IDF-3813

See merge request espressif/esp-idf!15158
This commit is contained in:
Michael (XIAO Xufeng) 2021-11-07 16:44:02 +00:00
commit d0dd9ce1b9
344 changed files with 59709 additions and 852 deletions

10
Kconfig
View File

@ -57,6 +57,14 @@ mainmenu "Espressif IoT Development Framework Configuration"
select FREERTOS_UNICORE
select IDF_TARGET_ARCH_RISCV
config IDF_TARGET_ESP8684
bool
default "y" if IDF_TARGET="esp8684"
select FREERTOS_UNICORE
select IDF_TARGET_ARCH_RISCV
select ESPTOOLPY_NO_STUB # remove if ESPTOOL-303
select IDF_ENV_FPGA
config IDF_TARGET_LINUX
bool
default "y" if IDF_TARGET="linux"
@ -68,6 +76,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
default 0x0005 if IDF_TARGET_ESP32C3
default 0x0009 if IDF_TARGET_ESP32S3
default 0x000A if IDF_TARGET_ESP32H2 # ESP32H2-TODO: IDF-3475
default 0x000C if IDF_TARGET_ESP8684
default 0xFFFF
menu "SDK tool configuration"
@ -78,6 +87,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
default "xtensa-esp32s3-elf-" if IDF_TARGET_ESP32S3
default "riscv32-esp-elf-" if IDF_TARGET_ESP32C3
default "riscv32-esp-elf-" if IDF_TARGET_ESP32H2
default "riscv32-esp-elf-" if IDF_TARGET_ESP8684
help
The prefix/path that is used to call the toolchain. The default setting assumes

View File

@ -681,7 +681,7 @@ menu "Security features"
choice SECURE_FLASH_ENCRYPTION_KEYSIZE
bool "Size of generated AES-XTS key"
default SECURE_FLASH_ENCRYPTION_AES128
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3) && SECURE_FLASH_ENC_ENABLED
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP8684) && SECURE_FLASH_ENC_ENABLED
help
Size of generated AES-XTS key.
@ -693,9 +693,11 @@ menu "Security features"
config SECURE_FLASH_ENCRYPTION_AES128
bool "AES-128 (256-bit key)"
depends on !IDF_TARGET_ESP8684 # TODO: IDF-3899
config SECURE_FLASH_ENCRYPTION_AES256
bool "AES-256 (512-bit key)"
depends on !IDF_TARGET_ESP8684 # TODO: IDF-3899
endchoice
choice SECURE_FLASH_ENCRYPTION_MODE
@ -862,9 +864,13 @@ menu "Security features"
If not set, the app does not care if the flash encryption eFuse bit is set or not.
config SECURE_ROM_DL_MODE_ENABLED
bool
default y if SECURE_TARGET_HAS_SECURE_ROM_DL_MODE && !SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
choice SECURE_UART_ROM_DL_MODE
bool "UART ROM download mode"
default SECURE_ENABLE_SECURE_ROM_DL_MODE if SECURE_TARGET_HAS_SECURE_ROM_DL_MODE && !SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT # NOERROR
default SECURE_ENABLE_SECURE_ROM_DL_MODE if SECURE_ROM_DL_MODE_ENABLED # NOERROR
default SECURE_INSECURE_ALLOW_DL_MODE
depends on SECURE_BOOT_V2_ENABLED || SECURE_FLASH_ENC_ENABLED
depends on !IDF_TARGET_ESP32 || ESP32_REV_MIN_3

View File

@ -4,10 +4,7 @@ idf_component_register(SRCS "bootloader_start.c"
idf_build_get_property(target IDF_TARGET)
set(scripts "ld/${target}/bootloader.ld")
if(NOT CONFIG_IDF_TARGET_ESP32H2)
list(APPEND scripts "ld/${target}/bootloader.rom.ld")
endif()
list(APPEND scripts "ld/${target}/bootloader.rom.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u bootloader_hooks_include")

View File

@ -0,0 +1,6 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* No definition for ESP32-H2 target */

View File

@ -0,0 +1,196 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
* We put 2nd bootloader in the high address space (before ROM stack/data/bss).
* See memory usage for ROM bootloader at the end of this file.
*/
MEMORY
{
iram_seg (RWX) : org = 0x403AE000, len = 0x2000
iram_loader_seg (RWX) : org = 0x403B0000, len = 0x6000
dram_seg (RW) : org = 0x3FCD6000, len = 0x4000
}
/* Default entry point: */
ENTRY(call_start_cpu0);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*liblog.a:(.literal .text .literal.* .text.*)
*libgcc.a:(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable)
*libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable)
*libbootloader_support.a:bootloader_efuse_esp8684.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*)
*libefuse.a:*.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} > dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} > dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__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)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} > dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
/** CPU will try to prefetch up to 16 bytes of
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += 16;
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}
/**
* Appendix: Memory Usage of ROM bootloader
*
* +--------+--------------+------+ 0x3FCC_B0B0
* | ^ |
* | | |
* | | data/bss |
* | | |
* | v |
* +------------------------------+ 0x3FCD_C9C0
* | ^ |
* | | |
* | | stack |
* | | |
* | v |
* +------------------------------+ 0x3FCD_E9C0
*/

View File

@ -0,0 +1,6 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* No definition for ESP8684 target */

View File

@ -32,14 +32,17 @@ COMPONENT_OBJEXCLUDE += src/bootloader_flash_config_esp32s2.o \
src/bootloader_flash_config_esp32s3.o \
src/bootloader_flash_config_esp32c3.o \
src/bootloader_flash_config_esp32h2.o \
src/bootloader_flash_config_esp8684.o \
src/bootloader_efuse_esp32s2.o \
src/bootloader_efuse_esp32s3.o \
src/bootloader_efuse_esp32c3.o \
src/bootloader_efuse_esp32h2.o \
src/bootloader_efuse_esp8684.o \
src/bootloader_random_esp32s2.o \
src/bootloader_random_esp32s3.o \
src/bootloader_random_esp32c3.o \
src/bootloader_random_esp32h2.o
src/bootloader_random_esp32h2.o \
src/bootloader_random_esp8684.o
ifdef IS_BOOTLOADER_BUILD
ifndef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME

View File

@ -20,6 +20,8 @@
#include "esp32c3/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/rtc.h"
#endif
#ifdef __cplusplus

View File

@ -17,6 +17,7 @@ typedef enum {
ESP_CHIP_ID_ESP32C3 = 0x0005, /*!< chip ID: ESP32-C3 */
ESP_CHIP_ID_ESP32S3 = 0x0009, /*!< chip ID: ESP32-S3 */
ESP_CHIP_ID_ESP32H2 = 0x000A, /*!< chip ID: ESP32-H2 */ // ESP32H2-TODO: IDF-3475
ESP_CHIP_ID_ESP8684 = 0x000C, /*!< chip ID: ESP32-8684 */
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
} __attribute__((packed)) esp_chip_id_t;

View File

@ -55,7 +55,11 @@ static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_e
#endif
#else
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT);
#if CONFIG_IDF_TARGET_ESP8684
// IDF-3899
#else
flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT);
#endif
#else
esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count);
#endif

View File

@ -28,6 +28,9 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/efuse.h"
#include "esp32h2/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/efuse.h"
#include "esp8684/rom/secure_boot.h"
#endif
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED

View File

@ -15,8 +15,8 @@
#include "bootloader_flash.h"
#define FLASH_SECTOR_SIZE 0x1000
#define FLASH_BLOCK_SIZE 0x10000
#define MMAP_ALIGNED_MASK 0x0000FFFF
#define FLASH_BLOCK_SIZE 0x10000
#define MMAP_ALIGNED_MASK 0x0000FFFF
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
Suitable for use with the bootloader_execute_flash_command static function.
@ -130,7 +130,7 @@ esp_err_t bootloader_flash_erase_sector(size_t sector);
esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size);
/* Cache MMU block size */
#define MMU_BLOCK_SIZE 0x00010000
#define MMU_BLOCK_SIZE 0x10000
/* Cache MMU address mask (MMU tables ignore bits which are zero) */
#define MMU_FLASH_MASK (~(MMU_BLOCK_SIZE - 1))

View File

@ -19,6 +19,8 @@
#include "esp32c3/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/spi_flash.h"
#endif
#include "esp_rom_crc.h"
#include "esp_rom_gpio.h"

View File

@ -25,6 +25,9 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/ets_sys.h"
#include "esp32h2/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/ets_sys.h"
#include "esp8684/rom/uart.h"
#endif
#include "esp_rom_gpio.h"
#include "esp_rom_uart.h"

View File

@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "soc/efuse_reg.h"
uint8_t bootloader_common_get_chip_revision(void)
{
// should return the same value as esp_efuse_get_chip_ver()
return REG_GET_FIELD(EFUSE_RD_BLK2_DATA1_REG, EFUSE_WAFER_VERSION);
}
uint32_t bootloader_common_get_chip_ver_pkg(void)
{
// should return the same value as esp_efuse_get_pkg_ver()
return REG_GET_FIELD(EFUSE_RD_BLK2_DATA1_REG, EFUSE_PKG_VERSION);
}

View File

@ -33,6 +33,8 @@
#include "esp32c3/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/spi_flash.h"
#endif
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
@ -143,6 +145,10 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
#include "esp32h2/rom/spi_flash.h"
#include "esp32h2/rom/cache.h"
#include "soc/cache_memory.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/spi_flash.h"
#include "esp8684/rom/cache.h"
#include "soc/cache_memory.h"
#endif
static const char *TAG = "bootloader_flash";

View File

@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <assert.h>
#include "string.h"
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp8684/rom/gpio.h"
#include "esp8684/rom/spi_flash.h"
#include "esp8684/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"
#define FLASH_IO_MATRIX_DUMMY_40M 0
#define FLASH_IO_MATRIX_DUMMY_80M 0
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) {
// TODO: change MSPI freq, IDF-3831
case ESP_IMAGE_SPI_SPEED_80M:
spi_clk_div = 1;
break;
case ESP_IMAGE_SPI_SPEED_40M:
spi_clk_div = 2;
break;
case ESP_IMAGE_SPI_SPEED_26M:
spi_clk_div = 3;
break;
case ESP_IMAGE_SPI_SPEED_20M:
spi_clk_div = 4;
break;
default:
break;
}
esp_rom_spiflash_config_clk(spi_clk_div, 0);
}
void IRAM_ATTR bootloader_flash_set_dummy_out(void)
{
REG_SET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL);
REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL);
}
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr)
{
bootloader_configure_spi_pins(1);
bootloader_flash_set_dummy_out();
}

View File

@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "bootloader_random.h"
#include "esp_log.h"
#include "soc/syscon_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_saradc_reg.h"
#include "soc/system_reg.h"
#include "regi2c_ctrl.h"
void bootloader_random_enable(void)
{
// TODO: IDF-4021
}
void bootloader_random_disable(void)
{
// TODO: IDF-4021
}

View File

@ -53,6 +53,18 @@
#include "esp32h2/rom/secure_boot.h"
#include "soc/extmem_reg.h"
#include "soc/cache_memory.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/cache.h"
#include "esp8684/rom/efuse.h"
#include "esp8684/rom/ets_sys.h"
#include "esp8684/rom/spi_flash.h"
#include "esp8684/rom/crc.h"
#include "esp8684/rom/rtc.h"
#include "esp8684/rom/uart.h"
#include "esp8684/rom/gpio.h"
#include "esp8684/rom/secure_boot.h"
#include "soc/extmem_reg.h"
#include "soc/cache_memory.h"
#else // CONFIG_IDF_TARGET_*
#error "Unsupported IDF_TARGET"
#endif

View File

@ -0,0 +1,302 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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 "soc/efuse_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/io_mux_reg.h"
#include "soc/assist_debug_reg.h"
#include "soc/cpu.h"
#include "soc/rtc.h"
#include "soc/spi_periph.h"
#include "soc/extmem_reg.h"
#include "soc/io_mux_reg.h"
#include "soc/system_reg.h"
#include "esp8684/rom/efuse.h"
#include "esp8684/rom/spi_flash.h"
#include "esp8684/rom/cache.h"
#include "esp8684/rom/ets_sys.h"
#include "esp8684/rom/spi_flash.h"
#include "esp8684/rom/rtc.h"
#include "bootloader_common.h"
#include "bootloader_init.h"
#include "bootloader_clock.h"
#include "bootloader_flash_config.h"
#include "bootloader_mem.h"
#include "regi2c_ctrl.h"
#include "bootloader_console.h"
#include "bootloader_flash_priv.h"
#include "esp_efuse.h"
static const char *TAG = "boot.esp8684";
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
{
// IDF-4066
const uint32_t spiconfig = 0;
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;
if (spiconfig == 0) {
}
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);
if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
}
if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
}
}
static void bootloader_reset_mmu(void)
{
int page_mode = MMU_Get_Page_Mode();
int size = (page_mode == 0? 16:
page_mode == 1? 32:
page_mode == 2? 64: 0);
ESP_LOGI(TAG, "mmu page mode = %dK", size);
Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
Cache_MMU_Init();
REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_IBUS);
REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_DBUS);
}
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;
}
uint32_t autoload = Cache_Suspend_ICache();
// 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_Resume_ICache(autoload);
}
static void print_flash_info(const esp_image_header_t *bootloader_hdr)
{
ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic);
ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count);
ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode);
ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed);
ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size);
const char *str;
switch (bootloader_hdr->spi_speed) {
case ESP_IMAGE_SPI_SPEED_40M:
str = "40MHz";
break;
case ESP_IMAGE_SPI_SPEED_26M:
str = "26.7MHz";
break;
case ESP_IMAGE_SPI_SPEED_20M:
str = "20MHz";
break;
default:
str = "20MHz";
break;
}
ESP_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_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_LOGI(TAG, "SPI Flash Size : %s", str);
}
static void IRAM_ATTR bootloader_init_flash_configure(void)
{
bootloader_flash_dummy_config(&bootloader_image_hdr);
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);
}
static esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
bootloader_spi_flash_resume();
esp_rom_spiflash_unlock();
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
bootloader_enable_qio_mode();
#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;
}
static void wdt_reset_cpu0_info_enable(void)
{
REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
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_CPU0_MWDT0 || 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(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
}
esp_err_t bootloader_init(void)
{
esp_err_t ret = ESP_OK;
bootloader_super_wdt_auto_feed();
// 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();
// 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
// reset MMU
bootloader_reset_mmu();
// 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();
// update flash ID
bootloader_flash_update_id();
// read bootloader header
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
goto err;
}
// read chip revision and check if it's compatible to bootloader
if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
goto err;
}
// initialize spi flash
if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
goto err;
}
// check whether a WDT reset happend
bootloader_check_wdt_reset();
// config WDT
bootloader_config_wdt();
// enable RNG early entropy source
bootloader_enable_random();
err:
return ret;
}

View File

@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "bootloader_sha.h"
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <sys/param.h>
#include "esp8684/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);
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);
}

View File

@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
void bootloader_ana_super_wdt_reset_config(bool enable)
{
(void)enable; // ESP8684 has none of these features.
}
void bootloader_ana_bod_reset_config(bool enable)
{
(void)enable; // ESP8684 has none of these features.
}
void bootloader_ana_clock_glitch_reset_config(bool enable)
{
(void)enable; // ESP8684 has none of these features.
}

View File

@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <strings.h>
#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
ESP_LOGI(TAG, "Disable UART bootloader cache...");
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
ESP_LOGI(TAG, "Disable JTAG...");
esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
#else
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
#endif
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
return ESP_OK;
}

View File

@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <strings.h>
#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_LEGACY_SPI_BOOT);
#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
ESP_LOGI(TAG, "Enabling Security download mode...");
esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
#else
ESP_LOGW(TAG, "Not enabling Security download mode - 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_bit(ESP_EFUSE_SOFT_DIS_JTAG);
#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);
return ESP_OK;
}

View File

@ -19,6 +19,7 @@
#include "bootloader_common.h"
#include "esp_rom_sys.h"
#include "soc/soc_memory_types.h"
#include "soc/soc_caps.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32S2
@ -29,6 +30,9 @@
#include "esp32c3/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/rtc.h"
#include "esp8684/rom/secure_boot.h"
#endif
/* Checking signatures as part of verifying images is necessary:
@ -427,13 +431,22 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
}
}
/* Sections entirely in RTC memory won't overlap with a vanilla bootloader but are valid load addresses, thus skipping them from the check */
} else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_inclusive_end_p)){
}
#if SOC_RTC_FAST_MEM_SUPPORTED
else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_inclusive_end_p)){
return true;
} else if (esp_ptr_in_rtc_dram_fast(load_addr_p) && esp_ptr_in_rtc_dram_fast(load_inclusive_end_p)){
return true;
} else if (esp_ptr_in_rtc_slow(load_addr_p) && esp_ptr_in_rtc_slow(load_inclusive_end_p)) {
}
#endif
#if SOC_RTC_SLOW_MEM_SUPPORTED
else if (esp_ptr_in_rtc_slow(load_addr_p) && esp_ptr_in_rtc_slow(load_inclusive_end_p)) {
return true;
} else { /* Not a DRAM or an IRAM or RTC Fast IRAM, RTC Fast DRAM or RTC Slow address */
}
#endif
else { /* Not a DRAM or an IRAM or RTC Fast IRAM, RTC Fast DRAM or RTC Slow address */
reason = "bad load address range";
goto invalid;
}
@ -696,6 +709,7 @@ static bool should_load(uint32_t load_addr)
}
if (!load_rtc_memory) {
#if SOC_RTC_FAST_MEM_SUPPORTED
if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x", load_addr);
return false;
@ -704,10 +718,14 @@ static bool should_load(uint32_t load_addr)
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x", load_addr);
return false;
}
#endif
#if SOC_RTC_SLOW_MEM_SUPPORTED
if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x", load_addr);
return false;
}
#endif
}
return true;

View File

@ -15,6 +15,10 @@
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "hal/wdt_hal.h"
#ifdef CONFIG_IDF_TARGET_ESP8684
// IDF-3899
#warning "Not support flash encryption on esp8684 yet."
#endif
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED

View File

@ -15,6 +15,8 @@
#include "esp32s3/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/spi_flash.h"
#else
#include "esp32/rom/spi_flash.h"
#endif
@ -48,7 +50,7 @@ esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table
return ESP_ERR_INVALID_STATE;
}
struct MD5Context context;
md5_context_t context;
unsigned char digest[16];
esp_rom_md5_init(&context);
esp_rom_md5_update(&context, (unsigned char *) partition_table, num_parts * sizeof(esp_partition_info_t));

View File

@ -23,6 +23,8 @@
#include "esp32c3/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/spi_flash.h"
#endif
#include "soc/efuse_periph.h"
#include "soc/io_mux_reg.h"
@ -146,7 +148,6 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
uint8_t status_qio_bit)
{
uint32_t status;
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
@ -181,9 +182,17 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
esp_rom_spiflash_config_readmode(mode);
#if !CONFIG_IDF_TARGET_ESP8684
//IDF-3914
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
#endif
#if CONFIG_IDF_TARGET_ESP32
int wp_pin = bootloader_flash_get_wp_pin();
esp_rom_spiflash_select_qio_pins(wp_pin, spiconfig);
#elif CONFIG_IDF_TARGET_ESP8684
//IDF-3914
esp_rom_spiflash_select_qio_pins(0, 0);
#else
esp_rom_spiflash_select_qio_pins(esp_rom_efuse_get_flash_wp_gpio(), spiconfig);
#endif

View File

@ -3,23 +3,19 @@ idf_build_get_property(target IDF_TARGET)
set(srcs
"gpio.c"
"i2c.c"
"i2s.c"
"ledc.c"
"pcnt.c"
"periph_ctrl.c"
"rmt.c"
"rtc_io.c"
"rtc_module.c"
"sdspi_crc.c"
"sdspi_host.c"
"sdspi_transaction.c"
"sigmadelta.c"
"spi_common.c"
"spi_master.c"
"spi_slave.c"
"spi_bus_lock.c"
"timer.c"
"twai.c"
"uart.c")
set(includes "include" "${target}/include")
@ -31,11 +27,15 @@ if(${target} STREQUAL "esp32")
"mcpwm.c"
"sdio_slave.c"
"sdmmc_host.c"
"i2s.c"
"rmt.c"
"sigmadelta.c"
"sdmmc_transaction.c"
"touch_sensor_common.c"
"esp32/touch_sensor.c"
"esp32/adc.c"
"esp32/dac.c")
"esp32/dac.c"
"twai.c")
endif()
if(IDF_TARGET STREQUAL "esp32s2")
@ -44,6 +44,10 @@ if(IDF_TARGET STREQUAL "esp32s2")
"dedic_gpio.c"
"spi_slave_hd.c"
"touch_sensor_common.c"
"sigmadelta.c"
"i2s.c"
"rmt.c"
"twai.c"
"esp32s2/rtc_tempsensor.c"
"esp32s2/touch_sensor.c"
"esp32s2/adc.c"
@ -58,11 +62,14 @@ if(${target} STREQUAL "esp32s3")
"sdmmc_host.c"
"sdmmc_transaction.c"
"mcpwm.c"
"rmt.c"
"sigmadelta.c"
"usb_serial_jtag.c"
"spi_slave_hd.c"
"touch_sensor_common.c"
"esp32s3/touch_sensor.c"
)
"i2s.c"
"twai.c")
endif()
if(IDF_TARGET STREQUAL "esp32c3")
@ -71,9 +78,13 @@ if(IDF_TARGET STREQUAL "esp32c3")
"adc_common.c"
"dedic_gpio.c"
"usb_serial_jtag.c"
"i2s.c"
"rmt.c"
"sigmadelta.c"
"esp32c3/adc.c"
"esp32c3/adc2_init_cal.c"
"esp32c3/rtc_tempsensor.c")
"esp32c3/rtc_tempsensor.c"
"twai.c")
endif()
if(IDF_TARGET STREQUAL "esp32h2")
@ -81,9 +92,16 @@ if(IDF_TARGET STREQUAL "esp32h2")
"spi_slave_hd.c"
"adc_common.c"
"dedic_gpio.c"
"i2s.c"
"rmt.c"
"sigmadelta.c"
"esp32h2/adc.c"
"esp32h2/adc2_init_cal.c"
"esp32h2/rtc_tempsensor.c")
"esp32h2/rtc_tempsensor.c"
"twai.c")
endif()
if(IDF_TARGET STREQUAL "esp8684")
list(APPEND srcs "spi_slave_hd.c")
endif()
idf_component_register(SRCS "${srcs}"

View File

@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "driver/adc_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/*************************************/
/* Digital controller filter setting */
/*************************************/
/**
* @brief Reset adc digital controller filter.
*
* @param idx Filter index.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx);
/**
* @brief Set adc digital controller filter configuration.
*
* @param idx Filter index.
* @param config See ``adc_digi_filter_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config);
/**
* @brief Get adc digital controller filter configuration.
*
* @param idx Filter index.
* @param config See ``adc_digi_filter_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config);
/**
* @brief Enable/disable adc digital controller filter.
* Filtering the ADC data to obtain smooth data at higher sampling rates.
*
* @param idx Filter index.
* @param enable Enable/Disable filter.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable);
/**************************************/
/* Digital controller monitor setting */
/**************************************/
/**
* @brief Config monitor of adc digital controller.
*
* @param idx Monitor index.
* @param config See ``adc_digi_monitor_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config);
/**
* @brief Enable/disable monitor of adc digital controller.
*
* @param idx Monitor index.
* @param enable True or false enable monitor.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */
TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */
TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */
TSENS_DAC_MAX,
TSENS_DAC_DEFAULT = TSENS_DAC_L2,
} temp_sensor_dac_offset_t;
/**
* @brief Configuration for temperature sensor reading
*/
typedef struct {
temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
uint8_t clk_div; /*!< Default: 6 */
} temp_sensor_config_t;
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
.clk_div = 6}
/**
* @brief Set parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
/**
* @brief Get parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
/**
* @brief Start temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is started already.
*/
esp_err_t temp_sensor_start(void);
/**
* @brief Stop temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is stopped already.
*/
esp_err_t temp_sensor_stop(void);
/**
* @brief Read temperature sensor raw data.
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG `tsens_out` is NULL
* - ESP_ERR_INVALID_STATE temperature sensor dont start
*/
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
* @param celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temp_sensor_read_celsius(float *celsius);
#ifdef __cplusplus
}
#endif

View File

@ -11,6 +11,7 @@ extern "C" {
#endif
#include "esp_err.h"
#include "soc/soc_caps.h"
/**
* @brief For WIFI module to claim the usage of ADC2.
@ -35,7 +36,7 @@ esp_err_t adc2_wifi_acquire(void);
*/
esp_err_t adc2_wifi_release(void);
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
/**
* @brief This API help ADC2 calibration constructor be linked.
*

View File

@ -45,7 +45,7 @@ typedef enum {
ADC1_CHANNEL_9, /*!< ADC1 channel 9 is GPIO10 */
ADC1_CHANNEL_MAX,
} adc1_channel_t;
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684
/**** `adc1_channel_t` will be deprecated functions, combine into `adc_channel_t` ********/
typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO0 */
@ -72,7 +72,7 @@ typedef enum {
ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 (ESP32), GPIO20 (ESP32-S2) */
ADC2_CHANNEL_MAX,
} adc2_channel_t;
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684
/**** `adc2_channel_t` will be deprecated functions, combine into `adc_channel_t` ********/
typedef enum {
ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO5 */
@ -103,7 +103,7 @@ typedef enum {
#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11
#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684
/**
* @brief Digital ADC DMA read max timeout value, it may make the ``adc_digi_read_bytes`` block forever if the OS supports
*/
@ -121,7 +121,7 @@ typedef enum {
ADC_ENCODE_MAX,
} adc_i2s_encode_t;
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684
//This feature is currently supported on ESP32C3, will be supported on other chips soon
/**
* @brief Digital ADC DMA configuration
@ -167,7 +167,7 @@ void adc_power_acquire(void);
*/
void adc_power_release(void);
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP8684
/**
* @brief Initialize ADC pad
* @param adc_unit ADC unit index
@ -177,7 +177,7 @@ void adc_power_release(void);
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel);
#endif //#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
#endif //#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP8684
/*---------------------------------------------------------------
ADC Single Read Setting
@ -276,7 +276,7 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit);
*/
int adc1_get_raw(adc1_channel_t channel);
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP8684
/**
* @brief Set ADC data invert
* @param adc_unit ADC unit index
@ -317,7 +317,7 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
* to be called to configure ADC1 channels, before ADC1 is used by the ULP.
*/
void adc1_ulp_enable(void);
#endif //#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
#endif //#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP8684
/**
* @brief Get the GPIO number of a specific ADC2 channel.
@ -477,7 +477,7 @@ esp_err_t adc_digi_deinit(void);
*/
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config);
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684
//This feature is currently supported on ESP32C3, will be supported on other chips soon
/*---------------------------------------------------------------
DMA setting
@ -537,7 +537,7 @@ esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_l
*/
esp_err_t adc_digi_deinitialize(void);
#endif //#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#endif //#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684
#ifdef __cplusplus
}

View File

@ -35,6 +35,8 @@
#include "esp32s3/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/gpio.h"
#endif
#ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS

View File

@ -53,7 +53,7 @@ typedef struct {
} timer_obj_t;
static timer_obj_t *p_timer_obj[TIMER_GROUP_MAX][TIMER_MAX] = {0};
static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED};
static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = { [0 ... TIMER_GROUP_MAX - 1] = portMUX_INITIALIZER_UNLOCKED, };
esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *timer_val)
{

View File

@ -35,6 +35,8 @@
#include "esp32c3/clk.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/clk.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp_private/esp_clk.h"
#endif
#ifdef CONFIG_UART_ISR_IN_IRAM

View File

@ -486,7 +486,8 @@ def main():
global idf_target
parser = argparse.ArgumentParser(description='ESP32 eFuse Manager')
parser.add_argument('--idf_target', '-t', help='Target chip type', choices=['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32h2'], default='esp32')
parser.add_argument('--idf_target', '-t', help='Target chip type', choices=['esp32', 'esp32s2', 'esp32s3', 'esp32c3',
'esp32h2', 'esp8684'], default='esp32')
parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true')
parser.add_argument('--debug', help='Create header file with debug info', default=False, action='store_false')
parser.add_argument('--info', help='Print info about range of used bits', default=False, action='store_true')

View File

@ -0,0 +1,54 @@
/*
* SPDX-FileCopyrightText: 2017-2021 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 "esp8684/rom/efuse.h"
#include "assert.h"
#include "esp_err.h"
#include "esp_log.h"
#include "soc/efuse_periph.h"
#include "bootloader_random.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 version from efuse
uint8_t esp_efuse_get_chip_ver(void)
{
uint32_t chip_ver = 0;
esp_efuse_read_field_blob(ESP_EFUSE_WAFER_VERSION, &chip_ver, ESP_EFUSE_WAFER_VERSION[0]->bit_count);
return chip_ver;
}
// 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)
{
abort();
}
esp_err_t esp_efuse_disable_rom_download_mode(void)
{
abort();
}
esp_err_t esp_efuse_enable_rom_secure_download_mode(void)
{
abort();
}

View File

@ -0,0 +1,390 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_efuse.h"
#include <assert.h>
#include "esp_efuse_table.h"
// md5_digest_table 3bf086fa10d850cbaeccbd70fcba1c2f
// 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, 8}, // Write protection,
};
static const esp_efuse_desc_t WR_DIS_KEY0_RD_DIS[] = {
{EFUSE_BLK0, 0, 1}, // Write protection for KEY0_RD_DIS,
};
static const esp_efuse_desc_t WR_DIS_GROUP_1[] = {
{EFUSE_BLK0, 1, 1}, // Write protection for WDT_DELAY DIS_PAD_JTAG,
};
static const esp_efuse_desc_t WR_DIS_GROUP_2[] = {
{EFUSE_BLK0, 2, 1}, // Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_ENCRYPT_DECRYPT_CNT XTS_KEY_LENGTH_256,
};
static const esp_efuse_desc_t WR_DIS_GROUP_3[] = {
{EFUSE_BLK0, 3, 1}, // Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW SECURE_BOOT_EN,
};
static const esp_efuse_desc_t WR_DIS_BLK0_RESERVED[] = {
{EFUSE_BLK0, 4, 1}, // Write protection for BLK0_RESERVED,
};
static const esp_efuse_desc_t WR_DIS_SYS_DATA_PART0[] = {
{EFUSE_BLK0, 5, 1}, // Write protection for EFUSE_BLK1. SYS_DATA_PART0,
};
static const esp_efuse_desc_t WR_DIS_SYS_DATA_PART1[] = {
{EFUSE_BLK0, 6, 1}, // Write protection for EFUSE_BLK2. SYS_DATA_PART2,
};
static const esp_efuse_desc_t WR_DIS_KEY0[] = {
{EFUSE_BLK0, 7, 1}, // Write protection for EFUSE_BLK3. KEY0,
};
static const esp_efuse_desc_t RD_DIS[] = {
{EFUSE_BLK0, 8, 2}, // Read protection,
};
static const esp_efuse_desc_t RD_DIS_KEY0[] = {
{EFUSE_BLK0, 32, 2}, // Read protection for EFUSE_BLK3. KEY0,
};
static const esp_efuse_desc_t WDT_DELAY_SEL[] = {
{EFUSE_BLK0, 34, 2}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t DIS_PAD_JTAG[] = {
{EFUSE_BLK0, 36, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t EFUSE_DIS_DOWNLOAD_ICACHE[] = {
{EFUSE_BLK0, 37, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
{EFUSE_BLK0, 38, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t SPI_BOOT_ENCRYPT_DECRYPT_CNT[] = {
{EFUSE_BLK0, 39, 3}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t XTS_KEY_LENGTH_256[] = {
{EFUSE_BLK0, 42, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t UART_PRINT_CONTROL[] = {
{EFUSE_BLK0, 43, 2}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t FORCE_SEND_RESUME[] = {
{EFUSE_BLK0, 45, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t DIS_DOWNLOAD_MODE[] = {
{EFUSE_BLK0, 46, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t DIS_DIRECT_BOOT[] = {
{EFUSE_BLK0, 47, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t ENABLE_SECURITY_DOWNLOAD[] = {
{EFUSE_BLK0, 48, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t FLASH_TPUW[] = {
{EFUSE_BLK0, 49, 4}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t SECURE_BOOT_EN[] = {
{EFUSE_BLK0, 53, 1}, // /* TODO: Need Description*/,
};
static const esp_efuse_desc_t SYSTEM_DATA0[] = {
{EFUSE_BLK1, 0, 32}, // EFUSE_SYSTEM_DATA0,
};
static const esp_efuse_desc_t SYSTEM_DATA1[] = {
{EFUSE_BLK1, 32, 32}, // EFUSE_SYSTEM_DATA1,
};
static const esp_efuse_desc_t SYSTEM_DATA2[] = {
{EFUSE_BLK1, 64, 23}, // EFUSE_SYSTEM_DATA2,
};
static const esp_efuse_desc_t MAC_FACTORY[] = {
{EFUSE_BLK2, 40, 8}, // Factory MAC addr [0],
{EFUSE_BLK2, 32, 8}, // Factory MAC addr [1],
{EFUSE_BLK2, 24, 8}, // Factory MAC addr [2],
{EFUSE_BLK2, 16, 8}, // Factory MAC addr [3],
{EFUSE_BLK2, 8, 8}, // Factory MAC addr [4],
{EFUSE_BLK2, 0, 8}, // Factory MAC addr [5],
};
static const esp_efuse_desc_t WAFER_VERSION[] = {
{EFUSE_BLK2, 48, 3}, // EFUSE_WAFER_VERSION,
};
static const esp_efuse_desc_t PKG_VERSION[] = {
{EFUSE_BLK2, 51, 3}, // EFUSE_PKG_VERSION,
};
static const esp_efuse_desc_t BLOCK2_VERSION[] = {
{EFUSE_BLK2, 54, 3}, // EFUSE_BLOCK2_VERSION,
};
static const esp_efuse_desc_t RF_REF_I_BIAS_CONFIG[] = {
{EFUSE_BLK2, 57, 4}, // EFUSE_RF_REF_I_BIAS_CONFIG,
};
static const esp_efuse_desc_t LDO_VOL_BIAS_CONFIG_LOW[] = {
{EFUSE_BLK2, 61, 3}, // EFUSE_LDO_VOL_BIAS_CONFIG_LOW,
};
static const esp_efuse_desc_t LDO_VOL_BIAS_CONFIG_HIGH[] = {
{EFUSE_BLK2, 64, 27}, // EFUSE_LDO_VOL_BIAS_CONFIG_HIGH,
};
static const esp_efuse_desc_t PVT_LOW[] = {
{EFUSE_BLK2, 91, 5}, // EFUSE_PVT_LOW,
};
static const esp_efuse_desc_t PVT_HIGH[] = {
{EFUSE_BLK2, 96, 10}, // EFUSE_PVT_HIGH,
};
static const esp_efuse_desc_t ADC_CALIBRATION_0[] = {
{EFUSE_BLK2, 106, 22}, // EFUSE_ADC_CALIBRATION_0,
};
static const esp_efuse_desc_t ADC_CALIBRATION_1[] = {
{EFUSE_BLK2, 128, 32}, // EFUSE_ADC_CALIBRATION_1,
};
static const esp_efuse_desc_t ADC_CALIBRATION_2[] = {
{EFUSE_BLK2, 160, 32}, // EFUSE_ADC_CALIBRATION_2,
};
static const esp_efuse_desc_t KEY0[] = {
{EFUSE_BLK3, 0, 256}, // Key0 or user data,
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS[] = {
&WR_DIS[0], // Write protection
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0_RD_DIS[] = {
&WR_DIS_KEY0_RD_DIS[0], // Write protection for KEY0_RD_DIS
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_1[] = {
&WR_DIS_GROUP_1[0], // Write protection for WDT_DELAY DIS_PAD_JTAG
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_2[] = {
&WR_DIS_GROUP_2[0], // Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_ENCRYPT_DECRYPT_CNT XTS_KEY_LENGTH_256
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_3[] = {
&WR_DIS_GROUP_3[0], // Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW SECURE_BOOT_EN
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK0_RESERVED[] = {
&WR_DIS_BLK0_RESERVED[0], // Write protection for BLK0_RESERVED
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART0[] = {
&WR_DIS_SYS_DATA_PART0[0], // Write protection for EFUSE_BLK1. SYS_DATA_PART0
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[] = {
&WR_DIS_SYS_DATA_PART1[0], // Write protection for EFUSE_BLK2. SYS_DATA_PART2
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0[] = {
&WR_DIS_KEY0[0], // Write protection for EFUSE_BLK3. KEY0
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[] = {
&RD_DIS[0], // Read protection
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0[] = {
&RD_DIS_KEY0[0], // Read protection for EFUSE_BLK3. KEY0
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[] = {
&WDT_DELAY_SEL[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[] = {
&DIS_PAD_JTAG[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_EFUSE_DIS_DOWNLOAD_ICACHE[] = {
&EFUSE_DIS_DOWNLOAD_ICACHE[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
&DIS_DOWNLOAD_MANUAL_ENCRYPT[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_ENCRYPT_DECRYPT_CNT[] = {
&SPI_BOOT_ENCRYPT_DECRYPT_CNT[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_XTS_KEY_LENGTH_256[] = {
&XTS_KEY_LENGTH_256[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[] = {
&UART_PRINT_CONTROL[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[] = {
&FORCE_SEND_RESUME[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[] = {
&DIS_DOWNLOAD_MODE[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[] = {
&DIS_DIRECT_BOOT[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[] = {
&ENABLE_SECURITY_DOWNLOAD[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[] = {
&FLASH_TPUW[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[] = {
&SECURE_BOOT_EN[0], // /* TODO: Need Description*/
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_SYSTEM_DATA0[] = {
&SYSTEM_DATA0[0], // EFUSE_SYSTEM_DATA0
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_SYSTEM_DATA1[] = {
&SYSTEM_DATA1[0], // EFUSE_SYSTEM_DATA1
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_SYSTEM_DATA2[] = {
&SYSTEM_DATA2[0], // EFUSE_SYSTEM_DATA2
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[] = {
&MAC_FACTORY[0], // Factory MAC addr [0]
&MAC_FACTORY[1], // Factory MAC addr [1]
&MAC_FACTORY[2], // Factory MAC addr [2]
&MAC_FACTORY[3], // Factory MAC addr [3]
&MAC_FACTORY[4], // Factory MAC addr [4]
&MAC_FACTORY[5], // Factory MAC addr [5]
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION[] = {
&WAFER_VERSION[0], // EFUSE_WAFER_VERSION
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[] = {
&PKG_VERSION[0], // EFUSE_PKG_VERSION
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[] = {
&BLOCK2_VERSION[0], // EFUSE_BLOCK2_VERSION
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RF_REF_I_BIAS_CONFIG[] = {
&RF_REF_I_BIAS_CONFIG[0], // EFUSE_RF_REF_I_BIAS_CONFIG
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_LDO_VOL_BIAS_CONFIG_LOW[] = {
&LDO_VOL_BIAS_CONFIG_LOW[0], // EFUSE_LDO_VOL_BIAS_CONFIG_LOW
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_LDO_VOL_BIAS_CONFIG_HIGH[] = {
&LDO_VOL_BIAS_CONFIG_HIGH[0], // EFUSE_LDO_VOL_BIAS_CONFIG_HIGH
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_PVT_LOW[] = {
&PVT_LOW[0], // EFUSE_PVT_LOW
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_PVT_HIGH[] = {
&PVT_HIGH[0], // EFUSE_PVT_HIGH
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_0[] = {
&ADC_CALIBRATION_0[0], // EFUSE_ADC_CALIBRATION_0
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_1[] = {
&ADC_CALIBRATION_1[0], // EFUSE_ADC_CALIBRATION_1
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_2[] = {
&ADC_CALIBRATION_2[0], // EFUSE_ADC_CALIBRATION_2
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_KEY0[] = {
&KEY0[0], // Key0 or user data
NULL
};

View File

@ -0,0 +1,82 @@
# field_name, | efuse_block, | bit_start, | bit_count, |comment #
# | (EFUSE_BLK0 | (0..255) | (1..-) | #
# | EFUSE_BLK1 | |MAX_BLK_LEN*| #
# | ... | | | #
# | EFUSE_BLK10)| | | #
##########################################################################
# *) The value MAX_BLK_LEN depends on CONFIG_EFUSE_MAX_BLK_LEN, will be replaced with "None" - 256. "3/4" - 192. "REPEAT" - 128.
# !!!!!!!!!!! #
# After editing this file, run the command manually "make efuse_common_table" or "idf.py efuse_common_table"
# this will generate new source files, next rebuild all the sources.
# !!!!!!!!!!! #
# EFUSE_RD_REPEAT_DATA BLOCK #
##############################
# EFUSE_RD_WR_DIS_REG #
WR_DIS, EFUSE_BLK0, 0, 8, Write protection
WR_DIS.KEY0_RD_DIS, EFUSE_BLK0, 0, 1, Write protection for KEY0_RD_DIS
WR_DIS.GROUP_1, EFUSE_BLK0, 1, 1, Write protection for WDT_DELAY DIS_PAD_JTAG
WR_DIS.GROUP_2, EFUSE_BLK0, 2, 1, Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_ENCRYPT_DECRYPT_CNT XTS_KEY_LENGTH_256
WR_DIS.GROUP_3, EFUSE_BLK0, 3, 1, Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW SECURE_BOOT_EN
WR_DIS.BLK0_RESERVED, EFUSE_BLK0, 4, 1, Write protection for BLK0_RESERVED
WR_DIS.SYS_DATA_PART0, EFUSE_BLK0, 5, 1, Write protection for EFUSE_BLK1. SYS_DATA_PART0
WR_DIS.SYS_DATA_PART1, EFUSE_BLK0, 6, 1, Write protection for EFUSE_BLK2. SYS_DATA_PART2
WR_DIS.KEY0, EFUSE_BLK0, 7, 1, Write protection for EFUSE_BLK3. KEY0
# EFUSE_RD_REPEAT_DATA0_REG #
RD_DIS, EFUSE_BLK0, 8, 2, Read protection
RD_DIS.KEY0, EFUSE_BLK0, 8, 2, Read protection for EFUSE_BLK3. KEY0
WDT_DELAY_SEL, EFUSE_BLK0, 10, 2, /* TODO: Need Description*/
DIS_PAD_JTAG, EFUSE_BLK0, 12, 1, /* TODO: Need Description*/
EFUSE_DIS_DOWNLOAD_ICACHE, EFUSE_BLK0, 13, 1, /* TODO: Need Description*/
DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 14, 1, /* TODO: Need Description*/
SPI_BOOT_ENCRYPT_DECRYPT_CNT, EFUSE_BLK0, 15, 3, /* TODO: Need Description*/
XTS_KEY_LENGTH_256, EFUSE_BLK0, 18, 1, /* TODO: Need Description*/
UART_PRINT_CONTROL, EFUSE_BLK0, 19, 2, /* TODO: Need Description*/
FORCE_SEND_RESUME, EFUSE_BLK0, 21, 1, /* TODO: Need Description*/
DIS_DOWNLOAD_MODE, EFUSE_BLK0, 22, 1, /* TODO: Need Description*/
DIS_DIRECT_BOOT, EFUSE_BLK0, 23, 1, /* TODO: Need Description*/
ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 24, 1, /* TODO: Need Description*/
FLASH_TPUW, EFUSE_BLK0, 25, 4, /* TODO: Need Description*/
SECURE_BOOT_EN, EFUSE_BLK0, 29, 1, /* TODO: Need Description*/
# SYS_DATA_PART0 BLOCK# - System configuration
#######################
SYSTEM_DATA0, EFUSE_BLK1, 0, 32, EFUSE_SYSTEM_DATA0
SYSTEM_DATA1, EFUSE_BLK1, 32, 32, EFUSE_SYSTEM_DATA1
SYSTEM_DATA2, EFUSE_BLK1, 64, 23, EFUSE_SYSTEM_DATA2
# SYS_DATA_PART1 BLOCK# - System configuration
#######################
MAC_FACTORY, EFUSE_BLK2, 40, 8, Factory MAC addr [0]
, EFUSE_BLK2, 32, 8, Factory MAC addr [1]
, EFUSE_BLK2, 24, 8, Factory MAC addr [2]
, EFUSE_BLK2, 16, 8, Factory MAC addr [3]
, EFUSE_BLK2, 8, 8, Factory MAC addr [4]
, EFUSE_BLK2, 0, 8, Factory MAC addr [5]
WAFER_VERSION, EFUSE_BLK2, 48, 3, EFUSE_WAFER_VERSION
PKG_VERSION, EFUSE_BLK2, 51, 3, EFUSE_PKG_VERSION
BLOCK2_VERSION, EFUSE_BLK2, 54, 3, EFUSE_BLOCK2_VERSION
RF_REF_I_BIAS_CONFIG, EFUSE_BLK2, 57, 4, EFUSE_RF_REF_I_BIAS_CONFIG
LDO_VOL_BIAS_CONFIG_LOW, EFUSE_BLK2, 61, 3, EFUSE_LDO_VOL_BIAS_CONFIG_LOW
LDO_VOL_BIAS_CONFIG_HIGH, EFUSE_BLK2, 64, 27, EFUSE_LDO_VOL_BIAS_CONFIG_HIGH
PVT_LOW, EFUSE_BLK2, 91, 5, EFUSE_PVT_LOW
PVT_HIGH, EFUSE_BLK2, 96, 10, EFUSE_PVT_HIGH
ADC_CALIBRATION_0, EFUSE_BLK2, 106, 22, EFUSE_ADC_CALIBRATION_0
ADC_CALIBRATION_1, EFUSE_BLK2, 128, 32, EFUSE_ADC_CALIBRATION_1
ADC_CALIBRATION_2, EFUSE_BLK2, 160, 32, EFUSE_ADC_CALIBRATION_2
################
KEY0, EFUSE_BLK3, 0, 256, [256bit FE key] or [128bit FE key and 128key SB key] or [user data]
KEY0.FLASH_ENCRYPTION EFUSE_BLK3, 0, 256, [256bit FE key]
KEY0.FLASH_ENCRYPTION_128 EFUSE_BLK3, 0, 128, [128bit FE key]
KEY0.SECURE_BOOT_128 EFUSE_BLK3, 128, 256, [128bit SB key]
Can't render this file because it contains an unexpected character in line 7 and column 87.

View File

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "assert.h"
#include "esp_efuse_utility.h"
#include "soc/efuse_periph.h"
#include "esp_private/esp_clk.h"
#include "esp8684/rom/efuse.h"
/*Range addresses to read blocks*/
const esp_efuse_range_addr_t range_read_addr_blocks[] = {
{EFUSE_RD_WR_DIS_REG, EFUSE_RD_REPEAT_DATA0_REG}, // range address of EFUSE_BLK0 REPEAT
{EFUSE_RD_BLK1_DATA0_REG, EFUSE_RD_BLK1_DATA2_REG}, // range address of EFUSE_BLK1 SYS_DATA_PART0
{EFUSE_RD_BLK2_DATA0_REG, EFUSE_RD_BLK2_DATA7_REG}, // range address of EFUSE_BLK2 SYS_DATA_PART_1
{EFUSE_RD_BLK3_DATA0_REG, EFUSE_RD_BLK3_DATA7_REG}, // range address of EFUSE_BLK3 KEY0
};
// Efuse read operation: copies data from physical efuses to efuse read registers.
void esp_efuse_utility_clear_program_registers(void)
{
abort();
}
// Burn values written to the efuse write registers
void esp_efuse_utility_burn_chip(void)
{
abort();
}
// 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()
{
abort();
}

View File

@ -0,0 +1,54 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of eFuse blocks ESP8684
*/
typedef enum {
EFUSE_BLK0 = 0, /**< Number of eFuse BLOCK0. REPEAT_DATA */
EFUSE_BLK1 = 1, /**< Number of eFuse BLOCK1. SYS_DATA_PART0 */
EFUSE_BLK_SYS_DATA_PART0 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART0 */
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. KEY0*/
EFUSE_BLK_KEY0 = 3, /**< Number of eFuse BLOCK3. KEY0*/
EFUSE_BLK_KEY_MAX = 4,
EFUSE_BLK_MAX = 4,
} 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;
/** For ESP8684, there's no key purpose region for efuse keys, In order to maintain
* compatibility with the previous apis, we should set the parameter of 'ets_efuse_purpose_t'
* as default value ETS_EFUSE_KEY_PURPOSE_INVALID.
* (In fact, this parameter can be any value, the api in the rom will not process key_purpose region)
*/
typedef enum {
ESP_EFUSE_KEY_PURPOSE_INVALID = -1,
ESP_EFUSE_KEY_PURPOSE_USER = 0,
ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION = 1,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V1 = 2,
} esp_efuse_purpose_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
// md5_digest_table 3f91b5a37afbcdf1379820626a92e69c
// 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_GROUP_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_2[];
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_KEY0_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY1_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY2_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY3_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY4_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY5_PURPOSE[];
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_GROUP_3[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_USER_DATA[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY2[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY3[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY4[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY5[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART2[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY1[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY2[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY3[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY4[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY5[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_SYS_DATA_PART2[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_RTC_RAM_BOOT[];
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_DEVICE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_CAN[];
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_DREFH[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_DREFL[];
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_BTLC_GPIO_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_POWERGLITCH_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_POWER_GLITCH_DSENSE[];
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[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_2[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_3[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_4[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_5[];
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_LEGACY_SPI_BOOT[];
extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_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_PIN_POWER_SELECTION[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TYPE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_PAGE_SIZE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_EN[];
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_MAC_FACTORY[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CLK[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_Q_D1[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D_D0[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CS[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_HD_D3[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_WP_D2[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_DQS[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D4[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D5[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D6[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[];
extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK1_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[];
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_USER_DATA[];
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY2[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY3[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY4[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY5[];
extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART2[];
extern const esp_efuse_desc_t* ESP_EFUSE_K_RTC_LDO[];
extern const esp_efuse_desc_t* ESP_EFUSE_K_DIG_LDO[];
extern const esp_efuse_desc_t* ESP_EFUSE_V_RTC_DBIAS20[];
extern const esp_efuse_desc_t* ESP_EFUSE_V_DIG_DBIAS20[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIG_DBIAS_HVT[];
extern const esp_efuse_desc_t* ESP_EFUSE_THRES_HVT[];
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2020-2021 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

View File

@ -0,0 +1,3 @@
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
"esp_efuse_fields.c"
"esp_efuse_utility.c")

View File

@ -27,6 +27,8 @@ extern "C" {
#include "esp32s3/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/secure_boot.h"
#endif
#define ESP_ERR_EFUSE 0x1600 /*!< Base error code for efuse api. */

View File

@ -31,6 +31,9 @@ typedef struct {
} esp_efuse_revokes_t;
const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
#if CONFIG_IDF_TARGET_ESP8684
{ESP_EFUSE_KEY0, NULL, ESP_EFUSE_RD_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0, NULL},
#else
{ESP_EFUSE_KEY0, ESP_EFUSE_KEY_PURPOSE_0, ESP_EFUSE_RD_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0_PURPOSE},
{ESP_EFUSE_KEY1, ESP_EFUSE_KEY_PURPOSE_1, ESP_EFUSE_RD_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1_PURPOSE},
{ESP_EFUSE_KEY2, ESP_EFUSE_KEY_PURPOSE_2, ESP_EFUSE_RD_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2_PURPOSE},
@ -40,14 +43,16 @@ const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
#if 0
{ESP_EFUSE_KEY6, ESP_EFUSE_KEY_PURPOSE_6, ESP_EFUSE_RD_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6_PURPOSE},
#endif
#endif //#if CONFIG_IDF_TARGET_ESP8684
};
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
const esp_efuse_revokes_t s_revoke_table[] = {
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0},
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1},
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2},
};
#endif
bool esp_efuse_block_is_empty(esp_efuse_block_t block)
{
const unsigned blk_len_bit = 256;
@ -71,6 +76,7 @@ bool esp_efuse_block_is_empty(esp_efuse_block_t block)
// Sets a write protection for the whole block.
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
{
#if !CONFIG_IDF_TARGET_ESP8684
if (blk == EFUSE_BLK1) {
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
} else if (blk == EFUSE_BLK2) {
@ -83,7 +89,8 @@ esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
unsigned idx = blk - EFUSE_BLK_KEY0;
return esp_efuse_write_field_cnt(s_table[idx].key_wr_dis, 1);
}
return ESP_ERR_NOT_SUPPORTED;
#endif
return ESP_ERR_NOT_SUPPORTED; // IDF-3818
}
// read protect for blk.
@ -92,9 +99,12 @@ esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
if (blk >= EFUSE_BLK_KEY0 && blk < EFUSE_BLK_KEY_MAX) {
unsigned idx = blk - EFUSE_BLK_KEY0;
return esp_efuse_write_field_cnt(s_table[idx].key_rd_dis, 1);
} else if (blk == EFUSE_BLK10) {
}
#if !CONFIG_IDF_TARGET_ESP8684 // IDF-3818
else if (blk == EFUSE_BLK10) {
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_SYS_DATA_PART2, 1);
}
#endif
return ESP_ERR_NOT_SUPPORTED;
}
@ -161,6 +171,7 @@ esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
return esp_efuse_write_field_bit(s_table[idx].key_wr_dis);
}
#if !CONFIG_IDF_TARGET_ESP8684 // cause esp8684 efuse has no purpose region
esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
{
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
@ -183,6 +194,7 @@ esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t
unsigned idx = block - EFUSE_BLK_KEY0;
return esp_efuse_write_field_blob(s_table[idx].keypurpose, &purpose, s_table[idx].keypurpose[0]->bit_count);
}
#endif //CONFIG_IDF_TARGET_ESP8684
bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
{
@ -244,8 +256,11 @@ bool esp_efuse_key_block_unused(esp_efuse_block_t block)
return false; // Not a key block
}
if (esp_efuse_get_key_purpose(block) != ESP_EFUSE_KEY_PURPOSE_USER ||
if (
#if !CONFIG_IDF_TARGET_ESP8684
esp_efuse_get_key_purpose(block) != ESP_EFUSE_KEY_PURPOSE_USER ||
esp_efuse_get_keypurpose_dis_write(block) ||
#endif
esp_efuse_get_key_dis_read(block) ||
esp_efuse_get_key_dis_write(block)) {
return false; // Block in use!
@ -258,40 +273,19 @@ bool esp_efuse_key_block_unused(esp_efuse_block_t block)
return true; // Unused
}
bool esp_efuse_get_digest_revoke(unsigned num_digest)
{
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke);
}
esp_err_t esp_efuse_set_digest_revoke(unsigned num_digest)
{
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
return ESP_ERR_INVALID_ARG;
}
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke);
}
bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest)
{
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
}
esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest)
{
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
return ESP_ERR_INVALID_ARG;
}
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
}
esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpose, const void *key, size_t key_size_bytes)
{
esp_err_t err = ESP_OK;
#if CONFIG_IDF_TARGET_ESP8684
if (block != EFUSE_BLK_KEY0) {
return ESP_ERR_INVALID_ARG;
}
#else
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX || key_size_bytes > 32 || purpose >= ESP_EFUSE_KEY_PURPOSE_MAX) {
return ESP_ERR_INVALID_ARG;
}
#endif
esp_efuse_batch_write_begin();
@ -301,11 +295,13 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
unsigned idx = block - EFUSE_BLK_KEY0;
ESP_EFUSE_CHK(esp_efuse_write_field_blob(s_table[idx].key, key, key_size_bytes * 8));
ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block));
#if !CONFIG_IDF_TARGET_ESP8684
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 ||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 ||
#endif
#endif //#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL ||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG ||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE ||
@ -314,6 +310,7 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
}
ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose));
ESP_EFUSE_CHK(esp_efuse_set_keypurpose_dis_write(block));
#endif //#if !CONFIG_IDF_TARGET_ESP8684
return esp_efuse_batch_write_commit();
}
err_exit:
@ -354,6 +351,36 @@ err_exit:
return err;
}
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
bool esp_efuse_get_digest_revoke(unsigned num_digest)
{
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke);
}
esp_err_t esp_efuse_set_digest_revoke(unsigned num_digest)
{
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
return ESP_ERR_INVALID_ARG;
}
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke);
}
bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest)
{
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
}
esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest)
{
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
return ESP_ERR_INVALID_ARG;
}
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
}
esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys)
{
bool found = false;
@ -387,3 +414,4 @@ esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *truste
return ESP_OK;
}
#endif //#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY

View File

@ -32,6 +32,8 @@ void esp_efuse_reset(void)
esp_efuse_utility_reset();
}
#if !CONFIG_IDF_TARGET_ESP8684
// IDF-3818
uint32_t esp_efuse_read_secure_version(void)
{
uint32_t secure_version = 0;
@ -73,3 +75,4 @@ esp_err_t esp_efuse_update_secure_version(uint32_t secure_version)
}
return ESP_OK;
}
#endif

View File

@ -0,0 +1,13 @@
idf_build_get_property(target IDF_TARGET)
if(NOT "${target}" STREQUAL "esp8684")
return()
endif()
if(NOT BOOTLOADER_BUILD)
# [refactor-todo] propagate these requirements for compatibility
# remove in the future
set(legacy_reqs driver efuse soc)
endif()
idf_component_register(REQUIRES riscv "${legacy_reqs}"
REQUIRED_IDF_TARGETS esp8684)

220
components/esp8684/Kconfig Normal file
View File

@ -0,0 +1,220 @@
menu "ESP8684-Specific"
visible if IDF_TARGET_ESP8684
choice ESP8684_DEFAULT_CPU_FREQ_MHZ
prompt "CPU frequency"
default ESP8684_DEFAULT_CPU_FREQ_40 if IDF_ENV_FPGA
default ESP8684_DEFAULT_CPU_FREQ_120 if !IDF_ENV_FPGA
help
CPU frequency to be set on application startup.
config ESP8684_DEFAULT_CPU_FREQ_40
bool "40 MHz"
depends on IDF_ENV_FPGA
config ESP8684_DEFAULT_CPU_FREQ_80
bool "80 MHz"
config ESP8684_DEFAULT_CPU_FREQ_120
bool "120 MHz"
config ESP8684_DEFAULT_CPU_FREQ_160
bool "160 MHz"
endchoice
config ESP8684_DEFAULT_CPU_FREQ_MHZ
int
default 40 if ESP8684_DEFAULT_CPU_FREQ_40
default 80 if ESP8684_DEFAULT_CPU_FREQ_80
default 120 if ESP8684_DEFAULT_CPU_FREQ_120
default 160 if ESP8684_DEFAULT_CPU_FREQ_160
menu "Cache config"
choice ESP8684_MMU_PAGE_SIZE
# TODO: IDF-3821
prompt "Cache page size"
default ESP8684_MMU_PAGE_SIZE_64KB
help
Cache page size to be set on application startup
config ESP8684_MMU_PAGE_SIZE_16KB
bool "16KB"
config ESP8684_MMU_PAGE_SIZE_32KB
bool "32KB"
config ESP8684_MMU_PAGE_SIZE_64KB
bool "64KB"
endchoice
config ESP8684_INSTRUCTION_CACHE_WRAP
bool
prompt "Instruction cache wrap"
help
If enabled, instruction cache will use wrap mode to read spi flash.
The wrap length is fixed to 32B
config ESP8684_MMU_PAGE_MODE
int
default 0 if ESP8684_MMU_PAGE_SIZE_16KB
default 1 if ESP8684_MMU_PAGE_SIZE_32KB
default 2 if ESP8684_MMU_PAGE_SIZE_64KB
endmenu
config ESP8684_DEBUG_OCDAWARE
bool "Make exception and panic handlers JTAG/OCD aware"
default y
select FREERTOS_DEBUG_OCDAWARE
help
The FreeRTOS panic and unhandled exception handers can detect a JTAG OCD debugger and
instead of panicking, have the debugger stop on the offending instruction.
config ESP8684_DEBUG_STUBS_ENABLE
bool "OpenOCD debug stubs"
default COMPILER_OPTIMIZATION_LEVEL_DEBUG
depends on !ESP8684_TRAX
help
Debug stubs are used by OpenOCD to execute pre-compiled onboard code which does some useful debugging,
e.g. GCOV data dump.
config ESP8684_BROWNOUT_DET
bool "Hardware brownout detect & reset"
default y
help
The ESP8684 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 ESP8684_BROWNOUT_DET_LVL_SEL
prompt "Brownout voltage level"
depends on ESP8684_BROWNOUT_DET
default ESP8684_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 ESP8684_BROWNOUT_DET_LVL_SEL_7
bool "2.51V"
config ESP8684_BROWNOUT_DET_LVL_SEL_6
bool "2.64V"
config ESP8684_BROWNOUT_DET_LVL_SEL_5
bool "2.76V"
config ESP8684_BROWNOUT_DET_LVL_SEL_4
bool "2.92V"
config ESP8684_BROWNOUT_DET_LVL_SEL_3
bool "3.10V"
config ESP8684_BROWNOUT_DET_LVL_SEL_2
bool "3.27V"
endchoice
config ESP8684_BROWNOUT_DET_LVL
int
default 2 if ESP8684_BROWNOUT_DET_LVL_SEL_2
default 3 if ESP8684_BROWNOUT_DET_LVL_SEL_3
default 4 if ESP8684_BROWNOUT_DET_LVL_SEL_4
default 5 if ESP8684_BROWNOUT_DET_LVL_SEL_5
default 6 if ESP8684_BROWNOUT_DET_LVL_SEL_6
default 7 if ESP8684_BROWNOUT_DET_LVL_SEL_7
choice ESP8684_TIME_SYSCALL
prompt "Timers used for gettimeofday function"
default ESP8684_TIME_SYSCALL_USE_RTC_SYSTIMER
help
This setting defines which hardware timers are used to
implement 'gettimeofday' and 'time' functions in C library.
- If both high-resolution (systimer) and RTC timers are used, timekeeping will
continue in deep sleep. Time will be reported at 1 microsecond
resolution. This is the default, and the recommended option.
- If only high-resolution timer (systimer) is used, gettimeofday will
provide time at microsecond resolution.
Time will not be preserved when going into deep sleep mode.
- If only RTC timer is used, timekeeping will continue in
deep sleep, but time will be measured at 6.(6) microsecond
resolution. Also the gettimeofday function itself may take
longer to run.
- If no timers are used, gettimeofday and time functions
return -1 and set errno to ENOSYS.
- When RTC is used for timekeeping, two RTC_STORE registers are
used to keep time in deep sleep mode.
config ESP8684_TIME_SYSCALL_USE_RTC_SYSTIMER
bool "RTC and high-resolution timer"
select ESP_TIME_FUNCS_USE_RTC_TIMER
select ESP_TIME_FUNCS_USE_ESP_TIMER
config ESP8684_TIME_SYSCALL_USE_RTC
bool "RTC"
select ESP_TIME_FUNCS_USE_RTC_TIMER
config ESP8684_TIME_SYSCALL_USE_SYSTIMER
bool "High-resolution timer"
select ESP_TIME_FUNCS_USE_ESP_TIMER
config ESP8684_TIME_SYSCALL_USE_NONE
bool "None"
select ESP_TIME_FUNCS_USE_NONE
endchoice
choice ESP8684_RTC_CLK_SRC
prompt "RTC clock source"
default ESP8684_RTC_CLK_SRC_INT_RC
help
Choose which clock is used as RTC clock source.
config ESP8684_RTC_CLK_SRC_INT_RC
bool "Internal 150kHz RC oscillator"
config ESP8684_RTC_CLK_SRC_EXT_OSC
bool "External 32kHz oscillator at 32K_XP pin"
config ESP8684_RTC_CLK_SRC_INT_8MD256
bool "Internal 8MHz oscillator, divided by 256 (~32kHz)"
endchoice
config ESP8684_RTC_CLK_CAL_CYCLES
int "Number of cycles for RTC_SLOW_CLK calibration"
default 3000 if ESP8684_RTC_CLK_SRC_EXT_CRYS || ESP8684_RTC_CLK_SRC_EXT_OSC || ESP8684_RTC_CLK_SRC_INT_8MD256
default 1024 if ESP8684_RTC_CLK_SRC_INT_RC
range 0 27000 if ESP8684_RTC_CLK_SRC_EXT_CRYS || ESP8684_RTC_CLK_SRC_EXT_OSC || ESP8684_RTC_CLK_SRC_INT_8MD256
range 0 32766 if ESP8684_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:
- 150000 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.
config ESP8684_NO_BLOBS
bool "No Binary Blobs"
depends on !BT_ENABLED
default n
help
If enabled, this disables the linking of binary libraries in the application build. Note
that after enabling this Wi-Fi/Bluetooth will not work.
config ESP8684_LIGHTSLEEP_GPIO_RESET_WORKAROUND # IDF-3904
bool "light sleep GPIO reset workaround"
default y
select PM_SLP_DISABLE_GPIO if FREERTOS_USE_TICKLESS_IDLE
help
ESP8684 will reset at wake-up if GPIO is received a small electrostatic pulse during
light sleep, with specific condition
- GPIO needs to be configured as input-mode only
- The pin receives a small electrostatic pulse, and reset occurs when the pulse
voltage is higher than 6 V
For GPIO set to input mode only, it is not a good practice to leave it open/floating,
The hardware design needs to controlled it with determined supply or ground voltage
is necessary.
This option provides a software workaround for this issue. Configure to isolate all
GPIO pins in sleep state.
endmenu # ESP8684-Specific

View File

@ -0,0 +1 @@
# ESP8684 is not supported in the GNU Make build system.

View File

@ -0,0 +1,4 @@
#
# Component Makefile
#
COMPONENT_CONFIG_ONLY := 1

View File

@ -0,0 +1,5 @@
set(compile_options "-Wno-error=format="
"-nostartfiles"
"-Wno-format")
idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND)

View File

@ -3,4 +3,4 @@
#
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o esp_adc_cal_esp32c3.o esp_adc_cal_esp32h2.o esp_adc_cal_esp32s3.o
COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o esp_adc_cal_esp32c3.o esp_adc_cal_esp32h2.o esp_adc_cal_esp32s3.o esp_adc_cal_esp8684.o

View File

@ -1,17 +1,9 @@
// Copyright 2015-2016 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: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_ATTR_H__
#define __ESP_ATTR_H__

View File

@ -1,11 +1,13 @@
idf_build_get_property(target IDF_TARGET)
if(NOT "${target}" STREQUAL "esp8684") # TODO: IDF-4135
idf_component_register(SRCS "src/gdbstub.c" "src/packet.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
LDFRAGMENTS "linker.lf"
REQUIRES "freertos"
PRIV_REQUIRES "soc" "esp_rom")
endif()
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
target_include_directories(${COMPONENT_LIB} PUBLIC "xtensa" "${target}")

View File

@ -0,0 +1,86 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/uart_periph.h"
#include "soc/gpio_periph.h"
#include "soc/soc.h"
#include "esp_gdbstub_common.h"
#include "sdkconfig.h"
#define UART_NUM CONFIG_ESP_CONSOLE_UART_NUM
#define GDBSTUB_MEM_REGION_COUNT 9
#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},
// RTC DRAM and RTC DATA are identical with RTC IRAM, hence we skip them
// We shouldn't read the uart registers since it will disturb the debugging via UART,
// so skip UART part of the peripheral registers.
{DR_REG_UART_BASE + UART_REG_FIELD_LEN, SOC_PERIPHERAL_HIGH},
{SOC_DEBUG_LOW, SOC_DEBUG_HIGH},
};
static inline bool check_inside_valid_region(intptr_t addr)
{
for (size_t 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()
{
}
//assume UART gdbstub channel
int esp_gdbstub_getchar()
{
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()
{
//not needed for uart
}
int esp_gdbstub_readmem(intptr_t addr)
{
if (!check_inside_valid_region(addr)) {
/* see esp_cpu_configure_region_protection */
return -1;
}
uint32_t val_aligned = *(uint32_t *)(addr & (~3));
uint32_t shift = (addr & 3) * 8;
return (val_aligned >> shift) & 0xff;
}

View File

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once

View File

@ -1,16 +1,8 @@
// Copyright 2015-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: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_gdbstub.h"

View File

@ -39,7 +39,7 @@ static int md5_printf(char *md, const char *fmt, ...)
unsigned char *buf;
unsigned char digest[MD5_MAX_LEN];
int len, i;
struct MD5Context md5_ctx;
md5_context_t md5_ctx;
va_list ap;
va_start(ap, fmt);
len = vasprintf((char **)&buf, fmt, ap);

View File

@ -74,7 +74,8 @@ bool IRAM_ATTR esp_cpu_in_ocd_debug_mode(void)
CONFIG_ESP32S2_DEBUG_OCDAWARE || \
CONFIG_ESP32S3_DEBUG_OCDAWARE || \
CONFIG_ESP32C3_DEBUG_OCDAWARE || \
CONFIG_ESP32H2_DEBUG_OCDAWARE
CONFIG_ESP32H2_DEBUG_OCDAWARE || \
CONFIG_ESP8684_DEBUG_OCDAWARE
return cpu_ll_is_debugger_attached();
#else
return false; // Always return false if "OCD aware" is disabled

View File

@ -10,6 +10,8 @@
#include "esp_attr.h"
#include "soc/rtc.h"
#include "soc/soc_caps.h"
#include "esp_rom_caps.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/rtc.h"
@ -32,6 +34,10 @@
#include "esp32h2/rom/rtc.h"
#include "esp32h2/clk.h"
#include "esp32h2/rtc.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/rtc.h"
#include "esp_private/esp_clk.h"
#include "esp8684/rtc.h"
#endif
#define MHZ (1000000)
@ -45,11 +51,13 @@ extern uint32_t g_ticks_per_us_app;
#endif
static _lock_t s_esp_rtc_time_lock;
// TODO: IDF-4239
static RTC_DATA_ATTR uint64_t s_esp_rtc_time_us = 0, s_rtc_last_ticks = 0;
inline static int IRAM_ATTR s_get_cpu_freq_mhz(void)
{
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
#if ESP_ROM_GET_CLK_FREQ
return ets_get_cpu_frequency();
#else
return g_ticks_per_us_pro;
@ -71,7 +79,7 @@ int IRAM_ATTR esp_clk_xtal_freq(void)
return rtc_clk_xtal_freq_get() * MHZ;
}
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP8684
void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us)
{
/* Update scale factors used by esp_rom_delay_us */
@ -86,6 +94,10 @@ void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us)
uint64_t esp_rtc_get_time_us(void)
{
#if !SOC_RTC_FAST_MEM_SUPPORTED
//IDF-3901
return 0;
#endif
_lock_acquire(&s_esp_rtc_time_lock);
const uint32_t cal = esp_clk_slowclk_cal_get();
const uint64_t rtc_this_ticks = rtc_time_get();

View File

@ -23,6 +23,8 @@
#include "esp32c3/clk.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/clk.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp_private/esp_clk.h"
#endif
uint32_t IRAM_ATTR esp_random(void)

View File

@ -25,6 +25,7 @@ typedef enum {
CHIP_ESP32S3 = 9, //!< ESP32-S3
CHIP_ESP32C3 = 5, //!< ESP32-C3
CHIP_ESP32H2 = 6, //!< ESP32-H2
CHIP_ESP8684 = 12, //!< ESP-8684
} esp_chip_model_t;
/* Chip feature flags, used in esp_chip_info_t */

View File

@ -34,6 +34,8 @@ typedef enum {
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP32C3_UNIVERSAL_MAC_ADDRESSES
#elif CONFIG_IDF_TARGET_ESP32H2
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP32H2_UNIVERSAL_MAC_ADDRESSES
#elif CONFIG_IDF_TARGET_ESP8684
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP8684_UNIVERSAL_MAC_ADDRESSES
#endif
/** @endcond */

View File

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @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);
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrightText: 2015-2021 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);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,448 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* INTERNAL API
* generic interface to PMS memory protection features
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef IRAM_SRAM_START
#define IRAM_SRAM_START 0x4037C000
#endif
#ifndef DRAM_SRAM_START
#define DRAM_SRAM_START 0x3FC7C000
#endif
#ifndef MAP_DRAM_TO_IRAM
#define MAP_DRAM_TO_IRAM(addr) (addr - DRAM_SRAM_START + IRAM_SRAM_START)
#endif
#ifndef MAP_IRAM_TO_DRAM
#define MAP_IRAM_TO_DRAM(addr) (addr - IRAM_SRAM_START + DRAM_SRAM_START)
#endif
typedef enum {
MEMPROT_NONE = 0x00000000,
MEMPROT_IRAM0_SRAM = 0x00000001,
MEMPROT_DRAM0_SRAM = 0x00000002,
MEMPROT_ALL = 0xFFFFFFFF
} mem_type_prot_t;
typedef enum {
MEMPROT_SPLITLINE_NONE = 0,
MEMPROT_IRAM0_DRAM0_SPLITLINE,
MEMPROT_IRAM0_LINE_0_SPLITLINE,
MEMPROT_IRAM0_LINE_1_SPLITLINE,
MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE,
MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE
} split_line_t;
typedef enum {
MEMPROT_PMS_AREA_NONE = 0,
MEMPROT_IRAM0_PMS_AREA_0,
MEMPROT_IRAM0_PMS_AREA_1,
MEMPROT_IRAM0_PMS_AREA_2,
MEMPROT_IRAM0_PMS_AREA_3,
MEMPROT_DRAM0_PMS_AREA_0,
MEMPROT_DRAM0_PMS_AREA_1,
MEMPROT_DRAM0_PMS_AREA_2,
MEMPROT_DRAM0_PMS_AREA_3
} pms_area_t;
typedef enum
{
MEMPROT_PMS_WORLD_0 = 0,
MEMPROT_PMS_WORLD_1,
MEMPROT_PMS_WORLD_2,
MEMPROT_PMS_WORLD_INVALID = 0xFFFFFFFF
} pms_world_t;
typedef enum
{
MEMPROT_PMS_OP_READ = 0,
MEMPROT_PMS_OP_WRITE,
MEMPROT_PMS_OP_FETCH,
MEMPROT_PMS_OP_INVALID = 0xFFFFFFFF
} pms_operation_type_t;
/**
* @brief Converts Memory protection type to string
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
const char *esp_memprot_mem_type_to_str(mem_type_prot_t mem_type);
/**
* @brief Converts Split line type to string
*
* @param line_type Split line type (see split_line_t enum)
*/
const char *esp_memprot_split_line_to_str(split_line_t line_type);
/**
* @brief Converts PMS Area type to string
*
* @param area_type PMS Area type (see pms_area_t enum)
*/
const char *esp_memprot_pms_to_str(pms_area_t area_type);
/**
* @brief Returns PMS splitting address for given Split line type
*
* The value is taken from PMS configuration registers (IRam0 range)
* For details on split lines see 'esp_memprot_set_prot_int' function description
*
* @param line_type Split line type (see split_line_t enum)
*
* @return appropriate split line address
*/
uint32_t *esp_memprot_get_split_addr(split_line_t line_type);
/**
* @brief Returns default main IRAM/DRAM splitting address
*
* The address value is given by _iram_text_end global (IRam0 range)
* @return Main I/D split line (IRam0_DRam0_Split_Addr)
*/
void *esp_memprot_get_default_main_split_addr(void);
/**
* @brief Sets a lock for the main IRAM/DRAM splitting address
*
* Locks can be unlocked only by digital system reset
*/
void esp_memprot_set_split_line_lock(void);
/**
* @brief Gets a lock status for the main IRAM/DRAM splitting address
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_split_line_lock(void);
/**
* @brief Sets required split line address
*
* @param line_type Split line type (see split_line_t enum)
* @param line_addr target address from a memory range relevant to given line_type (IRAM/DRAM)
*/
void esp_memprot_set_split_line(split_line_t line_type, const void *line_addr);
/**
* @brief Sets a lock for PMS Area settings of required Memory type
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_pms_lock(mem_type_prot_t mem_type);
/**
* @brief Gets a lock status for PMS Area settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_pms_lock(mem_type_prot_t mem_type);
/**
* @brief Sets permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
*
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag
* @param w Write permission flag
* @param x Execute permission flag
*/
void esp_memprot_iram_set_pms_area(pms_area_t area_type, bool r, bool w, bool x);
/**
* @brief Gets current permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
*
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag holder
* @param w Write permission flag holder
* @param x Execute permission flag holder
*/
void esp_memprot_iram_get_pms_area(pms_area_t area_type, bool *r, bool *w, bool *x);
/**
* @brief Sets permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
*
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag
* @param w Write permission flag
*/
void esp_memprot_dram_set_pms_area(pms_area_t area_type, bool r, bool w);
/**
* @brief Gets current permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
*
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag holder
* @param w Write permission flag holder
*/
void esp_memprot_dram_get_pms_area(pms_area_t area_type, bool *r, bool *w);
/**
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_monitor_lock(mem_type_prot_t mem_type);
/**
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_monitor_lock(mem_type_prot_t mem_type);
/**
* @brief Enable PMS violation interrupt monitoring of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
* @param enable/disable
*/
void esp_memprot_set_monitor_en(mem_type_prot_t mem_type, bool enable);
/**
* @brief Gets enable/disable status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (enabled/disabled)
*/
bool esp_memprot_get_monitor_en(mem_type_prot_t mem_type);
/**
* @brief Gets CPU ID for currently active PMS violation interrupt
*
* @return CPU ID (CPU_PRO for ESP8684)
*/
int IRAM_ATTR esp_memprot_intr_get_cpuid(void);
/**
* @brief Clears current interrupt ON flag for given Memory type
*
* Interrupt clearing happens in two steps:
* 1. Interrupt CLR flag is set (to clear the interrupt ON status)
* 2. Interrupt CLR flag is reset (to allow further monitoring)
* This operation is non-atomic by PMS module design
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void IRAM_ATTR esp_memprot_monitor_clear_intr(mem_type_prot_t mem_type);
/**
* @brief Returns active PMS violation interrupt (if any)
*
* This function iterates through supported Memory type status registers
* and returns the first interrupt-on flag. If none is found active,
* MEMPROT_NONE is returned.
* Order of checking (in current version):
* 1. MEMPROT_IRAM0_SRAM
* 2. MEMPROT_DRAM0_SRAM
*
* @return mem_type Memory protection type related to active interrupt found (see mem_type_prot_t enum)
*/
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
/**
* @brief Checks whether any violation interrupt is active
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_is_locked_any(void);
/**
* @brief Checks whether any violation interrupt is enabled
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_is_intr_ena_any(void);
/**
* @brief Checks whether any violation interrupt is enabled
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_get_violate_intr_on(mem_type_prot_t mem_type);
/**
* @brief Returns the address which caused the violation interrupt (if any)
*
* The address is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return faulting address
*/
uint32_t IRAM_ATTR esp_memprot_get_violate_addr(mem_type_prot_t mem_type);
/**
* @brief Returns the World identifier of the code causing the violation interrupt (if any)
*
* The value is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return World identifier (see pms_world_t enum)
*/
pms_world_t IRAM_ATTR esp_memprot_get_violate_world(mem_type_prot_t mem_type);
/**
* @brief Returns Read or Write operation type which caused the violation interrupt (if any)
*
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return PMS operation type relevant to mem_type parameter (se pms_operation_type_t)
*/
pms_operation_type_t IRAM_ATTR esp_memprot_get_violate_wr(mem_type_prot_t mem_type);
/**
* @brief Returns LoadStore flag of the operation type which caused the violation interrupt (if any)
*
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
* Effective only on IRam0 access
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (LoadStore bit on/off)
*/
bool IRAM_ATTR esp_memprot_get_violate_loadstore(mem_type_prot_t mem_type);
/**
* @brief Returns byte-enables for the address which caused the violation interrupt (if any)
*
* The value is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return byte-enables
*/
uint32_t IRAM_ATTR esp_memprot_get_violate_byte_en(mem_type_prot_t mem_type);
/**
* @brief Returns raw contents of DRam0 status register 1
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_1(void);
/**
* @brief Returns raw contents of DRam0 status register 2
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_2(void);
/**
* @brief Returns raw contents of IRam0 status register
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_iram_status_reg(void);
/**
* @brief Register PMS violation interrupt in global interrupt matrix for given Memory type
*
* Memory protection components uses specific interrupt number, see ETS_MEMPROT_ERR_INUM
* The registration makes the panic-handler routine being called when the interrupt appears
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_intr_matrix(mem_type_prot_t mem_type);
/**
* @brief Convenient routine for setting the PMS defaults
*
* Called on application startup, depending on CONFIG_ESP_SYSTEM_MEMPROT_FEATURE Kconfig settings
* For implementation details see 'esp_memprot_set_prot_int' description
*
* @param invoke_panic_handler register all interrupts for panic handling (true/false)
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
* @param mem_type_mask 32-bit field of specific PMS parts to configure (see 'esp_memprot_set_prot_int')
*/
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
/**
* @brief Internal routine for setting the PMS defaults
*
* Called on application startup from within 'esp_memprot_set_prot'. Allows setting a specific splitting address
* (main I/D split line) - see the parameter 'split_addr'. If the 'split_addr' equals to NULL, default I/D split line
* is used (&_iram_text_end) and all the remaining lines share the same address.
* The function sets all the split lines and PMS areas to the same space,
* ie there is a single instruction space and single data space at the end.
* The PMS split lines and permission areas scheme described below:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* ... | IRam0_PMS_0 |
* DRam0_PMS_0 ----------------------------------------------- IRam0_line1_Split_addr
* ... | IRam0_PMS_1 |
* ... ----------------------------------------------- IRam0_line0_Split_addr
* | IRam0_PMS_2 |
* =============================================== IRam0_DRam0_Split_addr (main I/D)
* | DRam0_PMS_1 |
* DRam0_DMA_line0_Split_addr ----------------------------------------------- ...
* | DRam0_PMS_2 | ...
* DRam0_DMA_line1_Split_addr ----------------------------------------------- IRam0_PMS_3
* | DRam0_PMS_3 | ...
* -----------------------------------------------
*
* Default settings provided by 'esp_memprot_set_prot_int' are as follows:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
* | DRam0_PMS_0 | IRam0_line1_Split_addr
* DRam0_DMA_line0_Split_addr | | =
* = =============================================== IRam0_line0_Split_addr
* DRam0_DMA_line1_Split_addr | | =
* | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 | IRam0_DRam0_Split_addr (main I/D)
* | IRam0_PMS_3 |
* -----------------------------------------------
*
* Once the memprot feature is locked, it can be unlocked only by digital system reset
*
* @param invoke_panic_handler register all the violation interrupts for panic handling (true/false)
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
* @param split_addr specific main I/D adrees or NULL to use default ($_iram_text_end)
* @param mem_type_mask 32-bit field of specific PMS parts to configure (members of mem_type_prot_t)
*/
void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask);
/**
* @brief Returns raw contents of PMS interrupt monitor register for given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return 32-bit register value
*/
uint32_t esp_memprot_get_monitor_enable_reg(mem_type_prot_t mem_type);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp8684/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

View File

@ -35,6 +35,8 @@
#include "esp32c3/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/rom/ets_sys.h"
#endif
#define SOC_LOGE(tag, fmt, ...) esp_rom_printf("%s(err): " fmt, tag, ##__VA_ARGS__)

View File

@ -453,7 +453,14 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre
//ToDo: if we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region,
//we need to make sure the interrupt is connected to the CPU0.
//CPU1 does not have access to the RTC fast memory through this region.
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) && !esp_ptr_in_rtc_iram_fast(handler)) {
if ((flags & ESP_INTR_FLAG_IRAM)
&& handler
&& !esp_ptr_in_iram(handler)
#if SOC_RTC_FAST_MEM_SUPPORTED
// IDF-3901.
&& !esp_ptr_in_rtc_iram_fast(handler)
#endif
) {
return ESP_ERR_INVALID_ARG;
}

View File

@ -9,7 +9,7 @@ entries:
rtc_pm (noflash_text)
rtc_sleep (noflash_text)
rtc_time (noflash_text)
if IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n:
if IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n && IDF_TARGET_ESP8684 = n:
rtc_wdt (noflash_text)
if IDF_TARGET_ESP32S3 = y:
if SPIRAM_MODE_QUAD = y:

View File

@ -0,0 +1,21 @@
set(srcs "cpu_util_esp8684.c"
"rtc_clk_init.c"
"rtc_clk.c"
"rtc_init.c"
"rtc_pm.c"
"rtc_sleep.c"
"rtc_time.c"
"chip_info.c"
)
if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "../async_memcpy_impl_gdma.c"
"esp_crypto_lock.c"
"dport_access.c")
endif()
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
target_include_directories(${COMPONENT_LIB} PUBLIC . private_include)
target_include_directories(${COMPONENT_LIB} PRIVATE ../hal)

View File

@ -0,0 +1,44 @@
choice ESP8684_UNIVERSAL_MAC_ADDRESSES
bool "Number of universally administered (by IEEE) MAC address"
default ESP8684_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 ESP-8684 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 ESP8684_UNIVERSAL_MAC_ADDRESSES_TWO
bool "Two"
select ESP_MAC_ADDR_UNIVERSE_WIFI_STA
select ESP_MAC_ADDR_UNIVERSE_BT
config ESP8684_UNIVERSAL_MAC_ADDRESSES_FOUR
bool "Four"
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 ESP8684_UNIVERSAL_MAC_ADDRESSES
# TODO: check 8684 mac address WIFI-4134
int
default 2 if ESP8684_UNIVERSAL_MAC_ADDRESSES_TWO
default 4 if ESP8684_UNIVERSAL_MAC_ADDRESSES_FOUR

View File

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2013-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_chip_info.h"
#include "esp_efuse.h"
void esp_chip_info(esp_chip_info_t *out_info)
{
memset(out_info, 0, sizeof(*out_info));
out_info->model = CHIP_ESP8684;
out_info->revision = esp_efuse_get_chip_ver();
out_info->cores = 1;
out_info->features = CHIP_FEATURE_WIFI_BGN | CHIP_FEATURE_BLE;
}

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <assert.h>
#include "soc/cpu.h"
void esp_cpu_configure_region_protection(void)
{
/* Notes on implementation:
*
* 1) ESP-8684 CPU support overlapping PMP regions, configuration is based on static priority
* feature(lowest numbered entry has highest priority).
*
* 2) Therefore, we use TOR (top of range) and NAOPT entries to map the effective area.
* Finally, define any address without access permission.
*
* 3) 3-15 PMPADDR entries be hardcoded to fixed value, 0-2 PMPADDR be programmed to split ID SRAM
* as IRAM/DRAM. All PMPCFG entryies be available.
*
*/
const unsigned NONE = PMP_L ;
const unsigned R = PMP_L | PMP_R;
const unsigned X = PMP_L | PMP_X;
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;
// 1. IRAM
PMP_ENTRY_SET(0,SOC_DIRAM_IRAM_LOW, NONE);
PMP_ENTRY_SET(1,SOC_DIRAM_IRAM_HIGH, PMP_TOR|RWX); //TODO IRAM/DRAM spilt address
// 2. DRAM
PMP_ENTRY_SET(2,SOC_DIRAM_DRAM_LOW, NONE); //TODO IRAM/DRAM spilt address
PMP_ENTRY_CFG_SET(3,PMP_TOR|RW);
// 3. Debug region
PMP_ENTRY_CFG_SET(4,PMP_NAPOT|RWX);
// 4. DROM (flash dcache)
PMP_ENTRY_CFG_SET(5,PMP_NAPOT|R);
// 5. DROM_MASK
PMP_ENTRY_CFG_SET(6,NONE);
PMP_ENTRY_CFG_SET(7,PMP_TOR|R);
// 6. IROM_MASK
PMP_ENTRY_CFG_SET(8,NONE);
PMP_ENTRY_CFG_SET(9,PMP_TOR|RX);
// 7. IROM (flash icache)
PMP_ENTRY_CFG_SET(10,PMP_NAPOT|RX);
// 8. Peripheral addresses
PMP_ENTRY_CFG_SET(11,PMP_NAPOT|RW);
// 9. SRAM (used as ICache)
PMP_ENTRY_CFG_SET(12,PMP_NAPOT|X);
// 10. no access to any address below(0x0-0xFFFF_FFFF)
PMP_ENTRY_CFG_SET(13,PMP_NA4|NONE);// last 4 bytes(0xFFFFFFFC)
PMP_ENTRY_CFG_SET(14,NONE);
PMP_ENTRY_CFG_SET(15,PMP_TOR|NONE);
}

View File

@ -0,0 +1,17 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <string.h>
#include "soc/dport_access.h"
// Read a sequence of DPORT registers to the buffer.
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words)
{
for (uint32_t i = 0; i < num_words; ++i) {
buff_out[i] = DPORT_SEQUENCE_REG_READ(address + i * 4);
}
}

View File

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/lock.h>
#include <stdlib.h>
#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
HMAC: needs SHA
DS: needs HMAC (which needs SHA), AES and MPI
*/
#if 0 // TODO: IDF-4229
/* 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;
#endif
void esp_crypto_hmac_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_hmac_lock_release(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_ds_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_ds_lock_release(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_sha_aes_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_sha_aes_lock_release(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_mpi_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_mpi_lock_release(void)
{
abort(); // TODO: IDF-4229
}

View File

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file i2c_brownout.h
* @brief Register definitions for brownout detector
*
* This file lists register fields of the brownout detector, located on an internal configuration
* bus. These definitions are used via macros defined in i2c_rtc_clk.h.
*/
#define I2C_BOD 0x61
#define I2C_BOD_HOSTID 1
#define I2C_BOD_THRESHOLD 0x5
#define I2C_BOD_THRESHOLD_MSB 2
#define I2C_BOD_THRESHOLD_LSB 0

View File

@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "regi2c_ctrl.h"
/* Analog function control register */
#define ANA_CONFIG_REG 0x6000E044
#define ANA_CONFIG_S (8)
#define ANA_CONFIG_M (0x3FF)
/* Clear to enable APLL */
#define I2C_APLL_M (BIT(14))
/* Clear to enable BBPLL */
#define I2C_BBPLL_M (BIT(17))
/* ROM functions which read/write internal control bus */
uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb);
void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data);
void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data);
/* Convenience macros for the above functions, these use register definitions
* from i2c_apll.h/i2c_bbpll.h header files.
*/
#define I2C_WRITEREG_MASK_RTC(block, reg_add, indata) \
rom_i2c_writeReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata)
#define I2C_READREG_MASK_RTC(block, reg_add) \
rom_i2c_readReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB)
#define I2C_WRITEREG_RTC(block, reg_add, indata) \
rom_i2c_writeReg(block, block##_HOSTID, reg_add, indata)
#define I2C_READREG_RTC(block, reg_add) \
rom_i2c_readReg(block, block##_HOSTID, reg_add)

View File

@ -0,0 +1,175 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_bbpll.h
* @brief Register definitions for digital PLL (BBPLL)
*
* This file lists register fields of BBPLL, located on an internal configuration
* bus. These definitions are used via macros defined in regi2c_ctrl.h, by
* rtc_clk_cpu_freq_set function in rtc_clk.c.
*/
#define I2C_BBPLL 0x66
#define I2C_BBPLL_HOSTID 0
#define I2C_BBPLL_IR_CAL_DELAY 0
#define I2C_BBPLL_IR_CAL_DELAY_MSB 3
#define I2C_BBPLL_IR_CAL_DELAY_LSB 0
#define I2C_BBPLL_IR_CAL_CK_DIV 0
#define I2C_BBPLL_IR_CAL_CK_DIV_MSB 7
#define I2C_BBPLL_IR_CAL_CK_DIV_LSB 4
#define I2C_BBPLL_IR_CAL_EXT_CAP 1
#define I2C_BBPLL_IR_CAL_EXT_CAP_MSB 3
#define I2C_BBPLL_IR_CAL_EXT_CAP_LSB 0
#define I2C_BBPLL_IR_CAL_ENX_CAP 1
#define I2C_BBPLL_IR_CAL_ENX_CAP_MSB 4
#define I2C_BBPLL_IR_CAL_ENX_CAP_LSB 4
#define I2C_BBPLL_IR_CAL_RSTB 1
#define I2C_BBPLL_IR_CAL_RSTB_MSB 5
#define I2C_BBPLL_IR_CAL_RSTB_LSB 5
#define I2C_BBPLL_IR_CAL_START 1
#define I2C_BBPLL_IR_CAL_START_MSB 6
#define I2C_BBPLL_IR_CAL_START_LSB 6
#define I2C_BBPLL_IR_CAL_UNSTOP 1
#define I2C_BBPLL_IR_CAL_UNSTOP_MSB 7
#define I2C_BBPLL_IR_CAL_UNSTOP_LSB 7
#define I2C_BBPLL_OC_REF_DIV 2
#define I2C_BBPLL_OC_REF_DIV_MSB 3
#define I2C_BBPLL_OC_REF_DIV_LSB 0
#define I2C_BBPLL_OC_DCHGP 2
#define I2C_BBPLL_OC_DCHGP_MSB 6
#define I2C_BBPLL_OC_DCHGP_LSB 4
#define I2C_BBPLL_OC_ENB_FCAL 2
#define I2C_BBPLL_OC_ENB_FCAL_MSB 7
#define I2C_BBPLL_OC_ENB_FCAL_LSB 7
#define I2C_BBPLL_OC_DIV_7_0 3
#define I2C_BBPLL_OC_DIV_7_0_MSB 7
#define I2C_BBPLL_OC_DIV_7_0_LSB 0
#define I2C_BBPLL_RSTB_DIV_ADC 4
#define I2C_BBPLL_RSTB_DIV_ADC_MSB 0
#define I2C_BBPLL_RSTB_DIV_ADC_LSB 0
#define I2C_BBPLL_MODE_HF 4
#define I2C_BBPLL_MODE_HF_MSB 1
#define I2C_BBPLL_MODE_HF_LSB 1
#define I2C_BBPLL_DIV_ADC 4
#define I2C_BBPLL_DIV_ADC_MSB 3
#define I2C_BBPLL_DIV_ADC_LSB 2
#define I2C_BBPLL_DIV_DAC 4
#define I2C_BBPLL_DIV_DAC_MSB 4
#define I2C_BBPLL_DIV_DAC_LSB 4
#define I2C_BBPLL_DIV_CPU 4
#define I2C_BBPLL_DIV_CPU_MSB 5
#define I2C_BBPLL_DIV_CPU_LSB 5
#define I2C_BBPLL_OC_ENB_VCON 4
#define I2C_BBPLL_OC_ENB_VCON_MSB 6
#define I2C_BBPLL_OC_ENB_VCON_LSB 6
#define I2C_BBPLL_OC_TSCHGP 4
#define I2C_BBPLL_OC_TSCHGP_MSB 7
#define I2C_BBPLL_OC_TSCHGP_LSB 7
#define I2C_BBPLL_OC_DR1 5
#define I2C_BBPLL_OC_DR1_MSB 2
#define I2C_BBPLL_OC_DR1_LSB 0
#define I2C_BBPLL_OC_DR3 5
#define I2C_BBPLL_OC_DR3_MSB 6
#define I2C_BBPLL_OC_DR3_LSB 4
#define I2C_BBPLL_EN_USB 5
#define I2C_BBPLL_EN_USB_MSB 7
#define I2C_BBPLL_EN_USB_LSB 7
#define I2C_BBPLL_OC_DCUR 6
#define I2C_BBPLL_OC_DCUR_MSB 2
#define I2C_BBPLL_OC_DCUR_LSB 0
#define I2C_BBPLL_INC_CUR 6
#define I2C_BBPLL_INC_CUR_MSB 3
#define I2C_BBPLL_INC_CUR_LSB 3
#define I2C_BBPLL_OC_DHREF_SEL 6
#define I2C_BBPLL_OC_DHREF_SEL_MSB 5
#define I2C_BBPLL_OC_DHREF_SEL_LSB 4
#define I2C_BBPLL_OC_DLREF_SEL 6
#define I2C_BBPLL_OC_DLREF_SEL_MSB 7
#define I2C_BBPLL_OC_DLREF_SEL_LSB 6
#define I2C_BBPLL_OR_CAL_CAP 8
#define I2C_BBPLL_OR_CAL_CAP_MSB 3
#define I2C_BBPLL_OR_CAL_CAP_LSB 0
#define I2C_BBPLL_OR_CAL_UDF 8
#define I2C_BBPLL_OR_CAL_UDF_MSB 4
#define I2C_BBPLL_OR_CAL_UDF_LSB 4
#define I2C_BBPLL_OR_CAL_OVF 8
#define I2C_BBPLL_OR_CAL_OVF_MSB 5
#define I2C_BBPLL_OR_CAL_OVF_LSB 5
#define I2C_BBPLL_OR_CAL_END 8
#define I2C_BBPLL_OR_CAL_END_MSB 6
#define I2C_BBPLL_OR_CAL_END_LSB 6
#define I2C_BBPLL_OR_LOCK 8
#define I2C_BBPLL_OR_LOCK_MSB 7
#define I2C_BBPLL_OR_LOCK_LSB 7
#define I2C_BBPLL_OC_VCO_DBIAS 9
#define I2C_BBPLL_OC_VCO_DBIAS_MSB 1
#define I2C_BBPLL_OC_VCO_DBIAS_LSB 0
#define I2C_BBPLL_BBADC_DELAY2 9
#define I2C_BBPLL_BBADC_DELAY2_MSB 3
#define I2C_BBPLL_BBADC_DELAY2_LSB 2
#define I2C_BBPLL_BBADC_DVDD 9
#define I2C_BBPLL_BBADC_DVDD_MSB 5
#define I2C_BBPLL_BBADC_DVDD_LSB 4
#define I2C_BBPLL_BBADC_DREF 9
#define I2C_BBPLL_BBADC_DREF_MSB 7
#define I2C_BBPLL_BBADC_DREF_LSB 6
#define I2C_BBPLL_BBADC_DCUR 10
#define I2C_BBPLL_BBADC_DCUR_MSB 1
#define I2C_BBPLL_BBADC_DCUR_LSB 0
#define I2C_BBPLL_BBADC_INPUT_SHORT 10
#define I2C_BBPLL_BBADC_INPUT_SHORT_MSB 2
#define I2C_BBPLL_BBADC_INPUT_SHORT_LSB 2
#define I2C_BBPLL_ENT_PLL 10
#define I2C_BBPLL_ENT_PLL_MSB 3
#define I2C_BBPLL_ENT_PLL_LSB 3
#define I2C_BBPLL_DTEST 10
#define I2C_BBPLL_DTEST_MSB 5
#define I2C_BBPLL_DTEST_LSB 4
#define I2C_BBPLL_ENT_ADC 10
#define I2C_BBPLL_ENT_ADC_MSB 7
#define I2C_BBPLL_ENT_ADC_LSB 6

View File

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_bias.h
* @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_esp8684.c.
*/
#define I2C_BIAS 0X6A
#define I2C_BIAS_HOSTID 0
#define I2C_BIAS_DREG_1P1_PVT 1
#define I2C_BIAS_DREG_1P1_PVT_MSB 3
#define I2C_BIAS_DREG_1P1_PVT_LSB 0

View File

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_brownout.h
* @brief Register definitions for brownout detector
*
* This file lists register fields of the brownout detector, located on an internal configuration
* bus. These definitions are used via macros defined in regi2c_ctrl.h.
*/
#define I2C_BOD 0x61
#define I2C_BOD_HOSTID 0
#define I2C_BOD_THRESHOLD 0x5
#define I2C_BOD_THRESHOLD_MSB 2
#define I2C_BOD_THRESHOLD_LSB 0

View File

@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2015-2021 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_ENX_RTC_DREG_SLEEP 5
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP_MSB 7
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP_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_ENX_DIG_DREG_SLEEP 7
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP_MSB 7
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP_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

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_lp_bias.h
* @brief Register definitions for analog to calibrate o_code for getting a more precise voltage.
*
* This file lists register fields of low power dbais, located on an internal configuration
* bus. These definitions are used via macros defined in regi2c_ctrl.h, by
* rtc_init function in rtc_init.c.
*/
#define I2C_ULP 0x61
#define I2C_ULP_HOSTID 0
#define I2C_ULP_IR_RESETB 0
#define I2C_ULP_IR_RESETB_MSB 0
#define I2C_ULP_IR_RESETB_LSB 0
#define I2C_ULP_IR_FORCE_XPD_CK 0
#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
#define I2C_ULP_IR_FORCE_XPD_IPH 0
#define I2C_ULP_IR_FORCE_XPD_IPH_MSB 4
#define I2C_ULP_IR_FORCE_XPD_IPH_LSB 4
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK 0
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_MSB 6
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_LSB 6
#define I2C_ULP_O_DONE_FLAG 3
#define I2C_ULP_O_DONE_FLAG_MSB 0
#define I2C_ULP_O_DONE_FLAG_LSB 0
#define I2C_ULP_BG_O_DONE_FLAG 3
#define I2C_ULP_BG_O_DONE_FLAG_MSB 3
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
#define I2C_ULP_OCODE 4
#define I2C_ULP_OCODE_MSB 7
#define I2C_ULP_OCODE_LSB 0
#define I2C_ULP_IR_FORCE_CODE 5
#define I2C_ULP_IR_FORCE_CODE_MSB 6
#define I2C_ULP_IR_FORCE_CODE_LSB 6
#define I2C_ULP_EXT_CODE 6
#define I2C_ULP_EXT_CODE_MSB 7
#define I2C_ULP_EXT_CODE_LSB 0

View File

@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_saradc.h
* @brief Register definitions for analog to calibrate initial code for getting a more precise voltage of SAR ADC.
*
* This file lists register fields of SAR, located on an internal configuration
* bus. These definitions are used via macros defined in regi2c_ctrl.h, by
* function in adc_ll.h.
*/
#define I2C_SAR_ADC 0X69
#define I2C_SAR_ADC_HOSTID 0
#define ADC_SAR1_ENCAL_GND_ADDR 0x7
#define ADC_SAR1_ENCAL_GND_ADDR_MSB 5
#define ADC_SAR1_ENCAL_GND_ADDR_LSB 5
#define ADC_SAR2_ENCAL_GND_ADDR 0x7
#define ADC_SAR2_ENCAL_GND_ADDR_MSB 7
#define ADC_SAR2_ENCAL_GND_ADDR_LSB 7
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR 0x1
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0
#define ADC_SAR1_INITIAL_CODE_LOW_ADDR 0x0
#define ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB 0x7
#define ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB 0x0
#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR 0x4
#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3
#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0
#define ADC_SAR2_INITIAL_CODE_LOW_ADDR 0x3
#define ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7
#define ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0
#define ADC_SAR1_DREF_ADDR 0x2
#define ADC_SAR1_DREF_ADDR_MSB 0x6
#define ADC_SAR1_DREF_ADDR_LSB 0x4
#define ADC_SAR2_DREF_ADDR 0x5
#define ADC_SAR2_DREF_ADDR_MSB 0x6
#define ADC_SAR2_DREF_ADDR_LSB 0x4
#define ADC_SAR1_SAMPLE_CYCLE_ADDR 0x2
#define ADC_SAR1_SAMPLE_CYCLE_ADDR_MSB 0x2
#define ADC_SAR1_SAMPLE_CYCLE_ADDR_LSB 0x0
#define ADC_SARADC_DTEST_RTC_ADDR 0x7
#define ADC_SARADC_DTEST_RTC_ADDR_MSB 1
#define ADC_SARADC_DTEST_RTC_ADDR_LSB 0
#define ADC_SARADC_ENT_TSENS_ADDR 0x7
#define ADC_SARADC_ENT_TSENS_ADDR_MSB 2
#define ADC_SARADC_ENT_TSENS_ADDR_LSB 2
#define ADC_SARADC_ENT_RTC_ADDR 0x7
#define ADC_SARADC_ENT_RTC_ADDR_MSB 3
#define ADC_SARADC_ENT_RTC_ADDR_LSB 3
#define ADC_SARADC1_ENCAL_REF_ADDR 0x7
#define ADC_SARADC1_ENCAL_REF_ADDR_MSB 4
#define ADC_SARADC1_ENCAL_REF_ADDR_LSB 4
#define ADC_SARADC2_ENCAL_REF_ADDR 0x7
#define ADC_SARADC2_ENCAL_REF_ADDR_MSB 6
#define ADC_SARADC2_ENCAL_REF_ADDR_LSB 6
#define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 3
#define I2C_SARADC_TSENS_DAC_LSB 0

View File

@ -0,0 +1,88 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "regi2c_bbpll.h"
#include "regi2c_lp_bias.h"
#include "regi2c_dig_reg.h"
#include "regi2c_bias.h"
#include "regi2c_saradc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Analog function control register */
#define I2C_MST_ANA_CONF0_REG 0x6000E040
#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
#define ANA_CONFIG_REG 0x6000E044
#define ANA_CONFIG_S (8)
#define ANA_CONFIG_M (0x3FF)
#define ANA_I2C_SAR_FORCE_PD BIT(18)
#define ANA_I2C_BBPLL_M BIT(17) /* Clear to enable BBPLL */
#define ANA_I2C_APLL_M BIT(14) /* Clear to enable APLL */
#define ANA_CONFIG2_REG 0x6000E048
#define ANA_CONFIG2_M BIT(18)
#define ANA_I2C_SAR_FORCE_PU BIT(16)
/* ROM functions which read/write internal control bus */
uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb);
void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data);
void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data);
#ifdef BOOTLOADER_BUILD
/**
* If compiling for the bootloader, ROM functions can be called directly,
* without the need of a lock.
*/
#define regi2c_ctrl_read_reg rom_i2c_readReg
#define regi2c_ctrl_read_reg_mask rom_i2c_readReg_Mask
#define regi2c_ctrl_write_reg rom_i2c_writeReg
#define regi2c_ctrl_write_reg_mask rom_i2c_writeReg_Mask
#else
#define i2c_read_reg_raw rom_i2c_readReg
#define i2c_read_reg_mask_raw rom_i2c_readReg_Mask
#define i2c_write_reg_raw rom_i2c_writeReg
#define i2c_write_reg_mask_raw rom_i2c_writeReg_Mask
uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add);
uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb);
void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data);
void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data);
#endif // BOOTLOADER_BUILD
/* Convenience macros for the above functions, these use register definitions
* from regi2c_bbpll.h/regi2c_dig_reg.h/regi2c_lp_bias.h/regi2c_bias.h header files.
*/
#define REGI2C_WRITE_MASK(block, reg_add, indata) \
regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata)
#define REGI2C_READ_MASK(block, reg_add) \
regi2c_ctrl_read_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB)
#define REGI2C_WRITE(block, reg_add, indata) \
regi2c_ctrl_write_reg(block, block##_HOSTID, reg_add, indata)
#define REGI2C_READ(block, reg_add) \
regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add)
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,473 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "esp8684/rom/ets_sys.h"
#include "esp8684/rom/rtc.h"
#include "esp8684/rom/uart.h"
#include "esp8684/rom/gpio.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/efuse_reg.h"
#include "soc/syscon_reg.h"
#include "soc/system_reg.h"
#include "regi2c_ctrl.h"
#include "soc_log.h"
#include "rtc_clk_common.h"
#include "esp_rom_sys.h"
static const char *TAG = "rtc_clk";
#define RTC_PLL_FREQ_320M 320
#define RTC_PLL_FREQ_480M 480
#define DELAY_RTC_CLK_SWITCH 5
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
static int s_cur_pll_freq;
static void rtc_clk_cpu_freq_to_8m(void);
void rtc_clk_32k_bootstrap(uint32_t cycle)
{
/* No special bootstrapping needed for ESP-8684, 'cycle' argument is to keep the signature
* same as for the ESP32. Just enable the XTAL here.
*/
}
bool rtc_clk_32k_enabled(void)
{
return 0;
}
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
{
if (clk_8m_en) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
/* no need to wait once enabled by software */
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
esp_rom_delay_us(DELAY_8M_ENABLE);
} else {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
}
/* d256 should be independent configured with 8M
* Maybe we can split this function into 8m and dmd256
*/
if (d256_en) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
} else {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
}
}
bool rtc_clk_8m_enabled(void)
{
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
}
bool rtc_clk_8md256_enabled(void)
{
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
}
void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
{
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
/* Why we need to connect this clock to digital?
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
*/
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
(slow_freq == RTC_SLOW_FREQ_32K_XTAL) ? 1 : 0);
/* The clk_8m_d256 will be closed when rtc_state in SLEEP,
so if the slow_clk is 8md256, clk_8m must be force power on
*/
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU, (slow_freq == RTC_SLOW_FREQ_8MD256) ? 1 : 0);
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
}
rtc_slow_freq_t rtc_clk_slow_freq_get(void)
{
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
}
uint32_t rtc_clk_slow_freq_get_hz(void)
{
switch (rtc_clk_slow_freq_get()) {
case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_150K;
case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K;
case RTC_SLOW_FREQ_8MD256: return RTC_SLOW_CLK_FREQ_8MD256;
}
return 0;
}
void rtc_clk_fast_freq_set(rtc_fast_freq_t fast_freq)
{
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
}
rtc_fast_freq_t rtc_clk_fast_freq_get(void)
{
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
}
static void rtc_clk_bbpll_disable(void)
{
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
s_cur_pll_freq = 0;
}
static void rtc_clk_bbpll_enable(void)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
}
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
{
uint8_t div_ref;
uint8_t div7_0;
uint8_t dr1;
uint8_t dr3;
uint8_t dchgp;
uint8_t dcur;
uint8_t dbias;
CLEAR_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
SET_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
if (pll_freq == RTC_PLL_FREQ_480M) {
/* Set this register to let the digital part know 480M PLL is used */
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
/* Configure 480M PLL */
switch (xtal_freq) {
case RTC_XTAL_FREQ_40M:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
case RTC_XTAL_FREQ_32M:
div_ref = 1;
div7_0 = 26;
dr1 = 1;
dr3 = 1;
dchgp = 4;
dcur = 0;
dbias = 2;
break;
default:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
} else {
/* Clear this register to let the digital part know 320M PLL is used */
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
/* Configure 320M PLL */
switch (xtal_freq) {
case RTC_XTAL_FREQ_40M:
div_ref = 0;
div7_0 = 4;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
case RTC_XTAL_FREQ_32M:
div_ref = 1;
div7_0 = 6;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
default:
div_ref = 0;
div7_0 = 4;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
}
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 = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << 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);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 2);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
s_cur_pll_freq = pll_freq;
}
/**
* 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)
{
int per_conf = DPORT_CPUPERIOD_SEL_80;
if (cpu_freq_mhz == 80) {
/* nothing to do */
} else if (cpu_freq_mhz == 160) {
per_conf = DPORT_CPUPERIOD_SEL_160;
} else {
SOC_LOGE(TAG, "invalid frequency");
abort();
}
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
rtc_clk_apb_freq_update(80 * MHZ);
ets_update_cpu_frequency(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;
rtc_cpu_freq_src_t source;
uint32_t divider;
uint32_t real_freq_mhz;
uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
if (freq_mhz <= xtal_freq) {
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 = RTC_CPU_FREQ_SRC_XTAL;
} else if (freq_mhz == 80) {
real_freq_mhz = freq_mhz;
source = RTC_CPU_FREQ_SRC_PLL;
source_freq_mhz = RTC_PLL_FREQ_480M;
divider = 6;
} else if (freq_mhz == 160) {
real_freq_mhz = freq_mhz;
source = RTC_CPU_FREQ_SRC_PLL;
source_freq_mhz = RTC_PLL_FREQ_480M;
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;
}
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
{
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
rtc_clk_bbpll_disable();
}
} else if (config->source == RTC_CPU_FREQ_SRC_PLL) {
if (soc_clk_sel != DPORT_SOC_CLK_SEL_PLL) {
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);
} else if (config->source == RTC_CPU_FREQ_SRC_8M) {
rtc_clk_cpu_freq_to_8m();
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
rtc_clk_bbpll_disable();
}
}
}
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
{
rtc_cpu_freq_src_t source;
uint32_t source_freq_mhz;
uint32_t div;
uint32_t freq_mhz;
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
switch (soc_clk_sel) {
case DPORT_SOC_CLK_SEL_XTAL: {
source = RTC_CPU_FREQ_SRC_XTAL;
div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
}
break;
case DPORT_SOC_CLK_SEL_PLL: {
source = RTC_CPU_FREQ_SRC_PLL;
uint32_t cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
uint32_t pllfreq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
source_freq_mhz = (pllfreq_sel) ? RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M;
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4;
freq_mhz = 80;
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) {
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2;
div = 3;
freq_mhz = 160;
} else {
SOC_LOGE(TAG, "unsupported frequency configuration");
abort();
}
break;
}
case DPORT_SOC_CLK_SEL_8M:
source = RTC_CPU_FREQ_SRC_8M;
source_freq_mhz = 8;
div = 1;
freq_mhz = source_freq_mhz;
break;
default:
SOC_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 == RTC_CPU_FREQ_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
} else if (config->source == RTC_CPU_FREQ_SRC_PLL &&
s_cur_pll_freq == config->source_freq_mhz) {
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
} else {
/* fallback */
rtc_clk_cpu_freq_set_config(config);
}
}
void rtc_clk_cpu_freq_set_xtal(void)
{
int freq_mhz = (int) rtc_clk_xtal_freq_get();
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
rtc_clk_bbpll_disable();
}
/**
* Switch to XTAL frequency. Does not disable the PLL.
*/
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
{
ets_update_cpu_frequency(freq);
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
/* no need to adjust the REF_TICK */
/* switch clock source */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
rtc_clk_apb_freq_update(freq * MHZ);
}
static void rtc_clk_cpu_freq_to_8m(void)
{
ets_update_cpu_frequency(8);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
rtc_clk_apb_freq_update(RTC_FAST_CLK_FREQ_8M);
}
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
{
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if (!clk_val_is_valid(xtal_freq_reg)) {
SOC_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
return RTC_XTAL_FREQ_40M;
}
return reg_val_to_clk_val(xtal_freq_reg);
}
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
{
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
}
void rtc_clk_apb_freq_update(uint32_t apb_freq)
{
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
}
uint32_t rtc_clk_apb_freq_get(void)
{
uint32_t freq_hz = reg_val_to_clk_val(READ_PERI_REG(RTC_APB_FREQ_REG)) << 12;
// round to the nearest MHz
freq_hz += MHZ / 2;
uint32_t remainder = freq_hz % MHZ;
return freq_hz - remainder;
}
void rtc_clk_divider_set(uint32_t div)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div);
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
}
void rtc_clk_8m_divider_set(uint32_t div)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div);
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
}
void rtc_dig_clk8m_enable(void)
{
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
}
void rtc_dig_clk8m_disable(void)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
}
/* 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")));

View File

@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#define MHZ (1000000)
#define DPORT_CPUPERIOD_SEL_80 0
#define DPORT_CPUPERIOD_SEL_160 1
#define DPORT_SOC_CLK_SEL_XTAL 0
#define DPORT_SOC_CLK_SEL_PLL 1
#define DPORT_SOC_CLK_SEL_8M 2
#define RTC_FAST_CLK_FREQ_8M 8500000
#ifdef __cplusplus
extern "C" {
#endif
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
* lower and upper 16-bit halves. These are the routines to work with such a
* representation.
*/
static inline bool clk_val_is_valid(uint32_t val)
{
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
val != 0 &&
val != UINT32_MAX;
}
static inline uint32_t reg_val_to_clk_val(uint32_t val)
{
return val & UINT16_MAX;
}
static inline uint32_t clk_val_to_reg_val(uint32_t val)
{
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,77 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include "esp8684/rom/ets_sys.h"
#include "esp8684/rom/rtc.h"
#include "esp8684/rom/uart.h"
#include "soc/rtc.h"
#include "soc/rtc_periph.h"
#include "soc/efuse_periph.h"
#include "soc/apb_ctrl_reg.h"
#include "hal/cpu_hal.h"
#include "regi2c_ctrl.h"
#include "soc_log.h"
#include "sdkconfig.h"
#include "rtc_clk_common.h"
#include "esp_rom_uart.h"
static const char *TAG = "rtc_clk_init";
void rtc_clk_init(rtc_clk_config_t cfg)
{
rtc_cpu_freq_config_t old_config, new_config;
/* Set tuning parameters for 8M and 150k 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 150k clock.
* The higher the value of DCAP is, the lower is the frequency.
* - CK8M_DFREQ value controls tuning of 8M clock.
* CLK_8M_DFREQ constant gives the best temperature characteristics.
*/
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
/* Configure 150k clock division */
rtc_clk_divider_set(cfg.clk_rtc_clk_div);
/* Configure 8M clock division */
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
/* Enable the internal bus used to configure PLLs */
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_APLL_M | ANA_I2C_BBPLL_M);
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
esp_rom_uart_tx_wait_idle(0);
rtc_clk_xtal_freq_update(xtal_freq);
rtc_clk_apb_freq_update(xtal_freq * MHZ);
/* 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) {
SOC_LOGE(TAG, "invalid CPU frequency value");
abort();
}
rtc_clk_cpu_freq_set_config(&new_config);
/* Re-calculate the ccount to make time calculation correct. */
cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before );
/* fast clocks setup */
if (cfg.fast_freq == RTC_FAST_FREQ_8M) {
bool need_8md256 = cfg.slow_freq == RTC_SLOW_FREQ_8MD256;
rtc_clk_8m_enable(true, need_8md256);
}
rtc_clk_fast_freq_set(cfg.fast_freq);
rtc_clk_slow_freq_set(cfg.slow_freq);
}

View File

@ -0,0 +1,279 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "sdkconfig.h"
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/efuse_periph.h"
#include "soc/gpio_reg.h"
#include "soc/spi_mem_reg.h"
#include "soc/extmem_reg.h"
#include "soc/system_reg.h"
#include "regi2c_ctrl.h"
#include "soc_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
static const char *TAG = "rtc_init";
static void set_ocode_by_efuse(int calib_version);
static void calibrate_ocode(void);
static void set_rtc_dig_dbias(void);
void rtc_init(rtc_config_t cfg)
{
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait);
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
if (cfg.cali_ocode) {
uint32_t rtc_calib_version = 0;
esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &rtc_calib_version, 3);
if (err != ESP_OK) {
rtc_calib_version = 0;
SOC_LOGW(TAG, "efuse read fail, set default rtc_calib_version: %d\n", rtc_calib_version);
}
if (rtc_calib_version == 1) {
set_ocode_by_efuse(rtc_calib_version);
} else {
calibrate_ocode();
}
}
set_rtc_dig_dbias();
if (cfg.clkctl_init) {
//clear CMMU clock force on
CLEAR_PERI_REG_MASK(EXTMEM_CACHE_MMU_POWER_CTRL_REG, EXTMEM_CACHE_MMU_MEM_FORCE_ON);
//clear tag clock force on
CLEAR_PERI_REG_MASK(EXTMEM_ICACHE_TAG_POWER_CTRL_REG, EXTMEM_ICACHE_TAG_MEM_FORCE_ON);
//clear register clock force on
CLEAR_PERI_REG_MASK(SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLK_EN);
CLEAR_PERI_REG_MASK(SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLK_EN);
}
if (cfg.pwrctl_init) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
//cancel xtal force pu if no need to force power up
//cannot cancel xtal force pu if pll is force power on
if (!(cfg.xtal_fpu | cfg.bbpll_fpu)) {
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU);
} else {
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU);
}
//cancel bbpll force pu if setting no force power up
if (!cfg.bbpll_fpu) {
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_I2C_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
} else {
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU);
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_I2C_FORCE_PU);
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
}
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
//clear i2c_reset_protect pd force, need tested in low temperature.
//CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,RTC_CNTL_I2C_RESET_POR_FORCE_PD);
/* If this mask is enabled, all soc memories cannot enter power down mode */
/* We should control soc memory power down mode from RTC, so we will not touch this register any more */
CLEAR_PERI_REG_MASK(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK);
/* If this pd_cfg is set to 1, all memory won't enter low power mode during light sleep */
/* If this pd_cfg is set to 0, all memory will enter low power mode during light sleep */
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(0);
rtc_sleep_pu(pu_cfg);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_WRAP_FORCE_NOISO);
//cancel digital PADS force no iso
if (cfg.cpu_waiti_clk_gate) {
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON);
} else {
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON);
}
/*if SYSTEM_CPU_WAIT_MODE_FORCE_ON == 0 , the cpu clk will be closed when cpu enter WAITI mode*/
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
}
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);
}
rtc_vddsdio_config_t rtc_vddsdio_get_config(void)
{
rtc_vddsdio_config_t result = {0};
return result;
}
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
{
}
static void set_ocode_by_efuse(int calib_version)
{
#if !CONFIG_IDF_TARGET_ESP8684 //TODO: Need check for esp8684
assert(calib_version == 1);
// use efuse ocode.
uint32_t ocode;
esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_OCODE, &ocode, 8);
assert(err == ESP_OK);
(void) err;
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode);
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1);
#endif
abort();
}
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.
*/
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_freq == (rtc_slow_freq_x32k)) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_freq == rtc_slow_freq_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
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) {
SOC_LOGW(TAG, "o_code calibration fail\n");
break;
}
}
rtc_clk_cpu_freq_set_config(&old_config);
}
static uint32_t get_dig_dbias_by_efuse(uint8_t chip_version)
{
#if CONFIG_IDF_TARGET_ESP8684 //TODO: Need check for esp8684
return 0;
#else
assert(chip_version >= 3);
uint32_t dig_dbias = 28;
esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_DIG_DBIAS_HVT, &dig_dbias, 5);
if (err != ESP_OK) {
dig_dbias = 28;
SOC_LOGW(TAG, "efuse read fail, set default dig_dbias value: %d\n", dig_dbias);
}
return dig_dbias;
#endif
}
uint32_t get_rtc_dbias_by_efuse(uint8_t chip_version, uint32_t dig_dbias)
{
#if CONFIG_IDF_TARGET_ESP8684 //TODO: Need check for esp8684
return 0;
#else
assert(chip_version >= 3);
uint32_t rtc_dbias = 0;
signed int k_rtc_ldo = 0, k_dig_ldo = 0, v_rtc_bias20 = 0, v_dig_bias20 = 0;
esp_err_t err0 = esp_efuse_read_field_blob(ESP_EFUSE_K_RTC_LDO, &k_rtc_ldo, 7);
esp_err_t err1 = esp_efuse_read_field_blob(ESP_EFUSE_K_DIG_LDO, &k_dig_ldo, 7);
esp_err_t err2 = esp_efuse_read_field_blob(ESP_EFUSE_V_RTC_DBIAS20, &v_rtc_bias20, 8);
esp_err_t err3 = esp_efuse_read_field_blob(ESP_EFUSE_V_DIG_DBIAS20, &v_dig_bias20, 8);
if ((err0 != ESP_OK) | (err1 != ESP_OK) | (err2 != ESP_OK) | (err3 != ESP_OK)) {
k_rtc_ldo = 0;
k_dig_ldo = 0;
v_rtc_bias20 = 0;
v_dig_bias20 = 0;
SOC_LOGW(TAG, "efuse read fail, k_rtc_ldo: %d, k_dig_ldo: %d, v_rtc_bias20: %d, v_dig_bias20: %d\n", k_rtc_ldo, k_dig_ldo, v_rtc_bias20, v_dig_bias20);
}
k_rtc_ldo = ((k_rtc_ldo & BIT(6)) != 0)? -(k_rtc_ldo & 0x3f): k_rtc_ldo;
k_dig_ldo = ((k_dig_ldo & BIT(6)) != 0)? -(k_dig_ldo & 0x3f): (uint8_t)k_dig_ldo;
v_rtc_bias20 = ((v_rtc_bias20 & BIT(7)) != 0)? -(v_rtc_bias20 & 0x7f): (uint8_t)v_rtc_bias20;
v_dig_bias20 = ((v_dig_bias20 & BIT(7)) != 0)? -(v_dig_bias20 & 0x7f): (uint8_t)v_dig_bias20;
uint32_t v_rtc_dbias20_real_mul10000 = V_RTC_MID_MUL10000 + v_rtc_bias20 * 10000 / 500;
uint32_t v_dig_dbias20_real_mul10000 = V_DIG_MID_MUL10000 + v_dig_bias20 * 10000 / 500;
signed int k_rtc_ldo_real_mul10000 = K_RTC_MID_MUL10000 + k_rtc_ldo;
signed int k_dig_ldo_real_mul10000 = K_DIG_MID_MUL10000 + k_dig_ldo;
uint32_t v_dig_nearest_1v15_mul10000 = v_dig_dbias20_real_mul10000 + k_dig_ldo_real_mul10000 * (dig_dbias - 20);
uint32_t v_rtc_nearest_1v15_mul10000 = 0;
for (rtc_dbias = 15; rtc_dbias < 32; rtc_dbias++) {
v_rtc_nearest_1v15_mul10000 = v_rtc_dbias20_real_mul10000 + k_rtc_ldo_real_mul10000 * (rtc_dbias - 20);
if (v_rtc_nearest_1v15_mul10000 >= v_dig_nearest_1v15_mul10000 - 250)
break;
}
return rtc_dbias;
#endif
}
static void set_rtc_dig_dbias()
{
/*
1. a reasonable dig_dbias which by scaning pvt to make 160 CPU run successful stored in efuse;
2. also we store some value in efuse, include:
k_rtc_ldo (slope of rtc voltage & rtc_dbias);
k_dig_ldo (slope of digital voltage & digital_dbias);
v_rtc_bias20 (rtc voltage when rtc dbais is 20);
v_dig_bias20 (digital voltage when digital dbais is 20).
3. a reasonable rtc_dbias can be calculated by a certion formula.
*/
uint32_t rtc_dbias = 28, dig_dbias = 28;
uint8_t chip_version = esp_efuse_get_chip_ver();
if (chip_version >= 3) {
dig_dbias = get_dig_dbias_by_efuse(chip_version);
if (dig_dbias != 0) {
if (dig_dbias + 4 > 28) {
dig_dbias = 28;
} else {
dig_dbias += 4;
}
rtc_dbias = get_rtc_dbias_by_efuse(chip_version, dig_dbias); // already burn dig_dbias in efuse
} else {
dig_dbias = 28;
SOC_LOGD(TAG, "not burn core voltage in efuse or burn wrong voltage value in chip version: 0%d\n", chip_version);
}
}
else {
SOC_LOGD(TAG, "chip_version is less than 3, not burn core voltage in efuse\n");
}
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, rtc_dbias);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dig_dbias);
}

View File

@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <assert.h>
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
typedef enum {
PM_LIGHT_SLEEP = BIT(2), /*!< WiFi PD, memory in light sleep */
} pm_sleep_mode_t;
typedef enum {
PM_SW_NOREJECT = 0,
PM_SW_REJECT = 1
} pm_sw_reject_t;
/* These MAC-related functions are defined in the closed source part of
* RTC library
*/
extern void pm_mac_init(void);
extern int pm_check_mac_idle(void);
extern void pm_mac_deinit(void);
/* This sleep-related function is called from the closed source part of RTC
* library.
*/
pm_sw_reject_t pm_set_sleep_mode(pm_sleep_mode_t sleep_mode, void(*pmac_save_params)(void))
{
(void) pmac_save_params; /* unused */
pm_mac_deinit();
if (pm_check_mac_idle()) {
pm_mac_init();
return PM_SW_REJECT;
}
rtc_sleep_config_t cfg = { 0 };
switch (sleep_mode) {
case PM_LIGHT_SLEEP:
cfg.wifi_pd_en = 1;
cfg.dig_dbias_wak = 4;
cfg.dig_dbias_slp = 0;
cfg.rtc_dbias_wak = 0;
cfg.rtc_dbias_slp = 0;
rtc_sleep_init(cfg);
break;
default:
assert(0 && "unsupported sleep mode");
}
return PM_SW_NOREJECT;
}

View File

@ -0,0 +1,224 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdlib.h>
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "soc/rtc.h"
#include "soc/bb_reg.h"
#include "soc/nrx_reg.h"
#include "soc/fe_reg.h"
#include "soc/timer_group_reg.h"
#include "soc/system_reg.h"
#include "soc/rtc.h"
#include "esp8684/rom/ets_sys.h"
#include "esp8684/rom/rtc.h"
#include "regi2c_ctrl.h"
#include "esp_efuse.h"
/**
* Configure whether certain peripherals are powered down in deep sleep
* @param cfg power down flags as rtc_sleep_pu_config_t structure
*/
void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
{
REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_DC_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_AGC_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
if (cfg.sram_fpu) {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_SRAM_POWER_UP, APB_CTRL_SRAM_POWER_UP);
} else {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_SRAM_POWER_UP, 0);
}
if (cfg.rom_ram_fpu) {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_ROM_POWER_UP, APB_CTRL_ROM_POWER_UP);
} else {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_ROM_POWER_UP, 0);
}
}
void rtc_sleep_init(rtc_sleep_config_t cfg)
{
if (cfg.lslp_mem_inf_fpu) {
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
rtc_sleep_pu(pu_cfg);
}
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, RTC_CNTL_BIASSLP_SLEEP_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, RTC_CNTL_PD_CUR_SLEEP_DEFAULT);
if (cfg.deep_slp) {
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
unsigned atten_deep_sleep = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
if (esp_efuse_get_chip_ver() < 3) {
atten_deep_sleep = 0; /* workaround for deep sleep issue in high temp on ECO2 and below */
}
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, atten_deep_sleep);
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
} else {
SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
}
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
/* gating XTAL clock */
REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
void rtc_sleep_set_wakeup_time(uint64_t t)
{
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
{
REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
/* Start entry into sleep mode */
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
;
}
return rtc_sleep_finish(lslp_mem_inf_fpu);
}
#define STR2(X) #X
#define STR(X) STR2(X)
uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
{
REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, reject_opt);
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
/* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
Because we may be running from RTC memory as stack, we can't easily call any
functions to do this (as registers will spill to stack, corrupting the CRC).
Instead, load all the values we need into registers then use register ops only to calculate
the CRC value, write it to the RTC CRC value register, and immediately go into deep sleep.
*/
/* Values used to set the SYSTEM_RTC_FASTMEM_CONFIG_REG value */
const unsigned CRC_START_ADDR = 0;
const unsigned CRC_LEN = 0x7ff;
asm volatile(
/* Start CRC calculation */
"sw %1, 0(%0)\n" // set RTC_MEM_CRC_ADDR & RTC_MEM_CRC_LEN
"or t0, %1, %2\n"
"sw t0, 0(%0)\n" // set RTC_MEM_CRC_START
/* Wait for the CRC calculation to finish */
".Lwaitcrc:\n"
"fence\n"
"lw t0, 0(%0)\n"
"li t1, "STR(SYSTEM_RTC_MEM_CRC_FINISH)"\n"
"and t0, t0, t1\n"
"beqz t0, .Lwaitcrc\n"
"not %2, %2\n" // %2 -> ~DPORT_RTC_MEM_CRC_START
"and t0, t0, %2\n"
"sw t0, 0(%0)\n" // clear RTC_MEM_CRC_START
"fence\n"
"not %2, %2\n" // %2 -> DPORT_RTC_MEM_CRC_START, probably unnecessary but gcc assumes inputs unchanged
/* Store the calculated value in RTC_MEM_CRC_REG */
"lw t0, 0(%3)\n"
"sw t0, 0(%4)\n"
"fence\n"
/* Set register bit to go into deep sleep */
"lw t0, 0(%5)\n"
"or t0, t0, %6\n"
"sw t0, 0(%5)\n"
"fence\n"
/* Wait for sleep reject interrupt (never finishes if successful) */
".Lwaitsleep:"
"fence\n"
"lw t0, 0(%7)\n"
"and t0, t0, %8\n"
"beqz t0, .Lwaitsleep\n"
:
:
"r" (SYSTEM_RTC_FASTMEM_CONFIG_REG), // %0
"r" ( (CRC_START_ADDR << SYSTEM_RTC_MEM_CRC_START_S)
| (CRC_LEN << SYSTEM_RTC_MEM_CRC_LEN_S)), // %1
"r" (SYSTEM_RTC_MEM_CRC_START), // %2
"r" (SYSTEM_RTC_FASTMEM_CRC_REG), // %3
"r" (RTC_MEMORY_CRC_REG), // %4
"r" (RTC_CNTL_STATE0_REG), // %5
"r" (RTC_CNTL_SLEEP_EN), // %6
"r" (RTC_CNTL_INT_RAW_REG), // %7
"r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) // %8
: "t0", "t1" // working registers
);
return rtc_sleep_finish(0);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
{
/* In deep sleep mode, we never get here */
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
/* restore config if it is a light sleep */
if (lslp_mem_inf_fpu) {
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
rtc_sleep_pu(pu_cfg);
}
return reject;
}

View File

@ -0,0 +1,181 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp8684/rom/ets_sys.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/timer_group_reg.h"
#include "esp_rom_sys.h"
/* 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.
*/
/**
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
* @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
*/
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
/* On ESP8684, choosing RTC_CAL_RTC_MUX results in calibration of
* the 150k RTC clock regardless of the currenlty selected SLOW_CLK.
* On the ESP32, it used the currently selected SLOW_CLK.
* The following code emulates ESP32 behavior:
*/
if (cal_clk == RTC_CAL_RTC_MUX) {
rtc_slow_freq_t slow_freq = rtc_clk_slow_freq_get();
if (slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_freq == RTC_SLOW_FREQ_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
}
/* Enable requested clock (150k clock is always on) */
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
}
if (cal_clk == RTC_CAL_8MD256) {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
/* 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_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY));
}
}
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 (cal_clk == RTC_CAL_32K_XTAL) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_32K;
} else if (cal_clk == RTC_CAL_8MD256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_8MD256;
} else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_150K;
}
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);
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);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
if (cal_clk == RTC_CAL_8MD256) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
}
return cal_val;
}
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles;
uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX);
return ratio;
}
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
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)
{
/* 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)
{
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
return t;
}
uint64_t rtc_light_slp_time_get(void)
{
uint64_t t_wake = READ_PERI_REG(RTC_CNTL_TIME_LOW0_REG);
t_wake |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH0_REG)) << 32;
uint64_t t_slp = READ_PERI_REG(RTC_CNTL_TIME_LOW1_REG);
t_slp |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH1_REG)) << 32;
return (t_wake - t_slp);
}
uint64_t rtc_deep_slp_time_get(void)
{
uint64_t t_slp = READ_PERI_REG(RTC_CNTL_TIME_LOW1_REG);
t_slp |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH1_REG)) << 32;
uint64_t t_wake = rtc_time_get();
return (t_wake - t_slp);
}
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
{
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_SLOW_CLK_NEXT_EDGE);
while (GET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_SLOW_CLK_NEXT_EDGE)) {
esp_rom_delay_us(1);
}
}
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;
}

View File

@ -74,6 +74,11 @@
#include "esp32h2/rom/cache.h"
#include "esp32h2/rom/rtc.h"
#include "soc/extmem_reg.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp_private/esp_clk.h"
#include "esp8684/rom/cache.h"
#include "esp8684/rom/rtc.h"
#include "soc/extmem_reg.h"
#endif
// If light sleep time is less than that, don't power down flash
@ -105,6 +110,10 @@
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32H2_DEFAULT_CPU_FREQ_MHZ
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37)
#elif CONFIG_IDF_TARGET_ESP8684
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP8684_DEFAULT_CPU_FREQ_MHZ
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37)
#endif
#define LIGHT_SLEEP_TIME_OVERHEAD_US DEFAULT_HARDWARE_OUT_OVERHEAD_US
@ -454,7 +463,10 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
#else
#if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
/* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
#if !CONFIG_IDF_TARGET_ESP8684
// RTC has no rtc memory, IDF-3901
set_rtc_memory_crc();
#endif
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu);
#else
/* Otherwise, need to call the dedicated soc function for this */

View File

@ -1,5 +1,10 @@
idf_build_get_property(idf_target IDF_TARGET)
if(IDF_TARGET STREQUAL "esp8684")
# TODO : IDF-3906
return()
endif()
if(CONFIG_ESP32_NO_BLOBS OR CONFIG_ESP32S2_NO_BLOBS)
set(link_binary_libs 0)
set(ldfragments)

View File

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "soc/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Power management config for ESP8684
*
* Pass a pointer to this structure as an argument to esp_pm_configure function.
*/
typedef struct {
int max_freq_mhz; /*!< Maximum CPU frequency, in MHz */
int min_freq_mhz; /*!< Minimum CPU frequency to use when no locks are taken, in MHz */
bool light_sleep_enable; /*!< Enter light sleep when no locks are taken */
} esp_pm_config_esp8684_t;
#ifdef __cplusplus
}
#endif

View File

@ -1,16 +1,8 @@
// Copyright 2016-2017 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: 2016-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
@ -27,6 +19,8 @@
#include "esp32c3/pm.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/pm.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp8684/pm.h"
#endif
#ifdef __cplusplus

View File

@ -56,6 +56,10 @@
#include "esp32h2/clk.h"
#include "esp32h2/pm.h"
#include "driver/gpio.h"
#elif CONFIG_IDF_TARGET_ESP8684
#include "esp_private/esp_clk.h"
#include "esp8684/pm.h"
#include "driver/gpio.h"
#endif
#define MHZ (1000000)
@ -95,6 +99,9 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#define REF_CLK_DIV_MIN 2
#define DEFAULT_CPU_FREQ CONFIG_ESP32H2_DEFAULT_CPU_FREQ_MHZ
#elif CONFIG_IDF_TARGET_ESP8684
#define REF_CLK_DIV_MIN 2
#define DEFAULT_CPU_FREQ CONFIG_ESP8684_DEFAULT_CPU_FREQ_MHZ
#endif
#ifdef CONFIG_PM_PROFILING
@ -229,6 +236,8 @@ esp_err_t esp_pm_configure(const void* vconfig)
const esp_pm_config_esp32c3_t* config = (const esp_pm_config_esp32c3_t*) vconfig;
#elif CONFIG_IDF_TARGET_ESP32H2
const esp_pm_config_esp32h2_t* config = (const esp_pm_config_esp32h2_t*) vconfig;
#elif CONFIG_IDF_TARGET_ESP8684
const esp_pm_config_esp8684_t* config = (const esp_pm_config_esp8684_t*) vconfig;
#endif
#ifndef CONFIG_FREERTOS_USE_TICKLESS_IDLE
@ -337,6 +346,8 @@ esp_err_t esp_pm_get_configuration(void* vconfig)
esp_pm_config_esp32c3_t* config = (esp_pm_config_esp32c3_t*) vconfig;
#elif CONFIG_IDF_TARGET_ESP32H2
esp_pm_config_esp32h2_t* config = (esp_pm_config_esp32h2_t*) vconfig;
#elif CONFIG_IDF_TARGET_ESP8684
esp_pm_config_esp8684_t* config = (esp_pm_config_esp8684_t*) vconfig;
#endif
portENTER_CRITICAL(&s_switch_lock);
@ -766,6 +777,8 @@ void esp_pm_impl_init(void)
esp_pm_config_esp32c3_t cfg = {
#elif CONFIG_IDF_TARGET_ESP32H2
esp_pm_config_esp32h2_t cfg = {
#elif CONFIG_IDF_TARGET_ESP8684
esp_pm_config_esp8684_t cfg = {
#endif
.max_freq_mhz = DEFAULT_CPU_FREQ,
.min_freq_mhz = xtal_freq,

Some files were not shown because too many files have changed in this diff Show More