ESP8684: add spi_flash, efuse, hw_support support

This commit is contained in:
Cao Sen Miao 2021-11-06 17:23:21 +08:00
parent bf6fa70812
commit 3934e24d22
57 changed files with 3858 additions and 122 deletions

View File

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

View File

@ -0,0 +1,54 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_efuse.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_table.h"
#include "stdlib.h"
#include "esp_types.h"
#include "esp8684/rom/efuse.h"
#include "assert.h"
#include "esp_err.h"
#include "esp_log.h"
#include "soc/efuse_periph.h"
#include "bootloader_random.h"
#include "sys/param.h"
static __attribute__((unused)) const char *TAG = "efuse";
// Contains functions that provide access to efuse fields which are often used in IDF.
// Returns chip version from efuse
uint8_t esp_efuse_get_chip_ver(void)
{
uint32_t chip_ver = 0;
esp_efuse_read_field_blob(ESP_EFUSE_WAFER_VERSION, &chip_ver, ESP_EFUSE_WAFER_VERSION[0]->bit_count);
return chip_ver;
}
// Returns chip package from efuse
uint32_t esp_efuse_get_pkg_ver(void)
{
uint32_t pkg_ver = 0;
esp_efuse_read_field_blob(ESP_EFUSE_PKG_VERSION, &pkg_ver, ESP_EFUSE_PKG_VERSION[0]->bit_count);
return pkg_ver;
}
esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme)
{
abort();
}
esp_err_t esp_efuse_disable_rom_download_mode(void)
{
abort();
}
esp_err_t esp_efuse_enable_rom_secure_download_mode(void)
{
abort();
}

View File

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

View File

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

View File

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "assert.h"
#include "esp_efuse_utility.h"
#include "soc/efuse_periph.h"
#include "esp_private/esp_clk.h"
#include "esp8684/rom/efuse.h"
/*Range addresses to read blocks*/
const esp_efuse_range_addr_t range_read_addr_blocks[] = {
{EFUSE_RD_WR_DIS_REG, EFUSE_RD_REPEAT_DATA0_REG}, // range address of EFUSE_BLK0 REPEAT
{EFUSE_RD_BLK1_DATA0_REG, EFUSE_RD_BLK1_DATA2_REG}, // range address of EFUSE_BLK1 SYS_DATA_PART0
{EFUSE_RD_BLK2_DATA0_REG, EFUSE_RD_BLK2_DATA7_REG}, // range address of EFUSE_BLK2 SYS_DATA_PART_1
{EFUSE_RD_BLK3_DATA0_REG, EFUSE_RD_BLK3_DATA7_REG}, // range address of EFUSE_BLK3 KEY0
};
// Efuse read operation: copies data from physical efuses to efuse read registers.
void esp_efuse_utility_clear_program_registers(void)
{
abort();
}
// Burn values written to the efuse write registers
void esp_efuse_utility_burn_chip(void)
{
abort();
}
// After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values.
// This function reads EFUSE_BLKx_WDATAx_REG registers, and checks possible to write these data with RS coding scheme.
// The RS coding scheme does not require data changes for the encoded data. esp32s2 has special registers for this.
// They will be filled during the burn operation.
esp_err_t esp_efuse_utility_apply_new_coding_scheme()
{
abort();
}

View File

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

View File

@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
// md5_digest_table 3f91b5a37afbcdf1379820626a92e69c
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
// To show efuse_table run the command 'show_efuse_table'.
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_2[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY1_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY2_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY3_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY4_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY5_PURPOSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_3[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_USER_DATA[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY2[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY3[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY4[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY5[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART2[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY1[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY2[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY3[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY4[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY5[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_SYS_DATA_PART2[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_RTC_RAM_BOOT[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_ICACHE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DEVICE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_CAN[];
extern const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_DREFH[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_DREFL[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_EXCHG_PINS[];
extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_AS_GPIO[];
extern const esp_efuse_desc_t* ESP_EFUSE_BTLC_GPIO_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_POWERGLITCH_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_POWER_GLITCH_DSENSE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_CRYPT_CNT[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_0[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_2[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_3[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_4[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_5[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_LEGACY_SPI_BOOT[];
extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[];
extern const esp_efuse_desc_t* ESP_EFUSE_PIN_POWER_SELECTION[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TYPE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_PAGE_SIZE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CLK[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_Q_D1[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D_D0[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CS[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_HD_D3[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_WP_D2[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_DQS[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D4[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D5[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D6[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[];
extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK1_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[];
extern const esp_efuse_desc_t* ESP_EFUSE_OCODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN1[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[];
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY2[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY3[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY4[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY5[];
extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART2[];
extern const esp_efuse_desc_t* ESP_EFUSE_K_RTC_LDO[];
extern const esp_efuse_desc_t* ESP_EFUSE_K_DIG_LDO[];
extern const esp_efuse_desc_t* ESP_EFUSE_V_RTC_DBIAS20[];
extern const esp_efuse_desc_t* ESP_EFUSE_V_DIG_DBIAS20[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIG_DBIAS_HVT[];
extern const esp_efuse_desc_t* ESP_EFUSE_THRES_HVT[];
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */
#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0
#define ESP_EFUSE_FIELD_CORRESPONDS_CODING_SCHEME(scheme, max_num_bit)
#ifdef __cplusplus
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Read a sequence of DPORT registers to the buffer.
*
* @param[out] buff_out Contains the read data.
* @param[in] address Initial address for reading registers.
* @param[in] num_words The number of words.
*/
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words);
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Acquire lock for HMAC cryptography peripheral
*
* Internally also locks the SHA peripheral, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_acquire(void);
/**
* @brief Release lock for HMAC cryptography peripheral
*
* Internally also releases the SHA peripheral, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_release(void);
/**
* @brief Acquire lock for DS cryptography peripheral
*
* Internally also locks the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
*/
void esp_crypto_ds_lock_acquire(void);
/**
* @brief Release lock for DS cryptography peripheral
*
* Internally also releases the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
*/
void esp_crypto_ds_lock_release(void);
/**
* @brief Acquire lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_acquire(void);
/**
* @brief Release lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_release(void);
/**
* @brief Acquire lock for the mpi cryptography peripheral.
*
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* @brief Release lock for the mpi/rsa cryptography peripheral.
*
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}
#endif

View File

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

View File

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp8684/rtc.h
*
* This file contains declarations of rtc related functions.
*/
/**
* @brief Get current value of RTC counter in microseconds
*
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
*
* @return current value of RTC counter in microseconds
*/
uint64_t esp_rtc_get_time_us(void);
#ifdef __cplusplus
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,44 @@
choice ESP8684_UNIVERSAL_MAC_ADDRESSES
bool "Number of universally administered (by IEEE) MAC address"
default ESP8684_UNIVERSAL_MAC_ADDRESSES_FOUR
help
Configure the number of universally administered (by IEEE) MAC addresses.
During initialization, MAC addresses for each network interface are generated or derived from a
single base MAC address.
If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap,
Bluetooth and Ethernet) receive a universally administered MAC address. These are generated
sequentially by adding 0, 1, 2 and 3 (respectively) to the final octet of the base MAC address.
If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth)
receive a universally administered MAC address. These are generated sequentially by adding 0
and 1 (respectively) to the base MAC address. The remaining two interfaces (WiFi softap and Ethernet)
receive local MAC addresses. These are derived from the universal WiFi station and Bluetooth MAC
addresses, respectively.
When using the default (Espressif-assigned) base MAC address, either setting can be used. When using
a custom universal MAC address range, the correct setting will depend on the allocation of MAC
addresses in this range (either 2 or 4 per device.)
Note that ESP-8684 has no integrated Ethernet MAC. Although it's possible to use the esp_read_mac()
API to return a MAC for Ethernet, this can only be used with an external MAC peripheral.
config ESP8684_UNIVERSAL_MAC_ADDRESSES_TWO
bool "Two"
select ESP_MAC_ADDR_UNIVERSE_WIFI_STA
select ESP_MAC_ADDR_UNIVERSE_BT
config ESP8684_UNIVERSAL_MAC_ADDRESSES_FOUR
bool "Four"
select ESP_MAC_ADDR_UNIVERSE_WIFI_STA
select ESP_MAC_ADDR_UNIVERSE_WIFI_AP
select ESP_MAC_ADDR_UNIVERSE_BT
select ESP_MAC_ADDR_UNIVERSE_ETH
endchoice
config ESP8684_UNIVERSAL_MAC_ADDRESSES
# TODO: check 8684 mac address WIFI-4134
int
default 2 if ESP8684_UNIVERSAL_MAC_ADDRESSES_TWO
default 4 if ESP8684_UNIVERSAL_MAC_ADDRESSES_FOUR

View File

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

View File

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

View File

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

View File

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/lock.h>
#include <stdlib.h>
#include "esp_crypto_lock.h"
/* Lock overview:
SHA: peripheral independent, but DMA is shared with AES
AES: peripheral independent, but DMA is shared with SHA
MPI/RSA: independent
HMAC: needs SHA
DS: needs HMAC (which needs SHA), AES and MPI
*/
#if 0 // TODO: IDF-4229
/* Lock for DS peripheral */
static _lock_t s_crypto_ds_lock;
/* Lock for HMAC peripheral */
static _lock_t s_crypto_hmac_lock;
/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */
static _lock_t s_crypto_mpi_lock;
/* Single lock for SHA and AES, sharing a reserved GDMA channel */
static _lock_t s_crypto_sha_aes_lock;
#endif
void esp_crypto_hmac_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_hmac_lock_release(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_ds_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_ds_lock_release(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_sha_aes_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_sha_aes_lock_release(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_mpi_lock_acquire(void)
{
abort(); // TODO: IDF-4229
}
void esp_crypto_mpi_lock_release(void)
{
abort(); // TODO: IDF-4229
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_bias.h
* @brief Register definitions for bias
*
* This file lists register fields of BIAS. These definitions are used via macros defined in regi2c_ctrl.h, by
* bootloader_hardware_init function in bootloader_esp8684.c.
*/
#define I2C_BIAS 0X6A
#define I2C_BIAS_HOSTID 0
#define I2C_BIAS_DREG_1P1_PVT 1
#define I2C_BIAS_DREG_1P1_PVT_MSB 3
#define I2C_BIAS_DREG_1P1_PVT_LSB 0

View File

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

View File

@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_dig_reg.h
* @brief Register definitions for digital to get rtc voltage & digital voltage
* by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration.
*/
#define I2C_DIG_REG 0x6D
#define I2C_DIG_REG_HOSTID 0
#define I2C_DIG_REG_EXT_RTC_DREG 4
#define I2C_DIG_REG_EXT_RTC_DREG_MSB 4
#define I2C_DIG_REG_EXT_RTC_DREG_LSB 0
#define I2C_DIG_REG_ENX_RTC_DREG 4
#define I2C_DIG_REG_ENX_RTC_DREG_MSB 7
#define I2C_DIG_REG_ENX_RTC_DREG_LSB 7
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP 5
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB 4
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB 0
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP 5
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP_MSB 7
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP_LSB 7
#define I2C_DIG_REG_EXT_DIG_DREG 6
#define I2C_DIG_REG_EXT_DIG_DREG_MSB 4
#define I2C_DIG_REG_EXT_DIG_DREG_LSB 0
#define I2C_DIG_REG_ENX_DIG_DREG 6
#define I2C_DIG_REG_ENX_DIG_DREG_MSB 7
#define I2C_DIG_REG_ENX_DIG_DREG_LSB 7
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP 7
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB 4
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB 0
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP 7
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP_MSB 7
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP_LSB 7
#define I2C_DIG_REG_OR_EN_CONT_CAL 9
#define I2C_DIG_REG_OR_EN_CONT_CAL_MSB 7
#define I2C_DIG_REG_OR_EN_CONT_CAL_LSB 7
#define I2C_DIG_REG_XPD_RTC_REG 13
#define I2C_DIG_REG_XPD_RTC_REG_MSB 2
#define I2C_DIG_REG_XPD_RTC_REG_LSB 2
#define I2C_DIG_REG_XPD_DIG_REG 13
#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
#define I2C_DIG_REG_XPD_DIG_REG_LSB 3

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,181 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp8684/rom/ets_sys.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/timer_group_reg.h"
#include "esp_rom_sys.h"
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
*/
/**
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @return number of XTAL clock cycles within the given number of slow clock cycles
*/
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
/* On ESP8684, choosing RTC_CAL_RTC_MUX results in calibration of
* the 150k RTC clock regardless of the currenlty selected SLOW_CLK.
* On the ESP32, it used the currently selected SLOW_CLK.
* The following code emulates ESP32 behavior:
*/
if (cal_clk == RTC_CAL_RTC_MUX) {
rtc_slow_freq_t slow_freq = rtc_clk_slow_freq_get();
if (slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_freq == RTC_SLOW_FREQ_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
}
/* Enable requested clock (150k clock is always on) */
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
}
if (cal_clk == RTC_CAL_8MD256) {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
/* There may be another calibration process already running during we call this function,
* so we should wait the last process is done.
*/
if (!GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY));
}
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/
uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_XTAL) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_32K;
} else if (cal_clk == RTC_CAL_8MD256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_8MD256;
} else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_150K;
}
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
/* Start calibration */
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* Wait for calibration to finish up to another us_time_estimate */
esp_rom_delay_us(us_time_estimate);
uint32_t cal_val;
while (true) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
break;
}
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
cal_val = 0;
break;
}
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
if (cal_clk == RTC_CAL_8MD256) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
}
return cal_val;
}
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles;
uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX);
return ratio;
}
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
return period;
}
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}
uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
{
return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
}
uint64_t rtc_time_get(void)
{
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
return t;
}
uint64_t rtc_light_slp_time_get(void)
{
uint64_t t_wake = READ_PERI_REG(RTC_CNTL_TIME_LOW0_REG);
t_wake |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH0_REG)) << 32;
uint64_t t_slp = READ_PERI_REG(RTC_CNTL_TIME_LOW1_REG);
t_slp |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH1_REG)) << 32;
return (t_wake - t_slp);
}
uint64_t rtc_deep_slp_time_get(void)
{
uint64_t t_slp = READ_PERI_REG(RTC_CNTL_TIME_LOW1_REG);
t_slp |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH1_REG)) << 32;
uint64_t t_wake = rtc_time_get();
return (t_wake - t_slp);
}
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
{
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_SLOW_CLK_NEXT_EDGE);
while (GET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_SLOW_CLK_NEXT_EDGE)) {
esp_rom_delay_us(1);
}
}
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
{
if (cal_val == 0) {
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
}
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
}

View File

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

View File

@ -1,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 <stdlib.h>
#include <assert.h>
@ -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 <soc/soc.h>
#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)
{

View File

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

View File

@ -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;
}

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <stdio.h>
@ -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";

View File

@ -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

View File

@ -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 <stdlib.h>
#include <assert.h>
@ -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) {

View File

@ -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"

View File

@ -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 <stdlib.h>
#include <assert.h>
@ -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);

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdarg.h>
#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);

View File

@ -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