diff --git a/components/app_trace/app_trace_util.c b/components/app_trace/app_trace_util.c index d7ad98497b..238fd60205 100644 --- a/components/app_trace/app_trace_util.c +++ b/components/app_trace/app_trace_util.c @@ -20,6 +20,8 @@ #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #endif /////////////////////////////////////////////////////////////////////////////// diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 9f326154a1..235f87778a 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(target IDF_TARGET) + set(srcs "adc_common.c" "dac_common.c" @@ -23,9 +25,9 @@ set(srcs "twai.c" "uart.c") -set(includes "include") +set(includes "include" "${target}/include") -if(IDF_TARGET STREQUAL "esp32") +if(${target} STREQUAL "esp32") # SDMMC and MCPWM are in ESP32 only. list(APPEND srcs "mcpwm.c" "sdio_slave.c" @@ -37,7 +39,7 @@ if(IDF_TARGET STREQUAL "esp32") list(APPEND includes "esp32/include") endif() -if(IDF_TARGET STREQUAL "esp32s2") +if(${target} STREQUAL "esp32s2") list(APPEND srcs "esp32s2/rtc_tempsensor.c" "esp32s2/touch_sensor.c" "esp32s2/adc.c" diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c index b8cdc7b8b9..109c9cabfc 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_common.c @@ -82,7 +82,7 @@ static _lock_t adc2_wifi_lock; #define ADC2_WIFI_LOCK_TRY_ACQUIRE() _lock_try_acquire( &adc2_wifi_lock ) #define ADC2_WIFI_LOCK_CHECK() ((uint32_t *)adc2_wifi_lock != NULL) -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) #define ADC2_WIFI_LOCK_ACQUIRE() #define ADC2_WIFI_LOCK_RELEASE() @@ -101,7 +101,7 @@ static _lock_t adc1_dma_lock; #define ADC1_DMA_LOCK_ACQUIRE() _lock_acquire( &adc1_dma_lock ) #define ADC1_DMA_LOCK_RELEASE() _lock_release( &adc1_dma_lock ) -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #ifdef CONFIG_PM_ENABLE static esp_pm_lock_handle_t s_adc2_arbiter_lock; #endif //CONFIG_PM_ENABLE @@ -209,7 +209,7 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits) { #ifdef CONFIG_IDF_TARGET_ESP32 ADC_CHECK(bits < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) ADC_CHECK(bits == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG); #endif @@ -231,7 +231,7 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits) * @return * - ESP_OK Success */ -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 esp_err_t adc_rtc_reset(void) { ADC_ENTER_CRITICAL(); @@ -284,7 +284,7 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit) { #ifdef CONFIG_IDF_TARGET_ESP32 ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG); #endif @@ -341,13 +341,17 @@ int adc1_get_raw(adc1_channel_t channel) adc_power_on(); ADC_ENTER_CRITICAL(); -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#ifdef CONFIG_IDF_TARGET_ESP32 + adc_hal_hall_disable(); //Disable other peripherals. + adc_hal_amp_disable(); //Currently the LNA is not open, close it by default. +#endif +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 adc_set_init_code(ADC_NUM_1, channel); // calibration for adc #endif adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); //Set controller adc_hal_convert(ADC_NUM_1, channel, &adc_value); //Start conversion, For ADC1, the data always valid. ADC_EXIT_CRITICAL(); -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 adc_hal_rtc_reset(); //Reset FSM of rtc controller #endif @@ -434,7 +438,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) static inline void adc2_config_width(adc_bits_width_t width_bit) { -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #ifdef CONFIG_PM_ENABLE /* Lock APB clock. */ if (s_adc2_arbiter_lock == NULL) { @@ -455,7 +459,7 @@ static inline void adc2_dac_disable( adc2_channel_t channel) } else if ( channel == ADC2_CHANNEL_9 ) { dac_output_disable(DAC_CHANNEL_2); } -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) if ( channel == ADC2_CHANNEL_6 ) { // the same as DAC channel 1 dac_output_disable(DAC_CHANNEL_1); } else if ( channel == ADC2_CHANNEL_7 ) { @@ -478,7 +482,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * ADC_CHECK(channel < ADC2_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); #ifdef CONFIG_IDF_TARGET_ESP32 ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG); #endif @@ -494,12 +498,12 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * adc2_dac_disable(channel); //disable other peripherals #endif adc2_config_width(width_bit); // in critical section with whole rtc module. because the PWDET use the same registers, place it here. -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 adc_set_init_code(ADC_NUM_2, channel); // calibration for adc #endif adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #ifdef CONFIG_PM_ENABLE if (s_adc2_arbiter_lock) { esp_pm_lock_acquire(s_adc2_arbiter_lock); @@ -511,7 +515,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * adc_value = -1; } -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #ifdef CONFIG_PM_ENABLE /* Release APB clock. */ if (s_adc2_arbiter_lock) { @@ -523,7 +527,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * ADC2_WIFI_LOCK_RELEASE(); ADC2_EXIT_CRITICAL(); -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 adc_rtc_reset(); #endif diff --git a/components/driver/esp32s3/include/driver/adc.h b/components/driver/esp32s3/include/driver/adc.h new file mode 100644 index 0000000000..423592db80 --- /dev/null +++ b/components/driver/esp32s3/include/driver/adc.h @@ -0,0 +1,277 @@ +// 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. + +#pragma once + +#include "driver/adc_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ + +/** + * @brief Config ADC module arbiter. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. + * + * @note Only ADC2 support arbiter. + * @note Default priority: Wi-Fi > RTC > Digital; + * @note In normal use, there is no need to call this interface to config arbiter. + * + * @param adc_unit ADC unit. + * @param config Refer to `adc_arbiter_t`. + * + * @return + * - ESP_OK Success + * - ESP_ERR_NOT_SUPPORTED ADC unit not support arbiter. + */ +esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config); + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ +/** + * @brief ADC digital controller initialization. + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_init(void); + +/** + * @brief ADC digital controller deinitialization. + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_deinit(void); + +/** + * @brief Setting the digital controller. + * + * @param config Pointer to digital controller paramter. Refer to `adc_digi_config_t`. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_controller_config(const adc_digi_config_t *config); + +/** + * @brief Enable digital controller to trigger the measurement. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_start(void); + +/** + * @brief Disable digital controller to trigger the measurement. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_stop(void); + +/*************************************/ +/* Digital controller filter setting */ +/*************************************/ +/** + * @brief Reset adc digital controller filter. + * + * @param idx Filter index. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx); + +/** + * @brief Set adc digital controller filter configuration. + * + * @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. + * + * @param idx Filter index. + * @param config See ``adc_digi_filter_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config); + +/** + * @brief Get adc digital controller filter configuration. + * + * @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. + * + * @param idx Filter index. + * @param config See ``adc_digi_filter_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config); + +/** + * @brief Enable/disable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. + * + * @param idx Filter index. + * @param enable Enable/Disable filter. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable); + +/**************************************/ +/* Digital controller monitor setting */ +/**************************************/ + +/** + * @brief Config monitor of adc digital controller. + * + * @note For ESP32S2, The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * + * @param idx Monitor index. + * @param config See ``adc_digi_monitor_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config); + +/** + * @brief Enable/disable monitor of adc digital controller. + * + * @note For ESP32S2, The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * + * @param idx Monitor index. + * @param enable True or false enable monitor. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable); + +/**************************************/ +/* Digital controller intr setting */ +/**************************************/ + +/** + * @brief Enable interrupt of adc digital controller by bitmask. + * + * @param adc_unit ADC unit. + * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); + +/** + * @brief Disable interrupt of adc digital controller by bitmask. + * + * @param adc_unit ADC unit. + * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); + +/** + * @brief Clear interrupt of adc digital controller by bitmask. + * + * @param adc_unit ADC unit. + * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); + +/** + * @brief Get interrupt status mask of adc digital controller. + * + * @param adc_unit ADC unit. + * @return + * - intr Interrupt bitmask, See ``adc_digi_intr_t``. + */ +uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit); + +/** + * @brief Register ADC interrupt handler, the handler is an ISR. + * The handler will be attached to the same CPU core that this function is running on. + * + * @param fn Interrupt handler function. + * @param arg Parameter for handler function + * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) + * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. + * + * @return + * - ESP_OK Success + * - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags. + * - ESP_ERR_INVALID_ARG Function pointer error. + */ +esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags); + +/** + * @brief Deregister ADC interrupt handler, the handler is an ISR. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG hander error. + * - ESP_FAIL ISR not be registered. + */ +esp_err_t adc_digi_isr_deregister(void); + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ + +/*--------------------------------------------------------------- + Deprecated API +---------------------------------------------------------------*/ +/** + * @brief Set I2S data source + * + * @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC. + * + * @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_controller_config`` instead. + * + * @return + * - ESP_OK success + */ +esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) __attribute__((deprecated)); + +/** + * @brief Initialize I2S ADC mode + * + * @param adc_unit ADC unit index + * @param channel ADC channel index + * + * @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_controller_config`` instead. + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) __attribute__((deprecated)); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/driver/esp32s3/include/driver/dac.h b/components/driver/esp32s3/include/driver/dac.h new file mode 100644 index 0000000000..6efcc5c2b0 --- /dev/null +++ b/components/driver/esp32s3/include/driver/dac.h @@ -0,0 +1,80 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "driver/dac_common.h" + +#ifdef __cplusplus +extern "C" { +#endif +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +/** + * @brief DAC digital controller initialization. + * @return + * - ESP_OK success + */ +esp_err_t dac_digi_init(void); + +/** + * @brief DAC digital controller deinitialization. + * @return + * - ESP_OK success + */ +esp_err_t dac_digi_deinit(void); + +/** + * @brief Setting the DAC digital controller. + * + * @param cfg Pointer to digital controller paramter. See ``dac_digi_config_t``. + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg); + +/** + * @brief DAC digital controller start output voltage. + * @return + * - ESP_OK success + */ +esp_err_t dac_digi_start(void); + +/** + * @brief DAC digital controller stop output voltage. + * @return + * - ESP_OK success + */ +esp_err_t dac_digi_stop(void); + +/** + * @brief Reset DAC digital controller FIFO. + * @return + * - ESP_OK success + */ +esp_err_t dac_digi_fifo_reset(void); + +/** + * @brief Reset DAC digital controller. + * @return + * - ESP_OK success + */ +esp_err_t dac_digi_reset(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/esp32s3/include/driver/temp_sensor.h b/components/driver/esp32s3/include/driver/temp_sensor.h new file mode 100644 index 0000000000..9a6a2b5c93 --- /dev/null +++ b/components/driver/esp32s3/include/driver/temp_sensor.h @@ -0,0 +1,105 @@ +// 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 + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief temperature sensor range option. + */ +typedef enum { + TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */ + TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */ + TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */ + TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */ + TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */ + TSENS_DAC_MAX, + TSENS_DAC_DEFAULT = TSENS_DAC_L2, +} temp_sensor_dac_offset_t; + +/** + * @brief Configuration for temperature sensor reading + */ +typedef struct { + temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */ + uint8_t clk_div; /*!< Default: 6 */ +} temp_sensor_config_t; + +/** + * @brief temperature sensor default setting. + */ +#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \ + .clk_div = 6} + +/** + * @brief Set parameter of temperature sensor. + * @param tsens + * @return + * - ESP_OK Success + */ +esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens); + +/** + * @brief Get parameter of temperature sensor. + * @param tsens + * @return + * - ESP_OK Success + */ +esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens); + +/** + * @brief Start temperature sensor measure. + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG + */ +esp_err_t temp_sensor_start(void); + +/** + * @brief Stop temperature sensor measure. + * @return + * - ESP_OK Success + */ +esp_err_t temp_sensor_stop(void); + +/** + * @brief Read temperature sensor raw data. + * @param tsens_out Pointer to raw data, Range: 0 ~ 255 + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG `tsens_out` is NULL + * - ESP_ERR_INVALID_STATE temperature sensor dont start + */ +esp_err_t temp_sensor_read_raw(uint32_t *tsens_out); + +/** + * @brief Read temperature sensor data that is converted to degrees Celsius. + * @note Should not be called from interrupt. + * @param celsius The measure output value. + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG ARG is NULL. + * - ESP_ERR_INVALID_STATE The ambient temperature is out of range. + */ +esp_err_t temp_sensor_read_celsius(float *celsius); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/esp32s3/include/driver/touch_sensor.h b/components/driver/esp32s3/include/driver/touch_sensor.h new file mode 100644 index 0000000000..9c7d6c6d6d --- /dev/null +++ b/components/driver/esp32s3/include/driver/touch_sensor.h @@ -0,0 +1,582 @@ +// 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. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "driver/touch_sensor_common.h" + +/** + * @brief Set touch sensor FSM start + * @note Start FSM after the touch sensor FSM mode is set. + * @note Call this function will reset benchmark of all touch channels. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_fsm_start(void); + +/** + * @brief Stop touch sensor FSM. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_fsm_stop(void); + +/** + * @brief Trigger a touch sensor measurement, only support in SW mode of FSM + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_sw_start(void); + +/** + * @brief Set touch sensor times of charge and discharge and sleep time. + * Excessive total time will slow down the touch response. + * Too small measurement time will not be sampled enough, resulting in inaccurate measurements. + * + * @note The greater the duty cycle of the measurement time, the more system power is consumed. + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_times); + +/** + * @brief Get touch sensor times of charge and discharge and sleep time + * @param sleep_cycle Pointer to accept sleep cycle number + * @param meas_times Pointer to accept measurement times count. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_times); + +/** + * @brief Set connection type of touch channel in idle status. + * When a channel is in measurement mode, other initialized channels are in idle mode. + * The touch channel is generally adjacent to the trace, so the connection state of the idle channel + * affects the stability and sensitivity of the test channel. + * The `CONN_HIGHZ`(high resistance) setting increases the sensitivity of touch channels. + * The `CONN_GND`(grounding) setting increases the stability of touch channels. + * @param type Select idle channel connect to high resistance state or ground. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_set_idle_channel_connect(touch_pad_conn_type_t type); + +/** + * @brief Set connection type of touch channel in idle status. + * When a channel is in measurement mode, other initialized channels are in idle mode. + * The touch channel is generally adjacent to the trace, so the connection state of the idle channel + * affects the stability and sensitivity of the test channel. + * The `CONN_HIGHZ`(high resistance) setting increases the sensitivity of touch channels. + * The `CONN_GND`(grounding) setting increases the stability of touch channels. + * @param type Pointer to connection type. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_get_idle_channel_connect(touch_pad_conn_type_t *type); + +/** + * @brief Set the trigger threshold of touch sensor. + * The threshold determines the sensitivity of the touch sensor. + * The threshold is the original value of the trigger state minus the benchmark value. + * @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered. + * @param touch_num touch pad index + * @param threshold threshold of touch sensor. Should be less than the max change value of touch. + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint32_t threshold); + +/** + * @brief Get touch sensor trigger threshold + * @param touch_num touch pad index + * @param threshold pointer to accept threshold + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if argument is wrong + */ +esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint32_t *threshold); + +/** + * @brief Register touch channel into touch sensor scan group. + * The working mode of the touch sensor is cyclically scanned. + * This function will set the scan bits according to the given bitmask. + * @note If set this mask, the FSM timer should be stop firsty. + * @note The touch sensor that in scan map, should be deinit GPIO function firstly by `touch_pad_io_init`. + * @param enable_mask bitmask of touch sensor scan group. + * e.g. TOUCH_PAD_NUM14 -> BIT(14) + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_set_channel_mask(uint16_t enable_mask); + +/** + * @brief Get the touch sensor scan group bit mask. + * @param enable_mask Pointer to bitmask of touch sensor scan group. + * e.g. TOUCH_PAD_NUM14 -> BIT(14) + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_get_channel_mask(uint16_t *enable_mask); + +/** + * @brief Clear touch channel from touch sensor scan group. + * The working mode of the touch sensor is cyclically scanned. + * This function will clear the scan bits according to the given bitmask. + * @note If clear all mask, the FSM timer should be stop firsty. + * @param enable_mask bitmask of touch sensor scan group. + * e.g. TOUCH_PAD_NUM14 -> BIT(14) + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_clear_channel_mask(uint16_t enable_mask); + +/** + * @brief Configure parameter for each touch channel. + * @note Touch num 0 is denoise channel, please use `touch_pad_denoise_enable` to set denoise function + * @param touch_num touch pad index + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG if argument wrong + * - ESP_FAIL if touch pad not initialized + */ +esp_err_t touch_pad_config(touch_pad_t touch_num); + +/** + * @brief Reset the FSM of touch module. + * @note Call this function after `touch_pad_fsm_stop`. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_reset(void); + +/** + * @brief Get the current measure channel. + * @note Should be called when touch sensor measurement is in cyclic scan mode. + * @return + * - touch channel number + */ +touch_pad_t touch_pad_get_current_meas_channel(void); + +/** + * @brief Get the touch sensor interrupt status mask. + * @return + * - touch interrupt bit + */ +uint32_t touch_pad_read_intr_status_mask(void); + +/** + * @brief Enable touch sensor interrupt by bitmask. + * @param int_mask Pad mask to enable interrupts + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_intr_enable(touch_pad_intr_mask_t int_mask); + +/** + * @brief Disable touch sensor interrupt by bitmask. + * @param int_mask Pad mask to disable interrupts + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_intr_disable(touch_pad_intr_mask_t int_mask); + +/** + * @brief Clear touch sensor interrupt by bitmask. + * @param int_mask Pad mask to clear interrupts + * @return + * - ESP_OK on success + */ +esp_err_t touch_pad_intr_clear(touch_pad_intr_mask_t int_mask); + +/** + * @brief Register touch-pad ISR. + * The handler will be attached to the same CPU core that this function is running on. + * @param fn Pointer to ISR handler + * @param arg Parameter for ISR + * @param intr_mask Enable touch sensor interrupt handler by bitmask. + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Arguments error + * - ESP_ERR_NO_MEM No memory + */ +esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg, touch_pad_intr_mask_t intr_mask); + +/** + * @brief Enable/disable the timeout check and set timeout threshold for all touch sensor channels measurements. + * If enable: When the touch reading of a touch channel exceeds the measurement threshold, a timeout interrupt will be generated. + * If disable: the FSM does not check if the channel under measurement times out. + * + * @note The threshold compared with touch readings. + * @note In order to avoid abnormal short circuit of some touch channels. This function should be turned on. + * Ensure the normal operation of other touch channels. + * + * @param enable true(default): Enable the timeout check; false: Disable the timeout check. + * @param threshold For all channels, the maximum value that will not be exceeded during normal operation. + * +* @return + * - ESP_OK Success + */ +esp_err_t touch_pad_timeout_set(bool enable, uint32_t threshold); + +/** + * @brief Call this interface after timeout to make the touch channel resume normal work. Point on the next channel to measure. + * If this API is not called, the touch FSM will stop the measurement after timeout interrupt. + * + * @note Call this API after finishes the exception handling by user. + * + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_timeout_resume(void); + +/** + * @brief get raw data of touch sensor. + * @note After the initialization is complete, the "raw_data" is max value. You need to wait for a measurement + * cycle before you can read the correct touch value. + * @param touch_num touch pad index + * @param raw_data pointer to accept touch sensor value + * @return + * - ESP_OK Success + * - ESP_FAIL Touch channel 0 haven't this parameter. + */ + +esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint32_t *raw_data); + +/** + * @brief get benchmark of touch sensor. + * @note After initialization, the benchmark value is the maximum during the first measurement period. + * @param touch_num touch pad index + * @param benchmark pointer to accept touch sensor benchmark value + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Touch channel 0 haven't this parameter. + */ +esp_err_t touch_pad_read_benchmark(touch_pad_t touch_num, uint32_t *benchmark); + +/** + * @brief Get smoothed data that obtained by filtering the raw data. + * + * @param touch_num touch pad index + * @param smooth pointer to smoothed data + */ +esp_err_t touch_pad_filter_read_smooth(touch_pad_t touch_num, uint32_t *smooth); + +/** + * @brief Force reset benchmark to raw data of touch sensor. + * @param touch_num touch pad index + * - TOUCH_PAD_MAX Reset basaline of all channels + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_reset_benchmark(touch_pad_t touch_num); + +/** + * @brief set parameter of touch sensor filter and detection algorithm. + * For more details on the detection algorithm, please refer to the application documentation. + * @param filter_info select filter type and threshold of detection algorithm + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_filter_set_config(touch_filter_config_t *filter_info); + +/** + * @brief get parameter of touch sensor filter and detection algorithm. + * For more details on the detection algorithm, please refer to the application documentation. + * @param filter_info select filter type and threshold of detection algorithm + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_filter_get_config(touch_filter_config_t *filter_info); + +/** + * @brief enable touch sensor filter for detection algorithm. + * For more details on the detection algorithm, please refer to the application documentation. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_filter_enable(void); + +/** + * @brief disable touch sensor filter for detection algorithm. + * For more details on the detection algorithm, please refer to the application documentation. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_filter_disable(void); + +/** + * @brief set parameter of denoise pad (TOUCH_PAD_NUM0). + * T0 is an internal channel that does not have a corresponding external GPIO. + * T0 will work simultaneously with the measured channel Tn. Finally, the actual + * measured value of Tn is the value after subtracting lower bits of T0. + * The noise reduction function filters out interference introduced simultaneously on all channels, + * such as noise introduced by power supplies and external EMI. + * @param denoise parameter of denoise + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_denoise_set_config(touch_pad_denoise_t *denoise); + +/** + * @brief get parameter of denoise pad (TOUCH_PAD_NUM0). + * @param denoise Pointer to parameter of denoise + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_denoise_get_config(touch_pad_denoise_t *denoise); + +/** + * @brief enable denoise function. + * T0 is an internal channel that does not have a corresponding external GPIO. + * T0 will work simultaneously with the measured channel Tn. Finally, the actual + * measured value of Tn is the value after subtracting lower bits of T0. + * The noise reduction function filters out interference introduced simultaneously on all channels, + * such as noise introduced by power supplies and external EMI. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_denoise_enable(void); + +/** + * @brief disable denoise function. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_denoise_disable(void); + +/** + * @brief Get denoise measure value (TOUCH_PAD_NUM0). + * @param data Pointer to receive denoise value + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_denoise_read_data(uint32_t *data); + +/** + * @brief set parameter of waterproof function. + * + * The waterproof function includes a shielded channel (TOUCH_PAD_NUM14) and a guard channel. + * Guard pad is used to detect the large area of water covering the touch panel. + * Shield pad is used to shield the influence of water droplets covering the touch panel. + * It is generally designed as a grid and is placed around the touch buttons. + * + * @param waterproof parameter of waterproof + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_waterproof_set_config(touch_pad_waterproof_t *waterproof); + +/** + * @brief get parameter of waterproof function. + * @param waterproof parameter of waterproof + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_waterproof_get_config(touch_pad_waterproof_t *waterproof); + +/** + * @brief Enable parameter of waterproof function. + * Should be called after function ``touch_pad_waterproof_set_config``. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_waterproof_enable(void); + +/** + * @brief Disable parameter of waterproof function. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_waterproof_disable(void); + +/** + * @brief Enable/disable proximity function of touch channels. + * The proximity sensor measurement is the accumulation of touch channel measurements. + * + * @note Supports up to three touch channels configured as proximity sensors. + * @param touch_num touch pad index + * @param enabled true: enable the proximity function; false: disable the proximity function + * @return + * - ESP_OK: Configured correctly. + * - ESP_ERR_INVALID_ARG: Touch channel number error. + * - ESP_ERR_NOT_SUPPORTED: Don't support configured. + */ +esp_err_t touch_pad_proximity_enable(touch_pad_t touch_num, bool enabled); + +/** + * @brief Set measure count of proximity channel. + * The proximity sensor measurement is the accumulation of touch channel measurements. + * + * @note All proximity channels use the same `count` value. So please pass the parameter `TOUCH_PAD_MAX`. + * @param touch_num Touch pad index. In this version, pass the parameter `TOUCH_PAD_MAX`. + * @param count The cumulative times of measurements for proximity pad. Range: 0 ~ 255. + * @return + * - ESP_OK: Configured correctly. + * - ESP_ERR_INVALID_ARG: Touch channel number error. + */ +esp_err_t touch_pad_proximity_set_count(touch_pad_t touch_num, uint32_t count); + +/** + * @brief Get measure count of proximity channel. + * The proximity sensor measurement is the accumulation of touch channel measurements. + * + * @note All proximity channels use the same `count` value. So please pass the parameter `TOUCH_PAD_MAX`. + * @param touch_num Touch pad index. In this version, pass the parameter `TOUCH_PAD_MAX`. + * @param count The cumulative times of measurements for proximity pad. Range: 0 ~ 255. + * @return + * - ESP_OK: Configured correctly. + * - ESP_ERR_INVALID_ARG: Touch channel number error. + */ +esp_err_t touch_pad_proximity_get_count(touch_pad_t touch_num, uint32_t *count); + +/** + * @brief Get the accumulated measurement of the proximity sensor. + * The proximity sensor measurement is the accumulation of touch channel measurements. + * @param touch_num touch pad index + * @param measure_out If the accumulation process does not end, the `measure_out` is the process value. + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Touch num is not proximity + */ +esp_err_t touch_pad_proximity_get_data(touch_pad_t touch_num, uint32_t *measure_out); + +/** + * @brief Get parameter of touch sensor sleep channel. + * The touch sensor can works in sleep mode to wake up sleep. + * + * @note After the sleep channel is configured, Please use special functions for sleep channel. + * e.g. The user should uses `touch_pad_sleep_channel_read_data` instead of `touch_pad_read_raw_data` to obtain the sleep channel reading. + * + * @param slp_config touch sleep pad config. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_channel_get_info(touch_pad_sleep_channel_t *slp_config); + +/** + * @brief Enable/Disable sleep channel function for touch sensor. + * The touch sensor can works in sleep mode to wake up sleep. + * + * @note ESP32S2 only support one sleep channel. + * @note After the sleep channel is configured, Please use special functions for sleep channel. + * e.g. The user should uses `touch_pad_sleep_channel_read_data` instead of `touch_pad_read_raw_data` to obtain the sleep channel reading. + * + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param enable true: enable sleep pad for touch sensor; false: disable sleep pad for touch sensor; + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_channel_enable(touch_pad_t pad_num, bool enable); + +/** + * @brief Enable/Disable proximity function for sleep channel. + * The touch sensor can works in sleep mode to wake up sleep. + * + * @note ESP32S2 only support one sleep channel. + * + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param enable true: enable proximity for sleep channel; false: disable proximity for sleep channel; + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_channel_enable_proximity(touch_pad_t pad_num, bool enable); + +/** + * @brief Set the trigger threshold of touch sensor in deep sleep. + * The threshold determines the sensitivity of the touch sensor. + * + * @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep. + * + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param touch_thres touch sleep pad threshold + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_set_threshold(touch_pad_t pad_num, uint32_t touch_thres); + +/** + * @brief Get the trigger threshold of touch sensor in deep sleep. + * The threshold determines the sensitivity of the touch sensor. + * + * @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep. + * + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param touch_thres touch sleep pad threshold + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_get_threshold(touch_pad_t pad_num, uint32_t *touch_thres); + +/** + * @brief Read benchmark of touch sensor sleep channel. + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param benchmark pointer to accept touch sensor benchmark value + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG parameter is NULL + */ +esp_err_t touch_pad_sleep_channel_read_benchmark(touch_pad_t pad_num, uint32_t *benchmark); + +/** + * @brief Read smoothed data of touch sensor sleep channel. + * Smoothed data is filtered from the raw data. + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param smooth_data pointer to accept touch sensor smoothed data + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG parameter is NULL + */ +esp_err_t touch_pad_sleep_channel_read_smooth(touch_pad_t pad_num, uint32_t *smooth_data); + +/** + * @brief Read raw data of touch sensor sleep channel. + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param raw_data pointer to accept touch sensor raw data + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG parameter is NULL + */ +esp_err_t touch_pad_sleep_channel_read_data(touch_pad_t pad_num, uint32_t *raw_data); + +/** + * @brief Reset benchmark of touch sensor sleep channel. + * + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_channel_reset_benchmark(void); + +/** + * @brief Read proximity count of touch sensor sleep channel. + * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. + * @param proximity_cnt pointer to accept touch sensor proximity count value + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG parameter is NULL + */ +esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32_t *proximity_cnt); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/i2s.c b/components/driver/i2s.c index 05ff802a0f..74f0fa4072 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -498,7 +498,7 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) portBASE_TYPE high_priority_task_awoken = 0; - lldesc_t *finish_desc; + lldesc_t *finish_desc = NULL; if ((status & I2S_INTR_OUT_DSCR_ERR) || (status & I2S_INTR_IN_DSCR_ERR)) { ESP_EARLY_LOGE(I2S_TAG, "dma error, interrupt status: 0x%08x", status); diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index e7c93ef9aa..59280896bd 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -138,6 +138,8 @@ static inline uint32_t get_dma_periph(int dma_chan) } #elif CONFIG_IDF_TARGET_ESP32 return PERIPH_SPI_DMA_MODULE; +#else + return 0; #endif } diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 95a6a3f3af..09fc34dfce 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -190,7 +190,7 @@ static inline bool is_valid_host(spi_host_device_t host) { #if CONFIG_IDF_TARGET_ESP32 return host >= SPI1_HOST && host <= SPI3_HOST; -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 // SPI_HOST (SPI1_HOST) is not supported by the SPI Master driver on ESP32-S2 return host >= SPI2_HOST && host <= SPI3_HOST; #endif diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index 2cecf4275d..b1dad114c0 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -80,7 +80,7 @@ static inline bool is_valid_host(spi_host_device_t host) { #if CONFIG_IDF_TARGET_ESP32 return host >= SPI1_HOST && host <= SPI3_HOST; -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 // SPI_HOST (SPI1_HOST) is not supported by the SPI Slave driver on ESP32-S2 return host >= SPI2_HOST && host <= SPI3_HOST; #endif diff --git a/components/driver/timer.c b/components/driver/timer.c index 5df314d034..1e3ed5a56f 100644 --- a/components/driver/timer.c +++ b/components/driver/timer.c @@ -272,18 +272,25 @@ esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, switch (group_num) { case TIMER_GROUP_0: default: - if ((intr_alloc_flags & ESP_INTR_FLAG_EDGE) == 0) { - intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer_num; - } else { + intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer_num; +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 + if ((intr_alloc_flags & ESP_INTR_FLAG_EDGE)) { intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer_num; } +#endif timer_hal_get_status_reg_mask_bit(&(p_timer_obj[TIMER_GROUP_0][timer_num]->hal), &status_reg, &mask); break; case TIMER_GROUP_1: + intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer_num; +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 + if ((intr_alloc_flags & ESP_INTR_FLAG_EDGE)) { + intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer_num; + } +#endif if ((intr_alloc_flags & ESP_INTR_FLAG_EDGE) == 0) { intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer_num; } else { - intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer_num; + intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer_num; } timer_hal_get_status_reg_mask_bit(&(p_timer_obj[TIMER_GROUP_1][timer_num]->hal), &status_reg, &mask); break; diff --git a/components/driver/touch_sensor_common.c b/components/driver/touch_sensor_common.c index e5bbc74906..6063dad4bb 100644 --- a/components/driver/touch_sensor_common.c +++ b/components/driver/touch_sensor_common.c @@ -42,7 +42,7 @@ static const char *TOUCH_TAG = "TOUCH_SENSOR"; #define TOUCH_CHANNEL_CHECK(channel) do { \ TOUCH_CHECK(channel < SOC_TOUCH_SENSOR_NUM && channel >= 0, "Touch channel error", ESP_ERR_INVALID_ARG); \ } while (0); -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif defined CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #define TOUCH_CHANNEL_CHECK(channel) do { \ TOUCH_CHECK(channel < SOC_TOUCH_SENSOR_NUM && channel >= 0, "Touch channel error", ESP_ERR_INVALID_ARG); \ TOUCH_CHECK(channel != SOC_TOUCH_DENOISE_CHANNEL, "TOUCH0 is internal denoise channel", ESP_ERR_INVALID_ARG); \ @@ -194,7 +194,7 @@ esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint16_t threshold) TOUCH_EXIT_CRITICAL(); return ESP_OK; } -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint32_t threshold) { TOUCH_CHANNEL_CHECK(touch_num); @@ -214,7 +214,7 @@ esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint16_t *threshold) touch_hal_get_threshold(touch_num, threshold); return ESP_OK; } -#elif defined CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint32_t *threshold) { TOUCH_CHANNEL_CHECK(touch_num); diff --git a/components/driver/uart.c b/components/driver/uart.c index 911d098189..81a85a263b 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -35,6 +35,8 @@ #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #endif #ifdef CONFIG_UART_ISR_IN_IRAM diff --git a/components/efuse/esp32s3/component.mk b/components/efuse/esp32s3/component.mk new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/efuse/esp32s3/esp_efuse_table.c b/components/efuse/esp32s3/esp_efuse_table.c new file mode 100644 index 0000000000..f3d9208bf8 --- /dev/null +++ b/components/efuse/esp32s3/esp_efuse_table.c @@ -0,0 +1,13 @@ +// Copyright 2017-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 diff --git a/components/efuse/esp32s3/esp_efuse_table.csv b/components/efuse/esp32s3/esp_efuse_table.csv new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/efuse/esp32s3/include/esp_efuse_table.h b/components/efuse/esp32s3/include/esp_efuse_table.h new file mode 100644 index 0000000000..57423323de --- /dev/null +++ b/components/efuse/esp32s3/include/esp_efuse_table.h @@ -0,0 +1,123 @@ +// Copyright 2017-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 + +#ifdef __cplusplus +extern "C" { +#endif + +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_RTC_RAM_BOOT[]; +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_WR_DIS_USB_EXCHG_PINS[]; +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_DCACHE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_DCACHE[]; +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_DIS_BOOT_REMAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_HARD_DIS_JTAG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_USB_EXCHG_PINS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_USB_EXT_PHY_ENABLE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_XPD[]; +extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_TIEH[]; +extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_FORCE[]; +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_DIS_TINY_BASIC[]; +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_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_CLK8M_FREQ[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[]; +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[]; + +#ifdef __cplusplus +} +#endif + diff --git a/components/efuse/esp32s3/sources.cmake b/components/efuse/esp32s3/sources.cmake new file mode 100644 index 0000000000..492216be21 --- /dev/null +++ b/components/efuse/esp32s3/sources.cmake @@ -0,0 +1 @@ +set(EFUSE_SOC_SRCS "esp_efuse_table.c") \ No newline at end of file diff --git a/components/efuse/include/esp32s3/esp_efuse.h b/components/efuse/include/esp32s3/esp_efuse.h new file mode 100644 index 0000000000..c33eca5bbb --- /dev/null +++ b/components/efuse/include/esp32s3/esp_efuse.h @@ -0,0 +1,69 @@ +// 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 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of eFuse blocks ESP32S3 + */ +typedef enum { + EFUSE_BLK0 = 0, /**< Number of eFuse BLOCK0. REPEAT_DATA */ + + EFUSE_BLK1 = 1, /**< Number of eFuse BLOCK1. MAC_SPI_8M_SYS */ + + EFUSE_BLK2 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */ + EFUSE_BLK_SYS_DATA_PART1 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */ + + EFUSE_BLK3 = 3, /**< Number of eFuse BLOCK3. USER_DATA*/ + EFUSE_BLK_USER_DATA = 3, /**< Number of eFuse BLOCK3. USER_DATA*/ + + EFUSE_BLK4 = 4, /**< Number of eFuse BLOCK4. KEY0 */ + EFUSE_BLK_KEY0 = 4, /**< Number of eFuse BLOCK4. KEY0 */ + + EFUSE_BLK5 = 5, /**< Number of eFuse BLOCK5. KEY1 */ + EFUSE_BLK_KEY1 = 5, /**< Number of eFuse BLOCK5. KEY1 */ + + EFUSE_BLK6 = 6, /**< Number of eFuse BLOCK6. KEY2 */ + EFUSE_BLK_KEY2 = 6, /**< Number of eFuse BLOCK6. KEY2 */ + + EFUSE_BLK7 = 7, /**< Number of eFuse BLOCK7. KEY3 */ + EFUSE_BLK_KEY3 = 7, /**< Number of eFuse BLOCK7. KEY3 */ + + EFUSE_BLK8 = 8, /**< Number of eFuse BLOCK8. KEY4 */ + EFUSE_BLK_KEY4 = 8, /**< Number of eFuse BLOCK8. KEY4 */ + + EFUSE_BLK9 = 9, /**< Number of eFuse BLOCK9. KEY5 */ + EFUSE_BLK_KEY5 = 9, /**< Number of eFuse BLOCK9. KEY5 */ + + EFUSE_BLK10 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */ + EFUSE_BLK_SYS_DATA_PART2 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */ + + EFUSE_BLK_MAX +} esp_efuse_block_t; + +/** + * @brief Type of coding scheme + */ +typedef enum { + EFUSE_CODING_SCHEME_NONE = 0, /**< None */ + EFUSE_CODING_SCHEME_RS = 3, /**< Reed-Solomon coding */ +} esp_efuse_coding_scheme_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index ab792a49b7..84d03c5a22 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -27,6 +27,8 @@ extern "C" { #include "esp32/esp_efuse.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/esp_efuse.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/esp_efuse.h" #endif #define ESP_ERR_EFUSE 0x1600 /*!< Base error code for efuse api. */ diff --git a/components/efuse/private_include/esp32s3/esp_efuse_utility.h b/components/efuse/private_include/esp32s3/esp_efuse_utility.h new file mode 100644 index 0000000000..68c855e0ae --- /dev/null +++ b/components/efuse/private_include/esp32s3/esp_efuse_utility.h @@ -0,0 +1,30 @@ +// 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#define COUNT_EFUSE_BLOCKS 11 /* The number of blocks. */ +#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */ + +#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0 + +#define ESP_EFUSE_FIELD_CORRESPONDS_CODING_SCHEME(scheme, max_num_bit) + +#ifdef __cplusplus +} +#endif diff --git a/components/efuse/private_include/esp_efuse_utility.h b/components/efuse/private_include/esp_efuse_utility.h index ad45fae0aa..6999127b66 100644 --- a/components/efuse/private_include/esp_efuse_utility.h +++ b/components/efuse/private_include/esp_efuse_utility.h @@ -27,6 +27,8 @@ extern "C" { #include "esp32/esp_efuse_utility.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/esp_efuse_utility.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/esp_efuse_utility.h" #endif /** diff --git a/components/efuse/src/esp32s3/esp_efuse_api.c b/components/efuse/src/esp32s3/esp_efuse_api.c new file mode 100644 index 0000000000..dbac5ffffc --- /dev/null +++ b/components/efuse/src/esp32s3/esp_efuse_api.c @@ -0,0 +1,13 @@ +// 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. diff --git a/components/efuse/src/esp32s3/esp_efuse_fields.c b/components/efuse/src/esp32s3/esp_efuse_fields.c new file mode 100644 index 0000000000..aa65783146 --- /dev/null +++ b/components/efuse/src/esp32s3/esp_efuse_fields.c @@ -0,0 +1,13 @@ +// Copyright 2017-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. diff --git a/components/efuse/src/esp32s3/esp_efuse_utility.c b/components/efuse/src/esp32s3/esp_efuse_utility.c new file mode 100644 index 0000000000..aa65783146 --- /dev/null +++ b/components/efuse/src/esp32s3/esp_efuse_utility.c @@ -0,0 +1,13 @@ +// Copyright 2017-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. diff --git a/components/esp32s3/CMakeLists.txt b/components/esp32s3/CMakeLists.txt index 911dee42b9..5c2890a73f 100644 --- a/components/esp32s3/CMakeLists.txt +++ b/components/esp32s3/CMakeLists.txt @@ -21,7 +21,6 @@ else() "memprot.c" "pm_esp32s3.c" "pm_trace.c" - "sleep_modes.c" "spiram.c" "spiram_psram.c" "system_api_esp32s3.c") diff --git a/components/esp32s3/include/esp32s3/rtc.h b/components/esp32s3/include/esp32s3/rtc.h new file mode 100644 index 0000000000..296292e21d --- /dev/null +++ b/components/esp32s3/include/esp32s3/rtc.h @@ -0,0 +1,39 @@ +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file esp32s2/rtc.h + * + * This file contains declarations of rtc related functions. + */ + +/** + * @brief Get current value of RTC counter in microseconds + * + * Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute + * + * @return current value of RTC counter in microseconds + */ +uint64_t esp_rtc_get_time_us(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp32s3/ld/esp32s3.ld b/components/esp32s3/ld/esp32s3.ld index ab069788ca..33d16c902a 100644 --- a/components/esp32s3/ld/esp32s3.ld +++ b/components/esp32s3/ld/esp32s3.ld @@ -11,7 +11,7 @@ #define SRAM_IRAM_START 0x40370000 #define SRAM_DRAM_START 0x3FC80000 #define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START) -#define SRAM_DRAM_END 0x40054000 - I_D_SRAM_OFFSET /* 2nd stage bootloader iram_loader_seg start address */ +#define SRAM_DRAM_END 0x403BC000 - I_D_SRAM_OFFSET /* 2nd stage bootloader iram_loader_seg start address */ #define SRAM_IRAM_ORG (SRAM_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE) #define SRAM_DRAM_ORG (SRAM_DRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE) diff --git a/components/esp32s3/memprot.c b/components/esp32s3/memprot.c index 00dbf2063c..b87c98ad6e 100644 --- a/components/esp32s3/memprot.c +++ b/components/esp32s3/memprot.c @@ -18,7 +18,7 @@ #include -bool esp_memprot_is_assoc_intr_any() +bool esp_memprot_is_assoc_intr_any(void) { return true; } diff --git a/components/esp32s3/sleep_modes.c b/components/esp32s3/sleep_modes.c deleted file mode 100644 index 5bdf392f19..0000000000 --- a/components/esp32s3/sleep_modes.c +++ /dev/null @@ -1,717 +0,0 @@ -// 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 -#include -#include -#include "esp_attr.h" -#include "esp_sleep.h" -#include "esp_private/esp_timer_private.h" -#include "esp_log.h" -#include "esp32s3/clk.h" -#include "esp_newlib.h" -#include "esp_spi_flash.h" -#include "esp32s3/rom/cache.h" -#include "esp32s3/rom/rtc.h" -#include "esp_rom_uart.h" -#include "esp_rom_sys.h" -#include "soc/cpu.h" -#include "soc/rtc.h" -#include "soc/spi_periph.h" -#include "soc/dport_reg.h" -#include "soc/extmem_reg.h" -#include "soc/soc_memory_layout.h" -#include "soc/uart_caps.h" -#include "hal/wdt_hal.h" -#include "hal/clk_gate_ll.h" -#include "driver/rtc_io.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "sdkconfig.h" - -// If light sleep time is less than that, don't power down flash -#define FLASH_PD_MIN_SLEEP_TIME_US 2000 - -// Time from VDD_SDIO power up to first flash read in ROM code -#define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700 - -// Extra time it takes to enter and exit light sleep and deep sleep -// For deep sleep, this is until the wake stub runs (not the app). -#ifdef CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS -#define LIGHT_SLEEP_TIME_OVERHEAD_US (650 + 30 * 240 / CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ) -#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ) -#else -#define LIGHT_SLEEP_TIME_OVERHEAD_US (250 + 30 * 240 / CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ) -#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ) -#endif // CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS - -// Minimal amount of time we can sleep for -#define LIGHT_SLEEP_MIN_TIME_US 200 - -#define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \ - (source == value)) - -/** - * Internal structure which holds all requested deep sleep parameters - */ -typedef struct { - esp_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX]; - uint64_t sleep_duration; - uint32_t wakeup_triggers : 15; - uint32_t ext1_trigger_mode : 1; - uint32_t ext1_rtc_gpio_mask : 18; - uint32_t ext0_trigger_level : 1; - uint32_t ext0_rtc_gpio_num : 5; - uint32_t sleep_time_adjustment; - uint64_t rtc_ticks_at_sleep_start; -} sleep_config_t; - -static sleep_config_t s_config = { - .pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO }, - .wakeup_triggers = 0 -}; - -/* Internal variable used to track if light sleep wakeup sources are to be - expected when determining wakeup cause. */ -static bool s_light_sleep_wakeup = false; - -/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() - is not thread-safe. */ -static _lock_t lock_rtc_memory_crc; - -static const char *TAG = "sleep"; - -static uint32_t get_power_down_flags(void); -static void ext0_wakeup_prepare(void); -static void ext1_wakeup_prepare(void); -static void timer_wakeup_prepare(void); -static void touch_wakeup_prepare(void); - -/* Wake from deep sleep stub - See esp_deepsleep.h esp_wake_deep_sleep() comments for details. -*/ -esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void) -{ - _lock_acquire(&lock_rtc_memory_crc); - uint32_t stored_crc = REG_READ(RTC_MEMORY_CRC_REG); - set_rtc_memory_crc(); - uint32_t calc_crc = REG_READ(RTC_MEMORY_CRC_REG); - REG_WRITE(RTC_MEMORY_CRC_REG, stored_crc); - _lock_release(&lock_rtc_memory_crc); - - if (stored_crc != calc_crc) { - return NULL; - } - esp_deep_sleep_wake_stub_fn_t stub_ptr = (esp_deep_sleep_wake_stub_fn_t) REG_READ(RTC_ENTRY_ADDR_REG); - if (!esp_ptr_executable(stub_ptr)) { - return NULL; - } - return stub_ptr; -} - -void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) -{ - _lock_acquire(&lock_rtc_memory_crc); - REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); - set_rtc_memory_crc(); - _lock_release(&lock_rtc_memory_crc); -} - -void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) -{ - REG_SET_BIT(EXTMEM_CACHE_CONF_MISC_REG, EXTMEM_CACHE_TRACE_ENA); -} - -void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); - -void esp_deep_sleep(uint64_t time_in_us) -{ - esp_sleep_enable_timer_wakeup(time_in_us); - esp_deep_sleep_start(); -} - -static void IRAM_ATTR flush_uarts(void) -{ - for (int i = 0; i < SOC_UART_NUM; ++i) { - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { - esp_rom_uart_tx_wait_idle(i); - } - } -} - -static void IRAM_ATTR suspend_uarts(void) -{ - for (int i = 0; i < SOC_UART_NUM; ++i) { - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { - REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); - REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); - while (REG_GET_FIELD(UART_FSM_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { - ; - } - } - } -} - -static void IRAM_ATTR resume_uarts(void) -{ - for (int i = 0; i < SOC_UART_NUM; ++i) { - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { - REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); - REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); - REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XON); - } - } -} - -static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) -{ - // Stop UART output so that output is not lost due to APB frequency change. - // For light sleep, suspend UART output — it will resume after wakeup. - // For deep sleep, wait for the contents of UART FIFO to be sent. - if (pd_flags & RTC_SLEEP_PD_DIG) { - flush_uarts(); - } else { - suspend_uarts(); - } - - // Save current frequency and switch to XTAL - // Save current frequency and switch to XTAL - rtc_cpu_freq_config_t cpu_freq_config; - rtc_clk_cpu_freq_get_config(&cpu_freq_config); - rtc_clk_cpu_freq_set_xtal(); - - // Configure pins for external wakeup - if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { - ext0_wakeup_prepare(); - } - if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) { - ext1_wakeup_prepare(); - } - // Enable ULP wakeup - if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { - // no-op for esp32s3 - } - // Enable Touch wakeup - if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) { - touch_wakeup_prepare(); - } - - uint32_t reject_triggers = 0; - if ((pd_flags & RTC_SLEEP_PD_DIG) == 0) { - /* Light sleep, enable sleep reject for faster return from this function, - * in case the wakeup is already triggerred. - */ - reject_triggers = s_config.wakeup_triggers; - } - - // Enter sleep - rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags); - rtc_sleep_init(config); - - // Configure timer wakeup - if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && - s_config.sleep_duration > 0) { - timer_wakeup_prepare(); - } - - uint32_t result = rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); - - // Restore CPU frequency - rtc_clk_cpu_freq_set_config(&cpu_freq_config); - - // re-enable UART output - resume_uarts(); - - return result; -} - -void IRAM_ATTR esp_deep_sleep_start(void) -{ - // record current RTC time - s_config.rtc_ticks_at_sleep_start = rtc_time_get(); - esp_sync_counters_rtc_and_frc(); - // Configure wake stub - if (esp_get_deep_sleep_wake_stub() == NULL) { - esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep); - } - - // Decide which power domains can be powered down - uint32_t pd_flags = get_power_down_flags(); - - // Correct the sleep time - s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; - - // Enter sleep - esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags); - - // Because RTC is in a slower clock domain than the CPU, it - // can take several CPU cycles for the sleep mode to start. - while (1) { - ; - } -} - -/** - * Helper function which handles entry to and exit from light sleep - * Placed into IRAM as flash may need some time to be powered on. - */ -static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); - -static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) -{ - // Enter sleep - esp_err_t err = esp_sleep_start(pd_flags); - - // If VDDSDIO regulator was controlled by RTC registers before sleep, - // restore the configuration. - if (vddsdio_config.force) { - rtc_vddsdio_set_config(vddsdio_config); - } - - // If SPI flash was powered down, wait for it to become ready - if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { - // Wait for the flash chip to start up - esp_rom_delay_us(flash_enable_time_us); - } - return err; -} - -esp_err_t esp_light_sleep_start(void) -{ - static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL(&light_sleep_lock); - /* We will be calling esp_timer_private_advance inside DPORT access critical - * section. Make sure the code on the other CPU is not holding esp_timer - * lock, otherwise there will be deadlock. - */ - esp_timer_private_lock(); - s_config.rtc_ticks_at_sleep_start = rtc_time_get(); - uint64_t frc_time_at_start = esp_timer_get_time(); - DPORT_STALL_OTHER_CPU_START(); - - // Decide which power domains can be powered down - uint32_t pd_flags = get_power_down_flags(); - - // Amount of time to subtract from actual sleep time. - // This is spent on entering and leaving light sleep. - s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US; - - // Decide if VDD_SDIO needs to be powered down; - // If it needs to be powered down, adjust sleep time. - const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US; - -#ifndef CONFIG_SPIRAM - const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US, - flash_enable_time_us + LIGHT_SLEEP_TIME_OVERHEAD_US + LIGHT_SLEEP_MIN_TIME_US); - - if (s_config.sleep_duration > vddsdio_pd_sleep_duration) { - pd_flags |= RTC_SLEEP_PD_VDDSDIO; - s_config.sleep_time_adjustment += flash_enable_time_us; - } -#endif //CONFIG_SPIRAM - - rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); - - // Safety net: enable WDT in case exit from light sleep fails - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - bool wdt_was_enabled = wdt_hal_is_enabled(&rtc_wdt_ctx); // If WDT was enabled in the user code, then do not change it here. - if (!wdt_was_enabled) { - wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); - uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); - wdt_hal_enable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - } - - // Enter sleep, then wait for flash to be ready on wakeup - esp_err_t err = esp_light_sleep_inner(pd_flags, - flash_enable_time_us, vddsdio_config); - - s_light_sleep_wakeup = true; - - // FRC1 has been clock gated for the duration of the sleep, correct for that. - uint64_t rtc_ticks_at_end = rtc_time_get(); - uint64_t frc_time_at_end = esp_timer_get_time(); - - uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, - esp_clk_slowclk_cal_get()); - uint64_t frc_time_diff = frc_time_at_end - frc_time_at_start; - - int64_t time_diff = rtc_time_diff - frc_time_diff; - /* Small negative values (up to 1 RTC_SLOW clock period) are possible, - * for very small values of sleep_duration. Ignore those to keep esp_timer - * monotonic. - */ - if (time_diff > 0) { - esp_timer_private_advance(time_diff); - } - esp_set_time_from_rtc(); - - esp_timer_private_unlock(); - DPORT_STALL_OTHER_CPU_END(); - if (!wdt_was_enabled) { - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - } - portEXIT_CRITICAL(&light_sleep_lock); - return err; -} - -esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) -{ - // For most of sources it is enough to set trigger mask in local - // configuration structure. The actual RTC wake up options - // will be updated by esp_sleep_start(). - if (source == ESP_SLEEP_WAKEUP_ALL) { - s_config.wakeup_triggers = 0; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN; - s_config.sleep_duration = 0; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) { - s_config.ext0_rtc_gpio_num = 0; - s_config.ext0_trigger_level = 0; - s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) { - s_config.ext1_rtc_gpio_mask = 0; - s_config.ext1_trigger_mode = 0; - s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_TOUCH_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) { - s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN); - } -#ifdef CONFIG_ESP32S3_ULP_COPROC_ENABLED - else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN; - } -#endif - else { - ESP_LOGE(TAG, "Incorrect wakeup source (%d) to disable.", (int) source); - return ESP_ERR_INVALID_STATE; - } - return ESP_OK; -} - -esp_err_t esp_sleep_enable_ulp_wakeup(void) -{ - s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); - return ESP_OK; -} - -esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us) -{ - s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN; - s_config.sleep_duration = time_in_us; - return ESP_OK; -} - -static void timer_wakeup_prepare(void) -{ - uint32_t period = esp_clk_slowclk_cal_get(); - int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment; - if (sleep_duration < 0) { - sleep_duration = 0; - } - int64_t rtc_count_delta = rtc_time_us_to_slowclk(sleep_duration, period); - rtc_sleep_set_wakeup_time(s_config.rtc_ticks_at_sleep_start + rtc_count_delta); - SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M); - SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); -} - -/* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ -static void touch_wakeup_prepare(void) -{ - touch_pad_sleep_channel_t slp_config; - touch_pad_fsm_stop(); - touch_pad_clear_channel_mask(SOC_TOUCH_SENSOR_BIT_MASK_MAX); - touch_pad_sleep_channel_get_info(&slp_config); - touch_pad_set_channel_mask(BIT(slp_config.touch_num)); - touch_pad_fsm_start(); -} - -esp_err_t esp_sleep_enable_touchpad_wakeup(void) -{ - if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) { - ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0"); - return ESP_ERR_INVALID_STATE; - } - s_config.wakeup_triggers |= RTC_TOUCH_TRIG_EN; - return ESP_OK; -} - -touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) -{ - if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) { - return TOUCH_PAD_MAX; - } - touch_pad_t pad_num; - esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); //TODO 723diff commit id:fda9ada1b - assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero"); - return pad_num; -} - -esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) -{ - if (level < 0 || level > 1) { - return ESP_ERR_INVALID_ARG; - } - if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { - ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); - return ESP_ERR_INVALID_STATE; - } - s_config.ext0_rtc_gpio_num = rtc_io_number_get(gpio_num); - s_config.ext0_trigger_level = level; - s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN; - return ESP_OK; -} - -static void ext0_wakeup_prepare(void) -{ - int rtc_gpio_num = s_config.ext0_rtc_gpio_num; - // Set GPIO to be used for wakeup - REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtc_gpio_num); - // Set level which will trigger wakeup - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - s_config.ext0_trigger_level, RTC_CNTL_EXT_WAKEUP0_LV_S); - // Find GPIO descriptor in the rtc_io_desc table and configure the pad - const rtc_io_desc_t *desc = &rtc_io_desc[rtc_gpio_num]; - REG_SET_BIT(desc->reg, desc->mux); - SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); - REG_SET_BIT(desc->reg, desc->ie); -} - -esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode) -{ - if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) { - return ESP_ERR_INVALID_ARG; - } - // Translate bit map of GPIO numbers into the bit map of RTC IO numbers - uint32_t rtc_gpio_mask = 0; - for (int gpio = 0; mask; ++gpio, mask >>= 1) { - if ((mask & 1) == 0) { - continue; - } - if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { - ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio); - return ESP_ERR_INVALID_ARG; - } - rtc_gpio_mask |= BIT(rtc_io_number_get(gpio)); - } - s_config.ext1_rtc_gpio_mask = rtc_gpio_mask; - s_config.ext1_trigger_mode = mode; - s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN; - return ESP_OK; -} - -static void ext1_wakeup_prepare(void) -{ - // Configure all RTC IOs selected as ext1 wakeup inputs - uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask; - for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) { - int rtc_pin = rtc_io_number_get(gpio); - if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { - continue; - } - const rtc_io_desc_t *desc = &rtc_io_desc[rtc_pin]; - // Route pad to RTC - REG_SET_BIT(desc->reg, desc->mux); - SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); - // set input enable in sleep mode - REG_SET_BIT(desc->reg, desc->ie); - // Pad configuration depends on RTC_PERIPH state in sleep mode - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { - // RTC_PERIPH will be powered down, so RTC_IO_ registers will - // loose their state. Lock pad configuration. - // Pullups/pulldowns also need to be disabled. - REG_CLR_BIT(desc->reg, desc->pulldown); - REG_CLR_BIT(desc->reg, desc->pullup); - REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, desc->hold_force); - } - // Keep track of pins which are processed to bail out early - rtc_gpio_mask &= ~BIT(rtc_pin); - } - // Clear state from previous wakeup - REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); - // Set pins to be used for wakeup - REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, s_config.ext1_rtc_gpio_mask); - // Set logic function (any low, all high) - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - s_config.ext1_trigger_mode, RTC_CNTL_EXT_WAKEUP1_LV_S); -} - -uint64_t esp_sleep_get_ext1_wakeup_status(void) -{ - if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) { - return 0; - } - uint32_t status = REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); - // Translate bit map of RTC IO numbers into the bit map of GPIO numbers - uint64_t gpio_mask = 0; - for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { - if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { - continue; - } - int rtc_pin = rtc_io_number_get(gpio); - if ((status & BIT(rtc_pin)) == 0) { - continue; - } - gpio_mask |= 1ULL << gpio; - } - return gpio_mask; -} - -esp_err_t esp_sleep_enable_gpio_wakeup(void) -{ - if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { - ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); - return ESP_ERR_INVALID_STATE; - } - s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN; - return ESP_OK; -} - -esp_err_t esp_sleep_enable_uart_wakeup(int uart_num) -{ - if (uart_num == 0) { - s_config.wakeup_triggers |= RTC_UART0_TRIG_EN; - } else if (uart_num == 1) { - s_config.wakeup_triggers |= RTC_UART1_TRIG_EN; - } else { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -esp_err_t esp_sleep_enable_wifi_wakeup(void) -{ - s_config.wakeup_triggers |= RTC_MAC_TRIG_EN; - return ESP_OK; -} - -esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) -{ - if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET && !s_light_sleep_wakeup) { - return ESP_SLEEP_WAKEUP_UNDEFINED; - } - - uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE); - if (wakeup_cause & RTC_EXT0_TRIG_EN) { - return ESP_SLEEP_WAKEUP_EXT0; - } else if (wakeup_cause & RTC_EXT1_TRIG_EN) { - return ESP_SLEEP_WAKEUP_EXT1; - } else if (wakeup_cause & RTC_TIMER_TRIG_EN) { - return ESP_SLEEP_WAKEUP_TIMER; - } else if (wakeup_cause & RTC_TOUCH_TRIG_EN) { - return ESP_SLEEP_WAKEUP_TOUCHPAD; - } else if (wakeup_cause & RTC_ULP_TRIG_EN) { - return ESP_SLEEP_WAKEUP_ULP; - } else if (wakeup_cause & RTC_GPIO_TRIG_EN) { - return ESP_SLEEP_WAKEUP_GPIO; - } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) { - return ESP_SLEEP_WAKEUP_UART; - } else if (wakeup_cause & RTC_MAC_TRIG_EN) { - return ESP_SLEEP_WAKEUP_WIFI; - } else if (wakeup_cause & RTC_COCPU_TRIG_EN) { - return ESP_SLEEP_WAKEUP_ULP; - } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) { - return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG; - } else { - return ESP_SLEEP_WAKEUP_UNDEFINED; - } -} - -esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, - esp_sleep_pd_option_t option) -{ - if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) { - return ESP_ERR_INVALID_ARG; - } - s_config.pd_options[domain] = option; - return ESP_OK; -} - -static uint32_t get_power_down_flags(void) -{ - // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF. - - // RTC_SLOW_MEM is needed for the ULP, so keep RTC_SLOW_MEM powered up if ULP - // is used and RTC_SLOW_MEM is Auto. - // If there is any data placed into .rtc.data or .rtc.bss segments, and - // RTC_SLOW_MEM is Auto, keep it powered up as well. - - // Labels are defined in the linker script, see esp32s3.ld. - extern int _rtc_slow_length; - - if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) && - ((size_t) &_rtc_slow_length > 0 || - (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON; - } - - // RTC_FAST_MEM is needed for deep sleep stub. - // If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub - // can run. - // In the new chip revision, deep sleep stub will be optional, - // and this can be changed. - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; - } - - // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup. - // If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH. - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) { - if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON; - } else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { - // In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH - // prevents ULP timer and touch FSMs from working correctly. - s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF; - } - } - - if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO) { - s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF; - } - - const char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; - ESP_LOGD(TAG, "RTC_PERIPH: %s, RTC_SLOW_MEM: %s, RTC_FAST_MEM: %s", - option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]], - option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]], - option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]); - - // Prepare flags based on the selected options - uint32_t pd_flags = 0; - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM; - } - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM; - } - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; - } - return pd_flags; -} diff --git a/components/esp_gdbstub/esp32s3/gdbstub_esp32s3.c b/components/esp_gdbstub/esp32s3/gdbstub_esp32s3.c new file mode 100644 index 0000000000..1f1a733d0c --- /dev/null +++ b/components/esp_gdbstub/esp32s3/gdbstub_esp32s3.c @@ -0,0 +1,51 @@ +// 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 "soc/uart_periph.h" +#include "soc/gpio_periph.h" +#include "esp_gdbstub_common.h" + +#define UART_NUM CONFIG_ESP_CONSOLE_UART_NUM + +void esp_gdbstub_target_init() +{ +} + +int esp_gdbstub_getchar() +{ + while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_RXFIFO_CNT) == 0) { + ; + } + return REG_READ(UART_FIFO_AHB_REG(UART_NUM)); +} + +void esp_gdbstub_putchar(int c) +{ + while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_TXFIFO_CNT) >= 126) { + ; + } + REG_WRITE(UART_FIFO_AHB_REG(UART_NUM), c); +} + +int esp_gdbstub_readmem(intptr_t addr) +{ + if (addr < 0x20000000 || addr >= 0x80000000) { + /* see cpu_configure_region_protection */ + return -1; + } + uint32_t val_aligned = *(uint32_t *)(addr & (~3)); + uint32_t shift = (addr & 3) * 8; + return (val_aligned >> shift) & 0xff; +} diff --git a/components/esp_gdbstub/esp32s3/gdbstub_target_config.h b/components/esp_gdbstub/esp32s3/gdbstub_target_config.h new file mode 100644 index 0000000000..c4adad7069 --- /dev/null +++ b/components/esp_gdbstub/esp32s3/gdbstub_target_config.h @@ -0,0 +1,18 @@ +// 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 + +/* Number of extra TIE defined registers, not listed in the XCHAL */ +#define GDBSTUB_EXTRA_TIE_SIZE 1 diff --git a/components/esp_rom/include/esp32s3/rom/opi_flash.h b/components/esp_rom/include/esp32s3/rom/opi_flash.h index bb209f67f0..be7fcb06a9 100644 --- a/components/esp_rom/include/esp32s3/rom/opi_flash.h +++ b/components/esp_rom/include/esp32s3/rom/opi_flash.h @@ -40,6 +40,7 @@ typedef struct { #define ESP_ROM_SPIFLASH_BP2 BIT4 #define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_QE BIT9 +#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2) #define FLASH_OP_MODE_RDCMD_DOUT 0x3B #define ESP_ROM_FLASH_SECTOR_SIZE 0x1000 diff --git a/components/esp_rom/include/esp32s3/rom/spi_flash.h b/components/esp_rom/include/esp32s3/rom/spi_flash.h index fb060c15c1..44d447e933 100644 --- a/components/esp_rom/include/esp32s3/rom/spi_flash.h +++ b/components/esp_rom/include/esp32s3/rom/spi_flash.h @@ -111,6 +111,7 @@ extern "C" { #define ESP_ROM_SPIFLASH_BP2 BIT4 #define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_QE BIT9 +#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2) #define FLASH_ID_GD25LQ32C 0xC86016 diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 92080e0004..a104b396b5 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -42,9 +42,18 @@ #include "esp32s2/rom/cache.h" #include "esp32s2/rom/rtc.h" #include "esp32s2/spiram.h" -#include "soc/periph_defs.h" #include "esp32s2/dport_access.h" #include "esp32s2/memprot.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rtc.h" +#include "esp32s3/brownout.h" +#include "esp32s3/cache_err_int.h" +#include "esp32s3/rom/cache.h" +#include "esp32s3/rom/rtc.h" +#include "esp32s3/spiram.h" +#include "esp32s3/dport_access.h" +#include "esp32s3/memprot.h" +#include "soc/assist_debug_reg.h" #endif #include "bootloader_flash_config.h" @@ -53,8 +62,10 @@ #include "hal/rtc_io_hal.h" #include "hal/wdt_hal.h" +#include "soc/rtc.h" #include "soc/dport_reg.h" #include "soc/efuse_reg.h" +#include "soc/periph_defs.h" #include "soc/cpu.h" #include "soc/rtc.h" #include "soc/spinlock.h" @@ -117,15 +128,20 @@ void IRAM_ATTR call_start_cpu1(void) bootloader_init_mem(); #if CONFIG_ESP_CONSOLE_UART_NONE - ets_install_putc1(NULL); - ets_install_putc2(NULL); + esp_rom_install_channel_putc(1, NULL); + esp_rom_install_channel_putc(2, NULL); #else // CONFIG_ESP_CONSOLE_UART_NONE ets_install_uart_printf(); esp_rom_uart_set_as_console(CONFIG_ESP_CONSOLE_UART_NUM); #endif +#if CONFIG_IDF_TARGET_ESP32 DPORT_REG_SET_BIT(DPORT_APP_CPU_RECORD_CTRL_REG, DPORT_APP_CPU_PDEBUG_ENABLE | DPORT_APP_CPU_RECORD_ENABLE); DPORT_REG_CLR_BIT(DPORT_APP_CPU_RECORD_CTRL_REG, DPORT_APP_CPU_RECORD_ENABLE); +#else + REG_WRITE(ASSIST_DEBUG_CORE_1_RCD_PDEBUGENABLE_REG, 1); + REG_WRITE(ASSIST_DEBUG_CORE_1_RCD_RECORDING_REG, 1); +#endif s_cpu_up[1] = true; ESP_EARLY_LOGI(TAG, "App cpu up."); @@ -153,23 +169,38 @@ static void start_other_core(void) { // If not the single core variant of ESP32 - check this since there is // no separate soc_caps.h for the single core variant. - if (!REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_DIS_APP_CPU)) { + bool is_single_core = false; +#if CONFIG_IDF_TARGET_ESP32 + is_single_core = REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_DIS_APP_CPU); +#endif + if (!is_single_core) { ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1); +#if CONFIG_IDF_TARGET_ESP32 Cache_Flush(1); Cache_Read_Enable(1); +#endif esp_cpu_unstall(1); // Enable clock and reset APP CPU. Note that OpenOCD may have already // enabled clock and taken APP CPU out of reset. In this case don't reset // APP CPU again, as that will clear the breakpoints which may have already // been set. +#if CONFIG_IDF_TARGET_ESP32 if (!DPORT_GET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN)) { DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN); DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL); DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); } +#elif CONFIG_IDF_TARGET_ESP32S3 + if (!REG_GET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN)) { + REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN); + REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL); + REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETING); + REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETING); + } +#endif ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1); volatile bool cpus_up = false; @@ -207,8 +238,6 @@ void IRAM_ATTR call_start_cpu0(void) RESET_REASON rst_reas[1]; #endif - bootloader_init_mem(); - // Move exception vectors to IRAM cpu_hal_set_vecbase(&_init_start); @@ -259,6 +288,20 @@ void IRAM_ATTR call_start_cpu0(void) #endif #endif +#if CONFIG_IDF_TARGET_ESP32S3 + /* Configure the mode of instruction cache : cache size, cache line size. */ + extern void rom_config_instruction_cache_mode(uint32_t cfg_cache_size, uint8_t cfg_cache_ways, uint8_t cfg_cache_line_size); + rom_config_instruction_cache_mode(CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE, CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS, CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE); + + /* If we need use SPIRAM, we should use data cache. + Configure the mode of data : cache size, cache line size.*/ + Cache_Suspend_DCache(); + extern void rom_config_data_cache_mode(uint32_t cfg_cache_size, uint8_t cfg_cache_ways, uint8_t cfg_cache_line_size); + rom_config_data_cache_mode(CONFIG_ESP32S3_DATA_CACHE_SIZE, CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS, CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE); + Cache_Resume_DCache(0); +#endif + + bootloader_init_mem(); #if CONFIG_SPIRAM_BOOT_INIT if (esp_spiram_init() != ESP_OK) { #if CONFIG_IDF_TARGET_ESP32 @@ -282,11 +325,7 @@ void IRAM_ATTR call_start_cpu0(void) #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE s_cpu_up[0] = true; #endif -#ifdef CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ - ESP_EARLY_LOGI(TAG, "cpu freq: %d", CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ); -#else - ESP_EARLY_LOGI(TAG, "cpu freq: %d", CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ); -#endif + ESP_EARLY_LOGI(TAG, "Pro cpu up."); #if SOC_CPU_CORES_NUM > 1 // there is no 'single-core mode' for natively single-core processors @@ -294,7 +333,11 @@ void IRAM_ATTR call_start_cpu0(void) start_other_core(); #else ESP_EARLY_LOGI(TAG, "Single core mode"); +#if CONFIG_IDF_TARGET_ESP32 DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN); // stop the other core +#elif CONFIG_IDF_TARGET_ESP32S3 + REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN); +#endif #endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE #endif // SOC_CPU_CORES_NUM > 1 @@ -368,7 +411,11 @@ void IRAM_ATTR call_start_cpu0(void) intr_matrix_clear(); #ifdef CONFIG_ESP_CONSOLE_UART - esp_rom_uart_set_clock_baudrate(CONFIG_ESP_CONSOLE_UART_NUM, APB_CLK_FREQ, CONFIG_ESP_CONSOLE_UART_BAUDRATE); + uint32_t clock_hz = rtc_clk_apb_freq_get(); +#if CONFIG_IDF_TARGET_ESP32S3 + clock_hz = UART_CLK_FREQ_ROM; // From esp32-s3 on, UART clock source is selected to XTAL in ROM +#endif + esp_rom_uart_set_clock_baudrate(CONFIG_ESP_CONSOLE_UART_NUM, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif rtcio_hal_unhold_all(); diff --git a/components/esp_system/port/panic_handler.c b/components/esp_system/port/panic_handler.c index 37d334a177..61382f4651 100644 --- a/components/esp_system/port/panic_handler.c +++ b/components/esp_system/port/panic_handler.c @@ -45,6 +45,12 @@ #include "soc/extmem_reg.h" #include "soc/cache_memory.h" #include "soc/rtc_cntl_reg.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/cache_err_int.h" +#include "esp32s3/memprot.h" +#include "soc/extmem_reg.h" +#include "soc/cache_memory.h" +#include "soc/rtc_cntl_reg.h" #endif #include "esp_private/panic_internal.h" @@ -378,6 +384,78 @@ static inline void print_memprot_err_details(const void *f) panic_print_hex( (uint32_t)fault_addr ); panic_print_str(" not permitted.\r\n"); } + +#elif CONFIG_IDF_TARGET_ESP32S3 +static inline void print_cache_err_details(const void* f) +{ + uint32_t vaddr = 0, size = 0; + uint32_t status; + status = REG_READ(EXTMEM_CACHE_ILG_INT_ST_REG); + for (int i = 0; i < 32; i++) { + switch (status & BIT(i)) { + case EXTMEM_ICACHE_SYNC_OP_FAULT_ST: + //TODO, which size should fetch + //vaddr = REG_READ(EXTMEM_ICACHE_MEM_SYNC0_REG); + //size = REG_READ(EXTMEM_ICACHE_MEM_SYNC1_REG); + panic_print_str("Icache sync parameter configuration error, the error address and size is 0x"); + panic_print_hex(vaddr); + panic_print_str("(0x"); + panic_print_hex(size); + panic_print_str(")\r\n"); + break; + case EXTMEM_ICACHE_PRELOAD_OP_FAULT_ST: + //TODO, which size should fetch + vaddr = REG_READ(EXTMEM_ICACHE_PRELOAD_ADDR_REG); + size = REG_READ(EXTMEM_ICACHE_PRELOAD_SIZE_REG); + panic_print_str("Icache preload parameter configuration error, the error address and size is 0x"); + panic_print_hex(vaddr); + panic_print_str("(0x"); + panic_print_hex(size); + panic_print_str(")\r\n"); + break; + case EXTMEM_DCACHE_SYNC_OP_FAULT_ST: + //TODO, which size should fetch + //vaddr = REG_READ(EXTMEM_DCACHE_MEM_SYNC0_REG); + //size = REG_READ(EXTMEM_DCACHE_MEM_SYNC1_REG); + panic_print_str("Dcache sync parameter configuration error, the error address and size is 0x"); + panic_print_hex(vaddr); + panic_print_str("(0x"); + panic_print_hex(size); + panic_print_str(")\r\n"); + break; + case EXTMEM_DCACHE_PRELOAD_OP_FAULT_ST: + //TODO, which size should fetch + vaddr = REG_READ(EXTMEM_DCACHE_PRELOAD_ADDR_REG); + size = REG_READ(EXTMEM_DCACHE_PRELOAD_SIZE_REG); + panic_print_str("Dcache preload parameter configuration error, the error address and size is 0x"); + panic_print_hex(vaddr); + panic_print_str("(0x"); + panic_print_hex(size); + panic_print_str(")\r\n"); + break; + case EXTMEM_DCACHE_WRITE_FLASH_ST: + panic_print_str("Write back error occurred while dcache tries to write back to flash\r\n"); + break; + case EXTMEM_MMU_ENTRY_FAULT_ST: + vaddr = REG_READ(EXTMEM_CACHE_MMU_FAULT_VADDR_REG); + panic_print_str("MMU entry fault error occurred while accessing the address 0x"); + panic_print_hex(vaddr); + + if (REG_READ(EXTMEM_CACHE_MMU_FAULT_CONTENT_REG) & MMU_INVALID) { + panic_print_str(" (invalid mmu entry)"); + } + panic_print_str("\r\n"); + break; + default: + break; + } + } + panic_print_str("\r\n"); +} + +static inline void print_memprot_err_details(const void *f) +{ +} #endif static void frame_to_panic_info(XtExcFrame *frame, panic_info_t *info, bool pseudo_excause) @@ -409,7 +487,7 @@ static void frame_to_panic_info(XtExcFrame *frame, panic_info_t *info, bool pseu "Interrupt wdt timeout on CPU1", #if CONFIG_IDF_TARGET_ESP32 "Cache disabled but cached memory region accessed", -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 "Cache exception", #endif }; @@ -426,7 +504,7 @@ static void frame_to_panic_info(XtExcFrame *frame, panic_info_t *info, bool pseu info->exception = PANIC_EXCEPTION_DEBUG; } -#if CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (frame->exccause == PANIC_RSN_CACHEERR) { if ( esp_memprot_is_assoc_intr_any() ) { info->details = print_memprot_err_details; diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index f61c52f305..b8d7b67cd8 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -48,14 +48,16 @@ #include "esp32/rom/cache.h" #include "esp32/clk.h" #include "esp32/rom/rtc.h" -#include "esp32/rom/uart.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/rom/cache.h" #include "esp32s2/rom/rtc.h" -#include "esp32s2/rom/ets_sys.h" #include "soc/extmem_reg.h" -#include "esp32s2/rom/uart.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" +#include "esp32s3/rom/cache.h" +#include "esp32s3/rom/rtc.h" +#include "soc/extmem_reg.h" #endif // If light sleep time is less than that, don't power down flash @@ -68,6 +70,8 @@ #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ #elif CONFIG_IDF_TARGET_ESP32S2 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ +#elif CONFIG_IDF_TARGET_ESP32S3 +#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ #endif #if defined(CONFIG_IDF_TARGET_ESP32) @@ -318,7 +322,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) #ifdef CONFIG_IDF_TARGET_ESP32 uint32_t result = rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 uint32_t result = rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); #endif @@ -524,7 +528,7 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void) #else // CONFIG_ESP32_ULP_COPROC_ENABLED return ESP_ERR_INVALID_STATE; #endif // CONFIG_ESP32_ULP_COPROC_ENABLED -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); return ESP_OK; #endif @@ -720,6 +724,9 @@ esp_err_t esp_sleep_enable_wifi_wakeup(void) #elif CONFIG_IDF_TARGET_ESP32S2 s_config.wakeup_triggers |= RTC_WIFI_TRIG_EN; return ESP_OK; +#elif CONFIG_IDF_TARGET_ESP32S3 + s_config.wakeup_triggers |= RTC_MAC_TRIG_EN; + return ESP_OK; #endif } @@ -732,7 +739,7 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) #ifdef CONFIG_IDF_TARGET_ESP32 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE); -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE); #endif diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index b801faba5a..6edb9359f9 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -59,12 +59,15 @@ // [refactor-todo] make this file completely target-independent #if CONFIG_IDF_TARGET_ESP32 +#include "esp32/clk.h" #include "esp32/spiram.h" #include "esp32/brownout.h" #elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/clk.h" #include "esp32s2/spiram.h" #include "esp32s2/brownout.h" #elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #include "esp32s3/spiram.h" #include "esp32s3/brownout.h" #endif @@ -311,6 +314,8 @@ static void start_cpu0_default(void) { ESP_EARLY_LOGI(TAG, "Pro cpu start user code"); + int cpu_freq = esp_clk_cpu_freq(); + ESP_EARLY_LOGI(TAG, "cpu freq: %d", cpu_freq); // Display information about the current running image. if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { diff --git a/components/esp_system/system_api.c b/components/esp_system/system_api.c index 137cab621a..33541c6072 100644 --- a/components/esp_system/system_api.c +++ b/components/esp_system/system_api.c @@ -10,6 +10,8 @@ #include "esp_rom_uart.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/memprot.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/memprot.h" #endif diff --git a/components/esp_system/system_time.c b/components/esp_system/system_time.c index dba3fc3c53..8fae106ce8 100644 --- a/components/esp_system/system_time.c +++ b/components/esp_system/system_time.c @@ -25,6 +25,8 @@ #include "esp32/rtc.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rtc.h" #endif #include "esp_private/startup_internal.h" diff --git a/components/esp_system/test/test_sleep.c b/components/esp_system/test/test_sleep.c index 716e5b1ebe..fed5dd7338 100644 --- a/components/esp_system/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -26,6 +26,9 @@ #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" +#include "esp32s3/rom/rtc.h" #endif diff --git a/components/esp_timer/Kconfig b/components/esp_timer/Kconfig index 15fd196bc2..f7dabf23fe 100644 --- a/components/esp_timer/Kconfig +++ b/components/esp_timer/Kconfig @@ -26,7 +26,7 @@ menu "High resolution timer (esp_timer)" choice ESP_TIMER_IMPL prompt "Hardware timer to use for esp_timer" default ESP_TIMER_IMPL_TG0_LAC if IDF_TARGET_ESP32 - default ESP_TIMER_IMPL_SYSTIMER if IDF_TARGET_ESP32S2 + default ESP_TIMER_IMPL_SYSTIMER help esp_timer APIs can be implemented using different hardware timers. @@ -47,7 +47,7 @@ menu "High resolution timer (esp_timer)" config ESP_TIMER_IMPL_SYSTIMER bool "SYSTIMER" - depends on IDF_TARGET_ESP32S2 + depends on !IDF_TARGET_ESP32 endchoice diff --git a/components/esp_timer/src/esp_timer_impl_systimer.c b/components/esp_timer/src/esp_timer_impl_systimer.c index fce86a5eaf..169366eebc 100644 --- a/components/esp_timer/src/esp_timer_impl_systimer.c +++ b/components/esp_timer/src/esp_timer_impl_systimer.c @@ -103,8 +103,13 @@ void esp_timer_impl_advance(int64_t time_us) esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler) { s_alarm_handler = alarm_handler; +#ifdef SOC_SYSTIMER_INT_LEVEL + int int_type = 0; +#else + int int_type = ESP_INTR_FLAG_EDGE; +#endif // SOC_SYSTIMER_INT_LEVEL esp_err_t err = esp_intr_alloc(ETS_SYSTIMER_TARGET2_EDGE_INTR_SOURCE, - ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_EDGE, + ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_IRAM | int_type, &timer_alarm_isr, NULL, &s_timer_interrupt_handle); if (err != ESP_OK) { @@ -112,9 +117,10 @@ esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler) goto err_intr_alloc; } - systimer_hal_enable_counter(SYSTIMER_COUNTER_0); systimer_hal_init(); + systimer_hal_enable_counter(SYSTIMER_COUNTER_0); systimer_hal_select_alarm_mode(SYSTIMER_ALARM_2, SYSTIMER_ALARM_MODE_ONESHOT); + systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_2, SYSTIMER_COUNTER_0); /* TODO: if SYSTIMER is used for anything else, access to SYSTIMER_INT_ENA_REG has to be * protected by a shared spinlock. Since this code runs as part of early startup, this diff --git a/components/esp_timer/src/ets_timer_legacy.c b/components/esp_timer/src/ets_timer_legacy.c index dc5586a240..14d5f02a7d 100644 --- a/components/esp_timer/src/ets_timer_legacy.c +++ b/components/esp_timer/src/ets_timer_legacy.c @@ -24,7 +24,6 @@ #include "esp_log.h" #include "esp_attr.h" #include "esp_intr_alloc.h" -#include "soc/frc_timer_reg.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index ee3ce89634..c101a054d9 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -1,5 +1,13 @@ idf_build_get_property(idf_target IDF_TARGET) +# remove these when wifi support is ready on esp32-s3 +if(${idf_target} STREQUAL "esp32s3") + idf_component_register(INCLUDE_DIRS "include" + REQUIRES esp_event + PRIV_REQUIRES wpa_supplicant nvs_flash esp_netif) + return() +endif() + if(CONFIG_ESP32_NO_BLOBS OR CONFIG_ESP32S2_NO_BLOBS) set(link_binary_libs 0) set(ldfragments) diff --git a/components/esp_wifi/esp32s3/esp_adapter.c b/components/esp_wifi/esp32s3/esp_adapter.c new file mode 100644 index 0000000000..e989f005e8 --- /dev/null +++ b/components/esp_wifi/esp32s3/esp_adapter.c @@ -0,0 +1,13 @@ +// 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. diff --git a/components/esp_wifi/esp32s3/include/phy_init_data.h b/components/esp_wifi/esp32s3/include/phy_init_data.h new file mode 100644 index 0000000000..b09acb8e4b --- /dev/null +++ b/components/esp_wifi/esp32s3/include/phy_init_data.h @@ -0,0 +1,13 @@ +// Copyright 2016-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. diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 3069be8a69..f078cb6159 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -57,7 +57,7 @@ menu "Serial flasher config" config ESPTOOLPY_WITH_STUB # Only real reason to disable this is when ESP32-S2 Secure Download Mode is set bool - default "y" + default "y" if !IDF_ENV_FPGA depends on !SECURE_ENABLE_SECURE_ROM_DL_MODE choice ESPTOOLPY_FLASHMODE diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 10225816df..09549c0311 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 10225816df4c9c1b078e677e8a75a87778786ad1 +Subproject commit 09549c03111a2b330371d361d56227a457af66c5 diff --git a/components/freertos/xtensa/include/freertos/FreeRTOSConfig.h b/components/freertos/xtensa/include/freertos/FreeRTOSConfig.h index 6e589c673e..95dd00df6f 100644 --- a/components/freertos/xtensa/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/xtensa/include/freertos/FreeRTOSConfig.h @@ -125,6 +125,8 @@ int xt_clock_freq(void) __attribute__((deprecated)); #include "esp32/rom/ets_sys.h" // will be removed in idf v5.0 #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/ets_sys.h" #endif #if defined(CONFIG_FREERTOS_ASSERT_DISABLE) diff --git a/components/freertos/xtensa/xtensa_init.c b/components/freertos/xtensa/xtensa_init.c index 8581c5bbbb..4bb8b61210 100644 --- a/components/freertos/xtensa/xtensa_init.c +++ b/components/freertos/xtensa/xtensa_init.c @@ -39,6 +39,8 @@ that are implemented in C. #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #endif #ifdef XT_RTOS_TIMER_INT diff --git a/components/hal/esp32s3/include/hal/clk_gate_ll.h b/components/hal/esp32s3/include/hal/clk_gate_ll.h index bc897ac305..c8fc693b61 100644 --- a/components/hal/esp32s3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s3/include/hal/clk_gate_ll.h @@ -214,6 +214,18 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } +static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +{ + DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); + DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); +} + +static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void) +{ + DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); + DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); +} + static inline void periph_ll_reset(periph_module_t periph) { DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); @@ -228,3 +240,4 @@ static inline bool IRAM_ATTR periph_ll_periph_enabled(periph_module_t periph) #ifdef __cplusplus } +#endif diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 5f6eb3c423..d1051d2c04 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -55,14 +55,14 @@ typedef enum { static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) { if (func == RTCIO_FUNC_RTC) { - SENS.sar_io_mux_conf.iomux_clk_gate_en = 1; + // SENS.sar_io_mux_conf.iomux_clk_gate_en = 1; // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux)); //0:RTC FUNCTION 1,2,3:Reserved SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, SOC_PIN_FUNC_RTC_IO, rtc_io_desc[rtcio_num].func); } else if (func == RTCIO_FUNC_DIGITAL) { CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux)); - SENS.sar_io_mux_conf.iomux_clk_gate_en = 0; + // SENS.sar_io_mux_conf.iomux_clk_gate_en = 0; } } diff --git a/components/hal/include/hal/dac_types.h b/components/hal/include/hal/dac_types.h index b1f4b6fe65..1adc511a6c 100644 --- a/components/hal/include/hal/dac_types.h +++ b/components/hal/include/hal/dac_types.h @@ -40,7 +40,7 @@ typedef struct { Note: Unreasonable settings can cause waveform to be oversaturated. Range: -128 ~ 127. */ } dac_cw_config_t; -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 /** * @brief DAC digital controller (DMA mode) work mode. diff --git a/components/idf_test/include/esp32s3/idf_performance_target.h b/components/idf_test/include/esp32s3/idf_performance_target.h new file mode 100644 index 0000000000..75bbce7015 --- /dev/null +++ b/components/idf_test/include/esp32s3/idf_performance_target.h @@ -0,0 +1,17 @@ +#pragma once + +#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 14.4 + +// SHA256 hardware throughput at 240MHz, threshold set lower than worst case +#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 19.8 +// esp_sha() time to process 32KB of input data from RAM +#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000 +#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900 + +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 14000 +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 100000 +#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 60000 +#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 600000 + +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 32 +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index 1abc70c13b..a6ac60ea79 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -23,6 +23,8 @@ #include "esp32/rom/ets_sys.h" // will be removed in idf v5.0 #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/ets_sys.h" #endif #ifdef __cplusplus diff --git a/components/mbedtls/port/esp32s3/aes.c b/components/mbedtls/port/esp32s3/aes.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/mbedtls/port/esp32s3/bignum.c b/components/mbedtls/port/esp32s3/bignum.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/mbedtls/port/esp32s3/esp_sha1.c b/components/mbedtls/port/esp32s3/esp_sha1.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/mbedtls/port/esp32s3/esp_sha256.c b/components/mbedtls/port/esp32s3/esp_sha256.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/mbedtls/port/esp32s3/esp_sha512.c b/components/mbedtls/port/esp32s3/esp_sha512.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/mbedtls/port/esp32s3/sha.c b/components/mbedtls/port/esp32s3/sha.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/mbedtls/port/esp_sha.c b/components/mbedtls/port/esp_sha.c index 9265033c5f..1791cbf3ca 100644 --- a/components/mbedtls/port/esp_sha.c +++ b/components/mbedtls/port/esp_sha.c @@ -19,6 +19,8 @@ #include "esp32/sha.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/sha.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/sha.h" #endif #include diff --git a/components/mbedtls/port/include/aes_alt.h b/components/mbedtls/port/include/aes_alt.h index ee6cfed6b0..f313d508bd 100644 --- a/components/mbedtls/port/include/aes_alt.h +++ b/components/mbedtls/port/include/aes_alt.h @@ -32,6 +32,8 @@ extern "C" { #include "esp32/aes.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/aes.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/aes.h" #endif typedef esp_aes_context mbedtls_aes_context; diff --git a/components/mbedtls/port/include/esp32s3/aes.h b/components/mbedtls/port/include/esp32s3/aes.h new file mode 100644 index 0000000000..904a0ecdf5 --- /dev/null +++ b/components/mbedtls/port/include/esp32s3/aes.h @@ -0,0 +1,369 @@ +/** + * \brief AES block cipher, ESP32 hardware accelerated version + * Based on mbedTLS FIPS-197 compliant version. + * + * 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. + * + * + */ + +#ifndef ESP_AES_H +#define ESP_AES_H + +#include "esp_types.h" +#include "esp32s3/rom/aes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* padlock.c and aesni.c rely on these values! */ +#define ESP_AES_ENCRYPT 1 +#define ESP_AES_DECRYPT 0 + +#define ERR_ESP_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define ERR_ESP_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + + +/** + * \brief AES context structure + * + * \note buf is able to hold 32 extra bytes, which can be used: + * - for alignment purposes if VIA padlock is used, and/or + * - to simplify key expansion in the 256-bit case by + * generating an extra round key + */ +typedef struct { + uint8_t key_bytes; + volatile uint8_t key_in_hardware; /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */ + uint8_t key[32]; +} esp_aes_context; + + +/** + * \brief The AES XTS context-type definition. + */ +typedef struct { + esp_aes_context crypt; /*!< The AES context to use for AES block + encryption or decryption. */ + esp_aes_context tweak; /*!< The AES context used for tweak + computation. */ +} esp_aes_xts_context; + +/** + * \brief Lock access to AES hardware unit + * + * AES hardware unit can only be used by one + * consumer at a time. + * + * esp_aes_xxx API calls automatically manage locking & unlocking of + * hardware, this function is only needed if you want to call + * ets_aes_xxx functions directly. + */ +void esp_aes_acquire_hardware( void ); + +/** + * \brief Unlock access to AES hardware unit + * + * esp_aes_xxx API calls automatically manage locking & unlocking of + * hardware, this function is only needed if you want to call + * ets_aes_xxx functions directly. + */ +void esp_aes_release_hardware( void ); + +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void esp_aes_init( esp_aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void esp_aes_free( esp_aes_context *ctx ); + +/* + * \brief This function initializes the specified AES XTS context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES XTS context to initialize. + */ +void esp_aes_xts_init( esp_aes_xts_context *ctx ); + +/** + * \brief This function releases and clears the specified AES XTS context. + * + * \param ctx The AES XTS context to clear. + */ +void esp_aes_xts_free( esp_aes_xts_context *ctx ); + +/** + * \brief AES set key schedule (encryption or decryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH + */ + +/** + * \brief AES set key schedule (encryption or decryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH + */ +int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int esp_aes_crypt_ecb( esp_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16] ); + +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or ERR_AES_INVALID_INPUT_LENGTH + */ +int esp_aes_crypt_cbc( esp_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + + +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int esp_aes_crypt_cfb128( esp_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int esp_aes_crypt_cfb8( esp_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int esp_aes_crypt_ctr( esp_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs an AES-OFB (Output Feedback Mode) + * encryption or decryption operation. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +int esp_aes_crypt_ofb( esp_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function prepares an XTS context for encryption and + * sets the encryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * \param key The encryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief Internal AES block encryption function + * (Only exposed to allow overriding it, + * see AES_ENCRYPT_ALT) + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + + +/** + * \brief Internal AES block encryption function + * (Only exposed to allow overriding it, + * see AES_ENCRYPT_ALT) + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +int esp_internal_aes_encrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ); + +/** Deprecated, see esp_aes_internal_encrypt */ +void esp_aes_encrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) __attribute__((deprecated)); + +/** + * \brief Internal AES block decryption function + * (Only exposed to allow overriding it, + * see AES_DECRYPT_ALT) + * + * \param ctx AES context + * \param input Ciphertext block + * \param output Output (plaintext) block + */ +int esp_internal_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ); + +/** Deprecated, see esp_aes_internal_decrypt */ +void esp_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) __attribute__((deprecated)); + +/** AES-XTS buffer encryption/decryption */ +int esp_aes_crypt_xts( esp_aes_xts_context *ctx, int mode, size_t length, const unsigned char data_unit[16], const unsigned char *input, unsigned char *output ); + + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/components/mbedtls/port/include/esp32s3/crypto_dma.h b/components/mbedtls/port/include/esp32s3/crypto_dma.h new file mode 100644 index 0000000000..ce7d67efad --- /dev/null +++ b/components/mbedtls/port/include/esp32s3/crypto_dma.h @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Additions Copyright (C) 2016, 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. + * + * + */ + +#ifndef ESP_CRYPTO_DMA_H +#define ESP_CRYPTO_DMA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Since crypto DMA is shared between DMA-AES and SHA blocks + * Needs to be taken by respective blocks before using Crypto DMA + */ +extern _lock_t crypto_dma_lock; + +#ifdef __cplusplus +} +#endif + +#endif /* crypto_dma.h */ diff --git a/components/mbedtls/port/include/esp32s3/gcm.h b/components/mbedtls/port/include/esp32s3/gcm.h new file mode 100644 index 0000000000..07c80ad5e6 --- /dev/null +++ b/components/mbedtls/port/include/esp32s3/gcm.h @@ -0,0 +1,238 @@ +/** + * \brief AES block cipher, ESP32C hardware accelerated version + * Based on mbedTLS FIPS-197 compliant version. + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Additions Copyright (C) 2019-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. + * + * + */ + +#ifndef ESP_GCM_H +#define ESP_GCM_H + +#include "aes.h" +#include "mbedtls/cipher.h" +#ifdef __cplusplus +extern "C" { +#endif + + +#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ +#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function.*/ + +typedef enum { + ESP_AES_GCM_STATE_INIT, + ESP_AES_GCM_STATE_UPDATE, + ESP_AES_GCM_STATE_FINISH +} esp_aes_gcm_state; +/** + * \brief The GCM context structure. + */ +typedef struct { + uint8_t H[16]; /*!< Initial hash value */ + uint8_t ghash[16]; /*!< GHASH value. */ + uint8_t J0[16]; + uint64_t HL[16]; /*!< Precalculated HTable low. */ + uint64_t HH[16]; /*!< Precalculated HTable high. */ + uint8_t ori_j0[16]; /*!< J0 from first iteration. */ + const uint8_t *iv; + size_t iv_len; /*!< The length of IV. */ + uint64_t aad_len; /*!< The total length of the additional data. */ + size_t data_len; + int mode; + const unsigned char *aad; /*!< The additional data. */ + esp_aes_context aes_ctx; + esp_aes_gcm_state gcm_state; +} esp_gcm_context; + +/** + * \brief This function initializes the specified GCM context + * + * \param ctx The GCM context to initialize. + */ +void esp_aes_gcm_init( esp_gcm_context *ctx); + +/** + * \brief This function associates a GCM context with a + * key. + * + * \param ctx The GCM context to initialize. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. + * \param keybits The key size in bits. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return A cipher-specific error code on failure. + */ +int esp_aes_gcm_setkey( esp_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function starts a GCM encryption or decryption + * operation. + * + * \param ctx The GCM context. + * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or + * #MBEDTLS_GCM_DECRYPT. + * \param iv The initialization vector. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data, or NULL + * if \p add_len is 0. + * \param add_len The length of the additional data. If 0, + * \p add is NULL. + * + * \return \c 0 on success. + */ +int esp_aes_gcm_starts( esp_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *aad, + size_t aad_len ); + +/** + * \brief This function feeds an input buffer into an ongoing GCM + * encryption or decryption operation. + * + * ` The function expects input to be a multiple of 16 + * Bytes. Only the last call before calling + * mbedtls_gcm_finish() can be less than 16 Bytes. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. + * \param length The length of the input data. This must be a multiple of + * 16 except in the last call before mbedtls_gcm_finish(). + * \param input The buffer holding the input data. + * \param output The buffer for holding the output data. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + */ +int esp_aes_gcm_update( esp_gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function finishes the GCM operation and generates + * the authentication tag. + * + * It wraps up the GCM stream, and generates the + * tag. The tag can have a maximum length of 16 Bytes. + * + * \param ctx The GCM context. + * \param tag The buffer for holding the tag. + * \param tag_len The length of the tag to generate. Must be at least four. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + */ +int esp_aes_gcm_finish( esp_gcm_context *ctx, + unsigned char *tag, + size_t tag_len ); + +/** + * \brief This function clears a GCM context + * + * \param ctx The GCM context to clear. + */ +void esp_aes_gcm_free( esp_gcm_context *ctx); + +/** + * \brief This function performs GCM encryption or decryption of a buffer. + * + * \note For encryption, the output buffer can be the same as the + * input buffer. For decryption, the output buffer cannot be + * the same as input buffer. If the buffers overlap, the output + * buffer must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context to use for encryption or decryption. + * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or + * #MBEDTLS_GCM_DECRYPT. + * \param length The length of the input data. This must be a multiple of + * 16 except in the last call before mbedtls_gcm_finish(). + * \param iv The initialization vector. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. + * \param add_len The length of the additional data. + * \param input The buffer holding the input data. + * \param output The buffer for holding the output data. + * \param tag_len The length of the tag to generate. + * \param tag The buffer for holding the tag. + * + * \return \c 0 on success. + */ +int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ); + + +/** + * \brief This function performs a GCM authenticated decryption of a + * buffer. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. + * \param length The length of the input data. This must be a multiple + * of 16 except in the last call before mbedtls_gcm_finish(). + * \param iv The initialization vector. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. + * \param add_len The length of the additional data. + * \param tag The buffer holding the tag. + * \param tag_len The length of the tag. + * \param input The buffer holding the input data. + * \param output The buffer for holding the output data. + * + * \return 0 if successful and authenticated. + * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. + */ +int esp_aes_gcm_auth_decrypt( esp_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ); + +#ifdef __cplusplus +} +#endif + +#endif /* gcm.h */ diff --git a/components/mbedtls/port/include/esp32s3/sha.h b/components/mbedtls/port/include/esp32s3/sha.h new file mode 100644 index 0000000000..960d63b770 --- /dev/null +++ b/components/mbedtls/port/include/esp32s3/sha.h @@ -0,0 +1,165 @@ +// 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. + +#ifndef _ESP_SHA_H_ +#define _ESP_SHA_H_ + +#include "esp32s3/rom/sha.h" + +/** @brief Low-level support functions for the hardware SHA engine using DMA + * + * @note If you're looking for a SHA API to use, try mbedtls component + * mbedtls/shaXX.h. That API supports hardware acceleration. + * + * The API in this header provides some building blocks for implementing a + * full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha(). + * + * Some technical details about the hardware SHA engine: + * + * - The crypto DMA is shared between the SHA and AES engine, it is not + * possible for them to run calcalutions in parallel. + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined in rom/sha.h */ +typedef SHA_TYPE esp_sha_type; + +/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine + * + * @note For more versatile SHA calculations, where data doesn't need + * to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. + * + * @note It is not necessary to lock any SHA hardware before calling + * this function, thread safety is managed internally. + * + * @param sha_type SHA algorithm to use. + * + * @param input Input data buffer. + * + * @param ilen Length of input data in bytes. + * + * @param output Buffer for output SHA digest. Output is 20 bytes for + * sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for + * sha_type SHA2_384, 64 bytes for sha_type SHA2_512. + */ +void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output); + +/** @brief Execute SHA block operation using DMA + * + * @note This is a piece of a SHA algorithm, rather than an entire SHA + * algorithm. + * + * @note Call esp_sha_aquire_hardware() before calling this + * function. + * + * @param sha_type SHA algorithm to use. + * + * @param input Pointer to the input data. Block size is + * determined by algorithm (SHA1/SHA2_256 = 64 bytes, + * SHA2_384/SHA2_512 = 128 bytes) + * + * @param ilen length of input data should be multiple of block length. + * + * @param buf Pointer to blocks of data that will be prepended + * to data_block before hashing. Useful when there is two sources of + * data that need to be efficiently calculated in a single SHA DMA + * operation. + * + * @param buf_len length of buf data should be multiple of block length. + * Should not be longer than the maximum amount of bytes in a single block + * (128 bytes) + * + * @param is_first_block If this parameter is true, the SHA state will + * be initialised (with the initial state of the given SHA algorithm) + * before the block is calculated. If false, the existing state of the + * SHA engine will be used. + * + * @param t The number of bits for the SHA512/t hash function, with + * output truncated to t bits. Used for calculating the inital hash. + * t is any positive integer between 1 and 512, except 384. + * + * @return 0 if successful + */ +int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, + const void *buf, uint32_t buf_len, bool is_first_block); + +/** + * @brief Read out the current state of the SHA digest + * + * @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm. + * + * @note Call esp_sha_aquire_hardware() before calling this + * function. + * + * If the SHA suffix padding block has been executed already, the + * value that is read is the SHA digest. + * Otherwise, the value that is read is an interim SHA state. + * + * @param sha_type SHA algorithm in use. + * @param digest_state Pointer to a memory buffer to hold the SHA state. Size + * is 20 bytes (SHA1), 32 bytes (SHA2_256), or 64 bytes (SHA2_384, SHA2_512). + */ +void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state); + +/** + * @brief Set the current state of the SHA digest + * + * @note Call esp_sha_aquire_hardware() before calling this + * function. + * + * When resuming a + * + * @param sha_type SHA algorithm in use. + * @param digest_state + */ +void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state); + + +/** + * @brief Enables the SHA and crypto DMA peripheral and takes the + * locks for both of them. + */ +void esp_sha_acquire_hardware(void); + +/** + * @brief Disables the SHA and crypto DMA peripheral and releases the + * locks. + */ +void esp_sha_release_hardware(void); + +/** + * @brief Sets the initial hash value for SHA512/t. + * + * @note Is generated according to the algorithm described in the TRM, + * chapter SHA-Accelerator + * + * @note The engine must be locked until the value is used for an operation + * or read out. Else you risk another operation overwriting it. + * + * @param t + * + * @return 0 if successful + */ +int esp_sha_512_t_init_hash(uint16_t t); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/mbedtls/port/include/gcm_alt.h b/components/mbedtls/port/include/gcm_alt.h index c3d886a7c9..9a79850c02 100644 --- a/components/mbedtls/port/include/gcm_alt.h +++ b/components/mbedtls/port/include/gcm_alt.h @@ -29,6 +29,23 @@ extern "C" { #if defined(MBEDTLS_GCM_ALT) +#if CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/gcm.h" + + +typedef esp_gcm_context mbedtls_gcm_context; + +#define mbedtls_gcm_init esp_aes_gcm_init +#define mbedtls_gcm_free esp_aes_gcm_free +#define mbedtls_gcm_setkey esp_aes_gcm_setkey +#define mbedtls_gcm_starts esp_aes_gcm_starts +#define mbedtls_gcm_update esp_aes_gcm_update +#define mbedtls_gcm_finish esp_aes_gcm_finish +#define mbedtls_gcm_auth_decrypt esp_aes_gcm_auth_decrypt +#define mbedtls_gcm_crypt_and_tag esp_aes_gcm_crypt_and_tag + +#endif // CONFIG_IDF_TARGET_ESP32S3 + #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/gcm.h" diff --git a/components/mbedtls/port/include/sha1_alt.h b/components/mbedtls/port/include/sha1_alt.h index a3f05a84c4..628607518e 100644 --- a/components/mbedtls/port/include/sha1_alt.h +++ b/components/mbedtls/port/include/sha1_alt.h @@ -29,6 +29,28 @@ extern "C" { #if defined(MBEDTLS_SHA1_ALT) +#if CONFIG_IDF_TARGET_ESP32S3 + +#include "esp32s3/sha.h" +typedef enum { + ESP_SHA1_STATE_INIT, + ESP_SHA1_STATE_IN_PROCESS +} esp_sha1_state; + +/** + * \brief SHA-1 context structure + */ +typedef struct { + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + int first_block; /*!< if first then true else false */ + esp_sha_type mode; + esp_sha1_state sha_state; +} mbedtls_sha1_context; + +#endif //CONFIG_IDF_TARGET_ESP32S3 + #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/sha.h" diff --git a/components/mbedtls/port/include/sha256_alt.h b/components/mbedtls/port/include/sha256_alt.h index db82fb6453..fabb22f9ad 100644 --- a/components/mbedtls/port/include/sha256_alt.h +++ b/components/mbedtls/port/include/sha256_alt.h @@ -29,6 +29,29 @@ extern "C" { #if defined(MBEDTLS_SHA256_ALT) +#if CONFIG_IDF_TARGET_ESP32S3 + +#include "esp32s3/sha.h" + +typedef enum { + ESP_SHA256_STATE_INIT, + ESP_SHA256_STATE_IN_PROCESS +} esp_sha256_state; + +/** + * \brief SHA-256 context structure + */ +typedef struct { + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[8]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + int first_block; /*!< if first then true, else false */ + esp_sha_type mode; + esp_sha256_state sha_state; +} +mbedtls_sha256_context; + +#endif //CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S2 diff --git a/components/mbedtls/port/include/sha512_alt.h b/components/mbedtls/port/include/sha512_alt.h index da58e8a71c..d5c5f6981d 100644 --- a/components/mbedtls/port/include/sha512_alt.h +++ b/components/mbedtls/port/include/sha512_alt.h @@ -30,6 +30,42 @@ extern "C" { #if defined(MBEDTLS_SHA512_ALT) +#if CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/sha.h" + +typedef enum { + ESP_SHA512_STATE_INIT, + ESP_SHA512_STATE_IN_PROCESS +} esp_sha512_state; + +/** + * \brief SHA-512 context structure + */ +typedef struct { + uint64_t total[2]; /*!< number of bytes processed */ + uint64_t state[8]; /*!< intermediate digest state */ + unsigned char buffer[128]; /*!< data block being processed */ + int first_block; + esp_sha_type mode; + uint32_t t_val; /*!< t_val for 512/t mode */ + esp_sha512_state sha_state; +} mbedtls_sha512_context; + +/** + * @brief Sets the specfic algorithm for SHA512 + * + * @param ctx The mbedtls sha512 context + * + * @param type The mode, used for setting SHA2_512224 and SHA2_512256: + * + */ +void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type); + +/* For SHA512/t mode the intial hash value will depend on t */ +void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val); + +#endif //CONFIG_IDF_TARGET_ESP32S3 + #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/sha.h" diff --git a/components/newlib/port/esp_time_impl.c b/components/newlib/port/esp_time_impl.c index f719f228f0..450c71ceea 100644 --- a/components/newlib/port/esp_time_impl.c +++ b/components/newlib/port/esp_time_impl.c @@ -35,12 +35,18 @@ #include "esp32s2/rom/rtc.h" #include "esp32s2/clk.h" #include "esp32s2/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/rtc.h" +#include "esp32s3/clk.h" +#include "esp32s3/rtc.h" #endif #if defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC ) \ || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 ) \ || defined( CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC ) \ - || defined( CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1 ) + || defined( CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1 ) \ + || defined( CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC ) \ + || defined( CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1 ) #define WITH_RTC 1 #endif diff --git a/components/newlib/syscall_table.c b/components/newlib/syscall_table.c index 40ad8bb9af..5f8fea2d0a 100644 --- a/components/newlib/syscall_table.c +++ b/components/newlib/syscall_table.c @@ -31,6 +31,8 @@ #include "esp32/rom/libc_stubs.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/libc_stubs.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/libc_stubs.h" #endif static struct _reent s_reent; diff --git a/components/newlib/time.c b/components/newlib/time.c index 5ec5957c14..e4f0eda085 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -25,7 +25,6 @@ #include "esp_system.h" #include "esp_attr.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" diff --git a/components/soc/soc/esp32s3/include/soc/twai_caps.h b/components/soc/soc/esp32s3/include/soc/twai_caps.h index 88968ba90a..4ad5fbd829 100644 --- a/components/soc/soc/esp32s3/include/soc/twai_caps.h +++ b/components/soc/soc/esp32s3/include/soc/twai_caps.h @@ -18,10 +18,8 @@ extern "C" { #endif -//Chip specific TWAI related macros -//Any even number from 2 to 32768 -#define TWAI_BRP_IS_VALID(brp) ((brp) >= 2 && (brp) <= 32768 && ((brp) & 0x1) == 0) -#define TWAI_BRP_MAX 32768 +#define TWAI_BRP_MIN 2 +#define TWAI_BRP_MAX 32768 #ifdef __cplusplus } diff --git a/components/soc/soc/esp32s3/include/soc/wdev_reg.h b/components/soc/soc/esp32s3/include/soc/wdev_reg.h index 3427eb1077..9d4981c8d7 100644 --- a/components/soc/soc/esp32s3/include/soc/wdev_reg.h +++ b/components/soc/soc/esp32s3/include/soc/wdev_reg.h @@ -17,4 +17,4 @@ #include "soc.h" /* Hardware random number generator register */ -#define WDEV_RND_REG 0x60035110 +#define WDEV_RND_REG 0x6003507C diff --git a/components/soc/src/esp32s3/rtc_clk.c b/components/soc/src/esp32s3/rtc_clk.c index 152cbc6461..ebe6ed27cc 100644 --- a/components/soc/src/esp32s3/rtc_clk.c +++ b/components/soc/src/esp32s3/rtc_clk.c @@ -334,6 +334,7 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0); I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias); 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); } diff --git a/components/soc/src/esp32s3/soc_memory_layout.c b/components/soc/src/esp32s3/soc_memory_layout.c index b9a4784b15..de5f26d9cf 100644 --- a/components/soc/src/esp32s3/soc_memory_layout.c +++ b/components/soc/src/esp32s3/soc_memory_layout.c @@ -57,7 +57,7 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor */ const soc_memory_region_t soc_memory_regions[] = { #ifdef CONFIG_SPIRAM - { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW, 4, 0}, //SPI SRAM, if available + { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_SIZE, 4, 0}, //SPI SRAM, if available #endif #if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB { 0x40374000, 0x4000, 3, 0}, //Level 1, IRAM @@ -101,7 +101,9 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start - I_D_OFFSET, (intptr_t)&_iram_ #endif #ifdef CONFIG_SPIRAM -SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region); //SPI RAM gets added later if needed, in spiram.c; reserve it for now +/* Reserve the whole possible SPIRAM region here, spiram.c will add some or all of this + * memory to heap depending on the actual SPIRAM chip size. */ +SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region); #endif #if CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM > 0 diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 0c27c81d8c..def10c00ae 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -28,6 +28,11 @@ #include "esp32s2/rom/cache.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/cache.h" +#include "soc/extmem_reg.h" +#include "soc/cache_memory.h" #endif #include #include @@ -304,6 +309,11 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_st *saved_state = ret; #elif CONFIG_IDF_TARGET_ESP32S2 *saved_state = Cache_Suspend_ICache(); +#elif CONFIG_IDF_TARGET_ESP32S3 + uint32_t icache_state, dcache_state; + icache_state = Cache_Suspend_ICache() << 16; + dcache_state = Cache_Suspend_DCache(); + *saved_state = icache_state | dcache_state; #endif } @@ -323,6 +333,9 @@ static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_sta #endif #elif CONFIG_IDF_TARGET_ESP32S2 Cache_Resume_ICache(saved_state); +#elif CONFIG_IDF_TARGET_ESP32S3 + Cache_Resume_DCache(saved_state & 0xffff); + Cache_Resume_ICache(saved_state >> 16); #endif } @@ -335,6 +348,8 @@ 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 + bool result = (REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE) != 0); #endif return result; } @@ -448,16 +463,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 + drom0_in_icache = 0; +#endif if (icache_wrap_enable) { -#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B +#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_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 +#if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B dcache_wrap_size = 16; #else dcache_wrap_size = 32; @@ -549,13 +567,13 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable #ifdef CONFIG_FLASHMODE_QIO flash_support_wrap = true; -extern bool spi_flash_support_wrap_size(uint32_t wrap_size); + extern bool spi_flash_support_wrap_size(uint32_t wrap_size); if (!spi_flash_support_wrap_size(flash_wrap_size)) { flash_support_wrap = false; ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); } #else - ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); + ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); #endif #ifdef CONFIG_ESP32S2_SPIRAM_SUPPORT @@ -588,6 +606,261 @@ extern bool spi_flash_support_wrap_size(uint32_t wrap_size); return ESP_OK; +} +#endif +#if CONFIG_IDF_TARGET_ESP32S3 +IRAM_ATTR void esp_config_instruction_cache_mode(void) +{ + cache_size_t cache_size; + cache_ways_t cache_ways; + cache_line_size_t cache_line_size; + +#if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB + Cache_Occupy_ICache_MEMORY(CACHE_MEMORY_IBANK0, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_HALF; +#else + Cache_Occupy_ICache_MEMORY(CACHE_MEMORY_IBANK0, CACHE_MEMORY_IBANK1); + cache_size = CACHE_SIZE_FULL; +#endif +#if CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS + cache_ways = CACHE_4WAYS_ASSOC; +#else + cache_ways = CACHE_8WAYS_ASSOC; +#endif +#if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B + cache_line_size = CACHE_LINE_SIZE_16B; +#elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B + cache_line_size = CACHE_LINE_SIZE_32B; +#else + cache_line_size = CACHE_LINE_SIZE_64B; +#endif + ESP_EARLY_LOGI(TAG, "Instruction cache: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_HALF ? 16 : 32, cache_ways == CACHE_4WAYS_ASSOC ? 4 : 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 32 : 64)); + Cache_Set_ICache_Mode(cache_size, cache_ways, cache_line_size); + Cache_Invalidate_ICache_All(); + extern void Cache_Enable_ICache(uint32_t autoload); + Cache_Enable_ICache(0); +} + +IRAM_ATTR void esp_config_data_cache_mode(void) +{ + cache_size_t cache_size; + cache_ways_t cache_ways; + cache_line_size_t cache_line_size; + +#if CONFIG_ESP32S3_DATA_CACHE_32KB + Cache_Occupy_DCache_MEMORY(CACHE_MEMORY_DBANK1, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_HALF; +#else + Cache_Occupy_DCache_MEMORY(CACHE_MEMORY_DBANK0, CACHE_MEMORY_DBANK1); + cache_size = CACHE_SIZE_FULL; +#endif +#if CONFIG_ESP32S3_DATA_CACHE_4WAYS + cache_ways = CACHE_4WAYS_ASSOC; +#else + cache_ways = CACHE_8WAYS_ASSOC; +#endif +#if CONFIG_ESP32S3_DATA_CACHE_LINE_16B + cache_line_size = CACHE_LINE_SIZE_16B; +#elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B + cache_line_size = CACHE_LINE_SIZE_32B; +#else + cache_line_size = CACHE_LINE_SIZE_64B; +#endif + // ESP_EARLY_LOGI(TAG, "Data cache: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_HALF ? 32 : 64, cache_ways == CACHE_4WAYS_ASSOC ? 4 : 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 32 : 64)); + Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size); + Cache_Invalidate_DCache_All(); +} + +static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache) +{ + uint32_t i_autoload, d_autoload; + if (icache) { + i_autoload = Cache_Suspend_ICache(); + } + if (dcache) { + d_autoload = Cache_Suspend_DCache(); + } + REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_FLASH_WRAP_AROUND); + if (icache) { + Cache_Resume_ICache(i_autoload); + } + if (dcache) { + Cache_Resume_DCache(d_autoload); + } +} + +#if CONFIG_ESP32S3_SPIRAM_SUPPORT +static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache) +{ + uint32_t i_autoload, d_autoload; + if (icache) { + i_autoload = Cache_Suspend_ICache(); + } + if (dcache) { + d_autoload = Cache_Suspend_DCache(); + } + REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_SRAM_RD_WRAP_AROUND); + if (icache) { + Cache_Resume_ICache(i_autoload); + } + if (dcache) { + Cache_Resume_DCache(d_autoload); + } +} +#endif + +esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable) +{ + int icache_wrap_size = 0, dcache_wrap_size = 0; + int flash_wrap_sizes[2] = {-1, -1}, spiram_wrap_sizes[2] = {-1, -1}; + int flash_wrap_size = 0, spiram_wrap_size = 0; + int flash_count = 0, spiram_count = 0; + int i; + bool flash_spiram_wrap_together, flash_support_wrap = false, spiram_support_wrap = true; + uint32_t drom0_in_icache = 0;//always 0 in chip7.2.4 + + if (icache_wrap_enable) { +#if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B + icache_wrap_size = 16; +#elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B + icache_wrap_size = 32; +#else + icache_wrap_size = 64; +#endif + } + if (dcache_wrap_enable) { +#if CONFIG_ESP32S3_DATA_CACHE_LINE_16B + dcache_wrap_size = 16; +#elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B + dcache_wrap_size = 32; +#else + dcache_wrap_size = 64; +#endif + } + + uint32_t instruction_use_spiram = 0; + uint32_t rodata_use_spiram = 0; +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS + extern uint32_t esp_spiram_instruction_access_enabled(); + instruction_use_spiram = esp_spiram_instruction_access_enabled(); +#endif +#if CONFIG_SPIRAM_RODATA + extern uint32_t esp_spiram_rodata_access_enabled(); + rodata_use_spiram = esp_spiram_rodata_access_enabled(); +#endif + + if (instruction_use_spiram) { + spiram_wrap_sizes[0] = icache_wrap_size; + } else { + flash_wrap_sizes[0] = icache_wrap_size; + } + if (rodata_use_spiram) { + if (drom0_in_icache) { + spiram_wrap_sizes[0] = icache_wrap_size; + } else { + spiram_wrap_sizes[1] = dcache_wrap_size; + } +#ifdef CONFIG_EXT_RODATA_SUPPORT + spiram_wrap_sizes[1] = dcache_wrap_size; +#endif + } else { + if (drom0_in_icache) { + flash_wrap_sizes[0] = icache_wrap_size; + } else { + flash_wrap_sizes[1] = dcache_wrap_size; + } +#ifdef CONFIG_EXT_RODATA_SUPPORT + flash_wrap_sizes[1] = dcache_wrap_size; +#endif + } +#ifdef CONFIG_ESP32S3_SPIRAM_SUPPORT + spiram_wrap_sizes[1] = dcache_wrap_size; +#endif + for (i = 0; i < 2; i++) { + if (flash_wrap_sizes[i] != -1) { + flash_count++; + flash_wrap_size = flash_wrap_sizes[i]; + } + } + for (i = 0; i < 2; i++) { + if (spiram_wrap_sizes[i] != -1) { + spiram_count++; + spiram_wrap_size = spiram_wrap_sizes[i]; + } + } + if (flash_count + spiram_count <= 2) { + flash_spiram_wrap_together = false; + } else { + flash_spiram_wrap_together = true; + } + if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) { + ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.", flash_wrap_sizes[0], flash_wrap_sizes[1]); + if (spiram_wrap_size == 0) { + return ESP_FAIL; + } + if (flash_spiram_wrap_together) { + ESP_EARLY_LOGE(TAG, "Abort spiram wrap because flash wrap length not fixed."); + return ESP_FAIL; + } + } + if (spiram_count > 1 && spiram_wrap_sizes[0] != spiram_wrap_sizes[1]) { + ESP_EARLY_LOGW(TAG, "SPIRAM wrap with different length %d and %d, abort wrap.", spiram_wrap_sizes[0], spiram_wrap_sizes[1]); + if (flash_wrap_size == 0) { + return ESP_FAIL; + } + if (flash_spiram_wrap_together) { + ESP_EARLY_LOGW(TAG, "Abort flash wrap because spiram wrap length not fixed."); + return ESP_FAIL; + } + } + + if (flash_spiram_wrap_together && flash_wrap_size != spiram_wrap_size) { + ESP_EARLY_LOGW(TAG, "SPIRAM has different wrap length with flash, %d and %d, abort wrap.", spiram_wrap_size, flash_wrap_size); + return ESP_FAIL; + } + +#ifdef CONFIG_FLASHMODE_QIO + flash_support_wrap = true; + extern bool spi_flash_support_wrap_size(uint32_t wrap_size); + if (!spi_flash_support_wrap_size(flash_wrap_size)) { + flash_support_wrap = false; + ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); + } +#else + ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); +#endif + + +#ifdef CONFIG_ESP32S3_SPIRAM_SUPPORT + extern bool psram_support_wrap_size(uint32_t wrap_size); + if (!psram_support_wrap_size(spiram_wrap_size)) { + spiram_support_wrap = false; + ESP_EARLY_LOGW(TAG, "SPIRAM do not support wrap size %d.", spiram_wrap_size); + } +#endif + + if (flash_spiram_wrap_together && !(flash_support_wrap && spiram_support_wrap)) { + ESP_EARLY_LOGW(TAG, "Flash and SPIRAM should support wrap together."); + return ESP_FAIL; + } + + extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size); + if (flash_support_wrap && flash_wrap_size > 0) { + ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); + spi_flash_enable_wrap(flash_wrap_size); + esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); + } +#if CONFIG_ESP32S3_SPIRAM_SUPPORT + extern esp_err_t psram_enable_wrap(uint32_t wrap_size); + if (spiram_support_wrap && spiram_wrap_size > 0) { + ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled, size = %d.", spiram_wrap_size); + psram_enable_wrap(spiram_wrap_size); + esp_enable_cache_spiram_wrap((spiram_wrap_sizes[0] > 0), (spiram_wrap_sizes[1] > 0)); + } +#endif + + return ESP_OK; + } #endif diff --git a/components/spi_flash/cache_utils.h b/components/spi_flash/cache_utils.h index bc3de9f964..e12f2f8442 100644 --- a/components/spi_flash/cache_utils.h +++ b/components/spi_flash/cache_utils.h @@ -60,7 +60,7 @@ void spi_flash_enable_interrupts_caches_no_os(void); bool spi_flash_check_and_flush_cache(uint32_t start_addr, uint32_t length); //config cache mode -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 //config instrcutin cache size and cache block size by menuconfig void esp_config_instruction_cache_mode(void); //config data cache size and cache block size by menuconfig diff --git a/components/spi_flash/esp32s3/flash_ops_esp32s3.c b/components/spi_flash/esp32s3/flash_ops_esp32s3.c new file mode 100644 index 0000000000..4014c8ba1e --- /dev/null +++ b/components/spi_flash/esp32s3/flash_ops_esp32s3.c @@ -0,0 +1,120 @@ +// 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 "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/cache.h" +#include "bootloader_flash.h" +#include "hal/spi_flash_hal.h" +#include "esp_flash.h" +#include "esp_log.h" + +static const char *TAG = "spiflash_s3"; + +#define SPICACHE SPIMEM0 +#define SPIFLASH SPIMEM1 + +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); + + if (!esp_ptr_internal(src)) { + 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 SPI_Encrypt_Write 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(); + } + rc = SPI_Encrypt_Write(dest_addr, src, size); + if (ops && ops->end) { + ops->end(); + } + return rc; + } +} + +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + return bootloader_flash_wrap_set(mode); +} + +esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) +{ + switch (wrap_size) { + case 8: + return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B); + case 16: + return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B); + case 32: + return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B); + case 64: + return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B); + default: + return ESP_FAIL; + } +} + +void spi_flash_disable_wrap(void) +{ + bootloader_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/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index eefe8a9779..f0d48a62d9 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -17,7 +17,6 @@ #include "memspi_host_driver.h" #include "esp_flash_spi_init.h" #include "driver/gpio.h" -#include "esp32/rom/spi_flash.h" #include "esp_rom_gpio.h" #include "esp_rom_efuse.h" #include "esp_log.h" @@ -25,6 +24,14 @@ #include "hal/spi_types.h" #include "driver/spi_common_internal.h" #include "esp_flash_internal.h" +#include "esp_rom_gpio.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#endif __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -68,6 +75,15 @@ __attribute__((unused)) static const char TAG[] = "spi_flash"; .iomux = true, \ .input_delay_ns = 0,\ } +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/efuse.h" +#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ + .host_id = SPI_HOST,\ + .speed = DEFAULT_FLASH_SPEED, \ + .cs_num = 0, \ + .iomux = true, \ + .input_delay_ns = 0,\ +} #endif @@ -207,7 +223,7 @@ esp_err_t esp_flash_init_default_chip(void) { memspi_host_config_t cfg = ESP_FLASH_HOST_CONFIG_DEFAULT(); - #ifdef CONFIG_IDF_TARGET_ESP32S2 + #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 // For esp32s2 spi IOs are configured as from IO MUX by default cfg.iomux = esp_rom_efuse_get_flash_gpio_info() == 0 ? true : false; #endif diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 6789d4211a..6020157e15 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -39,6 +39,12 @@ #include "esp32s2/spiram.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/cache.h" +#include "esp32s3/spiram.h" +#include "soc/extmem_reg.h" +#include "soc/cache_memory.h" #endif #ifndef NDEBUG @@ -48,6 +54,7 @@ #include "sys/queue.h" #ifdef CONFIG_IDF_TARGET_ESP32 +#define PAGES_PER_REGION 64 #define REGIONS_COUNT 4 #define IROM0_PAGES_START 64 #define IROM0_PAGES_END 256 @@ -56,7 +63,10 @@ #define PAGE_IN_FLASH(page) (page) #define INVALID_ENTRY_VAL DPORT_FLASH_MMU_TABLE_INVALID_VAL #define MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK +#define VADDR1_START_ADDR 0x40000000 +#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START) #elif CONFIG_IDF_TARGET_ESP32S2 +#define PAGES_PER_REGION 64 #define REGIONS_COUNT 6 #define IROM0_PAGES_START (PRO_CACHE_IBUS0_MMU_START / sizeof(uint32_t)) #define IROM0_PAGES_END (PRO_CACHE_IBUS1_MMU_END / sizeof(uint32_t)) @@ -66,16 +76,28 @@ #define INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL #define MMU_ADDR_MASK MMU_ADDRESS_MASK #define PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) +#define VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW +#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START) +#elif CONFIG_IDF_TARGET_ESP32S3 +#define REGIONS_COUNT 2 +#define PAGES_PER_REGION 256 +#define IROM0_PAGES_START (CACHE_IBUS_MMU_START / sizeof(uint32_t)) +#define IROM0_PAGES_END (CACHE_IBUS_MMU_END / sizeof(uint32_t)) +#define DROM0_PAGES_START (CACHE_DBUS_MMU_START / sizeof(uint32_t)) +#define DROM0_PAGES_END (CACHE_DBUS_MMU_END / sizeof(uint32_t)) +#define DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE +#define INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL +#define MMU_ADDR_MASK MMU_ADDRESS_MASK +#define PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) +#define VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW +#define PRO_IRAM0_FIRST_USABLE_PAGE (IROM0_PAGES_START) #endif -#define PAGES_PER_REGION 64 #define IROM0_PAGES_NUM (IROM0_PAGES_END - IROM0_PAGES_START) #define DROM0_PAGES_NUM (DROM0_PAGES_END - DROM0_PAGES_START) #define PAGES_LIMIT (IROM0_PAGES_END > DROM0_PAGES_END ? IROM0_PAGES_END:DROM0_PAGES_END) #define VADDR0_START_ADDR SOC_DROM_LOW -#define VADDR1_START_ADDR 0x40000000 #define VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW -#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START) typedef struct mmap_entry_{ uint32_t handle; @@ -99,7 +121,7 @@ static void IRAM_ATTR spi_flash_mmap_init(void) DPORT_INTERRUPT_DISABLE(); for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) { uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]); -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]); if (entry_pro != entry_app) { @@ -112,7 +134,7 @@ static void IRAM_ATTR spi_flash_mmap_init(void) s_mmap_page_refcnt[i] = 1; } else { DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; #endif } @@ -229,27 +251,27 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp for (int i = start; i != start + page_count; ++i, ++pageno) { // sanity check: we won't reconfigure entries with non-zero reference count uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]); -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]); #endif assert(s_mmap_page_refcnt[i] == 0 || (entry_pro == PAGE_IN_FLASH(pages[pageno]) -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 && entry_app == PAGE_IN_FLASH(pages[pageno]) #endif )); if (s_mmap_page_refcnt[i] == 0) { if (entry_pro != PAGE_IN_FLASH(pages[pageno]) -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 || entry_app != PAGE_IN_FLASH(pages[pageno]) #endif ) { DPORT_PRO_FLASH_MMU_TABLE[i] = PAGE_IN_FLASH(pages[pageno]); -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 DPORT_APP_FLASH_MMU_TABLE[i] = pages[pageno]; #endif -#if CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 Cache_Invalidate_Addr(region_addr + (i - region_begin) * SPI_FLASH_MMU_PAGE_SIZE, SPI_FLASH_MMU_PAGE_SIZE); #endif need_flush = true; @@ -306,7 +328,7 @@ void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle) assert(s_mmap_page_refcnt[i] > 0); if (--s_mmap_page_refcnt[i] == 0) { DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; -#if !CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; #endif } @@ -481,7 +503,7 @@ static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_page, const void **o for (int j = 0; j < 2; j++) { for (int i = start[j]; i < end[j]; i++) { if (DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]) == PAGE_IN_FLASH(phys_page)) { -#if CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (j == 0) { /* SPI_FLASH_MMAP_DATA */ *out_ptr = (const void *)(VADDR0_START_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0])); } else { /* SPI_FLASH_MMAP_INST */ @@ -522,7 +544,7 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length) Cache_Flush(1); #endif return true; -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (vaddr != NULL) { Cache_Invalidate_Addr((uint32_t)vaddr, SPI_FLASH_MMU_PAGE_SIZE); ret = true; diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index eb331b06bf..0068f4cd69 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -36,6 +36,10 @@ #include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/cache.h" #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/cache.h" +#include "esp32s3/clk.h" #endif #include "esp_flash_partitions.h" #include "cache_utils.h" @@ -776,7 +780,7 @@ void spi_flash_dump_counters(void) #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS -#if defined(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) && defined(CONFIG_IDF_TARGET_ESP32S2) +#if defined(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)) // TODO esp32s2: Remove once ESP32S2 has new SPI Flash API support esp_flash_t *esp_flash_default_chip = NULL; #endif diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index 5f2002d638..9286b10fb1 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/components/spi_flash/memspi_host_driver.c @@ -25,7 +25,7 @@ static const char TAG[] = "memspi"; DRAM_ATTR static const spi_flash_host_driver_t esp_flash_default_host = ESP_FLASH_DEFAULT_HOST_DRIVER(); -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 extern void spi_flash_hal_gpspi_poll_cmd_done(spi_flash_host_inst_t *host); extern esp_err_t spi_flash_hal_gpspi_device_config(spi_flash_host_inst_t *host); esp_err_t spi_flash_hal_gpspi_configure_host_io_mode( @@ -67,7 +67,7 @@ esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_ { #ifdef CONFIG_IDF_TARGET_ESP32 host->inst.driver = &esp_flash_default_host; -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (cfg->host_id == SPI_HOST) host->inst.driver = &esp_flash_default_host; else { diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index b36ff345f1..493aad0aa4 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -22,11 +22,14 @@ #include "esp32/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/ets_sys.h" +#include "esp32s3/rom/cache.h" #endif #include "esp_attr.h" -#if CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 typedef struct { uint32_t icache_autoload; uint32_t dcache_autoload; @@ -40,7 +43,7 @@ static IRAM_ATTR esp_err_t start(void *arg) #if CONFIG_IDF_TARGET_ESP32 Cache_Read_Disable(0); Cache_Read_Disable(1); -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); spi_arg->dcache_autoload = Cache_Suspend_DCache(); @@ -55,7 +58,7 @@ static IRAM_ATTR esp_err_t end(void *arg) Cache_Flush(1); Cache_Read_Enable(0); Cache_Read_Enable(1); -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 spi_noos_arg_t *spi_arg = arg; Cache_Invalidate_ICache_All(); Cache_Resume_ICache(spi_arg->icache_autoload); @@ -85,7 +88,7 @@ esp_err_t IRAM_ATTR esp_flash_app_disable_os_functions(esp_flash_t* chip) { chip->os_func = &esp_flash_noos_functions; -#if CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 chip->os_func_data = &spi_arg; #endif diff --git a/components/ulp/include/esp32s3/ulp.h b/components/ulp/include/esp32s3/ulp.h new file mode 100644 index 0000000000..9207a00ead --- /dev/null +++ b/components/ulp/include/esp32s3/ulp.h @@ -0,0 +1,840 @@ +// Copyright 2016-2018 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 +#include "esp_err.h" +#include "soc/soc.h" +#include "ulp_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ULP_FSM_PREPARE_SLEEP_CYCLES 2 /*!< Cycles spent by FSM preparing ULP for sleep */ +#define ULP_FSM_WAKEUP_SLEEP_CYCLES 2 /*!< Cycles spent by FSM waking up ULP from sleep */ + +/** + * @defgroup ulp_registers ULP coprocessor registers + * @{ + */ + + +#define R0 0 /*!< general purpose register 0 */ +#define R1 1 /*!< general purpose register 1 */ +#define R2 2 /*!< general purpose register 2 */ +#define R3 3 /*!< general purpose register 3 */ +/**@}*/ + +/** @defgroup ulp_opcodes ULP coprocessor opcodes, sub opcodes, and various modifiers/flags + * + * These definitions are not intended to be used directly. + * They are used in definitions of instructions later on. + * + * @{ + */ + +#define OPCODE_WR_REG 1 /*!< Instruction: write peripheral register (RTC_CNTL/RTC_IO/SARADC) (not implemented yet) */ + +#define OPCODE_RD_REG 2 /*!< Instruction: read peripheral register (RTC_CNTL/RTC_IO/SARADC) (not implemented yet) */ + +#define RD_REG_PERIPH_RTC_CNTL 0 /*!< Identifier of RTC_CNTL peripheral for RD_REG and WR_REG instructions */ +#define RD_REG_PERIPH_RTC_IO 1 /*!< Identifier of RTC_IO peripheral for RD_REG and WR_REG instructions */ +#define RD_REG_PERIPH_SENS 2 /*!< Identifier of SARADC peripheral for RD_REG and WR_REG instructions */ +#define RD_REG_PERIPH_RTC_I2C 3 /*!< Identifier of RTC_I2C peripheral for RD_REG and WR_REG instructions */ + +#define OPCODE_I2C 3 /*!< Instruction: read/write I2C (not implemented yet) */ + +#define OPCODE_DELAY 4 /*!< Instruction: delay (nop) for a given number of cycles */ + +#define OPCODE_ADC 5 /*!< Instruction: SAR ADC measurement (not implemented yet) */ + +#define OPCODE_ST 6 /*!< Instruction: store indirect to RTC memory */ +#define SUB_OPCODE_ST 4 /*!< Store 32 bits, 16 MSBs contain PC, 16 LSBs contain value from source register */ + +#define OPCODE_ALU 7 /*!< Arithmetic instructions */ +#define SUB_OPCODE_ALU_REG 0 /*!< Arithmetic instruction, both source values are in register */ +#define SUB_OPCODE_ALU_IMM 1 /*!< Arithmetic instruction, one source value is an immediate */ +#define SUB_OPCODE_ALU_CNT 2 /*!< Arithmetic instruction between counter register and an immediate (not implemented yet)*/ +#define ALU_SEL_ADD 0 /*!< Addition */ +#define ALU_SEL_SUB 1 /*!< Subtraction */ +#define ALU_SEL_AND 2 /*!< Logical AND */ +#define ALU_SEL_OR 3 /*!< Logical OR */ +#define ALU_SEL_MOV 4 /*!< Copy value (immediate to destination register or source register to destination register */ +#define ALU_SEL_LSH 5 /*!< Shift left by given number of bits */ +#define ALU_SEL_RSH 6 /*!< Shift right by given number of bits */ + +#define OPCODE_BRANCH 8 /*!< Branch instructions */ +#define SUB_OPCODE_BX 0 /*!< Branch to absolute PC (immediate or in register) */ +#define BX_JUMP_TYPE_DIRECT 0 /*!< Unconditional jump */ +#define BX_JUMP_TYPE_ZERO 1 /*!< Branch if last ALU result is zero */ +#define BX_JUMP_TYPE_OVF 2 /*!< Branch if last ALU operation caused and overflow */ +#define SUB_OPCODE_B 1 /*!< Branch to a relative offset */ +#define B_CMP_L 0 /*!< Branch if R0 is less than an immediate */ +#define B_CMP_GE 1 /*!< Branch if R0 is greater than or equal to an immediate */ + +#define OPCODE_END 9 /*!< Stop executing the program */ +#define SUB_OPCODE_END 0 /*!< Stop executing the program and optionally wake up the chip */ +#define SUB_OPCODE_SLEEP 1 /*!< Stop executing the program and run it again after selected interval */ + +#define OPCODE_TSENS 10 /*!< Instruction: temperature sensor measurement (not implemented yet) */ + +#define OPCODE_HALT 11 /*!< Halt the coprocessor */ + +#define OPCODE_LD 13 /*!< Indirect load lower 16 bits from RTC memory */ + +#define OPCODE_MACRO 15 /*!< Not a real opcode. Used to identify labels and branches in the program */ +#define SUB_OPCODE_MACRO_LABEL 0 /*!< Label macro */ +#define SUB_OPCODE_MACRO_BRANCH 1 /*!< Branch macro */ +/**@}*/ + +/** + * @brief Instruction format structure + * + * All ULP instructions are 32 bit long. + * This union contains field layouts used by all of the supported instructions. + * This union also includes a special "macro" instruction layout. + * This is not a real instruction which can be executed by the CPU. It acts + * as a token which is removed from the program by the + * ulp_process_macros_and_load function. + * + * These structures are not intended to be used directly. + * Preprocessor definitions provided below fill the fields of these structure with + * the right arguments. + */ +union ulp_insn { + + struct { + uint32_t cycles : 16; /*!< Number of cycles to sleep */ + uint32_t unused : 12; /*!< Unused */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_DELAY) */ + } delay; /*!< Format of DELAY instruction */ + + struct { + uint32_t dreg : 2; /*!< Register which contains data to store */ + uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */ + uint32_t unused1 : 6; /*!< Unused */ + uint32_t offset : 11; /*!< Offset to add to sreg */ + uint32_t unused2 : 4; /*!< Unused */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ST) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_ST) */ + } st; /*!< Format of ST instruction */ + + struct { + uint32_t dreg : 2; /*!< Register where the data should be loaded to */ + uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */ + uint32_t unused1 : 6; /*!< Unused */ + uint32_t offset : 11; /*!< Offset to add to sreg */ + uint32_t unused2 : 7; /*!< Unused */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_LD) */ + } ld; /*!< Format of LD instruction */ + + struct { + uint32_t unused : 28; /*!< Unused */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_HALT) */ + } halt; /*!< Format of HALT instruction */ + + struct { + uint32_t dreg : 2; /*!< Register which contains target PC, expressed in words (used if .reg == 1) */ + uint32_t addr : 11; /*!< Target PC, expressed in words (used if .reg == 0) */ + uint32_t unused : 8; /*!< Unused */ + uint32_t reg : 1; /*!< Target PC in register (1) or immediate (0) */ + uint32_t type : 3; /*!< Jump condition (BX_JUMP_TYPE_xxx) */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_BX) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */ + } bx; /*!< Format of BRANCH instruction (absolute address) */ + + struct { + uint32_t imm : 16; /*!< Immediate value to compare against */ + uint32_t cmp : 1; /*!< Comparison to perform: B_CMP_L or B_CMP_GE */ + uint32_t offset : 7; /*!< Absolute value of target PC offset w.r.t. current PC, expressed in words */ + uint32_t sign : 1; /*!< Sign of target PC offset: 0: positive, 1: negative */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_B) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */ + } b; /*!< Format of BRANCH instruction (relative address) */ + + struct { + uint32_t dreg : 2; /*!< Destination register */ + uint32_t sreg : 2; /*!< Register with operand A */ + uint32_t treg : 2; /*!< Register with operand B */ + uint32_t unused : 15; /*!< Unused */ + uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_REG) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */ + } alu_reg; /*!< Format of ALU instruction (both sources are registers) */ + + struct { + uint32_t dreg : 2; /*!< Destination register */ + uint32_t sreg : 2; /*!< Register with operand A */ + uint32_t imm : 16; /*!< Immediate value of operand B */ + uint32_t unused : 1; /*!< Unused */ + uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_IMM) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */ + } alu_imm; /*!< Format of ALU instruction (one source is an immediate) */ + + struct { + uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */ + uint32_t periph_sel : 2; /*!< Select peripheral: RTC_CNTL (0), RTC_IO(1), SARADC(2) */ + uint32_t data : 8; /*!< 8 bits of data to write */ + uint32_t low : 5; /*!< Low bit */ + uint32_t high : 5; /*!< High bit */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */ + } wr_reg; /*!< Format of WR_REG instruction */ + + struct { + uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */ + uint32_t periph_sel : 2; /*!< Select peripheral: RTC_CNTL (0), RTC_IO(1), SARADC(2) */ + uint32_t unused : 8; /*!< Unused */ + uint32_t low : 5; /*!< Low bit */ + uint32_t high : 5; /*!< High bit */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */ + } rd_reg; /*!< Format of RD_REG instruction */ + + struct { + uint32_t dreg : 2; /*!< Register where to store ADC result */ + uint32_t mux : 4; /*!< Select SARADC pad (mux + 1) */ + uint32_t sar_sel : 1; /*!< Select SARADC0 (0) or SARADC1 (1) */ + uint32_t unused1 : 1; /*!< Unused */ + uint32_t cycles : 16; /*!< TBD, cycles used for measurement */ + uint32_t unused2 : 4; /*!< Unused */ + uint32_t opcode: 4; /*!< Opcode (OPCODE_ADC) */ + } adc; /*!< Format of ADC instruction */ + + struct { + uint32_t dreg : 2; /*!< Register where to store temperature measurement result */ + uint32_t wait_delay: 14; /*!< Cycles to wait after measurement is done */ + uint32_t reserved: 12; /*!< Reserved, set to 0 */ + uint32_t opcode: 4; /*!< Opcode (OPCODE_TSENS) */ + } tsens; /*!< Format of TSENS instruction */ + + struct { + uint32_t i2c_addr : 8; /*!< I2C slave address */ + uint32_t data : 8; /*!< Data to read or write */ + uint32_t low_bits : 3; /*!< TBD */ + uint32_t high_bits : 3; /*!< TBD */ + uint32_t i2c_sel : 4; /*!< TBD, select reg_i2c_slave_address[7:0] */ + uint32_t unused : 1; /*!< Unused */ + uint32_t rw : 1; /*!< Write (1) or read (0) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_I2C) */ + } i2c; /*!< Format of I2C instruction */ + + struct { + uint32_t wakeup : 1; /*!< Set to 1 to wake up chip */ + uint32_t unused : 24; /*!< Unused */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_WAKEUP) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */ + } end; /*!< Format of END instruction with wakeup */ + + struct { + uint32_t cycle_sel : 4; /*!< Select which one of SARADC_ULP_CP_SLEEP_CYCx_REG to get the sleep duration from */ + uint32_t unused : 21; /*!< Unused */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_SLEEP) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */ + } sleep; /*!< Format of END instruction with sleep */ + + struct { + uint32_t label : 16; /*!< Label number */ + uint32_t unused : 8; /*!< Unused */ + uint32_t sub_opcode : 4; /*!< SUB_OPCODE_MACRO_LABEL or SUB_OPCODE_MACRO_BRANCH */ + uint32_t opcode: 4; /*!< Opcode (OPCODE_MACRO) */ + } macro; /*!< Format of tokens used by LABEL and BRANCH macros */ + +}; + +typedef union ulp_insn ulp_insn_t; + +_Static_assert(sizeof(ulp_insn_t) == 4, "ULP coprocessor instruction size should be 4 bytes"); + +/** + * Delay (nop) for a given number of cycles + */ +#define I_DELAY(cycles_) { .delay = {\ + .cycles = cycles_, \ + .unused = 0, \ + .opcode = OPCODE_DELAY } } + +/** + * Halt the coprocessor. + * + * This instruction halts the coprocessor, but keeps ULP timer active. + * As such, ULP program will be restarted again by timer. + * To stop the program and prevent the timer from restarting the program, + * use I_END(0) instruction. + */ +#define I_HALT() { .halt = {\ + .unused = 0, \ + .opcode = OPCODE_HALT } } + +/** + * Map SoC peripheral register to periph_sel field of RD_REG and WR_REG + * instructions. + * + * @param reg peripheral register in RTC_CNTL_, RTC_IO_, SENS_, RTC_I2C peripherals. + * @return periph_sel value for the peripheral to which this register belongs. + */ +static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) +{ + uint32_t ret = 3; + if (reg < DR_REG_RTCCNTL_BASE) { + assert(0 && "invalid register base"); + } else if (reg < DR_REG_RTCIO_BASE) { + ret = RD_REG_PERIPH_RTC_CNTL; + } else if (reg < DR_REG_SENS_BASE) { + ret = RD_REG_PERIPH_RTC_IO; + } else if (reg < DR_REG_RTC_I2C_BASE) { + ret = RD_REG_PERIPH_SENS; + } else if (reg < DR_REG_IO_MUX_BASE) { + ret = RD_REG_PERIPH_RTC_I2C; + } else { + assert(0 && "invalid register base"); + } + return ret; +} + +/** + * Write literal value to a peripheral register + * + * reg[high_bit : low_bit] = val + * This instruction can access RTC_CNTL_, RTC_IO_, SENS_, and RTC_I2C peripheral registers. + */ +#define I_WR_REG(reg, low_bit, high_bit, val) {.wr_reg = {\ + .addr = (reg & 0xff) / sizeof(uint32_t), \ + .periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \ + .data = val, \ + .low = low_bit, \ + .high = high_bit, \ + .opcode = OPCODE_WR_REG } } + +/** + * Read from peripheral register into R0 + * + * R0 = reg[high_bit : low_bit] + * This instruction can access RTC_CNTL_, RTC_IO_, SENS_, and RTC_I2C peripheral registers. + */ +#define I_RD_REG(reg, low_bit, high_bit) {.rd_reg = {\ + .addr = (reg & 0xff) / sizeof(uint32_t), \ + .periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \ + .unused = 0, \ + .low = low_bit, \ + .high = high_bit, \ + .opcode = OPCODE_RD_REG } } + +/** + * Set or clear a bit in the peripheral register. + * + * Sets bit (1 << shift) of register reg to value val. + * This instruction can access RTC_CNTL_, RTC_IO_, SENS_, and RTC_I2C peripheral registers. + */ +#define I_WR_REG_BIT(reg, shift, val) I_WR_REG(reg, shift, shift, val) + +/** + * Wake the SoC from deep sleep. + * + * This instruction initiates wake up from deep sleep. + * Use esp_deep_sleep_enable_ulp_wakeup to enable deep sleep wakeup + * triggered by the ULP before going into deep sleep. + * Note that ULP program will still keep running until the I_HALT + * instruction, and it will still be restarted by timer at regular + * intervals, even when the SoC is woken up. + * + * To stop the ULP program, use I_HALT instruction. + * + * To disable the timer which start ULP program, use I_END() + * instruction. I_END instruction clears the + * RTC_CNTL_ULP_CP_SLP_TIMER_EN_S bit of RTC_CNTL_STATE0_REG + * register, which controls the ULP timer. + */ +#define I_WAKE() { .end = { \ + .wakeup = 1, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_END, \ + .opcode = OPCODE_END } } + +/** + * Stop ULP program timer. + * + * This is a convenience macro which disables the ULP program timer. + * Once this instruction is used, ULP program will not be restarted + * anymore until ulp_run function is called. + * + * ULP program will continue running after this instruction. To stop + * the currently running program, use I_HALT(). + */ +#define I_END() \ + I_WR_REG_BIT(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN_S, 0) +/** + * Select the time interval used to run ULP program. + * + * This instructions selects which of the SENS_SLEEP_CYCLES_Sx + * registers' value is used by the ULP program timer. + * When the ULP program stops at I_HALT instruction, ULP program + * timer start counting. When the counter reaches the value of + * the selected SENS_SLEEP_CYCLES_Sx register, ULP program + * start running again from the start address (passed to the ulp_run + * function). + * There are 5 SENS_SLEEP_CYCLES_Sx registers, so 0 <= timer_idx < 5. + * + * By default, SENS_SLEEP_CYCLES_S0 register is used by the ULP + * program timer. + */ +#define I_SLEEP_CYCLE_SEL(timer_idx) { .sleep = { \ + .cycle_sel = timer_idx, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_SLEEP, \ + .opcode = OPCODE_END } } + +/** + * Perform temperature sensor measurement and store it into reg_dest. + * + * Delay can be set between 1 and ((1 << 14) - 1). Higher values give + * higher measurement resolution. + */ +#define I_TSENS(reg_dest, delay) { .tsens = { \ + .dreg = reg_dest, \ + .wait_delay = delay, \ + .reserved = 0, \ + .opcode = OPCODE_TSENS } } + +/** + * Perform ADC measurement and store result in reg_dest. + * + * adc_idx selects ADC (0 or 1). + * pad_idx selects ADC pad (0 - 7). + */ +#define I_ADC(reg_dest, adc_idx, pad_idx) { .adc = {\ + .dreg = reg_dest, \ + .mux = pad_idx + 1, \ + .sar_sel = adc_idx, \ + .unused1 = 0, \ + .cycles = 0, \ + .unused2 = 0, \ + .opcode = OPCODE_ADC } } + +/** + * Store value from register reg_val into RTC memory. + * + * The value is written to an offset calculated by adding value of + * reg_addr register and offset_ field (this offset is expressed in 32-bit words). + * 32 bits written to RTC memory are built as follows: + * - bits [31:21] hold the PC of current instruction, expressed in 32-bit words + * - bits [20:16] = 5'b1 + * - bits [15:0] are assigned the contents of reg_val + * + * RTC_SLOW_MEM[addr + offset_] = { 5'b0, insn_PC[10:0], val[15:0] } + */ +#define I_ST(reg_val, reg_addr, offset_) { .st = { \ + .dreg = reg_val, \ + .sreg = reg_addr, \ + .unused1 = 0, \ + .offset = offset_, \ + .unused2 = 0, \ + .sub_opcode = SUB_OPCODE_ST, \ + .opcode = OPCODE_ST } } + + +/** + * Load value from RTC memory into reg_dest register. + * + * Loads 16 LSBs from RTC memory word given by the sum of value in reg_addr and + * value of offset_. + */ +#define I_LD(reg_dest, reg_addr, offset_) { .ld = { \ + .dreg = reg_dest, \ + .sreg = reg_addr, \ + .unused1 = 0, \ + .offset = offset_, \ + .unused2 = 0, \ + .opcode = OPCODE_LD } } + + +/** + * Branch relative if R0 less than immediate value. + * + * pc_offset is expressed in words, and can be from -127 to 127 + * imm_value is a 16-bit value to compare R0 against + */ +#define I_BL(pc_offset, imm_value) { .b = { \ + .imm = imm_value, \ + .cmp = B_CMP_L, \ + .offset = abs(pc_offset), \ + .sign = (pc_offset >= 0) ? 0 : 1, \ + .sub_opcode = SUB_OPCODE_B, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch relative if R0 greater or equal than immediate value. + * + * pc_offset is expressed in words, and can be from -127 to 127 + * imm_value is a 16-bit value to compare R0 against + */ +#define I_BGE(pc_offset, imm_value) { .b = { \ + .imm = imm_value, \ + .cmp = B_CMP_GE, \ + .offset = abs(pc_offset), \ + .sign = (pc_offset >= 0) ? 0 : 1, \ + .sub_opcode = SUB_OPCODE_B, \ + .opcode = OPCODE_BRANCH } } + +/** + * Unconditional branch to absolute PC, address in register. + * + * reg_pc is the register which contains address to jump to. + * Address is expressed in 32-bit words. + */ +#define I_BXR(reg_pc) { .bx = { \ + .dreg = reg_pc, \ + .addr = 0, \ + .unused = 0, \ + .reg = 1, \ + .type = BX_JUMP_TYPE_DIRECT, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Unconditional branch to absolute PC, immediate address. + * + * Address imm_pc is expressed in 32-bit words. + */ +#define I_BXI(imm_pc) { .bx = { \ + .dreg = 0, \ + .addr = imm_pc, \ + .unused = 0, \ + .reg = 0, \ + .type = BX_JUMP_TYPE_DIRECT, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU result is zero, address in register. + * + * reg_pc is the register which contains address to jump to. + * Address is expressed in 32-bit words. + */ +#define I_BXZR(reg_pc) { .bx = { \ + .dreg = reg_pc, \ + .addr = 0, \ + .unused = 0, \ + .reg = 1, \ + .type = BX_JUMP_TYPE_ZERO, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU result is zero, immediate address. + * + * Address imm_pc is expressed in 32-bit words. + */ +#define I_BXZI(imm_pc) { .bx = { \ + .dreg = 0, \ + .addr = imm_pc, \ + .unused = 0, \ + .reg = 0, \ + .type = BX_JUMP_TYPE_ZERO, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU overflow, address in register + * + * reg_pc is the register which contains address to jump to. + * Address is expressed in 32-bit words. + */ +#define I_BXFR(reg_pc) { .bx = { \ + .dreg = reg_pc, \ + .addr = 0, \ + .unused = 0, \ + .reg = 1, \ + .type = BX_JUMP_TYPE_OVF, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU overflow, immediate address + * + * Address imm_pc is expressed in 32-bit words. + */ +#define I_BXFI(imm_pc) { .bx = { \ + .dreg = 0, \ + .addr = imm_pc, \ + .unused = 0, \ + .reg = 0, \ + .type = BX_JUMP_TYPE_OVF, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + + +/** + * Addition: dest = src1 + src2 + */ +#define I_ADDR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_ADD, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Subtraction: dest = src1 - src2 + */ +#define I_SUBR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_SUB, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Logical AND: dest = src1 & src2 + */ +#define I_ANDR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_AND, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Logical OR: dest = src1 | src2 + */ +#define I_ORR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_OR, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Copy: dest = src + */ +#define I_MOVR(reg_dest, reg_src) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .treg = 0, \ + .unused = 0, \ + .sel = ALU_SEL_MOV, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Logical shift left: dest = src << shift + */ +#define I_LSHR(reg_dest, reg_src, reg_shift) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .treg = reg_shift, \ + .unused = 0, \ + .sel = ALU_SEL_LSH, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + + +/** + * Logical shift right: dest = src >> shift + */ +#define I_RSHR(reg_dest, reg_src, reg_shift) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .treg = reg_shift, \ + .unused = 0, \ + .sel = ALU_SEL_RSH, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Add register and an immediate value: dest = src1 + imm + */ +#define I_ADDI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_ADD, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + + +/** + * Subtract register and an immediate value: dest = src - imm + */ +#define I_SUBI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_SUB, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Logical AND register and an immediate value: dest = src & imm + */ +#define I_ANDI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_AND, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Logical OR register and an immediate value: dest = src | imm + */ +#define I_ORI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_OR, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Copy an immediate value into register: dest = imm + */ +#define I_MOVI(reg_dest, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = 0, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_MOV, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Logical shift left register value by an immediate: dest = src << imm + */ +#define I_LSHI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_LSH, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + + +/** + * Logical shift right register value by an immediate: dest = val >> imm + */ +#define I_RSHI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_RSH, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Define a label with number label_num. + * + * This is a macro which doesn't generate a real instruction. + * The token generated by this macro is removed by ulp_process_macros_and_load + * function. Label defined using this macro can be used in branch macros defined + * below. + */ +#define M_LABEL(label_num) { .macro = { \ + .label = label_num, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_MACRO_LABEL, \ + .opcode = OPCODE_MACRO } } + +/** + * Token macro used by M_B and M_BX macros. Not to be used directly. + */ +#define M_BRANCH(label_num) { .macro = { \ + .label = label_num, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_MACRO_BRANCH, \ + .opcode = OPCODE_MACRO } } + +/** + * Macro: branch to label label_num if R0 is less than immediate value. + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BL(label_num, imm_value) \ + M_BRANCH(label_num), \ + I_BL(0, imm_value) + +/** + * Macro: branch to label label_num if R0 is greater or equal than immediate value + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BGE(label_num, imm_value) \ + M_BRANCH(label_num), \ + I_BGE(0, imm_value) + +/** + * Macro: unconditional branch to label + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BX(label_num) \ + M_BRANCH(label_num), \ + I_BXI(0) + +/** + * Macro: branch to label if ALU result is zero + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BXZ(label_num) \ + M_BRANCH(label_num), \ + I_BXZI(0) + +/** + * Macro: branch to label if ALU overflow + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BXF(label_num) \ + M_BRANCH(label_num), \ + I_BXFI(0) + + + +#define RTC_SLOW_MEM ((uint32_t*) 0x50000000) /*!< RTC slow memory, 8k size */ + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/ulp.c b/components/ulp/ulp.c index f01e5b9826..8bce618d8d 100644 --- a/components/ulp/ulp.c +++ b/components/ulp/ulp.c @@ -25,6 +25,9 @@ #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/ulp.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" +#include "esp32s3/ulp.h" #endif #include "soc/soc.h" diff --git a/components/ulp/ulp_private.h b/components/ulp/ulp_private.h index 3d5b281493..df3fcf6cd1 100644 --- a/components/ulp/ulp_private.h +++ b/components/ulp/ulp_private.h @@ -16,6 +16,8 @@ #ifdef CONFIG_ESP32_ULP_COPROC_RESERVE_MEM #define ULP_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM -#else +#elif defined(CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM) #define ULP_RESERVE_MEM CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM +#elif defined(CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM) +#define ULP_RESERVE_MEM CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM #endif diff --git a/components/unity/unity_port_esp32.c b/components/unity/unity_port_esp32.c index 1500f57ce2..f85aa503ab 100644 --- a/components/unity/unity_port_esp32.c +++ b/components/unity/unity_port_esp32.c @@ -20,6 +20,8 @@ #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #endif static uint32_t s_test_start, s_test_stop; diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c index 93b9e14cae..5ef09d7040 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -162,7 +162,7 @@ static void uart_tx_char(int fd, int c) } #if CONFIG_IDF_TARGET_ESP32 uart->fifo.rw_byte = c; -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 uart->ahb_fifo.rw_byte = c; #endif } @@ -181,7 +181,7 @@ static int uart_rx_char(int fd) } #if CONFIG_IDF_TARGET_ESP32 return uart->fifo.rw_byte; -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 return READ_PERI_REG(UART_FIFO_AHB_REG(fd)); #endif } diff --git a/tools/ci/config/post_check.yml b/tools/ci/config/post_check.yml index 3ee5903f6d..27b095fb3a 100644 --- a/tools/ci/config/post_check.yml +++ b/tools/ci/config/post_check.yml @@ -23,6 +23,7 @@ check_submodule_sync: - *show_submodule_urls - git submodule update --recursive - echo "IDF was cloned from ${PUBLIC_IDF_URL} completely" + allow_failure: true # remove this line when esp32s3 support in esptool got merged into master check_ut_cmake_make: extends: .check_job_template_with_filter diff --git a/tools/tools.json b/tools/tools.json index d659599bbc..64063885e9 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -112,6 +112,62 @@ } ] }, + { + "description": "Toolchain for Xtensa (ESP32-S3) based on GCC", + "export_paths": [ + [ + "xtensa-esp32s3-elf", + "bin" + ] + ], + "export_vars": {}, + "info_url": "https://github.com/espressif/crosstool-NG", + "install": "always", + "license": "GPL-3.0-with-GCC-exception", + "name": "xtensa-esp32s3-elf", + "version_cmd": [ + "xtensa-esp32s3-elf-gcc", + "--version" + ], + "version_regex": "\\(crosstool-NG\\s+(?:crosstool-ng-)?([0-9a-zA-Z\\.\\-]+)\\)\\s*([0-9\\.]+)", + "version_regex_replace": "\\1-\\2", + "versions": [ + { + "linux-amd64": { + "sha256": "22bf5e63baf3f3f5103ae21bcc35d80cd888d8032095e7b9e8f9631074ac462a", + "size": 86029457, + "url": "https://dl.espressif.com/dl/xtensa-esp32s3-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz" + }, + "linux-armel": { + "sha256": "27f423af3cfb9d8ed7a02173ccd8dc3b0fd3b3e76a92e9ba507121e73bfa5df3", + "size": 84120606, + "url": "https://dl.espressif.com/dl/xtensa-esp32s3-elf-gcc8_4_0-esp-2020r3-linux-armel.tar.gz" + }, + "linux-i686": { + "sha256": "479a71cfb4b0c0b36371a1aaed2e6095dfc3241937a54f60a1ba115da73ddec5", + "size": 88015798, + "url": "https://dl.espressif.com/dl/xtensa-esp32s3-elf-gcc8_4_0-esp-2020r3-linux-i686.tar.gz" + }, + "macos": { + "sha256": "c09b8fcbb840540a3f59429b1bbfbe5abfcacccf7a8a955e4e01e3f50b53a079", + "size": 93013216, + "url": "https://dl.espressif.com/dl/xtensa-esp32s3-elf-gcc8_4_0-esp-2020r3-macos.tar.gz" + }, + "name": "esp-2020r3-8.4.0", + "status": "recommended", + "win32": { + "sha256": "9591fc32896b13d7fe77310afbbff197cbbc20437d316e0e2460c5c50a10d7b5", + "size": 104536285, + "url": "https://dl.espressif.com/dl/xtensa-esp32s3-elf-gcc8_4_0-esp-2020r3-win32.zip" + }, + "win64": { + "sha256": "1caf56e9588214d8f1bc17734680ebab2906da3b5f31095e60407dad170f1221", + "size": 107245907, + "url": "https://dl.espressif.com/dl/xtensa-esp32s3-elf-gcc8_4_0-esp-2020r3-win64.zip" + } + } + ] + }, { "description": "Toolchain for RISC-V", "export_paths": [ diff --git a/tools/unit-test-app/components/test_utils/ccomp_timer.c b/tools/unit-test-app/components/test_utils/ccomp_timer.c index c218b22f65..104d8f8a50 100644 --- a/tools/unit-test-app/components/test_utils/ccomp_timer.c +++ b/tools/unit-test-app/components/test_utils/ccomp_timer.c @@ -27,6 +27,8 @@ #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #endif diff --git a/tools/unit-test-app/components/test_utils/ccomp_timer_impl.c b/tools/unit-test-app/components/test_utils/ccomp_timer_impl.c index 2caddf2481..e56b743e53 100644 --- a/tools/unit-test-app/components/test_utils/ccomp_timer_impl.c +++ b/tools/unit-test-app/components/test_utils/ccomp_timer_impl.c @@ -31,6 +31,8 @@ #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/clk.h" #endif #define D_STALL_COUNTER_ID 0