From 3934e24d22a60c81c535d2d096e631201f09168d Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Sat, 6 Nov 2021 17:23:21 +0800 Subject: [PATCH] ESP8684: add spi_flash, efuse, hw_support support --- components/efuse/efuse_table_gen.py | 3 +- components/efuse/esp8684/esp_efuse_fields.c | 54 ++ components/efuse/esp8684/esp_efuse_table.c | 390 +++++++++++++++ components/efuse/esp8684/esp_efuse_table.csv | 82 +++ components/efuse/esp8684/esp_efuse_utility.c | 43 ++ components/efuse/esp8684/include/esp_efuse.h | 54 ++ .../efuse/esp8684/include/esp_efuse_table.h | 145 ++++++ .../private_include/esp_efuse_utility.h | 21 + components/efuse/esp8684/sources.cmake | 3 + components/efuse/include/esp_efuse.h | 2 + .../efuse/src/esp_efuse_api_key_esp32xx.c | 94 ++-- components/efuse/src/esp_efuse_fields.c | 3 + components/esp_hw_support/cpu_util.c | 3 +- components/esp_hw_support/esp_clk.c | 16 +- components/esp_hw_support/hw_random.c | 2 + .../esp_hw_support/include/esp_chip_info.h | 1 + components/esp_hw_support/include/esp_mac.h | 2 + .../include/soc/esp8684/dport_access.h | 34 ++ .../include/soc/esp8684/esp_crypto_lock.h | 68 +++ .../include/soc/esp8684/memprot.h | 448 +++++++++++++++++ .../esp_hw_support/include/soc/esp8684/rtc.h | 32 ++ components/esp_hw_support/include/soc_log.h | 2 + components/esp_hw_support/intr_alloc.c | 9 +- components/esp_hw_support/linker.lf | 2 +- .../port/esp8684/CMakeLists.txt | 21 + .../esp_hw_support/port/esp8684/Kconfig.mac | 44 ++ .../esp_hw_support/port/esp8684/chip_info.c | 18 + .../port/esp8684/cpu_util_esp8684.c | 65 +++ .../port/esp8684/dport_access.c | 17 + .../port/esp8684/esp_crypto_lock.c | 71 +++ .../port/esp8684/i2c_brownout.h | 22 + .../esp_hw_support/port/esp8684/i2c_rtc_clk.h | 40 ++ .../esp8684/private_include/regi2c_bbpll.h | 175 +++++++ .../esp8684/private_include/regi2c_bias.h | 22 + .../esp8684/private_include/regi2c_brownout.h | 22 + .../esp8684/private_include/regi2c_dig_reg.h | 60 +++ .../esp8684/private_include/regi2c_lp_bias.h | 55 ++ .../esp8684/private_include/regi2c_saradc.h | 79 +++ .../esp_hw_support/port/esp8684/regi2c_ctrl.h | 88 ++++ .../esp_hw_support/port/esp8684/rtc_clk.c | 473 ++++++++++++++++++ .../port/esp8684/rtc_clk_common.h | 49 ++ .../port/esp8684/rtc_clk_init.c | 77 +++ .../esp_hw_support/port/esp8684/rtc_init.c | 279 +++++++++++ .../esp_hw_support/port/esp8684/rtc_pm.c | 59 +++ .../esp_hw_support/port/esp8684/rtc_sleep.c | 224 +++++++++ .../esp_hw_support/port/esp8684/rtc_time.c | 181 +++++++ components/esp_hw_support/sleep_modes.c | 12 + components/spi_flash/cache_utils.c | 39 +- .../spi_flash/esp8684/flash_ops_esp8684.c | 141 ++++++ .../spi_flash/esp8684/spi_flash_rom_patch.c | 18 + components/spi_flash/esp_flash_api.c | 20 +- components/spi_flash/esp_flash_spi_init.c | 9 +- components/spi_flash/flash_mmap.c | 27 +- components/spi_flash/flash_ops.c | 6 +- components/spi_flash/partition.c | 25 +- components/spi_flash/spi_flash_os_func_noos.c | 27 +- components/spi_flash/test/test_esp_flash.c | 2 + 57 files changed, 3858 insertions(+), 122 deletions(-) create mode 100644 components/efuse/esp8684/esp_efuse_fields.c create mode 100644 components/efuse/esp8684/esp_efuse_table.c create mode 100644 components/efuse/esp8684/esp_efuse_table.csv create mode 100644 components/efuse/esp8684/esp_efuse_utility.c create mode 100644 components/efuse/esp8684/include/esp_efuse.h create mode 100644 components/efuse/esp8684/include/esp_efuse_table.h create mode 100644 components/efuse/esp8684/private_include/esp_efuse_utility.h create mode 100644 components/efuse/esp8684/sources.cmake create mode 100644 components/esp_hw_support/include/soc/esp8684/dport_access.h create mode 100644 components/esp_hw_support/include/soc/esp8684/esp_crypto_lock.h create mode 100644 components/esp_hw_support/include/soc/esp8684/memprot.h create mode 100644 components/esp_hw_support/include/soc/esp8684/rtc.h create mode 100644 components/esp_hw_support/port/esp8684/CMakeLists.txt create mode 100644 components/esp_hw_support/port/esp8684/Kconfig.mac create mode 100644 components/esp_hw_support/port/esp8684/chip_info.c create mode 100644 components/esp_hw_support/port/esp8684/cpu_util_esp8684.c create mode 100644 components/esp_hw_support/port/esp8684/dport_access.c create mode 100644 components/esp_hw_support/port/esp8684/esp_crypto_lock.c create mode 100644 components/esp_hw_support/port/esp8684/i2c_brownout.h create mode 100644 components/esp_hw_support/port/esp8684/i2c_rtc_clk.h create mode 100644 components/esp_hw_support/port/esp8684/private_include/regi2c_bbpll.h create mode 100644 components/esp_hw_support/port/esp8684/private_include/regi2c_bias.h create mode 100644 components/esp_hw_support/port/esp8684/private_include/regi2c_brownout.h create mode 100644 components/esp_hw_support/port/esp8684/private_include/regi2c_dig_reg.h create mode 100644 components/esp_hw_support/port/esp8684/private_include/regi2c_lp_bias.h create mode 100644 components/esp_hw_support/port/esp8684/private_include/regi2c_saradc.h create mode 100644 components/esp_hw_support/port/esp8684/regi2c_ctrl.h create mode 100644 components/esp_hw_support/port/esp8684/rtc_clk.c create mode 100644 components/esp_hw_support/port/esp8684/rtc_clk_common.h create mode 100644 components/esp_hw_support/port/esp8684/rtc_clk_init.c create mode 100644 components/esp_hw_support/port/esp8684/rtc_init.c create mode 100644 components/esp_hw_support/port/esp8684/rtc_pm.c create mode 100644 components/esp_hw_support/port/esp8684/rtc_sleep.c create mode 100644 components/esp_hw_support/port/esp8684/rtc_time.c create mode 100644 components/spi_flash/esp8684/flash_ops_esp8684.c create mode 100644 components/spi_flash/esp8684/spi_flash_rom_patch.c diff --git a/components/efuse/efuse_table_gen.py b/components/efuse/efuse_table_gen.py index 7ec268cbbd..b7d10701c5 100755 --- a/components/efuse/efuse_table_gen.py +++ b/components/efuse/efuse_table_gen.py @@ -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') diff --git a/components/efuse/esp8684/esp_efuse_fields.c b/components/efuse/esp8684/esp_efuse_fields.c new file mode 100644 index 0000000000..8233b3c13d --- /dev/null +++ b/components/efuse/esp8684/esp_efuse_fields.c @@ -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(); +} diff --git a/components/efuse/esp8684/esp_efuse_table.c b/components/efuse/esp8684/esp_efuse_table.c new file mode 100644 index 0000000000..378f7e40bf --- /dev/null +++ b/components/efuse/esp8684/esp_efuse_table.c @@ -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 +#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 +}; diff --git a/components/efuse/esp8684/esp_efuse_table.csv b/components/efuse/esp8684/esp_efuse_table.csv new file mode 100644 index 0000000000..730ea9e4db --- /dev/null +++ b/components/efuse/esp8684/esp_efuse_table.csv @@ -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] diff --git a/components/efuse/esp8684/esp_efuse_utility.c b/components/efuse/esp8684/esp_efuse_utility.c new file mode 100644 index 0000000000..1542e9b44b --- /dev/null +++ b/components/efuse/esp8684/esp_efuse_utility.c @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "assert.h" +#include "esp_efuse_utility.h" +#include "soc/efuse_periph.h" +#include "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(); +} diff --git a/components/efuse/esp8684/include/esp_efuse.h b/components/efuse/esp8684/include/esp_efuse.h new file mode 100644 index 0000000000..245bb0f5ae --- /dev/null +++ b/components/efuse/esp8684/include/esp_efuse.h @@ -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 diff --git a/components/efuse/esp8684/include/esp_efuse_table.h b/components/efuse/esp8684/include/esp_efuse_table.h new file mode 100644 index 0000000000..3ebc34ac27 --- /dev/null +++ b/components/efuse/esp8684/include/esp_efuse_table.h @@ -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 diff --git a/components/efuse/esp8684/private_include/esp_efuse_utility.h b/components/efuse/esp8684/private_include/esp_efuse_utility.h new file mode 100644 index 0000000000..37573eea8f --- /dev/null +++ b/components/efuse/esp8684/private_include/esp_efuse_utility.h @@ -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 diff --git a/components/efuse/esp8684/sources.cmake b/components/efuse/esp8684/sources.cmake new file mode 100644 index 0000000000..32e2583fcc --- /dev/null +++ b/components/efuse/esp8684/sources.cmake @@ -0,0 +1,3 @@ +set(EFUSE_SOC_SRCS "esp_efuse_table.c" + "esp_efuse_fields.c" + "esp_efuse_utility.c") diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index a44aa79872..f84f090246 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -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. */ diff --git a/components/efuse/src/esp_efuse_api_key_esp32xx.c b/components/efuse/src/esp_efuse_api_key_esp32xx.c index eb745ad769..091a04e2c2 100644 --- a/components/efuse/src/esp_efuse_api_key_esp32xx.c +++ b/components/efuse/src/esp_efuse_api_key_esp32xx.c @@ -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 diff --git a/components/efuse/src/esp_efuse_fields.c b/components/efuse/src/esp_efuse_fields.c index 5e27f936c2..330bf8e327 100644 --- a/components/efuse/src/esp_efuse_fields.c +++ b/components/efuse/src/esp_efuse_fields.c @@ -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 diff --git a/components/esp_hw_support/cpu_util.c b/components/esp_hw_support/cpu_util.c index 54700e2b69..a101ce6a03 100644 --- a/components/esp_hw_support/cpu_util.c +++ b/components/esp_hw_support/cpu_util.c @@ -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 diff --git a/components/esp_hw_support/esp_clk.c b/components/esp_hw_support/esp_clk.c index 591a33370b..01c5e6d0b0 100644 --- a/components/esp_hw_support/esp_clk.c +++ b/components/esp_hw_support/esp_clk.c @@ -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(); diff --git a/components/esp_hw_support/hw_random.c b/components/esp_hw_support/hw_random.c index 9ba4e66a15..d0d32f4d43 100644 --- a/components/esp_hw_support/hw_random.c +++ b/components/esp_hw_support/hw_random.c @@ -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) diff --git a/components/esp_hw_support/include/esp_chip_info.h b/components/esp_hw_support/include/esp_chip_info.h index 69d23c08d3..527e0a8cd0 100644 --- a/components/esp_hw_support/include/esp_chip_info.h +++ b/components/esp_hw_support/include/esp_chip_info.h @@ -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 */ diff --git a/components/esp_hw_support/include/esp_mac.h b/components/esp_hw_support/include/esp_mac.h index f0efddfc2f..3a3a006a22 100644 --- a/components/esp_hw_support/include/esp_mac.h +++ b/components/esp_hw_support/include/esp_mac.h @@ -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 */ diff --git a/components/esp_hw_support/include/soc/esp8684/dport_access.h b/components/esp_hw_support/include/soc/esp8684/dport_access.h new file mode 100644 index 0000000000..e5aedd2e1b --- /dev/null +++ b/components/esp_hw_support/include/soc/esp8684/dport_access.h @@ -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 + +#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_ */ diff --git a/components/esp_hw_support/include/soc/esp8684/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp8684/esp_crypto_lock.h new file mode 100644 index 0000000000..67a08741b5 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp8684/esp_crypto_lock.h @@ -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 diff --git a/components/esp_hw_support/include/soc/esp8684/memprot.h b/components/esp_hw_support/include/soc/esp8684/memprot.h new file mode 100644 index 0000000000..0954e46cb6 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp8684/memprot.h @@ -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 +#include +#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 diff --git a/components/esp_hw_support/include/soc/esp8684/rtc.h b/components/esp_hw_support/include/soc/esp8684/rtc.h new file mode 100644 index 0000000000..b8aef36805 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp8684/rtc.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#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 diff --git a/components/esp_hw_support/include/soc_log.h b/components/esp_hw_support/include/soc_log.h index 64268433fb..4ce812e1a5 100644 --- a/components/esp_hw_support/include/soc_log.h +++ b/components/esp_hw_support/include/soc_log.h @@ -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__) diff --git a/components/esp_hw_support/intr_alloc.c b/components/esp_hw_support/intr_alloc.c index 208653cdf4..3aca2fa4eb 100644 --- a/components/esp_hw_support/intr_alloc.c +++ b/components/esp_hw_support/intr_alloc.c @@ -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; } diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index e8adfc884d..0a542bccff 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -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: diff --git a/components/esp_hw_support/port/esp8684/CMakeLists.txt b/components/esp_hw_support/port/esp8684/CMakeLists.txt new file mode 100644 index 0000000000..c1725ecac1 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/CMakeLists.txt @@ -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) diff --git a/components/esp_hw_support/port/esp8684/Kconfig.mac b/components/esp_hw_support/port/esp8684/Kconfig.mac new file mode 100644 index 0000000000..23a18c0237 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/Kconfig.mac @@ -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 diff --git a/components/esp_hw_support/port/esp8684/chip_info.c b/components/esp_hw_support/port/esp8684/chip_info.c new file mode 100644 index 0000000000..d3ab76f620 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/chip_info.c @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2013-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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; +} diff --git a/components/esp_hw_support/port/esp8684/cpu_util_esp8684.c b/components/esp_hw_support/port/esp8684/cpu_util_esp8684.c new file mode 100644 index 0000000000..096b4c960e --- /dev/null +++ b/components/esp_hw_support/port/esp8684/cpu_util_esp8684.c @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#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); +} diff --git a/components/esp_hw_support/port/esp8684/dport_access.c b/components/esp_hw_support/port/esp8684/dport_access.c new file mode 100644 index 0000000000..8364f5687e --- /dev/null +++ b/components/esp_hw_support/port/esp8684/dport_access.c @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#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); + } +} diff --git a/components/esp_hw_support/port/esp8684/esp_crypto_lock.c b/components/esp_hw_support/port/esp8684/esp_crypto_lock.c new file mode 100644 index 0000000000..e8f8aeb9c6 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/esp_crypto_lock.c @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_crypto_lock.h" + +/* Lock overview: +SHA: peripheral independent, but DMA is shared with AES +AES: peripheral independent, but DMA is shared with SHA +MPI/RSA: independent +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 +} diff --git a/components/esp_hw_support/port/esp8684/i2c_brownout.h b/components/esp_hw_support/port/esp8684/i2c_brownout.h new file mode 100644 index 0000000000..1d2ab34411 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/i2c_brownout.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/i2c_rtc_clk.h b/components/esp_hw_support/port/esp8684/i2c_rtc_clk.h new file mode 100644 index 0000000000..dbb7d73dc4 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/i2c_rtc_clk.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#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) diff --git a/components/esp_hw_support/port/esp8684/private_include/regi2c_bbpll.h b/components/esp_hw_support/port/esp8684/private_include/regi2c_bbpll.h new file mode 100644 index 0000000000..8235741d58 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/private_include/regi2c_bbpll.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/private_include/regi2c_bias.h b/components/esp_hw_support/port/esp8684/private_include/regi2c_bias.h new file mode 100644 index 0000000000..35e859fda6 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/private_include/regi2c_bias.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/private_include/regi2c_brownout.h b/components/esp_hw_support/port/esp8684/private_include/regi2c_brownout.h new file mode 100644 index 0000000000..1aa54a2017 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/private_include/regi2c_brownout.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/private_include/regi2c_dig_reg.h b/components/esp_hw_support/port/esp8684/private_include/regi2c_dig_reg.h new file mode 100644 index 0000000000..9d2032b60e --- /dev/null +++ b/components/esp_hw_support/port/esp8684/private_include/regi2c_dig_reg.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/private_include/regi2c_lp_bias.h b/components/esp_hw_support/port/esp8684/private_include/regi2c_lp_bias.h new file mode 100644 index 0000000000..c50c1a941a --- /dev/null +++ b/components/esp_hw_support/port/esp8684/private_include/regi2c_lp_bias.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/private_include/regi2c_saradc.h b/components/esp_hw_support/port/esp8684/private_include/regi2c_saradc.h new file mode 100644 index 0000000000..1c35fd61ef --- /dev/null +++ b/components/esp_hw_support/port/esp8684/private_include/regi2c_saradc.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/regi2c_ctrl.h b/components/esp_hw_support/port/esp8684/regi2c_ctrl.h new file mode 100644 index 0000000000..a4d25628f9 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/regi2c_ctrl.h @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#include +#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 diff --git a/components/esp_hw_support/port/esp8684/rtc_clk.c b/components/esp_hw_support/port/esp8684/rtc_clk.c new file mode 100644 index 0000000000..5cc9c63654 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_clk.c @@ -0,0 +1,473 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#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"))); diff --git a/components/esp_hw_support/port/esp8684/rtc_clk_common.h b/components/esp_hw_support/port/esp8684/rtc_clk_common.h new file mode 100644 index 0000000000..07f8c1243c --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_clk_common.h @@ -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 diff --git a/components/esp_hw_support/port/esp8684/rtc_clk_init.c b/components/esp_hw_support/port/esp8684/rtc_clk_init.c new file mode 100644 index 0000000000..8b573ba0d5 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_clk_init.c @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#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); +} diff --git a/components/esp_hw_support/port/esp8684/rtc_init.c b/components/esp_hw_support/port/esp8684/rtc_init.c new file mode 100644 index 0000000000..a95737bbfd --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_init.c @@ -0,0 +1,279 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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); +} diff --git a/components/esp_hw_support/port/esp8684/rtc_pm.c b/components/esp_hw_support/port/esp8684/rtc_pm.c new file mode 100644 index 0000000000..c73ae9edf3 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_pm.c @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#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; +} diff --git a/components/esp_hw_support/port/esp8684/rtc_sleep.c b/components/esp_hw_support/port/esp8684/rtc_sleep.c new file mode 100644 index 0000000000..e0b5f251d2 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_sleep.c @@ -0,0 +1,224 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#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; +} diff --git a/components/esp_hw_support/port/esp8684/rtc_time.c b/components/esp_hw_support/port/esp8684/rtc_time.c new file mode 100644 index 0000000000..580179d5d0 --- /dev/null +++ b/components/esp_hw_support/port/esp8684/rtc_time.c @@ -0,0 +1,181 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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; +} diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 3d68397abd..632b1a19ed 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -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 */ diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index dedd5f2b35..4a92c51f75 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -1,16 +1,8 @@ -// 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 + */ #include #include @@ -44,6 +36,11 @@ #include "esp32h2/rom/cache.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#elif CONFIG_IDF_TARGET_ESP8684 +#include "esp8684/rom/spi_flash.h" +#include "esp8684/rom/cache.h" +#include "soc/extmem_reg.h" +#include "soc/cache_memory.h" #endif #include #include "sdkconfig.h" @@ -324,7 +321,7 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_st icache_state = Cache_Suspend_ICache() << 16; dcache_state = Cache_Suspend_DCache(); *saved_state = icache_state | dcache_state; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 uint32_t icache_state; icache_state = Cache_Suspend_ICache() << 16; *saved_state = icache_state; @@ -350,7 +347,7 @@ static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_sta #elif CONFIG_IDF_TARGET_ESP32S3 Cache_Resume_DCache(saved_state & 0xffff); Cache_Resume_ICache(saved_state >> 16); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 Cache_Resume_ICache(saved_state >> 16); #endif } @@ -364,7 +361,7 @@ IRAM_ATTR bool spi_flash_cache_enabled(void) #endif #elif CONFIG_IDF_TARGET_ESP32S2 bool result = (REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE) != 0); -#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 bool result = (REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE) != 0); #endif return result; @@ -479,19 +476,19 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable int i; bool flash_spiram_wrap_together, flash_support_wrap = true, spiram_support_wrap = true; uint32_t drom0_in_icache = 1;//always 1 in esp32s2 -#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 drom0_in_icache = 0; #endif if (icache_wrap_enable) { -#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32C3_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32H2_INSTRUCTION_CACHE_LINE_16B +#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32C3_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32H2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP8684_INSTRUCTION_CACHE_LINE_16B icache_wrap_size = 16; #else icache_wrap_size = 32; #endif } if (dcache_wrap_enable) { -#if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B || CONFIG_ESP32C3_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32H2_INSTRUCTION_CACHE_LINE_16B +#if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B || CONFIG_ESP32C3_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32H2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP8684_INSTRUCTION_CACHE_LINE_16B dcache_wrap_size = 16; #else dcache_wrap_size = 32; @@ -880,7 +877,7 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable } #endif -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache) { @@ -922,7 +919,7 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) } return ESP_OK; } -#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) { diff --git a/components/spi_flash/esp8684/flash_ops_esp8684.c b/components/spi_flash/esp8684/flash_ops_esp8684.c new file mode 100644 index 0000000000..b90f90215e --- /dev/null +++ b/components/spi_flash/esp8684/flash_ops_esp8684.c @@ -0,0 +1,141 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "esp_spi_flash.h" +#include "soc/system_reg.h" +#include "soc/soc_memory_layout.h" +#include "esp8684/rom/spi_flash.h" +#include "esp8684/rom/cache.h" +#include "hal/spi_flash_hal.h" +#include "esp_flash.h" +#include "esp_log.h" +#include "esp_attr.h" + +static const char *TAG = "spiflash_c3"; + +#define SPICACHE SPIMEM0 +#define SPIFLASH SPIMEM1 + +extern void IRAM_ATTR flash_rom_init(void); +esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size) +{ + const spi_flash_guard_funcs_t *ops = spi_flash_guard_get(); + esp_rom_spiflash_result_t rc; + + assert((dest_addr % 16) == 0); + assert((size % 16) == 0); + + /* src needs to be 32 bit aligned */ + if (!esp_ptr_internal(src) || (intptr_t)src & 0x3) { + WORD_ALIGNED_ATTR uint8_t block[128]; // Need to buffer in RAM as we write + while (size > 0) { + size_t next_block = MIN(size, sizeof(block)); + memcpy(block, src, next_block); + + esp_rom_spiflash_result_t r = spi_flash_write_encrypted_chip(dest_addr, block, next_block); + if (r != ESP_ROM_SPIFLASH_RESULT_OK) { + return r; + } + + size -= next_block; + dest_addr += next_block; + src = ((uint8_t *)src) + next_block; + } + bzero(block, sizeof(block)); + + return ESP_ROM_SPIFLASH_RESULT_OK; + } else { // Already in internal memory + ESP_LOGV(TAG, "calling esp_rom_spiflash_write_encrypted addr 0x%x src %p size 0x%x", dest_addr, src, size); + +#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL + /* The ROM function SPI_Encrypt_Write assumes ADDR_BITLEN is already set but new + implementation doesn't automatically set this to a usable value */ + SPIFLASH.user1.usr_addr_bitlen = 23; +#endif + + if (ops && ops->start) { + ops->start(); + } + flash_rom_init(); + rc = esp_rom_spiflash_write_encrypted(dest_addr, (uint32_t *)src, size); + if (ops && ops->end) { + ops->end(); + } + return rc; + } +} + +#define FLASH_WRAP_CMD 0x77 +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; + uint32_t reg_bkp_usr = SPIFLASH.user.val; + SPIFLASH.user.fwrite_dio = 0; + SPIFLASH.user.fwrite_dual = 0; + SPIFLASH.user.fwrite_qio = 1; + SPIFLASH.user.fwrite_quad = 0; + SPIFLASH.ctrl.fcmd_dual = 0; + SPIFLASH.ctrl.fcmd_quad = 0; + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 1; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD; + SPIFLASH.user1.usr_addr_bitlen = 23; + SPIFLASH.addr = 0; + SPIFLASH.user.usr_miso = 0; + SPIFLASH.user.usr_mosi = 1; + SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7; + SPIFLASH.data_buf[0] = (uint32_t) mode << 4;; + SPIFLASH.cmd.usr = 1; + while (SPIFLASH.cmd.usr != 0) + { } + + SPIFLASH.ctrl.val = reg_bkp_ctrl; + SPIFLASH.user.val = reg_bkp_usr; + return ESP_OK; +} + +esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) +{ + switch (wrap_size) { + case 8: + return spi_flash_wrap_set(FLASH_WRAP_MODE_8B); + case 16: + return spi_flash_wrap_set(FLASH_WRAP_MODE_16B); + case 32: + return spi_flash_wrap_set(FLASH_WRAP_MODE_32B); + case 64: + return spi_flash_wrap_set(FLASH_WRAP_MODE_64B); + default: + return ESP_FAIL; + } +} + +void spi_flash_disable_wrap(void) +{ + spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); +} + +bool spi_flash_support_wrap_size(uint32_t wrap_size) +{ + if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) { + return ESP_FAIL; + } + switch (wrap_size) { + case 0: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} diff --git a/components/spi_flash/esp8684/spi_flash_rom_patch.c b/components/spi_flash/esp8684/spi_flash_rom_patch.c new file mode 100644 index 0000000000..a48d22222b --- /dev/null +++ b/components/spi_flash/esp8684/spi_flash_rom_patch.c @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "esp8684/rom/spi_flash.h" +#include "soc/spi_periph.h" +#include "spi_flash_defs.h" + +#define SPI_IDX 1 + +esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void) +{ + REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WRDI); + while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); + return ESP_ROM_SPIFLASH_RESULT_OK; +} diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index dacfda2580..7d0489a913 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -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 #include @@ -37,6 +29,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 static const char TAG[] = "spi_flash"; diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 8fce5a47de..36441c148e 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -27,9 +27,13 @@ #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/efuse.h" #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/efuse.h" +#include "esp8684/rom/spi_flash.h" #endif __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -100,8 +104,7 @@ esp_flash_t *esp_flash_default_chip = NULL; .input_delay_ns = 0,\ .cs_setup = 1,\ } -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/efuse.h" +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684 #if !CONFIG_SPI_FLASH_AUTO_SUSPEND #define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ .host_id = SPI1_HOST,\ @@ -284,7 +287,7 @@ esp_err_t esp_flash_init_default_chip(void) const esp_rom_spiflash_chip_t *legacy_chip = &g_rom_flashchip; memspi_host_config_t cfg = ESP_FLASH_HOST_CONFIG_DEFAULT(); - #if !CONFIG_IDF_TARGET_ESP32 + #if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP8684 // For esp32s2 spi IOs are configured as from IO MUX by default cfg.iomux = esp_rom_efuse_get_flash_gpio_info() == 0 ? true : false; #endif diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 9523bc7959..4de236cc56 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -1,16 +1,8 @@ -// 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 + */ #include #include @@ -36,6 +28,8 @@ #include "esp32/rom/spi_flash.h" #include "esp32/spiram.h" #include "soc/mmu.h" +// TODO: IDF-3821 +#define INVALID_PHY_PAGE 0xffff #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/cache.h" #include "esp32s2/rom/spi_flash.h" @@ -60,6 +54,11 @@ #include "esp32h2/rom/spi_flash.h" #include "soc/cache_memory.h" #include "soc/mmu.h" +#elif CONFIG_IDF_TARGET_ESP8684 +#include "esp8684/rom/cache.h" +#include "esp8684/rom/spi_flash.h" +#include "soc/cache_memory.h" +#include "soc/mmu.h" #endif #ifndef NDEBUG @@ -136,7 +135,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ const void** out_ptr, spi_flash_mmap_handle_t* out_handle) { esp_err_t ret; - if (src_addr & 0xffff) { + if (src_addr & INVALID_PHY_PAGE) { return ESP_ERR_INVALID_ARG; } if (src_addr + size > g_rom_flashchip.chip_size) { diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index d3b696c96a..47e2d4c5e8 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,6 +45,10 @@ #include "esp32h2/rom/cache.h" #include "esp32h2/rom/spi_flash.h" #include "esp32h2/clk.h" +#elif CONFIG_IDF_TARGET_ESP8684 +#include "esp8684/rom/cache.h" +#include "esp8684/rom/spi_flash.h" +#include "esp_private/esp_clk.h" #endif #include "esp_flash_partitions.h" #include "cache_utils.h" diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index 506afc6caa..b4a0f3c5c1 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -1,16 +1,8 @@ -// 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 + */ #include #include @@ -181,13 +173,15 @@ static esp_err_t load_partitions(void) #endif // map 64kB block where partition table is located - esp_err_t err = spi_flash_mmap(ESP_PARTITION_TABLE_OFFSET & 0xffff0000, + uint32_t partition_align_pg_size = (ESP_PARTITION_TABLE_OFFSET) & ~(0x10000 - 1); + uint32_t partition_pad = ESP_PARTITION_TABLE_OFFSET - partition_align_pg_size; + esp_err_t err = spi_flash_mmap(partition_align_pg_size, SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_DATA, (const void **)&p_start, &handle); if (err != ESP_OK) { return err; } // calculate partition address within mmap-ed region - p_start += (ESP_PARTITION_TABLE_OFFSET & 0xffff); + p_start += partition_pad; p_end = p_start + SPI_FLASH_SEC_SIZE; for(const uint8_t *p_entry = p_start; p_entry < p_end; p_entry += sizeof(esp_partition_info_t)) { @@ -256,6 +250,7 @@ static esp_err_t load_partitions(void) esp_rom_md5_final(calc_md5, &context); + ESP_LOG_BUFFER_HEXDUMP("calculated md5", calc_md5, ESP_ROM_MD5_DIGEST_LEN, ESP_LOG_VERBOSE); ESP_LOG_BUFFER_HEXDUMP("stored md5", stored_md5, ESP_ROM_MD5_DIGEST_LEN, ESP_LOG_VERBOSE); diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index 6d61f8b82b..a04eeedfb4 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -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 #include "sdkconfig.h" @@ -31,6 +23,9 @@ #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/ets_sys.h" #include "esp32h2/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP8684 +#include "esp8684/rom/ets_sys.h" +#include "esp8684/rom/cache.h" #endif #include "esp_attr.h" @@ -42,7 +37,7 @@ typedef struct { } spi_noos_arg_t; static DRAM_ATTR spi_noos_arg_t spi_arg = { 0 }; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 typedef struct { uint32_t icache_autoload; } spi_noos_arg_t; @@ -59,7 +54,7 @@ static IRAM_ATTR esp_err_t start(void *arg) spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); spi_arg->dcache_autoload = Cache_Suspend_DCache(); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); #endif @@ -78,7 +73,7 @@ static IRAM_ATTR esp_err_t end(void *arg) Cache_Invalidate_ICache_All(); Cache_Resume_ICache(spi_arg->icache_autoload); Cache_Resume_DCache(spi_arg->dcache_autoload); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 spi_noos_arg_t *spi_arg = arg; Cache_Invalidate_ICache_All(); Cache_Resume_ICache(spi_arg->icache_autoload); diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c index 27d7c228e6..bbf61a7d61 100644 --- a/components/spi_flash/test/test_esp_flash.c +++ b/components/spi_flash/test/test_esp_flash.c @@ -32,6 +32,8 @@ #include "esp32c3/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP8684 +#include "esp8684/rom/cache.h" #endif #define FUNC_SPI 1