diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index 45ca958d26..fe38ea79f7 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -26,7 +26,7 @@ menu "ESP-TLS" config ESP_TLS_USE_DS_PERIPHERAL bool "Use Digital Signature (DS) Peripheral with ESP-TLS" - depends on (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S2) && ESP_TLS_USING_MBEDTLS + depends on (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32H2) && ESP_TLS_USING_MBEDTLS default y help Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral diff --git a/components/esp_adc_cal/CMakeLists.txt b/components/esp_adc_cal/CMakeLists.txt index 61d15d185f..8b859d31ec 100644 --- a/components/esp_adc_cal/CMakeLists.txt +++ b/components/esp_adc_cal/CMakeLists.txt @@ -14,4 +14,9 @@ elseif(${target} STREQUAL "esp32c3") idf_component_register(SRCS "esp_adc_cal_esp32c3.c" INCLUDE_DIRS "include" REQUIRES driver efuse) + +elseif(${target} STREQUAL "esp32h2") + idf_component_register(SRCS "esp_adc_cal_esp32h2.c" + INCLUDE_DIRS "include" + REQUIRES driver efuse) endif() diff --git a/components/esp_adc_cal/esp_adc_cal_esp32h2.c b/components/esp_adc_cal/esp_adc_cal_esp32h2.c new file mode 100644 index 0000000000..8281837ba6 --- /dev/null +++ b/components/esp_adc_cal/esp_adc_cal_esp32h2.c @@ -0,0 +1,170 @@ +// Copyright 2019-2020 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. + +#include +#include +#include +#include "esp_types.h" +#include "esp_err.h" +#include "esp_log.h" +#include "driver/adc.h" +#include "hal/adc_ll.h" +#include "esp_efuse_rtc_calib.h" +#include "esp_adc_cal.h" + + +#define ADC_CALIB_CHECK(cond, err_msg, ret) do {\ + if (!(cond)) { \ + ESP_LOGE(LOG_TAG, err_msg); \ + return (ret); \ + } \ + } while(0) + +const static char LOG_TAG[] = "adc_calib"; + + +/* ------------------------ Characterization Constants ---------------------- */ + +// coeff_a and coeff_b are actually floats +// they are scaled to put them into uint32_t so that the headers do not have to be changed +static const int coeff_a_scaling = 65536; +static const int coeff_b_scaling = 1024; +/* -------------------- Characterization Helper Data Types ------------------ */ +typedef struct { + uint32_t voltage; + uint32_t digi; +} adc_calib_data_ver1; + +typedef struct { + char version_num; + adc_unit_t adc_num; + adc_atten_t atten_level; + union { + adc_calib_data_ver1 ver1; + } efuse_data; +} adc_calib_parsed_info; + +static esp_err_t prepare_calib_data_for(int version_num, adc_unit_t adc_num, adc_atten_t atten, adc_calib_parsed_info *parsed_data_storage) +{ + assert(version_num == 1); + esp_err_t ret; + + parsed_data_storage->version_num = version_num; + parsed_data_storage->adc_num = adc_num; + parsed_data_storage->atten_level = atten; + // V1 we don't have calibration data for ADC2, using the efuse data of ADC1 + uint32_t voltage, digi; + ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, atten, &digi, &voltage); + if (ret != ESP_OK) { + return ret; + } + parsed_data_storage->efuse_data.ver1.voltage = voltage; + parsed_data_storage->efuse_data.ver1.digi = digi; + return ret; +} + +/* ----------------------- Characterization Functions ----------------------- */ +/* + * Estimate the (assumed) linear relationship btwn the measured raw value and the voltage + * with the previously done measurement when the chip was manufactured. + */ +static void calculate_characterization_coefficients(const adc_calib_parsed_info *parsed_data, esp_adc_cal_characteristics_t *chars) +{ + ESP_LOGD(LOG_TAG, "Calib V1, Cal Voltage = %d, Digi out = %d\n", parsed_data->efuse_data.ver1.voltage, parsed_data->efuse_data.ver1.digi); + + chars->coeff_a = coeff_a_scaling * parsed_data->efuse_data.ver1.voltage / parsed_data->efuse_data.ver1.digi; + chars->coeff_b = 0; +} + +/* ------------------------- Public API ------------------------------------- */ +esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source) +{ + if (source != ESP_ADC_CAL_VAL_EFUSE_TP) { + return ESP_ERR_NOT_SUPPORTED; + } + uint8_t adc_encoding_version = esp_efuse_rtc_calib_get_ver(); + if (adc_encoding_version != 1) { + // current version only accepts encoding ver 1. + return ESP_ERR_INVALID_VERSION; + } + return ESP_OK; +} + +esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, + adc_atten_t atten, + adc_bits_width_t bit_width, + uint32_t default_vref, + esp_adc_cal_characteristics_t *chars) +{ + esp_err_t ret; + adc_calib_parsed_info efuse_parsed_data = {0}; + // Check parameters + ADC_CALIB_CHECK(adc_num == ADC_UNIT_1 || adc_num == ADC_UNIT_2, "Invalid unit num", ESP_ADC_CAL_VAL_NOT_SUPPORTED); + ADC_CALIB_CHECK(chars != NULL, "Invalid characteristic", ESP_ADC_CAL_VAL_NOT_SUPPORTED); + ADC_CALIB_CHECK(bit_width == ADC_WIDTH_BIT_12, "Invalid bit_width", ESP_ADC_CAL_VAL_NOT_SUPPORTED); + ADC_CALIB_CHECK(atten < 4, "Invalid attenuation", ESP_ADC_CAL_VAL_NOT_SUPPORTED); + + int version_num = esp_efuse_rtc_calib_get_ver(); + ADC_CALIB_CHECK(version_num == 1, "No calibration efuse burnt", ESP_ADC_CAL_VAL_NOT_SUPPORTED); + + memset(chars, 0, sizeof(esp_adc_cal_characteristics_t)); + + // make sure adc is calibrated. + ret = prepare_calib_data_for(version_num, adc_num, atten, &efuse_parsed_data); + if (ret != ESP_OK) { + abort(); + } + + calculate_characterization_coefficients(&efuse_parsed_data, chars); + ESP_LOGD(LOG_TAG, "adc%d (atten leven %d) calibration done: A:%d B:%d\n", adc_num, atten, chars->coeff_a, chars->coeff_b); + + // Initialize remaining fields + chars->adc_num = adc_num; + chars->atten = atten; + chars->bit_width = bit_width; + + // in esp32h2 we only use the two point method to calibrate the adc. + return ESP_ADC_CAL_VAL_EFUSE_TP; +} + +uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) +{ + ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG); + + return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; +} + +esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, + const esp_adc_cal_characteristics_t *chars, + uint32_t *voltage) +{ + // Check parameters + ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG); + ADC_CALIB_CHECK(voltage != NULL, "No output buffer.", ESP_ERR_INVALID_ARG); + + int adc_reading; + if (chars->adc_num == ADC_UNIT_1) { + //Check if channel is valid on ADC1 + ADC_CALIB_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, "Invalid channel", ESP_ERR_INVALID_ARG); + adc_reading = adc1_get_raw(channel); + } else { + //Check if channel is valid on ADC2 + ADC_CALIB_CHECK((adc2_channel_t)channel < ADC2_CHANNEL_MAX, "Invalid channel", ESP_ERR_INVALID_ARG); + if (adc2_get_raw(channel, chars->bit_width, &adc_reading) != ESP_OK) { + return ESP_ERR_TIMEOUT; //Timed out waiting for ADC2 + } + } + *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); + return ESP_OK; +} diff --git a/components/esp_pm/include/esp32h2/pm.h b/components/esp_pm/include/esp32h2/pm.h new file mode 100644 index 0000000000..ce09d8a2b6 --- /dev/null +++ b/components/esp_pm/include/esp32h2/pm.h @@ -0,0 +1,42 @@ +// Copyright 2020 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. + + +#pragma once +#include +#include +#include "esp_err.h" + +#include "soc/rtc.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Power management config for ESP32H2 + * + * Pass a pointer to this structure as an argument to esp_pm_configure function. + */ +typedef struct { + int max_freq_mhz; /*!< Maximum CPU frequency, in MHz */ + int min_freq_mhz; /*!< Minimum CPU frequency to use when no locks are taken, in MHz */ + bool light_sleep_enable; /*!< Enter light sleep when no locks are taken */ +} esp_pm_config_esp32h2_t; + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_pm/include/esp_pm.h b/components/esp_pm/include/esp_pm.h index 86a404286f..5bd2bd1b11 100644 --- a/components/esp_pm/include/esp_pm.h +++ b/components/esp_pm/include/esp_pm.h @@ -25,6 +25,8 @@ #include "esp32s3/pm.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/pm.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/pm.h" #endif #ifdef __cplusplus diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 9f43317922..9e10afe5d3 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -60,6 +60,10 @@ #include "esp32c3/clk.h" #include "esp32c3/pm.h" #include "driver/gpio.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/clk.h" +#include "esp32h2/pm.h" +#include "driver/gpio.h" #endif #define MHZ (1000000) @@ -96,6 +100,9 @@ #elif CONFIG_IDF_TARGET_ESP32C3 #define REF_CLK_DIV_MIN 2 #define DEFAULT_CPU_FREQ CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ +#elif CONFIG_IDF_TARGET_ESP32H2 +#define REF_CLK_DIV_MIN 2 +#define DEFAULT_CPU_FREQ CONFIG_ESP32H2_DEFAULT_CPU_FREQ_MHZ #endif #ifdef CONFIG_PM_PROFILING @@ -230,6 +237,8 @@ esp_err_t esp_pm_configure(const void* vconfig) const esp_pm_config_esp32s3_t* config = (const esp_pm_config_esp32s3_t*) vconfig; #elif CONFIG_IDF_TARGET_ESP32C3 const esp_pm_config_esp32c3_t* config = (const esp_pm_config_esp32c3_t*) vconfig; +#elif CONFIG_IDF_TARGET_ESP32H2 + const esp_pm_config_esp32h2_t* config = (const esp_pm_config_esp32h2_t*) vconfig; #endif #ifndef CONFIG_FREERTOS_USE_TICKLESS_IDLE @@ -336,6 +345,8 @@ esp_err_t esp_pm_get_configuration(void* vconfig) esp_pm_config_esp32s3_t* config = (esp_pm_config_esp32s3_t*) vconfig; #elif CONFIG_IDF_TARGET_ESP32C3 esp_pm_config_esp32c3_t* config = (esp_pm_config_esp32c3_t*) vconfig; +#elif CONFIG_IDF_TARGET_ESP32H2 + esp_pm_config_esp32h2_t* config = (esp_pm_config_esp32h2_t*) vconfig; #endif portENTER_CRITICAL(&s_switch_lock); @@ -764,6 +775,8 @@ void esp_pm_impl_init(void) esp_pm_config_esp32s3_t cfg = { #elif CONFIG_IDF_TARGET_ESP32C3 esp_pm_config_esp32c3_t cfg = { +#elif CONFIG_IDF_TARGET_ESP32H2 + esp_pm_config_esp32h2_t cfg = { #endif .max_freq_mhz = DEFAULT_CPU_FREQ, .min_freq_mhz = xtal_freq, diff --git a/components/esp_pm/pm_trace.c b/components/esp_pm/pm_trace.c index 291897aa11..1da9c93f55 100644 --- a/components/esp_pm/pm_trace.c +++ b/components/esp_pm/pm_trace.c @@ -21,7 +21,7 @@ * Feel free to change when debugging. */ static const int DRAM_ATTR s_trace_io[] = { -#ifndef CONFIG_IDF_TARGET_ESP32C3 +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32H2) BIT(4), BIT(5), // ESP_PM_TRACE_IDLE BIT(16), BIT(17), // ESP_PM_TRACE_TICK BIT(18), BIT(18), // ESP_PM_TRACE_FREQ_SWITCH diff --git a/components/esp_pm/test/test_pm.c b/components/esp_pm/test/test_pm.c index ee7319231e..3931f737d3 100644 --- a/components/esp_pm/test/test_pm.c +++ b/components/esp_pm/test/test_pm.c @@ -28,6 +28,8 @@ #include "esp32s3/ulp.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/clk.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/clk.h" #endif TEST_CASE("Can dump power management lock stats", "[pm]") @@ -48,6 +50,8 @@ static void switch_freq(int mhz) esp_pm_config_esp32s3_t pm_config = { #elif CONFIG_IDF_TARGET_ESP32C3 esp_pm_config_esp32c3_t pm_config = { +#elif CONFIG_IDF_TARGET_ESP32H2 + esp_pm_config_esp32h2_t pm_config = { #endif .max_freq_mhz = mhz, .min_freq_mhz = MIN(mhz, xtal_freq), @@ -60,7 +64,7 @@ static void switch_freq(int mhz) } } -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 static const int test_freqs[] = {40, 160, 80, 40, 80, 10, 80, 20, 40}; #else static const int test_freqs[] = {240, 40, 160, 240, 80, 40, 240, 40, 80, 10, 80, 20, 40}; @@ -93,6 +97,8 @@ static void light_sleep_enable(void) esp_pm_config_esp32s3_t pm_config = { #elif CONFIG_IDF_TARGET_ESP32C3 esp_pm_config_esp32c3_t pm_config = { +#elif CONFIG_IDF_TARGET_ESP32H2 + esp_pm_config_esp32h2_t pm_config = { #endif .max_freq_mhz = cur_freq_mhz, .min_freq_mhz = xtal_freq, @@ -113,6 +119,8 @@ static void light_sleep_disable(void) esp_pm_config_esp32s3_t pm_config = { #elif CONFIG_IDF_TARGET_ESP32C3 esp_pm_config_esp32c3_t pm_config = { +#elif CONFIG_IDF_TARGET_ESP32H2 + esp_pm_config_esp32h2_t pm_config = { #endif .max_freq_mhz = cur_freq_mhz, .min_freq_mhz = cur_freq_mhz, diff --git a/components/esp_serial_slave_link/include/essl_spi/esp32h2_defs.h b/components/esp_serial_slave_link/include/essl_spi/esp32h2_defs.h new file mode 100644 index 0000000000..3dfd4a14b7 --- /dev/null +++ b/components/esp_serial_slave_link/include/essl_spi/esp32h2_defs.h @@ -0,0 +1,38 @@ +// Copyright 2010-2020 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. + + +#pragma once + +// NOTE: From the view of master +#define CMD_HD_WRBUF_REG 0x01 +#define CMD_HD_RDBUF_REG 0x02 +#define CMD_HD_WRDMA_REG 0x03 +#define CMD_HD_RDDMA_REG 0x04 + +#define CMD_HD_ONEBIT_MODE 0x00 +#define CMD_HD_DOUT_MODE 0x10 +#define CMD_HD_QOUT_MODE 0x20 +#define CMD_HD_DIO_MODE 0x50 +#define CMD_HD_QIO_MODE 0xA0 + +#define CMD_HD_SEG_END_REG 0x05 +#define CMD_HD_EN_QPI_REG 0x06 +#define CMD_HD_WR_END_REG 0x07 +#define CMD_HD_INT0_REG 0x08 +#define CMD_HD_INT1_REG 0x09 +#define CMD_HD_INT2_REG 0x0A +#define CMD_HD_EX_QPI_REG 0xDD + +#define SPI_SLAVE_HD_BUFFER_SIZE 64 diff --git a/components/esp_timer/src/esp_timer.c b/components/esp_timer/src/esp_timer.c index ff45b58147..ad185760f5 100644 --- a/components/esp_timer/src/esp_timer.c +++ b/components/esp_timer/src/esp_timer.c @@ -39,6 +39,8 @@ #include "esp32s3/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rtc.h" #endif #include "sdkconfig.h" diff --git a/components/esp_timer/src/system_time.c b/components/esp_timer/src/system_time.c index 08f0e7d292..5f00534b8f 100644 --- a/components/esp_timer/src/system_time.c +++ b/components/esp_timer/src/system_time.c @@ -30,6 +30,8 @@ #include "esp32s3/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rtc.h" #endif // Correction for underlying timer to keep definition diff --git a/components/esp_timer/test/test_ets_timer.c b/components/esp_timer/test/test_ets_timer.c index 4725027095..e32077024b 100644 --- a/components/esp_timer/test/test_ets_timer.c +++ b/components/esp_timer/test/test_ets_timer.c @@ -16,6 +16,8 @@ #include "esp32s3/rom/ets_sys.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/ets_sys.h" #endif TEST_CASE("ets_timer produces correct delay", "[ets_timer]") diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index cf335e9b5e..3f275f2023 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -6,7 +6,7 @@ endif() idf_build_get_property(target IDF_TARGET) -if(NOT "${target}" STREQUAL "esp32c3") # should test arch here not target, TODO ESP32-C3 IDF-1754 +if(NOT "${target}" STREQUAL "esp32c3" AND NOT "${target}" STREQUAL "esp32h2") # should test arch here not target, TODO ESP32-C3 IDF-1754 set(srcs "port/xtensa/port.c" "port/xtensa/portasm.S" diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index 60d3505337..155436e8f6 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -9,7 +9,7 @@ entries: tasks: uxTaskGetSnapshotAll (default) tasks: prvTaskGetSnapshot (default) tasks: prvTaskGetSnapshotsFromList (default) - if IDF_TARGET_ESP32S2 =n && IDF_TARGET_ESP32C3 = n : + if IDF_TARGET_ESP32S2 = n && IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n : port: vPortReleaseTaskMPUSettings (default) tasks: xTaskCreateRestricted (default) port: vPortStoreTaskMPUSettings (default) diff --git a/components/freertos/port/port_common.c b/components/freertos/port/port_common.c index b6eb0bd00e..9ba5e381a0 100644 --- a/components/freertos/port/port_common.c +++ b/components/freertos/port/port_common.c @@ -33,7 +33,7 @@ #include "esp32s2/spiram.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/spiram.h" -#elif CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 // SPIRAM is not supported on ESP32-C3 #endif diff --git a/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h b/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h index 6eb52699c7..a7d534343f 100644 --- a/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h @@ -79,6 +79,8 @@ #ifndef __ASSEMBLER__ #if CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/ets_sys.h" #endif #endif // __ASSEMBLER__ diff --git a/components/idf_test/include/esp32h2/idf_performance_target.h b/components/idf_test/include/esp32h2/idf_performance_target.h new file mode 100644 index 0000000000..f7d3bba6ad --- /dev/null +++ b/components/idf_test/include/esp32h2/idf_performance_target.h @@ -0,0 +1,70 @@ +// Copyright 2020 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. + +#pragma once + +#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 43 + +// SHA256 hardware throughput at 160 MHz, threshold set lower than worst case +#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 90 +// esp_sha() time to process 32KB of input data from RAM +#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 560 + +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 19000 +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 210000 +#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 45000 +#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 670000 + +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 32 +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 + +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B 53400 +#endif +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB (701*1000) +#endif + +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 27400 +#endif +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B 53600 +#endif +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 44300 +#endif + +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B 24400 +#endif + +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 64900 +#endif +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B (309*1000) +#endif + +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB (1697*1000) +#endif + +#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE +#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 76600 +#endif + +// floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround) +#define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 +#define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT 140 diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index d46e8068b1..6fb4476d1c 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -21,6 +21,8 @@ #include "esp32s3/rom/ets_sys.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/ets_sys.h" #endif #ifdef __cplusplus diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 9097102786..cbc608a497 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -859,7 +859,7 @@ menu "mbedTLS" config MBEDTLS_LARGE_KEY_SOFTWARE_MPI bool "Fallback to software implementation for larger MPI values" depends on MBEDTLS_HARDWARE_MPI - default y if IDF_TARGET_ESP32C3 # HW max 3072 bits + default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32H2 # HW max 3072 bits default n help Fallback to software implementation for RSA key lengths diff --git a/components/mbedtls/port/esp32h2/bignum.c b/components/mbedtls/port/esp32h2/bignum.c new file mode 100644 index 0000000000..75d5336270 --- /dev/null +++ b/components/mbedtls/port/esp32h2/bignum.c @@ -0,0 +1,230 @@ +/** + * \brief Multi-precision integer library, ESP32 H2 hardware accelerated parts + * + * based on mbedTLS implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE Ltd + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + */ +#include +#include +#include "soc/hwcrypto_periph.h" +#include "driver/periph_ctrl.h" +#include "mbedtls/bignum.h" +#include "bignum_impl.h" +#include "soc/system_reg.h" +#include "soc/periph_defs.h" +#include "esp_crypto_lock.h" + + +size_t esp_mpi_hardware_words(size_t words) +{ + return words; +} + +void esp_mpi_enable_hardware_hw_op( void ) +{ + esp_crypto_mpi_lock_acquire(); + + /* Enable RSA hardware */ + periph_module_enable(PERIPH_RSA_MODULE); + + REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); + + while (REG_READ(RSA_QUERY_CLEAN_REG) != 1) { + } + // Note: from enabling RSA clock to here takes about 1.3us +} + +void esp_mpi_disable_hardware_hw_op( void ) +{ + REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); + + /* Disable RSA hardware */ + periph_module_disable(PERIPH_RSA_MODULE); + + esp_crypto_mpi_lock_release(); +} + + +/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. + + If num_words is higher than the number of words in the bignum then + these additional words will be zeroed in the memory buffer. +*/ +static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) +{ + uint32_t *pbase = (uint32_t *)mem_base; + uint32_t copy_words = MIN(num_words, mpi->n); + + /* Copy MPI data to memory block registers */ + for (int i = 0; i < copy_words; i++) { + pbase[i] = mpi->p[i]; + } + + /* Zero any remaining memory block data */ + for (int i = copy_words; i < num_words; i++) { + pbase[i] = 0; + } +} + +/* Read mbedTLS MPI bignum back from hardware memory block. + + Reads num_words words from block. +*/ +static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) +{ + + /* Copy data from memory block registers */ + const size_t REG_WIDTH = sizeof(uint32_t); + for (size_t i = 0; i < num_words; i++) { + x->p[i] = REG_READ(mem_base + (i * REG_WIDTH)); + } + /* Zero any remaining limbs in the bignum, if the buffer is bigger + than num_words */ + for (size_t i = num_words; i < x->n; i++) { + x->p[i] = 0; + } +} + + + +/* Begin an RSA operation. op_reg specifies which 'START' register + to write to. +*/ +static inline void start_op(uint32_t op_reg) +{ + /* Clear interrupt status */ + REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); + + /* Note: above REG_WRITE includes a memw, so we know any writes + to the memory blocks are also complete. */ + + REG_WRITE(op_reg, 1); +} + +/* Wait for an RSA operation to complete. +*/ +static inline void wait_op_complete(void) +{ + while (REG_READ(RSA_QUERY_INTERRUPT_REG) != 1) + { } + + /* clear the interrupt */ + REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); +} + + +/* Read result from last MPI operation */ +void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) +{ + wait_op_complete(); + mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words); +} + + +/* Z = (X * Y) mod M + + Not an mbedTLS function +*/ +void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) +{ + REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); + + /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); + mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); + mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); + REG_WRITE(RSA_M_DASH_REG, Mprime); + + start_op(RSA_MOD_MULT_START_REG); +} + +/* Z = (X ^ Y) mod M +*/ +void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) +{ + size_t y_bits = mbedtls_mpi_bitlen(Y); + + REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); + + /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); + mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); + mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); + REG_WRITE(RSA_M_DASH_REG, Mprime); + + /* Enable acceleration options */ + REG_WRITE(RSA_CONSTANT_TIME_REG, 0); + REG_WRITE(RSA_SEARCH_ENABLE_REG, 1); + REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1); + + /* Execute first stage montgomery multiplication */ + start_op(RSA_MODEXP_START_REG); + + REG_WRITE(RSA_SEARCH_ENABLE_REG, 0); +} + + +/* Z = X * Y */ +void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) +{ + /* Copy X (right-extended) & Y (left-extended) to memory block */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + num_words * 4, Y, num_words); + /* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block. + This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware(). + */ + REG_WRITE(RSA_LENGTH_REG, (num_words * 2 - 1)); + start_op(RSA_MULT_START_REG); +} + + + +/** + * @brief Special-case of (X * Y), where we use hardware montgomery mod + multiplication to calculate result where either A or B are >2048 bits so + can't use the standard multiplication method. + * + */ +void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) +{ + /* M = 2^num_words - 1, so block is entirely FF */ + for (int i = 0; i < num_words; i++) { + REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX); + } + + /* Mprime = 1 */ + REG_WRITE(RSA_M_DASH_REG, 1); + REG_WRITE(RSA_LENGTH_REG, num_words - 1); + + /* Load X & Y */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); + + /* Rinv = 1, write first word */ + REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1); + + /* Zero out rest of the Rinv words */ + for (int i = 1; i < num_words; i++) { + REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0); + } + + start_op(RSA_MOD_MULT_START_REG); +} diff --git a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c index 258f05094e..a01134fae0 100644 --- a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c +++ b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c @@ -19,6 +19,8 @@ #include "esp32s2/rom/digital_signature.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/digital_signature.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/digital_signature.h" #else #error "Selected target does not support esp_rsa_sign_alt (for DS)" #endif diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index 91f098411c..65046beedb 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/components/mbedtls/port/sha/dma/sha.c @@ -52,6 +52,8 @@ #include "esp32s3/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32s3/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/cache.h" #endif #if SOC_SHA_GDMA diff --git a/components/newlib/locks.c b/components/newlib/locks.c index 23c7e112aa..f418066047 100644 --- a/components/newlib/locks.c +++ b/components/newlib/locks.c @@ -252,7 +252,7 @@ static StaticSemaphore_t s_common_mutex; static StaticSemaphore_t s_common_recursive_mutex; -#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) /* C3 and S3 ROMs are built without Newlib static lock symbols exported, and * with an extra level of _LOCK_T indirection in mind. * The following is a workaround for this: @@ -267,7 +267,7 @@ static StaticSemaphore_t s_common_recursive_mutex; */ #define ROM_NEEDS_MUTEX_OVERRIDE -#endif // defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +#endif // defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) #ifdef ROM_NEEDS_MUTEX_OVERRIDE #define ROM_MUTEX_MAGIC 0xbb10c433 @@ -393,7 +393,7 @@ void esp_newlib_locks_init(void) __sinit_recursive_mutex = (_lock_t) &s_common_recursive_mutex; extern _lock_t __sfp_recursive_mutex; __sfp_recursive_mutex = (_lock_t) &s_common_recursive_mutex; -#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) /* Newlib 3.3.0 is used in ROM, built with _RETARGETABLE_LOCKING. * No access to lock variables for the purpose of ECO forward compatibility, * however we have an API to initialize lock variables used in the ROM. diff --git a/components/newlib/newlib_init.c b/components/newlib/newlib_init.c index e137b794d5..33075da39c 100644 --- a/components/newlib/newlib_init.c +++ b/components/newlib/newlib_init.c @@ -37,6 +37,8 @@ #include "esp32s3/rom/libc_stubs.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/libc_stubs.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/libc_stubs.h" #endif static struct _reent s_reent; @@ -113,7 +115,7 @@ static struct syscall_stub_table s_stub_table = { ._printf_float = NULL, ._scanf_float = NULL, #endif -#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 /* TODO IDF-2570 : mark that this assert failed in ROM, to avoid confusion between IDF & ROM assertion failures (as function names & source file names will be similar) */ @@ -136,7 +138,7 @@ void esp_newlib_init(void) syscall_table_ptr_pro = syscall_table_ptr_app = &s_stub_table; #elif CONFIG_IDF_TARGET_ESP32S2 syscall_table_ptr_pro = &s_stub_table; -#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 syscall_table_ptr = &s_stub_table; #endif diff --git a/components/newlib/port/esp_time_impl.c b/components/newlib/port/esp_time_impl.c index db8bc529d7..28238168d5 100644 --- a/components/newlib/port/esp_time_impl.c +++ b/components/newlib/port/esp_time_impl.c @@ -44,6 +44,10 @@ #include "esp32c3/rom/rtc.h" #include "esp32c3/clk.h" #include "esp32c3/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/rtc.h" +#include "esp32h2/clk.h" +#include "esp32h2/rtc.h" #endif diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c index 6851ce1eb5..8f0a36ff3d 100644 --- a/components/newlib/test/test_newlib.c +++ b/components/newlib/test/test_newlib.c @@ -141,7 +141,7 @@ TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") #if defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM) TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(strtol)); -#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) /* S3 and C3 always use these from ROM */ TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(strtol)); diff --git a/components/newlib/test/test_time.c b/components/newlib/test/test_time.c index 64ca582fca..2cf5c91140 100644 --- a/components/newlib/test/test_time.c +++ b/components/newlib/test/test_time.c @@ -31,6 +31,9 @@ #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/clk.h" #define TARGET_DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/clk.h" +#define TARGET_DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32H2_DEFAULT_CPU_FREQ_MHZ #endif #if portNUM_PROCESSORS == 2 diff --git a/components/perfmon/CMakeLists.txt b/components/perfmon/CMakeLists.txt index bf463e4f73..4363e04bdf 100644 --- a/components/perfmon/CMakeLists.txt +++ b/components/perfmon/CMakeLists.txt @@ -1,5 +1,5 @@ idf_build_get_property(target IDF_TARGET) -if(${target} STREQUAL "esp32c3") +if(${target} STREQUAL "esp32c3" OR ${target} STREQUAL "esp32h2") return() endif() diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 81f1d56ddc..dedd5f2b35 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -39,6 +39,11 @@ #include "esp32c3/rom/cache.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/rom/cache.h" +#include "soc/extmem_reg.h" +#include "soc/cache_memory.h" #endif #include #include "sdkconfig.h" @@ -319,7 +324,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 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 uint32_t icache_state; icache_state = Cache_Suspend_ICache() << 16; *saved_state = icache_state; @@ -345,7 +350,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 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 Cache_Resume_ICache(saved_state >> 16); #endif } @@ -359,7 +364,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 +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 bool result = (REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE) != 0); #endif return result; @@ -474,19 +479,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 +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 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 +#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 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 +#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 dcache_wrap_size = 16; #else dcache_wrap_size = 32; @@ -875,7 +880,7 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable } #endif -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache) { @@ -917,7 +922,7 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) } return ESP_OK; } -#endif // CONFIG_IDF_TARGET_ESP32C3 +#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) { diff --git a/components/spi_flash/esp32h2/flash_ops_esp32h2.c b/components/spi_flash/esp32h2/flash_ops_esp32h2.c new file mode 100644 index 0000000000..10231bdfdd --- /dev/null +++ b/components/spi_flash/esp32h2/flash_ops_esp32h2.c @@ -0,0 +1,149 @@ +// Copyright 2020 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. + +#include +#include + +#include "esp_spi_flash.h" +#include "soc/system_reg.h" +#include "soc/soc_memory_layout.h" +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/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_h2"; + +#define SPICACHE SPIMEM0 +#define SPIFLASH SPIMEM1 + +extern void IRAM_ATTR flash_rom_init(void); +esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size) +{ + const spi_flash_guard_funcs_t *ops = spi_flash_guard_get(); + esp_rom_spiflash_result_t rc; + + assert((dest_addr % 16) == 0); + assert((size % 16) == 0); + + /* src needs to be 32 bit aligned */ + if (!esp_ptr_internal(src) || (intptr_t)src & 0x3) { + WORD_ALIGNED_ATTR uint8_t block[128]; // Need to buffer in RAM as we write + while (size > 0) { + size_t next_block = MIN(size, sizeof(block)); + memcpy(block, src, next_block); + + esp_rom_spiflash_result_t r = spi_flash_write_encrypted_chip(dest_addr, block, next_block); + if (r != ESP_ROM_SPIFLASH_RESULT_OK) { + return r; + } + + size -= next_block; + dest_addr += next_block; + src = ((uint8_t *)src) + next_block; + } + bzero(block, sizeof(block)); + + return ESP_ROM_SPIFLASH_RESULT_OK; + } else { // Already in internal memory + ESP_LOGV(TAG, "calling esp_rom_spiflash_write_encrypted addr 0x%x src %p size 0x%x", dest_addr, src, size); + +#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL + /* The ROM function SPI_Encrypt_Write assumes ADDR_BITLEN is already set but new + implementation doesn't automatically set this to a usable value */ + SPIFLASH.user1.usr_addr_bitlen = 23; +#endif + + if (ops && ops->start) { + ops->start(); + } + flash_rom_init(); + rc = esp_rom_spiflash_write_encrypted(dest_addr, (uint32_t *)src, size); + if (ops && ops->end) { + ops->end(); + } + return rc; + } +} + +#define FLASH_WRAP_CMD 0x77 +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; + uint32_t reg_bkp_usr = SPIFLASH.user.val; + SPIFLASH.user.fwrite_dio = 0; + SPIFLASH.user.fwrite_dual = 0; + SPIFLASH.user.fwrite_qio = 1; + SPIFLASH.user.fwrite_quad = 0; + SPIFLASH.ctrl.fcmd_dual = 0; + SPIFLASH.ctrl.fcmd_quad = 0; + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 1; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD; + SPIFLASH.user1.usr_addr_bitlen = 23; + SPIFLASH.addr = 0; + SPIFLASH.user.usr_miso = 0; + SPIFLASH.user.usr_mosi = 1; + SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7; + SPIFLASH.data_buf[0] = (uint32_t) mode << 4;; + SPIFLASH.cmd.usr = 1; + while (SPIFLASH.cmd.usr != 0) + { } + + SPIFLASH.ctrl.val = reg_bkp_ctrl; + SPIFLASH.user.val = reg_bkp_usr; + return ESP_OK; +} + +esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) +{ + switch (wrap_size) { + case 8: + return spi_flash_wrap_set(FLASH_WRAP_MODE_8B); + case 16: + return spi_flash_wrap_set(FLASH_WRAP_MODE_16B); + case 32: + return spi_flash_wrap_set(FLASH_WRAP_MODE_32B); + case 64: + return spi_flash_wrap_set(FLASH_WRAP_MODE_64B); + default: + return ESP_FAIL; + } +} + +void spi_flash_disable_wrap(void) +{ + spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); +} + +bool spi_flash_support_wrap_size(uint32_t wrap_size) +{ + if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) { + return ESP_FAIL; + } + switch (wrap_size) { + case 0: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} diff --git a/components/spi_flash/esp32h2/spi_flash_rom_patch.c b/components/spi_flash/esp32h2/spi_flash_rom_patch.c new file mode 100644 index 0000000000..a133de307c --- /dev/null +++ b/components/spi_flash/esp32h2/spi_flash_rom_patch.c @@ -0,0 +1,26 @@ +// Copyright 2015-2020 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. +#include "sdkconfig.h" +#include "esp32h2/rom/spi_flash.h" +#include "soc/spi_periph.h" +#include "spi_flash_defs.h" + +#define SPI_IDX 1 + +esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void) +{ + REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WRDI); + while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); + return ESP_ROM_SPIFLASH_RESULT_OK; +} diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 6294da04c3..934ec7b2a2 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -35,6 +35,8 @@ #include "esp32s3/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" #endif __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -114,6 +116,26 @@ __attribute__((unused)) static const char TAG[] = "spi_flash"; .cs_setup = 1,\ } #endif //!CONFIG_SPI_FLASH_AUTO_SUSPEND +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/efuse.h" +#if !CONFIG_SPI_FLASH_AUTO_SUSPEND +#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ + .host_id = SPI1_HOST,\ + .speed = DEFAULT_FLASH_SPEED, \ + .cs_num = 0, \ + .iomux = true, \ + .input_delay_ns = 0,\ +} +#else +#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ + .host_id = SPI1_HOST,\ + .speed = DEFAULT_FLASH_SPEED, \ + .cs_num = 0, \ + .iomux = true, \ + .input_delay_ns = 0,\ + .auto_sus_en = true,\ +} +#endif //!CONFIG_SPI_FLASH_AUTO_SUSPEND #endif diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 529160e3d0..9523bc7959 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -55,6 +55,11 @@ #include "esp32c3/rom/spi_flash.h" #include "soc/cache_memory.h" #include "soc/mmu.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/cache.h" +#include "esp32h2/rom/spi_flash.h" +#include "soc/cache_memory.h" +#include "soc/mmu.h" #endif #ifndef NDEBUG diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 485476d502..e0c1b2bbbc 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -46,6 +46,10 @@ #include "esp32c3/rom/cache.h" #include "esp32c3/rom/spi_flash.h" #include "esp32c3/clk.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/cache.h" +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/clk.h" #endif #include "esp_flash_partitions.h" #include "cache_utils.h" diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index bc48ea0665..6d61f8b82b 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -28,6 +28,9 @@ #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/ets_sys.h" #include "esp32c3/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/ets_sys.h" +#include "esp32h2/rom/cache.h" #endif #include "esp_attr.h" @@ -39,7 +42,7 @@ typedef struct { } spi_noos_arg_t; static DRAM_ATTR spi_noos_arg_t spi_arg = { 0 }; -#elif CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 typedef struct { uint32_t icache_autoload; } spi_noos_arg_t; @@ -56,7 +59,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 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); #endif @@ -75,7 +78,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 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 spi_noos_arg_t *spi_arg = arg; Cache_Invalidate_ICache_All(); Cache_Resume_ICache(spi_arg->icache_autoload); diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c index 7cfc551cfe..141a0d67bb 100644 --- a/components/spi_flash/test/test_esp_flash.c +++ b/components/spi_flash/test/test_esp_flash.c @@ -30,6 +30,8 @@ #include "esp32s3/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/cache.h" #endif #define FUNC_SPI 1 diff --git a/components/spiffs/esp_spiffs.c b/components/spiffs/esp_spiffs.c index 1f43943a0d..7e82cbfd01 100644 --- a/components/spiffs/esp_spiffs.c +++ b/components/spiffs/esp_spiffs.c @@ -37,6 +37,8 @@ #include "esp32s3/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" #endif #include "spiffs_api.h" diff --git a/components/ulp/CMakeLists.txt b/components/ulp/CMakeLists.txt index a2dcb8abf0..099daaffe0 100644 --- a/components/ulp/CMakeLists.txt +++ b/components/ulp/CMakeLists.txt @@ -1,6 +1,6 @@ idf_build_get_property(target IDF_TARGET) -if(NOT (IDF_TARGET STREQUAL "esp32c3")) +if(NOT (IDF_TARGET STREQUAL "esp32c3") AND NOT (IDF_TARGET STREQUAL "esp32h2")) set(srcs "ulp.c" "ulp_macro.c") diff --git a/components/unity/unity_port_esp32.c b/components/unity/unity_port_esp32.c index e47960828d..8d7d81ac4d 100644 --- a/components/unity/unity_port_esp32.c +++ b/components/unity/unity_port_esp32.c @@ -25,6 +25,8 @@ #include "esp32s3/clk.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/clk.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/clk.h" #endif static uint32_t s_test_start, s_test_stop; diff --git a/components/vfs/vfs_semihost.c b/components/vfs/vfs_semihost.c index a872a708a8..971f4f7e14 100644 --- a/components/vfs/vfs_semihost.c +++ b/components/vfs/vfs_semihost.c @@ -114,7 +114,7 @@ static vfs_semihost_ctx_t s_semhost_ctx[CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS]; static inline int generic_syscall(int sys_nr, int arg1, int arg2, int arg3, int arg4, int* ret_errno) { -#if !CONFIG_IDF_TARGET_ESP32C3 // TODO ESP32-C3 reenable semihost in C3 IDF-2287 +#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 // TODO ESP32-C3 reenable semihost in C3 IDF-2287 int host_ret, host_errno; if (!esp_cpu_in_ocd_debug_mode()) {