From 84b2f9f14d16533c84db2210f13a24cd817e0b0a Mon Sep 17 00:00:00 2001 From: suda-morris <362953310@qq.com> Date: Thu, 6 Jun 2019 10:57:29 +0800 Subject: [PATCH] build and link hello-world for esp32s2beta --- components/app_trace/app_trace_util.c | 5 + components/app_update/CMakeLists.txt | 1 + components/app_update/esp_ota_ops.c | 4 +- .../src/bootloader_utility.c | 2 +- components/driver/can.c | 4 +- components/driver/gpio.c | 12 + components/driver/i2s.c | 12 + components/driver/include/driver/gpio.h | 67 ++ components/driver/include/driver/spi_common.h | 42 +- components/driver/include/driver/spi_master.h | 16 +- components/driver/ledc.c | 4 + components/driver/mcpwm.c | 6 +- components/driver/pcnt.c | 10 +- components/driver/periph_ctrl.c | 64 +- components/driver/rmt.c | 4 + components/driver/rtc_module.c | 76 +- components/driver/sdmmc_host.c | 3 +- components/driver/spi_common.c | 90 +- components/driver/spi_master.c | 26 +- components/driver/spi_slave.c | 7 +- components/driver/timer.c | 11 +- components/driver/uart.c | 49 +- components/efuse/include/esp_efuse.h | 5 +- components/esp32s2beta/CMakeLists.txt | 6 +- components/esp32s2beta/clk.c | 2 + components/esp32s2beta/cpu_start.c | 22 +- .../esp32s2beta/include/esp32s2beta/spiram.h | 3 +- components/esp32s2beta/include/esp_attr.h | 58 -- components/esp32s2beta/include/esp_intr.h | 2 +- .../esp32s2beta/include/esp_intr_alloc.h | 34 +- components/esp32s2beta/intr_alloc.c | 3 +- .../esp32s2beta/ld/esp32s2beta.common.ld | 253 ----- .../esp32s2beta/ld/esp32s2beta.project.ld.in | 36 +- components/esp32s2beta/pm_esp32s2beta.c | 20 +- components/esp32s2beta/sleep_modes.c | 1 + components/esp32s2beta/system_api.c | 1 + components/esp32s2beta/task_wdt.c | 6 +- components/esp_adc_cal/CMakeLists.txt | 3 + components/esp_common/include/esp_pm.h | 7 +- components/esp_common/src/ets_timer_legacy.c | 6 +- components/esp_event/CMakeLists.txt | 2 +- components/esp_event/event_send_compat.inc | 16 +- components/esp_rom/CMakeLists.txt | 16 +- components/esp_rom/include/esp32/rom/rtc.h | 1 + .../esp_rom/include/esp32s2beta/rom/aes.h | 5 +- .../esp_rom/include/esp32s2beta/rom/ets_sys.h | 5 +- .../esp_rom/include/esp32s2beta/rom/rtc.h | 5 +- components/esp_wifi/CMakeLists.txt | 4 +- components/espcoredump/src/core_dump_uart.c | 6 +- components/esptool_py/esptool | 2 +- components/esptool_py/project_include.cmake | 2 +- components/ethernet/CMakeLists.txt | 22 +- components/freemodbus/port/porttimer.c | 10 +- components/freemodbus/port/porttimer_m.c | 13 + .../include/freertos/FreeRTOSConfig.h | 8 +- .../freertos/include/freertos/portmacro.h | 2 + components/freertos/port.c | 7 +- components/freertos/queue.c | 6 +- components/freertos/tasks.c | 6 +- components/freertos/xtensa_init.c | 11 +- components/freertos/xtensa_intr.c | 6 +- components/heap/multi_heap_platform.h | 7 +- components/log/include/esp_log.h | 16 +- components/mbedtls/CMakeLists.txt | 12 +- components/mbedtls/component.mk | 2 +- .../mbedtls/port/{ => esp32}/esp_bignum.c | 0 components/mbedtls/port/esp32s2beta/aes.c | 2 +- .../mbedtls/port/esp32s2beta/esp_bignum.c | 613 ++++++++++++ components/mbedtls/port/esp32s2beta/sha.c | 4 +- .../mbedtls/port/include/esp32s2beta/aes.h | 2 +- .../mbedtls/port/include/esp32s2beta/sha.h | 2 +- components/mdns/mdns.c | 28 +- .../mdns/private_include/mdns_networking.h | 4 +- components/newlib/time.c | 14 +- components/nvs_flash/include/nvs.h | 4 +- components/soc/CMakeLists.txt | 7 +- components/soc/esp32s2beta/gpio_periph.c | 66 ++ .../soc/esp32s2beta/include/soc/periph_defs.h | 4 - .../esp32s2beta/include/soc/sdio_slave_pins.h | 34 + .../soc/esp32s2beta/include/soc/sdmmc_pins.h | 38 + components/soc/esp32s2beta/include/soc/soc.h | 4 +- components/soc/esp32s2beta/rtc_periph.c | 20 + components/soc/include/soc/can_periph.h | 6 + components/spi_flash/CMakeLists.txt | 4 +- components/spi_flash/cache_utils.c | 318 +++++- components/spi_flash/cache_utils.h | 8 + components/spi_flash/component.mk | 3 +- components/spi_flash/esp32/flash_ops_esp32.c | 87 ++ .../esp32s2beta/flash_ops_esp32s2beta.c | 65 ++ components/spi_flash/esp_spi_flash_chip.h | 29 + components/spi_flash/flash_mmap.c | 108 +- components/spi_flash/flash_ops.c | 127 ++- components/spi_flash/include/esp_spi_flash.h | 20 +- components/spi_flash/spi_flash_rom_patch.c | 206 +++- components/spiffs/CMakeLists.txt | 4 + components/spiffs/component.mk | 2 + components/tcpip_adapter/event_handlers.c | 25 +- components/ulp/include/esp32s2beta/ulp.h | 920 ++++++++++++++++++ components/ulp/ulp.c | 11 +- components/unity/unity_port_esp32.c | 7 +- components/vfs/vfs_uart.c | 12 + .../wpa_supplicant/include/crypto/includes.h | 5 +- components/wpa_supplicant/include/wpa/wpa.h | 6 +- components/wpa_supplicant/include/wps/wps.h | 6 +- components/wpa_supplicant/port/include/os.h | 6 +- .../wpa_supplicant/src/wps/wps_enrollee.c | 5 +- components/xtensa/CMakeLists.txt | 5 +- tools/cmake/toolchain-esp32s2beta.cmake | 6 +- 108 files changed, 3377 insertions(+), 645 deletions(-) delete mode 100644 components/esp32s2beta/include/esp_attr.h delete mode 100644 components/esp32s2beta/ld/esp32s2beta.common.ld rename components/mbedtls/port/{ => esp32}/esp_bignum.c (100%) create mode 100644 components/mbedtls/port/esp32s2beta/esp_bignum.c create mode 100644 components/soc/esp32s2beta/gpio_periph.c create mode 100644 components/soc/esp32s2beta/include/soc/sdio_slave_pins.h create mode 100644 components/soc/esp32s2beta/include/soc/sdmmc_pins.h create mode 100644 components/soc/esp32s2beta/rtc_periph.c create mode 100644 components/spi_flash/esp32/flash_ops_esp32.c create mode 100644 components/spi_flash/esp32s2beta/flash_ops_esp32s2beta.c create mode 100644 components/spi_flash/esp_spi_flash_chip.h create mode 100644 components/ulp/include/esp32s2beta/ulp.h diff --git a/components/app_trace/app_trace_util.c b/components/app_trace/app_trace_util.c index 0558351b7..a23d906a2 100644 --- a/components/app_trace/app_trace_util.c +++ b/components/app_trace/app_trace_util.c @@ -15,7 +15,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_app_trace_util.h" +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#endif /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// TIMEOUT ///////////////////////////////////// diff --git a/components/app_update/CMakeLists.txt b/components/app_update/CMakeLists.txt index 2c705d509..f0aa569b5 100644 --- a/components/app_update/CMakeLists.txt +++ b/components/app_update/CMakeLists.txt @@ -3,6 +3,7 @@ set(COMPONENT_SRCS "esp_ota_ops.c" set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_REQUIRES spi_flash partition_table bootloader_support) +set(COMPONENT_PRIV_REQUIRES) register_component() diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index df6d8a906..d8574d9b5 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -39,10 +39,12 @@ #include "bootloader_common.h" #include "sys/param.h" #include "esp_system.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp_efuse.h" +#endif -#define SUB_TYPE_ID(i) (i & 0x0F) +#define SUB_TYPE_ID(i) (i & 0x0F) typedef struct ota_ops_entry_ { uint32_t handle; diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 46486e500..374921bec 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -64,7 +64,7 @@ #include "bootloader_utility.h" #include "bootloader_sha.h" -#ifndef BOOTLOADER_BUILD // TODO: efuse component on esp32s2beta +#if CONFIG_IDF_TARGET_ESP32 #include "esp_efuse.h" #endif diff --git a/components/driver/can.c b/components/driver/can.c index 6001e65f2..63b95dd36 100644 --- a/components/driver/can.c +++ b/components/driver/can.c @@ -11,7 +11,7 @@ // 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 "freertos/FreeRTOS.h" #include "freertos/portmacro.h" #include "freertos/task.h" @@ -25,6 +25,7 @@ #include "driver/gpio.h" #include "driver/periph_ctrl.h" #include "driver/can.h" +#if CONFIG_IDF_TARGET_ESP32 /* ---------------------------- Definitions --------------------------------- */ //Internal Macros @@ -1004,3 +1005,4 @@ esp_err_t can_clear_receive_queue() return ESP_OK; } +#endif diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 2cb6512c5..e18c026bb 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -212,7 +212,11 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); +#if CONFIG_IDF_TARGET_ESP32 if (gpio_num >= 34 && (mode & GPIO_MODE_DEF_OUTPUT)) { +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if (gpio_num >= 46 && (mode & GPIO_MODE_DEF_OUTPUT)) { +#endif ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num); return ESP_ERR_INVALID_ARG; } @@ -516,7 +520,11 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num) if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) { r = rtc_gpio_hold_en(gpio_num); } else if (GPIO_HOLD_MASK[gpio_num]) { +#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); +#endif } else { r = ESP_ERR_NOT_SUPPORTED; } @@ -530,7 +538,11 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num) if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) { r = rtc_gpio_hold_dis(gpio_num); } else if (GPIO_HOLD_MASK[gpio_num]) { +#if CONFIG_IDF_TARGET_ESP32 CLEAR_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); +#endif } else { r = ESP_ERR_NOT_SUPPORTED; } diff --git a/components/driver/i2s.c b/components/driver/i2s.c index 02322b341..5381cf67c 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -34,6 +34,9 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_pm.h" +#include "sdkconfig.h" + +#if CONFIG_IDF_TARGET_ESP32 static const char* I2S_TAG = "I2S"; @@ -453,12 +456,20 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b I2S[i2s_num]->clkm_conf.clkm_div_a = 1; I2S[i2s_num]->sample_rate_conf.tx_bck_div_num = m_scale; I2S[i2s_num]->sample_rate_conf.rx_bck_div_num = m_scale; +#if CONFIG_IDF_TARGET_ESP32 I2S[i2s_num]->clkm_conf.clka_en = 1; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + I2S[i2s_num]->clkm_conf.clk_sel = 1; +#endif double fi2s_rate = i2s_apll_get_fi2s(bits, sdm0, sdm1, sdm2, odir); ESP_LOGI(I2S_TAG, "APLL: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK_M: %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d", rate, fi2s_rate/bits/channel/m_scale, bits, 1, m_scale, fi2s_rate, fi2s_rate/8, 1, 0); } else { +#if CONFIG_IDF_TARGET_ESP32 I2S[i2s_num]->clkm_conf.clka_en = 0; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + I2S[i2s_num]->clkm_conf.clk_sel = 2; +#endif I2S[i2s_num]->clkm_conf.clkm_div_a = 63; I2S[i2s_num]->clkm_conf.clkm_div_b = clkmDecimals; I2S[i2s_num]->clkm_conf.clkm_div_num = clkmInteger; @@ -1378,3 +1389,4 @@ int i2s_pop_sample(i2s_port_t i2s_num, void *sample, TickType_t ticks_to_wait) return bytes_pop; } } +#endif diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 9933cba81..6d7171b18 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -76,6 +76,7 @@ extern "C" { #define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /*!< Pin 38 selected */ #define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /*!< Pin 39 selected */ +#if CONFIG_IDF_TARGET_ESP32 #define GPIO_PIN_REG_0 IO_MUX_GPIO0_REG #define GPIO_PIN_REG_1 IO_MUX_GPIO1_REG #define GPIO_PIN_REG_2 IO_MUX_GPIO2_REG @@ -111,6 +112,56 @@ extern "C" { #define GPIO_PIN_REG_37 IO_MUX_GPIO37_REG #define GPIO_PIN_REG_38 IO_MUX_GPIO38_REG #define GPIO_PIN_REG_39 IO_MUX_GPIO39_REG +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#define GPIO_PIN_REG_0 IO_MUX_GPIO0_REG +#define GPIO_PIN_REG_1 IO_MUX_GPIO1_REG +#define GPIO_PIN_REG_2 IO_MUX_GPIO2_REG +#define GPIO_PIN_REG_3 IO_MUX_GPIO3_REG +#define GPIO_PIN_REG_4 IO_MUX_GPIO4_REG +#define GPIO_PIN_REG_5 IO_MUX_GPIO5_REG +#define GPIO_PIN_REG_6 IO_MUX_GPIO6_REG +#define GPIO_PIN_REG_7 IO_MUX_GPIO7_REG +#define GPIO_PIN_REG_8 IO_MUX_GPIO8_REG +#define GPIO_PIN_REG_9 IO_MUX_GPIO9_REG +#define GPIO_PIN_REG_10 IO_MUX_GPIO10_REG +#define GPIO_PIN_REG_11 IO_MUX_GPIO11_REG +#define GPIO_PIN_REG_12 IO_MUX_GPIO12_REG +#define GPIO_PIN_REG_13 IO_MUX_GPIO13_REG +#define GPIO_PIN_REG_14 IO_MUX_GPIO14_REG +#define GPIO_PIN_REG_15 IO_MUX_GPIO15_REG +#define GPIO_PIN_REG_16 IO_MUX_GPIO16_REG +#define GPIO_PIN_REG_17 IO_MUX_GPIO17_REG +#define GPIO_PIN_REG_18 IO_MUX_GPIO18_REG +#define GPIO_PIN_REG_19 IO_MUX_GPIO19_REG +#define GPIO_PIN_REG_20 IO_MUX_GPIO20_REG +#define GPIO_PIN_REG_21 IO_MUX_GPIO21_REG +#define GPIO_PIN_REG_22 IO_MUX_GPIO22_REG +#define GPIO_PIN_REG_23 IO_MUX_GPIO23_REG +#define GPIO_PIN_REG_24 IO_MUX_GPIO24_REG +#define GPIO_PIN_REG_25 IO_MUX_GPIO25_REG +#define GPIO_PIN_REG_26 IO_MUX_GPIO26_REG +#define GPIO_PIN_REG_27 IO_MUX_GPIO27_REG +#define GPIO_PIN_REG_28 IO_MUX_GPIO28_REG +#define GPIO_PIN_REG_29 IO_MUX_GPIO29_REG +#define GPIO_PIN_REG_30 IO_MUX_GPIO30_REG +#define GPIO_PIN_REG_31 IO_MUX_GPIO31_REG +#define GPIO_PIN_REG_32 IO_MUX_GPIO32_REG +#define GPIO_PIN_REG_33 IO_MUX_GPIO33_REG +#define GPIO_PIN_REG_34 IO_MUX_GPIO34_REG +#define GPIO_PIN_REG_35 IO_MUX_GPIO35_REG +#define GPIO_PIN_REG_36 IO_MUX_GPIO36_REG +#define GPIO_PIN_REG_37 IO_MUX_GPIO37_REG +#define GPIO_PIN_REG_38 IO_MUX_GPIO38_REG +#define GPIO_PIN_REG_39 IO_MUX_GPIO39_REG +#define GPIO_PIN_REG_40 IO_MUX_GPIO40_REG +#define GPIO_PIN_REG_41 IO_MUX_GPIO41_REG +#define GPIO_PIN_REG_42 IO_MUX_GPIO42_REG +#define GPIO_PIN_REG_43 IO_MUX_GPIO43_REG +#define GPIO_PIN_REG_44 IO_MUX_GPIO44_REG +#define GPIO_PIN_REG_45 IO_MUX_GPIO45_REG +#define GPIO_PIN_REG_46 IO_MUX_GPIO46_REG +#define GPIO_PIN_REG_47 IO_MUX_GPIO47_REG +#endif #define GPIO_APP_CPU_INTR_ENA (BIT(0)) #define GPIO_APP_CPU_NMI_INTR_ENA (BIT(1)) @@ -127,7 +178,11 @@ extern "C" { /** @endcond */ #define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) /*!< Check whether it is a valid GPIO number */ +#if CONFIG_IDF_TARGET_ESP32 #define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) /*!< Check whether it can be a valid GPIO number of output mode */ +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 46)) /*!< Check whether it can be a valid GPIO number of output mode */ +#endif typedef enum { GPIO_NUM_NC = -1, /*!< Use to signal not connected to S/W */ @@ -173,7 +228,19 @@ typedef enum { GPIO_NUM_37 = 37, /*!< GPIO37, input mode only */ GPIO_NUM_38 = 38, /*!< GPIO38, input mode only */ GPIO_NUM_39 = 39, /*!< GPIO39, input mode only */ +#if CONFIG_IDF_TARGET_ESP32 GPIO_NUM_MAX = 40, +#elif CONFIG_IDF_TARGET_ESP32S2BETA + GPIO_NUM_40 = 40, /*!< GPIO40, input mode only */ + GPIO_NUM_41 = 41, /*!< GPIO41, input mode only */ + GPIO_NUM_42 = 42, /*!< GPIO42, input mode only */ + GPIO_NUM_43 = 43, /*!< GPIO43, input mode only */ + GPIO_NUM_44 = 44, /*!< GPIO44, input mode only */ + GPIO_NUM_45 = 45, /*!< GPIO45, input mode only */ + GPIO_NUM_46 = 46, /*!< GPIO46, input mode only */ + GPIO_NUM_47 = 47, /*!< GPIO47, input mode only */ + GPIO_NUM_MAX = 48, +#endif /** @endcond */ } gpio_num_t; diff --git a/components/driver/include/driver/spi_common.h b/components/driver/include/driver/spi_common.h index 546735caa..e8ea2a68c 100644 --- a/components/driver/include/driver/spi_common.h +++ b/components/driver/include/driver/spi_common.h @@ -61,15 +61,52 @@ extern "C" */ #define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len)) +/** + * Transform unsigned integer of length <= 32 bits to the format which can be + * sent by the SPI driver directly. + * + * E.g. to send 9 bits of data, you can: + * + * uint16_t data = SPI_SWAP_DATA_TX(0x145, 9); + * + * Then points tx_buffer to ``&data``. + * + * @param data Data to be sent, can be uint8_t, uint16_t or uint32_t. @param + * len Length of data to be sent, since the SPI peripheral sends from the MSB, + * this helps to shift the data to the MSB. + */ +#define SPI_SWAP_DATA_TX(data, len) __builtin_bswap32((uint32_t)data<<(32-len)) + +/** + * Transform received data of length <= 32 bits to the format of an unsigned integer. + * + * E.g. to transform the data of 15 bits placed in a 4-byte array to integer: + * + * uint16_t data = SPI_SWAP_DATA_RX(*(uint32_t*)t->rx_data, 15); + * + * @param data Data to be rearranged, can be uint8_t, uint16_t or uint32_t. + * @param len Length of data received, since the SPI peripheral writes from + * the MSB, this helps to shift the data to the LSB. + */ +#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len)) + /** * @brief Enum with the three SPI peripherals that are software-accessible in it */ +#if CONFIG_IDF_TARGET_ESP32 typedef enum { SPI_HOST=0, ///< SPI1, SPI HSPI_HOST=1, ///< SPI2, HSPI VSPI_HOST=2 ///< SPI3, VSPI } spi_host_device_t; - +#elif CONFIG_IDF_TARGET_ESP32S2BETA +typedef enum { + SPI_HOST=0, ///< SPI1, SPI + FSPI_HOST=1, ///< SPI2, FSPI + HSPI_HOST=2, ///< SPI3, HSPI + VSPI_HOST=3 ///< SPI4, VSPI +} spi_host_device_t; +#endif /** * @brief This is a configuration structure for a SPI bus. * @@ -85,6 +122,9 @@ typedef struct { int sclk_io_num; ///< GPIO pin for Spi CLocK signal, or -1 if not used. int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal which is used as D2 in 4-bit communication modes, or -1 if not used. int quadhd_io_num; ///< GPIO pin for HD (HolD) signal which is used as D3 in 4-bit communication modes, or -1 if not used. +#if CONFIG_IDF_TARGET_ESP32S2BETA + int spicd_io_num; ///< CD GPIO pin for this device, or -1 if not used +#endif int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4094 if 0. uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags. int intr_flags; /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see diff --git a/components/driver/include/driver/spi_master.h b/components/driver/include/driver/spi_master.h index 01348d01a..1cf3aebc6 100644 --- a/components/driver/include/driver/spi_master.h +++ b/components/driver/include/driver/spi_master.h @@ -25,6 +25,7 @@ /** SPI master clock is divided by 80MHz apb clock. Below defines are example frequencies, and are accurate. Be free to specify a random frequency, it will be rounded to closest frequency (to macros below if above 8MHz). * 8MHz */ +#if APB_CLK_FREQ==80*1000*1000 #define SPI_MASTER_FREQ_8M (APB_CLK_FREQ/10) #define SPI_MASTER_FREQ_9M (APB_CLK_FREQ/9) ///< 8.89MHz #define SPI_MASTER_FREQ_10M (APB_CLK_FREQ/8) ///< 10MHz @@ -35,7 +36,14 @@ #define SPI_MASTER_FREQ_26M (APB_CLK_FREQ/3) ///< 26.67MHz #define SPI_MASTER_FREQ_40M (APB_CLK_FREQ/2) ///< 40MHz #define SPI_MASTER_FREQ_80M (APB_CLK_FREQ/1) ///< 80MHz - +#elif APB_CLK_FREQ==40*1000*1000 +#define SPI_MASTER_FREQ_7M (APB_CLK_FREQ/6) ///< 13.33MHz +#define SPI_MASTER_FREQ_8M (APB_CLK_FREQ/5) ///< 16MHz +#define SPI_MASTER_FREQ_10M (APB_CLK_FREQ/4) ///< 20MHz +#define SPI_MASTER_FREQ_13M (APB_CLK_FREQ/3) ///< 26.67MHz +#define SPI_MASTER_FREQ_20M (APB_CLK_FREQ/2) ///< 40MHz +#define SPI_MASTER_FREQ_40M (APB_CLK_FREQ/1) ///< 80MHz +#endif #ifdef __cplusplus extern "C" { @@ -54,6 +62,7 @@ extern "C" * Set this flag to confirm that you're going to work with output only, or read without dummy bits at your own risk. */ #define SPI_DEVICE_NO_DUMMY (1<<6) +#define SPI_DEVICE_DDRCLK (1<<7) typedef struct spi_transaction_t spi_transaction_t; @@ -67,8 +76,8 @@ typedef struct { uint8_t address_bits; ///< Default amount of bits in address phase (0-64), used when ``SPI_TRANS_VARIABLE_ADDR`` is not used, otherwise ignored. uint8_t dummy_bits; ///< Amount of dummy bits to insert between address and data phase uint8_t mode; ///< SPI mode (0-3) - uint8_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128. - uint8_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions. + uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128. + uint16_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions. uint8_t cs_ena_posttrans; ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16) int clock_speed_hz; ///< Clock speed, divisors of 80MHz, in Hz. See ``SPI_MASTER_FREQ_*``. int input_delay_ns; /**< Maximum data valid time of slave. The time required between SCLK and MISO @@ -110,6 +119,7 @@ typedef struct { #define SPI_TRANS_VARIABLE_CMD (1<<5) ///< Use the ``command_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``. #define SPI_TRANS_VARIABLE_ADDR (1<<6) ///< Use the ``address_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``. #define SPI_TRANS_VARIABLE_DUMMY (1<<7) ///< Use the ``dummy_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``. +#define SPI_TRANS_SET_CD (1<<7) ///< Set the CD pin /** * This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes. diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 92a055cbc..17354bbff 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -278,7 +278,9 @@ esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO); gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT); if (speed_mode == LEDC_HIGH_SPEED_MODE) { +#if CONFIG_IDF_TARGET_ESP32 gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0); +#endif } else { gpio_matrix_out(gpio_num, LEDC_LS_SIG_OUT0_IDX + ledc_channel, 0, 0); } @@ -318,7 +320,9 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t* ledc_conf) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO); gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT); if (speed_mode == LEDC_HIGH_SPEED_MODE) { +#if CONFIG_IDF_TARGET_ESP32 gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0); +#endif } else { gpio_matrix_out(gpio_num, LEDC_LS_SIG_OUT0_IDX + ledc_channel, 0, 0); } diff --git a/components/driver/mcpwm.c b/components/driver/mcpwm.c index 714855ea5..d3010ce89 100644 --- a/components/driver/mcpwm.c +++ b/components/driver/mcpwm.c @@ -23,6 +23,9 @@ #include "soc/gpio_periph.h" #include "driver/mcpwm.h" #include "driver/periph_ctrl.h" +#include "sdkconfig.h" + +#if CONFIG_IDF_TARGET_ESP32 static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1}; static const char *MCPWM_TAG = "MCPWM"; @@ -41,7 +44,7 @@ static portMUX_TYPE mcpwm_spinlock = portMUX_INITIALIZER_UNLOCKED; #define MCPWM_DB_ERROR "MCPWM DEADTIME TYPE ERROR" #define MCPWM_BASE_CLK (2 * APB_CLK_FREQ) //2*APB_CLK_FREQ 160Mhz -#define MCPWM_CLK_PRESCL 15 //MCPWM clock prescale +#define MCPWM_CLK_PRESCL 15 //MCPWM clock prescale #define TIMER_CLK_PRESCALE 9 //MCPWM timer prescales #define MCPWM_CLK (MCPWM_BASE_CLK/(MCPWM_CLK_PRESCL +1)) #define MCPWM_PIN_IGNORE (-1) @@ -727,3 +730,4 @@ esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *a ret = esp_intr_alloc((ETS_PWM0_INTR_SOURCE + mcpwm_num), intr_alloc_flags, fn, arg, handle); return ret; } +#endif diff --git a/components/driver/pcnt.c b/components/driver/pcnt.c index 249a7f828..16bf9a9ae 100644 --- a/components/driver/pcnt.c +++ b/components/driver/pcnt.c @@ -101,11 +101,11 @@ esp_err_t pcnt_set_pin(pcnt_unit_t unit, pcnt_channel_t channel, int pulse_io, i PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG); PCNT_CHECK(GPIO_IS_VALID_GPIO(pulse_io) || pulse_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG); PCNT_CHECK(GPIO_IS_VALID_GPIO(ctrl_io) || ctrl_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG); - + int sig_base = (channel == 0) ? PCNT_SIG_CH0_IN0_IDX : PCNT_SIG_CH1_IN0_IDX; int ctrl_base = (channel == 0) ? PCNT_CTRL_CH0_IN0_IDX : PCNT_CTRL_CH1_IN0_IDX; - if (unit > 4) { - sig_base += 12; // GPIO matrix assignments have a gap between units 4 & 5 + if (unit > 4) { + sig_base += 12; // GPIO matrix assignments have a gap between units 4 & 5 ctrl_base += 12; } int input_sig_index = sig_base + (4 * unit); @@ -156,7 +156,11 @@ esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit) { PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG); PCNT_ENTER_CRITICAL(&pcnt_spinlock); +#if CONFIG_IDF_TARGET_ESP32 uint32_t reset_bit = BIT(PCNT_PLUS_CNT_RST_U0_S + (pcnt_unit * 2)); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t reset_bit = BIT(PCNT_PULSE_CNT_RST_U0_S + (pcnt_unit * 2)); +#endif PCNT.ctrl.val |= reset_bit; PCNT.ctrl.val &= ~reset_bit; PCNT_EXIT_CRITICAL(&pcnt_spinlock); diff --git a/components/driver/periph_ctrl.c b/components/driver/periph_ctrl.c index 65ece09e1..2ef8c965a 100644 --- a/components/driver/periph_ctrl.c +++ b/components/driver/periph_ctrl.c @@ -16,7 +16,9 @@ #include "freertos/semphr.h" #include "freertos/xtensa_api.h" #include "soc/dport_reg.h" +#include "soc/syscon_reg.h" #include "driver/periph_ctrl.h" +#include "sdkconfig.h" static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED; @@ -61,8 +63,13 @@ static uint32_t get_clk_en_mask(periph_module_t periph) return DPORT_UART_CLK_EN; case PERIPH_UART1_MODULE: return DPORT_UART1_CLK_EN; +#if CONFIG_IDF_TARGET_ESP32 case PERIPH_UART2_MODULE: return DPORT_UART2_CLK_EN; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + case PERIPH_USB_MODULE: + return DPORT_USB_CLK_EN; +#endif case PERIPH_I2C0_MODULE: return DPORT_I2C_EXT0_CLK_EN; case PERIPH_I2C1_MODULE: @@ -91,12 +98,27 @@ static uint32_t get_clk_en_mask(periph_module_t periph) return DPORT_PCNT_CLK_EN; case PERIPH_SPI_MODULE: return DPORT_SPI01_CLK_EN; +#if CONFIG_IDF_TARGET_ESP32 case PERIPH_HSPI_MODULE: return DPORT_SPI2_CLK_EN; case PERIPH_VSPI_MODULE: return DPORT_SPI3_CLK_EN; case PERIPH_SPI_DMA_MODULE: return DPORT_SPI_DMA_CLK_EN; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + case PERIPH_FSPI_MODULE: + return DPORT_SPI2_CLK_EN; + case PERIPH_HSPI_MODULE: + return DPORT_SPI3_CLK_EN; + case PERIPH_VSPI_MODULE: + return DPORT_SPI4_CLK_EN; + case PERIPH_SPI2_DMA_MODULE: + return DPORT_SPI2_DMA_CLK_EN; + case PERIPH_SPI3_DMA_MODULE: + return DPORT_SPI3_DMA_CLK_EN; + case PERIPH_SPI_SHARED_DMA_MODULE: + return DPORT_SPI_SHARED_DMA_CLK_EN; +#endif case PERIPH_SDMMC_MODULE: return DPORT_WIFI_CLK_SDIO_HOST_EN; case PERIPH_SDIO_SLAVE_MODULE: @@ -117,12 +139,14 @@ static uint32_t get_clk_en_mask(periph_module_t periph) return DPORT_BT_BASEBAND_EN; case PERIPH_BT_LC_MODULE: return DPORT_BT_LC_EN; +#if CONFIG_IDF_TARGET_ESP32 case PERIPH_AES_MODULE: return DPORT_PERI_EN_AES; case PERIPH_SHA_MODULE: return DPORT_PERI_EN_SHA; case PERIPH_RSA_MODULE: return DPORT_PERI_EN_RSA; +#endif default: return 0; } @@ -139,8 +163,13 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable) return DPORT_UART_RST; case PERIPH_UART1_MODULE: return DPORT_UART1_RST; +#if CONFIG_IDF_TARGET_ESP32 case PERIPH_UART2_MODULE: return DPORT_UART2_RST; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + case PERIPH_USB_MODULE: + return DPORT_USB_RST; +#endif case PERIPH_I2C0_MODULE: return DPORT_I2C_EXT0_RST; case PERIPH_I2C1_MODULE: @@ -169,12 +198,27 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable) return DPORT_PCNT_RST; case PERIPH_SPI_MODULE: return DPORT_SPI01_RST; +#if CONFIG_IDF_TARGET_ESP32 case PERIPH_HSPI_MODULE: return DPORT_SPI2_RST; case PERIPH_VSPI_MODULE: return DPORT_SPI3_RST; case PERIPH_SPI_DMA_MODULE: return DPORT_SPI_DMA_RST; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + case PERIPH_FSPI_MODULE: + return DPORT_SPI2_RST; + case PERIPH_HSPI_MODULE: + return DPORT_SPI3_RST; + case PERIPH_VSPI_MODULE: + return DPORT_SPI4_RST; + case PERIPH_SPI2_DMA_MODULE: + return DPORT_SPI2_DMA_RST; + case PERIPH_SPI3_DMA_MODULE: + return DPORT_SPI3_DMA_RST; + case PERIPH_SPI_SHARED_DMA_MODULE: + return DPORT_SPI_SHARED_DMA_RST; +#endif case PERIPH_SDMMC_MODULE: return DPORT_SDIO_HOST_RST; case PERIPH_SDIO_SLAVE_MODULE: @@ -183,6 +227,7 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable) return DPORT_CAN_RST; case PERIPH_EMAC_MODULE: return DPORT_EMAC_RST; +#if CONFIG_IDF_TARGET_ESP32 case PERIPH_AES_MODULE: if (enable == true) { // Clear reset on digital signature & secure boot units, otherwise AES unit is held in reset also. @@ -207,6 +252,7 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable) // Don't reset digital signature unit, as this resets AES also return DPORT_PERI_EN_RSA; } +#endif case PERIPH_WIFI_MODULE: case PERIPH_BT_MODULE: case PERIPH_WIFI_BT_COMMON_MODULE: @@ -240,18 +286,32 @@ static bool is_wifi_clk_peripheral(periph_module_t periph) static uint32_t get_clk_en_reg(periph_module_t periph) { +#if CONFIG_IDF_TARGET_ESP32 if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) { return DPORT_PERI_CLK_EN_REG; - } else { + } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if(periph == PERIPH_SPI_SHARED_DMA_MODULE) { + return DPORT_PERIP_CLK_EN1_REG; + } +#endif + else { return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG; } } static uint32_t get_rst_en_reg(periph_module_t periph) { +#if CONFIG_IDF_TARGET_ESP32 if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) { return DPORT_PERI_RST_EN_REG; - } else { + } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if(periph == PERIPH_SPI_SHARED_DMA_MODULE){ + return DPORT_PERIP_CLK_EN1_REG; + } +#endif + else { return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG; } } diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 10605d2e2..4a273e7cf 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -317,7 +317,11 @@ esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool* idle_out_en, rmt_idle_ esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t* status) { RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG); +#if CONFIG_IDF_TARGET_ESP32 *status = RMT.status_ch[channel]; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + *status = RMT.status_ch[channel].val; +#endif return ESP_OK; } diff --git a/components/driver/rtc_module.c b/components/driver/rtc_module.c index eae287199..b3baa3ff7 100644 --- a/components/driver/rtc_module.c +++ b/components/driver/rtc_module.c @@ -15,12 +15,12 @@ #include #include #include -#include "esp32/rom/ets_sys.h" #include "esp_log.h" #include "soc/rtc_periph.h" #include "soc/sens_periph.h" #include "soc/syscon_periph.h" #include "soc/rtc.h" +#include "soc/periph_defs.h" #include "rtc_io.h" #include "touch_pad.h" #include "adc.h" @@ -34,6 +34,12 @@ #include "driver/rtc_cntl.h" #include "driver/gpio.h" #include "adc1_i2s_private.h" +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #ifndef NDEBUG // Enable built-in checks in queue.h in debug builds @@ -83,14 +89,14 @@ portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED; static SemaphoreHandle_t rtc_touch_mux = NULL; /* In ADC2, there're two locks used for different cases: -1. lock shared with app and WIFI: - when wifi using the ADC2, we assume it will never stop, +1. lock shared with app and WIFI: + when wifi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed. -2. lock shared between tasks: - when several tasks sharing the ADC2, we want to guarantee +2. lock shared between tasks: + when several tasks sharing the ADC2, we want to guarantee all the requests will be handled. - Since conversions are short (about 31us), app returns the lock very soon, + Since conversions are short (about 31us), app returns the lock very soon, we use a spinlock to stand there waiting to do conversions one by one. adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock. @@ -373,7 +379,9 @@ void rtc_gpio_force_hold_dis_all() for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio]; if (desc->hold_force != 0) { +#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force); +#endif } } } @@ -432,13 +440,21 @@ inline static touch_pad_t touch_pad_num_wrap(touch_pad_t touch_num) esp_err_t touch_pad_isr_handler_register(void (*fn)(void *), void *arg, int no_use, intr_handle_t *handle_no_use) { RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG); +#if CONFIG_IDF_TARGET_ESP32 return rtc_isr_register(fn, arg, RTC_CNTL_TOUCH_INT_ST_M); +#else + return ESP_FAIL; +#endif } esp_err_t touch_pad_isr_register(intr_handler_t fn, void* arg) { RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG); +#if CONFIG_IDF_TARGET_ESP32 return rtc_isr_register(fn, arg, RTC_CNTL_TOUCH_INT_ST_M); +#else + return ESP_FAIL; +#endif } esp_err_t touch_pad_isr_deregister(intr_handler_t fn, void *arg) @@ -566,7 +582,7 @@ esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, t ESP_ERR_INVALID_ARG); RTC_MODULE_CHECK(((atten < TOUCH_HVOLT_ATTEN_MAX) && (refh >= (int )TOUCH_HVOLT_ATTEN_KEEP)), "touch atten error", ESP_ERR_INVALID_ARG); - +#if CONFIG_IDF_TARGET_ESP32 portENTER_CRITICAL(&rtc_spinlock); if (refh > TOUCH_HVOLT_KEEP) { RTCIO.touch_cfg.drefh = refh; @@ -578,11 +594,13 @@ esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, t RTCIO.touch_cfg.drange = atten; } portEXIT_CRITICAL(&rtc_spinlock); +#endif return ESP_OK; } esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl, touch_volt_atten_t *atten) { +#if CONFIG_IDF_TARGET_ESP32 portENTER_CRITICAL(&rtc_spinlock); if (refh) { *refh = RTCIO.touch_cfg.drefh; @@ -594,6 +612,7 @@ esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl, *atten = RTCIO.touch_cfg.drange; } portEXIT_CRITICAL(&rtc_spinlock); +#endif return ESP_OK; } @@ -601,7 +620,7 @@ esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope, { RTC_MODULE_CHECK((slope < TOUCH_PAD_SLOPE_MAX), "touch slope error", ESP_ERR_INVALID_ARG); RTC_MODULE_CHECK((opt < TOUCH_PAD_TIE_OPT_MAX), "touch opt error", ESP_ERR_INVALID_ARG); - + touch_pad_t touch_pad_wrap = touch_pad_num_wrap(touch_num); portENTER_CRITICAL(&rtc_spinlock); RTCIO.touch_pad[touch_pad_wrap].tie_opt = opt; @@ -613,7 +632,7 @@ esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope, esp_err_t touch_pad_get_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t *slope, touch_tie_opt_t *opt) { RTC_MODULE_CHECK((touch_num < TOUCH_PAD_MAX), "touch IO error", ESP_ERR_INVALID_ARG); - + touch_pad_t touch_pad_wrap = touch_pad_num_wrap(touch_num); portENTER_CRITICAL(&rtc_spinlock); if(opt) { @@ -1152,7 +1171,7 @@ void adc_power_on() #ifndef CONFIG_ADC_FORCE_XPD_FSM //Set the power always on to increase precision. SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU; -#else +#else //Use the FSM to turn off the power while not used to save power. if (SENS.sar_meas_wait2.force_xpd_sar & SENS_FORCE_XPD_SAR_SW_M) { SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU; @@ -1266,12 +1285,12 @@ static void adc_set_controller(adc_unit_t unit, adc_controller_t ctrl ) break; default: ESP_LOGE(TAG, "adc1 selects invalid controller"); - break; + break; } } else if ( unit == ADC_UNIT_2) { switch( ctrl ) { case ADC_CTRL_RTC: - SENS.sar_meas_start2.meas2_start_force = true; //RTC controller controls the ADC,not ulp coprocessor + SENS.sar_meas_start2.meas2_start_force = true; //RTC controller controls the ADC,not ulp coprocessor SENS.sar_meas_start2.sar2_en_pad_force = true; //RTC controller controls the data port, not ulp coprocessor SENS.sar_read_ctrl2.sar2_dig_force = false; //RTC controller controls the ADC, not digital controller SENS.sar_read_ctrl2.sar2_pwdet_force = false; //RTC controller controls the ADC, not PWDET @@ -1301,7 +1320,7 @@ static void adc_set_controller(adc_unit_t unit, adc_controller_t ctrl ) break; default: ESP_LOGE(TAG, "adc2 selects invalid controller"); - break; + break; } } else { ESP_LOGE(TAG, "invalid adc unit"); @@ -1321,12 +1340,12 @@ static int adc_convert( adc_unit_t unit, int channel) while (SENS.sar_meas_start1.meas1_done_sar == 0); adc_value = SENS.sar_meas_start1.meas1_data_sar; } else if ( unit == ADC_UNIT_2 ) { - SENS.sar_meas_start2.sar2_en_pad = (1 << channel); //only one channel is selected. - + SENS.sar_meas_start2.sar2_en_pad = (1 << channel); //only one channel is selected. + SENS.sar_meas_start2.meas2_start_sar = 0; //start force 0 SENS.sar_meas_start2.meas2_start_sar = 1; //start force 1 while (SENS.sar_meas_start2.meas2_done_sar == 0) {}; //read done - adc_value = SENS.sar_meas_start2.meas2_data_sar; + adc_value = SENS.sar_meas_start2.meas2_data_sar; } else { ESP_LOGE(TAG, "invalid adc unit"); return ESP_ERR_INVALID_ARG; @@ -1479,7 +1498,7 @@ static inline void adc1_fsm_disable() SENS.sar_meas_ctrl.amp_short_ref_gnd_fsm = 0; SENS.sar_meas_wait1.sar_amp_wait1 = 1; SENS.sar_meas_wait1.sar_amp_wait2 = 1; - SENS.sar_meas_wait2.sar_amp_wait3 = 1; + SENS.sar_meas_wait2.sar_amp_wait3 = 1; } esp_err_t adc1_i2s_mode_acquire() @@ -1530,7 +1549,7 @@ int adc1_get_raw(adc1_channel_t channel) adc1_adc_mode_acquire(); adc_power_on(); - portENTER_CRITICAL(&rtc_spinlock); + portENTER_CRITICAL(&rtc_spinlock); //disable other peripherals adc1_hall_enable(false); adc1_fsm_disable(); //currently the LNA is not open, close it by default @@ -1652,7 +1671,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) } SENS.sar_atten2 = ( SENS.sar_atten2 & ~(3<<(channel*2)) ) | ((atten&3) << (channel*2)); _lock_release( &adc2_wifi_lock ); - + portEXIT_CRITICAL( &adc2_spinlock ); return ESP_OK; } @@ -1682,7 +1701,7 @@ static inline void adc2_dac_disable( adc2_channel_t channel) } //registers in critical section with adc1: -//SENS_SAR_START_FORCE_REG, +//SENS_SAR_START_FORCE_REG, esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int* raw_out) { uint16_t adc_value = 0; @@ -1692,7 +1711,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int* adc_power_on(); //avoid collision with other tasks - portENTER_CRITICAL(&adc2_spinlock); + portENTER_CRITICAL(&adc2_spinlock); //lazy initialization //try the lock, return if failed (wifi using). if ( _lock_try_acquire( &adc2_wifi_lock ) == -1 ) { @@ -1895,7 +1914,9 @@ esp_err_t dac_i2s_disable() static inline void adc1_hall_enable(bool enable) { - RTCIO.hall_sens.xpd_hall = enable; +#if CONFIG_IDF_TARGET_ESP32 + RTCIO.hall_sens.xpd_hall = enable; +#endif } static int hall_sensor_get_value() //hall sensor without LNA @@ -1904,14 +1925,15 @@ static int hall_sensor_get_value() //hall sensor without LNA int Sens_Vn0; int Sens_Vp1; int Sens_Vn1; - int hall_value; - + int hall_value = 0; + adc_power_on(); +#if CONFIG_IDF_TARGET_ESP32 portENTER_CRITICAL(&rtc_spinlock); //disable other peripherals - adc1_fsm_disable();//currently the LNA is not open, close it by default - adc1_hall_enable(true); + adc1_fsm_disable();//currently the LNA is not open, close it by default + adc1_hall_enable(true); // set controller adc_set_controller( ADC_UNIT_1, ADC_CTRL_RTC ); // convert for 4 times with different phase and outputs @@ -1923,7 +1945,7 @@ static int hall_sensor_get_value() //hall sensor without LNA Sens_Vn1 = adc_convert( ADC_UNIT_1, ADC1_CHANNEL_3 ); portEXIT_CRITICAL(&rtc_spinlock); hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0); - +#endif return hall_value; } diff --git a/components/driver/sdmmc_host.c b/components/driver/sdmmc_host.c index 7a8969fd2..b72fb5b0e 100644 --- a/components/driver/sdmmc_host.c +++ b/components/driver/sdmmc_host.c @@ -25,7 +25,7 @@ #include "sdmmc_private.h" #include "freertos/semphr.h" #include "soc/sdmmc_periph.h" - +#if CONFIG_IDF_TARGET_ESP32 #define SDMMC_EVENT_QUEUE_LENGTH 32 @@ -635,3 +635,4 @@ esp_err_t sdmmc_host_pullup_en(int slot, int width) } return ESP_OK; } +#endif diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index 6677ef656..8c989164b 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -14,6 +14,8 @@ #include +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 #include "driver/spi_master.h" #include "soc/spi_periph.h" #include "esp32/rom/ets_sys.h" @@ -30,6 +32,9 @@ #include "driver/spi_common.h" #include "stdatomic.h" #include "hal/spi_hal.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "cas.h" +#endif static const char *SPI_TAG = "spi"; @@ -112,7 +117,17 @@ bool spicommon_dma_chan_claim (int dma_chan) spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan); ret = true; } +#if CONFIG_IDF_TARGET_ESP32 periph_module_enable( PERIPH_SPI_DMA_MODULE ); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if (dma_chan==1) { + periph_module_enable(PERIPH_SPI2_DMA_MODULE); + } else if (dma_chan==2) { + periph_module_enable(PERIPH_SPI3_DMA_MODULE); + } else if (dma_chan==3) { + periph_module_enable(PERIPH_SPI_SHARED_DMA_MODULE); + } +#endif portEXIT_CRITICAL(&spi_dma_spinlock); return ret; @@ -131,10 +146,20 @@ bool spicommon_dma_chan_free(int dma_chan) portENTER_CRITICAL(&spi_dma_spinlock); spi_dma_chan_enabled &= ~DMA_CHANNEL_ENABLED(dma_chan); +#if CONFIG_IDF_TARGET_ESP32 if ( spi_dma_chan_enabled == 0 ) { //disable the DMA only when all the channels are freed. periph_module_disable( PERIPH_SPI_DMA_MODULE ); } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if (dma_chan==1) { + periph_module_disable(PERIPH_SPI2_DMA_MODULE); + } else if (dma_chan==2) { + periph_module_disable(PERIPH_SPI3_DMA_MODULE); + } else if (dma_chan==3) { + periph_module_disable(PERIPH_SPI_SHARED_DMA_MODULE); + } +#endif portEXIT_CRITICAL(&spi_dma_spinlock); return true; @@ -234,23 +259,43 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host+1); if (bus_config->mosi_io_num >= 0) { gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in); +#if CONFIG_IDF_TARGET_ESP32 gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + gpio_iomux_out(bus_config->mosi_io_num, spi_periph_signal[host].func, false); +#endif } if (bus_config->miso_io_num >= 0) { gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in); +#if CONFIG_IDF_TARGET_ESP32 gpio_iomux_out(bus_config->miso_io_num, FUNC_SPI, false); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + gpio_iomux_out(bus_config->miso_io_num, spi_periph_signal[host].func, false); +#endif } if (bus_config->quadwp_io_num >= 0) { gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in); +#if CONFIG_IDF_TARGET_ESP32 gpio_iomux_out(bus_config->quadwp_io_num, FUNC_SPI, false); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + gpio_iomux_out(bus_config->quadwp_io_num, spi_periph_signal[host].func, false); +#endif } if (bus_config->quadhd_io_num >= 0) { gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in); +#if CONFIG_IDF_TARGET_ESP32 gpio_iomux_out(bus_config->quadhd_io_num, FUNC_SPI, false); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + gpio_iomux_out(bus_config->quadhd_io_num, spi_periph_signal[host].func, false); +#endif } if (bus_config->sclk_io_num >= 0) { gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in); +#if CONFIG_IDF_TARGET_ESP32 gpio_iomux_out(bus_config->sclk_io_num, FUNC_SPI, false); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + gpio_iomux_out(bus_config->sclk_io_num, spi_periph_signal[host].func, false); +#endif } temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS; } else { @@ -264,6 +309,9 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT); } gpio_matrix_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false); +#if CONFIG_IDF_TARGET_ESP32S2BETA + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->mosi_io_num]); +#endif PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO); } if (bus_config->miso_io_num >= 0) { @@ -274,18 +322,27 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT); } gpio_matrix_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false); +#if CONFIG_IDF_TARGET_ESP32S2BETA + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->miso_io_num]); +#endif PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO); } if (bus_config->quadwp_io_num >= 0) { gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_INPUT_OUTPUT); gpio_matrix_out(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_out, false, false); gpio_matrix_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false); +#if CONFIG_IDF_TARGET_ESP32S2BETA + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num]); +#endif PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO); } if (bus_config->quadhd_io_num >= 0) { gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_INPUT_OUTPUT); gpio_matrix_out(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_out, false, false); gpio_matrix_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false); +#if CONFIG_IDF_TARGET_ESP32S2BETA + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num]); +#endif PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO); } if (bus_config->sclk_io_num >= 0) { @@ -296,12 +353,30 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT); } gpio_matrix_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false); +#if CONFIG_IDF_TARGET_ESP32S2BETA + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->sclk_io_num]); +#endif PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO); } +#if CONFIG_IDF_TARGET_ESP32S2BETA + if (bus_config->spicd_io_num >= 0) { + gpio_set_direction(bus_config->spicd_io_num, GPIO_MODE_INPUT_OUTPUT); + gpio_matrix_out(bus_config->spicd_io_num, spi_periph_signal[host].spicd_out, false, false); + gpio_matrix_in(bus_config->spicd_io_num, spi_periph_signal[host].spicd_in, false); + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->spicd_io_num]); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->spicd_io_num], FUNC_GPIO); + } +#endif } //Select DMA channel. +#if CONFIG_IDF_TARGET_ESP32 DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2)); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if (dma_chan==VSPI_HOST) { + DPORT_SET_PERI_REG_MASK(DPORT_SPI_DMA_CHAN_SEL_REG, DPORT_SPI_SHARED_DMA_SEL_M); + } +#endif if (flags_o) *flags_o = temp_flag; return ESP_OK; @@ -354,7 +429,11 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) { //The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define. gpio_iomux_in(cs_io_num, spi_periph_signal[host].spics_in); +#if CONFIG_IDF_TARGET_ESP32 gpio_iomux_out(cs_io_num, FUNC_SPI, false); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false); +#endif } else { //Use GPIO matrix if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) { @@ -364,6 +443,9 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, gpio_set_direction(cs_io_num, GPIO_MODE_INPUT); } if (cs_num == 0) gpio_matrix_in(cs_io_num, spi_periph_signal[host].spics_in, false); +#if CONFIG_IDF_TARGET_ESP32S2BETA + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[cs_io_num]); +#endif PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO); } } @@ -402,6 +484,7 @@ static int dmaworkaround_waiting_for_chan = 0; bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg) { +#if CONFIG_IDF_TARGET_ESP32 int otherchan = (dmachan == 1) ? 2 : 1; bool ret; portENTER_CRITICAL_ISR(&dmaworkaround_mux); @@ -418,6 +501,9 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t } portEXIT_CRITICAL_ISR(&dmaworkaround_mux); return ret; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + return true; +#endif } bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress() @@ -427,6 +513,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress() void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) { +#if CONFIG_IDF_TARGET_ESP32 portENTER_CRITICAL_ISR(&dmaworkaround_mux); dmaworkaround_channels_busy[dmachan-1] = 0; if (dmaworkaround_waiting_for_chan == dmachan) { @@ -438,6 +525,7 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) } portEXIT_CRITICAL_ISR(&dmaworkaround_mux); +#endif } void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan) @@ -447,4 +535,4 @@ void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan) portEXIT_CRITICAL_ISR(&dmaworkaround_mux); } - +#endif diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 90382fd01..970548910 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -122,7 +122,6 @@ We have two bits to control the interrupt: #include "driver/spi_common.h" #include "driver/spi_master.h" #include "soc/spi_periph.h" -#include "esp32/rom/ets_sys.h" #include "esp_types.h" #include "esp_attr.h" #include "esp_intr_alloc.h" @@ -139,8 +138,12 @@ We have two bits to control the interrupt: #include "esp_heap_caps.h" #include "stdatomic.h" #include "sdkconfig.h" - +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" #include "hal/spi_hal.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "cas.h" +#endif typedef struct spi_device_t spi_device_t; @@ -183,6 +186,9 @@ typedef struct { int dma_chan; int max_transfer_sz; spi_bus_config_t bus_cfg; +#if CONFIG_IDF_TARGET_ESP32S2BETA + int id; +#endif #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; #endif @@ -199,7 +205,7 @@ struct spi_device_t { bool waiting; //the device is waiting for the exclusive control of the bus }; -static spi_host_t *spihost[3]; +static spi_host_t *spihost[SPI_PERIPH_NUM]; static const char *SPI_TAG = "spi_master"; @@ -245,6 +251,10 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus } memset(spihost[host], 0, sizeof(spi_host_t)); memcpy( &spihost[host]->bus_cfg, bus_config, sizeof(spi_bus_config_t)); + +#if CONFIG_IDF_TARGET_ESP32S2BETA + spihost[host]->id = host; +#endif #ifdef CONFIG_PM_ENABLE err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master", &spihost[host]->pm_lock); @@ -259,7 +269,13 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus ret = err; goto cleanup; } - +#if CONFIG_IDF_TARGET_ESP32 + DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2)); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if (host==VSPI_HOST) { + DPORT_SET_PERI_REG_BITS(DPORT_SPI_SHARED_DMA_SEL_REG, DPORT_SPI_SHARED_DMA_SEL_M, 1, DPORT_SPI_SHARED_DMA_SEL_S); + } +#endif int dma_desc_ct=0; spihost[host]->dma_chan=dma_chan; if (dma_chan == 0) { @@ -1084,4 +1100,4 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_transmit(spi_device_handle_t ha return ESP_OK; } - +#endif diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index f9f792a28..f1a63e85d 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -13,13 +13,14 @@ // limitations under the License. #include +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 #include #include #include #include "driver/spi_common.h" #include "driver/spi_slave.h" #include "soc/spi_periph.h" -#include "esp32/rom/ets_sys.h" #include "esp_types.h" #include "esp_attr.h" #include "esp_intr_alloc.h" @@ -34,7 +35,7 @@ #include "esp32/rom/lldesc.h" #include "driver/gpio.h" #include "esp_heap_caps.h" - +#include "esp32/rom/ets_sys.h" static const char *SPI_TAG = "spi_slave"; #define SPI_CHECK(a, str, ret_val) \ if (!(a)) { \ @@ -392,4 +393,4 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) if (do_yield) portYIELD_FROM_ISR(); } - +#endif diff --git a/components/driver/timer.c b/components/driver/timer.c index 6a82d87fa..69248252b 100644 --- a/components/driver/timer.c +++ b/components/driver/timer.c @@ -19,6 +19,7 @@ #include "freertos/xtensa_api.h" #include "driver/timer.h" #include "driver/periph_ctrl.h" +#include "sdkconfig.h" static const char* TIMER_TAG = "timer_group"; #define TIMER_CHECK(a, str, ret_val) \ @@ -47,7 +48,11 @@ esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); TIMER_CHECK(timer_val != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); portENTER_CRITICAL_SAFE(&timer_spinlock[group_num]); +#if CONFIG_IDF_TARGET_ESP32 TG[group_num]->hw_timer[timer_num].update = 1; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + TG[group_num]->hw_timer[timer_num].update.update = 1; +#endif *timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32) | (TG[group_num]->hw_timer[timer_num].cnt_low); portEXIT_CRITICAL_SAFE(&timer_spinlock[group_num]); @@ -171,7 +176,7 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_ return ESP_OK; } -esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, +esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void*), void * arg, int intr_alloc_flags, timer_isr_handle_t *handle) { TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); @@ -222,7 +227,11 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer //but software reset does not clear interrupt status. This is not safe for application when enable the interrupt of timer_group. //we need to disable the interrupt and clear the interrupt status here. TG[group_num]->int_ena.val &= (~BIT(timer_num)); +#if CONFIG_IDF_TARGET_ESP32 TG[group_num]->int_clr_timers.val = BIT(timer_num); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + TG[group_num]->int_clr.val = BIT(timer_num); +#endif TG[group_num]->hw_timer[timer_num].config.autoreload = config->auto_reload; TG[group_num]->hw_timer[timer_num].config.divider = (uint16_t) config->divider; TG[group_num]->hw_timer[timer_num].config.enable = config->counter_en; diff --git a/components/driver/uart.c b/components/driver/uart.c index b9d222f56..f557f4f4e 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -17,7 +17,6 @@ #include "esp_intr_alloc.h" #include "esp_log.h" #include "esp_err.h" -#include "esp32/clk.h" #include "malloc.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" @@ -28,6 +27,12 @@ #include "driver/uart.h" #include "driver/gpio.h" #include "driver/uart_select.h" +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#endif #define XOFF (char)0x13 #define XON (char)0x11 @@ -79,7 +84,7 @@ typedef struct { intr_handle_t intr_handle; /*!< UART interrupt handle*/ uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */ bool coll_det_flg; /*!< UART collision detection flag */ - + //rx parameters int rx_buffered_len; /*!< UART cached data length */ SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/ @@ -298,9 +303,15 @@ static esp_err_t uart_reset_rx_fifo(uart_port_t uart_num) //See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <> v2.6 or later. // we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`. +#if CONFIG_IDF_TARGET_ESP32 while(UART[uart_num]->status.rxfifo_cnt != 0 || (UART[uart_num]->mem_rx_status.wr_addr != UART[uart_num]->mem_rx_status.rd_addr)) { READ_PERI_REG(UART_FIFO_REG(uart_num)); } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + while(UART[uart_num]->status.rxfifo_cnt != 0 || (UART[uart_num]->mem_rx_status.rx_waddr != UART[uart_num]->mem_rx_status.apb_rx_raddr)) { + READ_PERI_REG(UART_FIFO_AHB_REG(uart_num)); + } +#endif return ESP_OK; } @@ -577,12 +588,14 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r rts_sig = U1RTS_OUT_IDX; cts_sig = U1CTS_IN_IDX; break; +#if CONFIG_IDF_TARGET_ESP32 case UART_NUM_2: tx_sig = U2TXD_OUT_IDX; rx_sig = U2RXD_IN_IDX; rts_sig = U2RTS_OUT_IDX; cts_sig = U2CTS_IN_IDX; break; +#endif case UART_NUM_MAX: default: tx_sig = U0TXD_OUT_IDX; @@ -657,7 +670,11 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf } else if(uart_num == UART_NUM_1) { periph_module_enable(PERIPH_UART1_MODULE); } else if(uart_num == UART_NUM_2) { +#if CONFIG_IDF_TARGET_ESP32 periph_module_enable(PERIPH_UART2_MODULE); +#else + return ESP_FAIL; +#endif } r = uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); if (r != ESP_OK) return r; @@ -861,7 +878,11 @@ static void uart_rx_intr_handler_default(void *param) if (p_uart->rx_buffer_full_flg == false) { //We have to read out all data in RX FIFO to clear the interrupt signal while (buf_idx < rx_fifo_len) { +#if CONFIG_IDF_TARGET_ESP32 p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + p_uart->rx_data_buf[buf_idx++] = READ_PERI_REG(UART_FIFO_AHB_REG(uart_num)); +#endif } uint8_t pat_chr = uart_reg->at_cmd_char.data; int pat_num = uart_reg->at_cmd_char.char_num; @@ -997,13 +1018,13 @@ static void uart_rx_intr_handler_default(void *param) UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reset_rx_fifo(uart_num); // Set collision detection flag - p_uart_obj[uart_num]->coll_det_flg = true; + p_uart_obj[uart_num]->coll_det_flg = true; UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_event.type = UART_EVENT_MAX; } else if(uart_intr_status & UART_TX_DONE_INT_ST_M) { uart_disable_intr_mask_from_isr(uart_num, UART_TX_DONE_INT_ENA_M); uart_clear_intr_status(uart_num, UART_TX_DONE_INT_CLR_M); - // If RS485 half duplex mode is enable then reset FIFO and + // If RS485 half duplex mode is enable then reset FIFO and // reset RTS pin to start receiver driver if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); @@ -1461,7 +1482,11 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) } else if(uart_num == UART_NUM_1) { periph_module_disable(PERIPH_UART1_MODULE); } else if(uart_num == UART_NUM_2) { - periph_module_disable(PERIPH_UART2_MODULE); +#if CONFIG_IDF_TARGET_ESP32 + periph_module_disable(PERIPH_UART2_MODULE); +#else + return ESP_FAIL; +#endif } } return ESP_OK; @@ -1479,11 +1504,11 @@ portMUX_TYPE *uart_get_selectlock() return &uart_selectlock; } // Set UART mode -esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode) +esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode) { UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_STATE); UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG); - if ((mode == UART_MODE_RS485_COLLISION_DETECT) || (mode == UART_MODE_RS485_APP_CTRL) + if ((mode == UART_MODE_RS485_COLLISION_DETECT) || (mode == UART_MODE_RS485_APP_CTRL) || (mode == UART_MODE_RS485_HALF_DUPLEX)) { UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using RS485 mode", ESP_ERR_INVALID_ARG); @@ -1538,13 +1563,13 @@ esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode) return ESP_OK; } -esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh) +esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG); UART_CHECK((tout_thresh < 127), "tout_thresh max value is 126", ESP_ERR_INVALID_ARG); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - // The tout_thresh = 1, defines TOUT interrupt timeout equal to - // transmission time of one symbol (~11 bit) on current baudrate + // The tout_thresh = 1, defines TOUT interrupt timeout equal to + // transmission time of one symbol (~11 bit) on current baudrate if (tout_thresh > 0) { UART[uart_num]->conf1.rx_tout_thrhd = (tout_thresh & UART_RX_TOUT_THRHD_V); UART[uart_num]->conf1.rx_tout_en = 1; @@ -1559,8 +1584,8 @@ esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool* collision_flag) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG); UART_CHECK((collision_flag != NULL), "wrong parameter pointer", ESP_ERR_INVALID_ARG); - UART_CHECK((UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX) - || UART_IS_MODE_SET(uart_num, UART_MODE_RS485_COLLISION_DETECT)), + UART_CHECK((UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX) + || UART_IS_MODE_SET(uart_num, UART_MODE_RS485_COLLISION_DETECT)), "wrong mode", ESP_ERR_INVALID_ARG); *collision_flag = p_uart_obj[uart_num]->coll_det_flg; return ESP_OK; diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index b2afdbd9a..a0c811cb4 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _ESP_EFUSE_MANAGER_H_ -#define _ESP_EFUSE_MANAGER_H_ +#pragma once #ifdef __cplusplus extern "C" { @@ -358,5 +357,3 @@ void esp_efuse_init(uint32_t offset, uint32_t size); #ifdef __cplusplus } #endif - -#endif // _ESP_EFUSE_MANAGER_H_ diff --git a/components/esp32s2beta/CMakeLists.txt b/components/esp32s2beta/CMakeLists.txt index 34da19b4e..ca521cfce 100644 --- a/components/esp32s2beta/CMakeLists.txt +++ b/components/esp32s2beta/CMakeLists.txt @@ -46,12 +46,14 @@ elseif(CONFIG_IDF_TARGET_ESP32S2BETA) target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_BINARY_DIR}/esp32s2beta_out.ld") + # Rely on user code to define app_main + target_link_libraries(${COMPONENT_LIB} "-u app_main") + # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_LIST_DIR}/ld/esp32s2beta.project.ld.in" PROCESS) target_linker_script(${COMPONENT_LIB} "ld/esp32s2beta.peripherals.ld") - target_link_libraries(${COMPONENT_LIB} gcc) target_link_libraries(${COMPONENT_LIB} "-u call_user_start_cpu0") @@ -79,6 +81,4 @@ elseif(CONFIG_IDF_TARGET_ESP32S2BETA) cpu_start.c PROPERTIES COMPILE_FLAGS -fno-stack-protector) -else() - register_config_only_component() endif() diff --git a/components/esp32s2beta/clk.c b/components/esp32s2beta/clk.c index 9fefa402a..0966a4630 100644 --- a/components/esp32s2beta/clk.c +++ b/components/esp32s2beta/clk.c @@ -24,6 +24,8 @@ #include "esp32s2beta/rom/ets_sys.h" #include "esp32s2beta/rom/uart.h" #include "esp32s2beta/rom/rtc.h" +#include "soc/system_reg.h" +#include "soc/dport_access.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" diff --git a/components/esp32s2beta/cpu_start.c b/components/esp32s2beta/cpu_start.c index 99f92843c..ff787b4f9 100644 --- a/components/esp32s2beta/cpu_start.c +++ b/components/esp32s2beta/cpu_start.c @@ -14,7 +14,7 @@ #include #include - +#include "sdkconfig.h" #include "esp_attr.h" #include "esp_err.h" @@ -22,6 +22,10 @@ #include "esp32s2beta/rom/uart.h" #include "esp32s2beta/rom/rtc.h" #include "esp32s2beta/rom/cache.h" +#include "esp32s2beta/dport_access.h" +#include "esp32s2beta/brownout.h" +#include "esp32s2beta/cache_err_int.h" +#include "esp32s2beta/spiram.h" #include "soc/cpu.h" #include "soc/rtc.h" @@ -40,36 +44,33 @@ #include "freertos/portmacro.h" #include "esp_heap_caps_init.h" -#include "sdkconfig.h" #include "esp_system.h" #include "esp_spi_flash.h" #include "nvs_flash.h" #include "esp_event.h" #include "esp_spi_flash.h" #include "esp_ipc.h" -#include "esp32s2beta/dport_access.h" #include "esp_private/crosscore_int.h" #include "esp_log.h" #include "esp_vfs_dev.h" #include "esp_newlib.h" -#include "esp32s2beta/brownout.h" #include "esp_int_wdt.h" #include "esp_task.h" #include "esp_task_wdt.h" #include "esp_phy_init.h" -#include "esp32s2beta/cache_err_int.h" #include "esp_coexist_internal.h" #include "esp_debug_helpers.h" #include "esp_core_dump.h" #include "esp_app_trace.h" #include "esp_private/dbg_stubs.h" -#include "esp_efuse.h" -#include "esp32s2beta/spiram.h" #include "esp_clk_internal.h" #include "esp_timer.h" #include "esp_pm.h" #include "esp_private/pm_impl.h" #include "trax.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp_efuse.h" +#endif #define STRINGIFY(s) STRINGIFY2(s) #define STRINGIFY2(s) #s @@ -137,7 +138,9 @@ void IRAM_ATTR call_start_cpu0() || rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET #endif ) { - esp_panic_wdt_stop(); +#ifndef CONFIG_BOOTLOADER_WDT_ENABLE + rtc_wdt_disable(); +#endif } //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this. @@ -396,7 +399,6 @@ void start_cpu0_default(void) #endif //esp_cache_err_int_init(); esp_crosscore_int_init(); - esp_ipc_init(); #ifndef CONFIG_FREERTOS_UNICORE esp_dport_access_int_init(); #endif @@ -459,7 +461,7 @@ void start_cpu1_default(void) } #endif //!CONFIG_FREERTOS_UNICORE -#ifdef CONFIG_CXX_EXCEPTIONS +#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS size_t __cxx_eh_arena_size_get() { return CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE; diff --git a/components/esp32s2beta/include/esp32s2beta/spiram.h b/components/esp32s2beta/include/esp32s2beta/spiram.h index 9663dcddc..e623eacb9 100644 --- a/components/esp32s2beta/include/esp32s2beta/spiram.h +++ b/components/esp32s2beta/include/esp32s2beta/spiram.h @@ -18,6 +18,7 @@ #include #include +#include #include "esp_err.h" /** @@ -41,7 +42,7 @@ void esp_spiram_init_cache(); /** * @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and - * (in case of a dual-core system) the app CPU is online. This test overwrites the + * (in case of a dual-core system) the app CPU is online. This test overwrites the * memory with crap, so do not call after e.g. the heap allocator has stored important * stuff in SPI RAM. * diff --git a/components/esp32s2beta/include/esp_attr.h b/components/esp32s2beta/include/esp_attr.h deleted file mode 100644 index 5bf9a2292..000000000 --- a/components/esp32s2beta/include/esp_attr.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef __ESP_ATTR_H__ -#define __ESP_ATTR_H__ - -#define ROMFN_ATTR - -//Normally, the linker script will put all code and rodata in flash, -//and all variables in shared RAM. These macros can be used to redirect -//particular functions/variables to other memory regions. - -// Forces code into IRAM instead of flash. -#define IRAM_ATTR __attribute__((section(".iram1"))) - -// Forces data into DRAM instead of flash -#define DRAM_ATTR __attribute__((section(".dram1"))) - -// Forces data to be 4 bytes aligned -#define WORD_ALIGNED_ATTR __attribute__((aligned(4))) - -// Forces data to be placed to DMA-capable places -#define DMA_ATTR WORD_ALIGNED_ATTR DRAM_ATTR - -// Forces a string into DRAM instead of flash -// Use as ets_printf(DRAM_STR("Hello world!\n")); -#define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;})) - -// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst" -#define RTC_IRAM_ATTR __attribute__((section(".rtc.text"))) - -// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst" -// Any variable marked with this attribute will keep its value -// during a deep sleep / wake cycle. -#define RTC_DATA_ATTR __attribute__((section(".rtc.data"))) - -// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst" -#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata"))) - -// Forces data into noinit section to avoid initialization after restart. -#define __NOINIT_ATTR __attribute__((section(".noinit"))) - -// Forces data into RTC slow memory of .noinit section. -// Any variable marked with this attribute will keep its value -// after restart or during a deep sleep / wake cycle. -#define RTC_NOINIT_ATTR __attribute__((section(".rtc_noinit"))) - -#endif /* __ESP_ATTR_H__ */ diff --git a/components/esp32s2beta/include/esp_intr.h b/components/esp32s2beta/include/esp_intr.h index 579eb6353..6710e3c16 100644 --- a/components/esp32s2beta/include/esp_intr.h +++ b/components/esp32s2beta/include/esp_intr.h @@ -15,7 +15,7 @@ #ifndef __ESP_INTR_H__ #define __ESP_INTR_H__ -#include "rom/ets_sys.h" +#include "esp32s2beta/rom/ets_sys.h" #include "freertos/xtensa_api.h" #ifdef __cplusplus diff --git a/components/esp32s2beta/include/esp_intr_alloc.h b/components/esp32s2beta/include/esp_intr_alloc.h index b5420f798..688a2d749 100644 --- a/components/esp32s2beta/include/esp_intr_alloc.h +++ b/components/esp32s2beta/include/esp_intr_alloc.h @@ -18,6 +18,7 @@ #include #include #include "esp_err.h" +#include "freertos/xtensa_api.h" #ifdef __cplusplus extern "C" { @@ -80,7 +81,10 @@ extern "C" { // This is used to provide SystemView with positive IRQ IDs, otherwise sheduler events are not shown properly #define ETS_INTERNAL_INTR_SOURCE_OFF (-ETS_INTERNAL_PROFILING_INTR_SOURCE) -typedef void (*intr_handler_t)(void *arg); +#define ESP_INTR_ENABLE(inum) xt_ints_on((1<3 * is requested, because these types of interrupts aren't C-callable. @@ -158,7 +162,7 @@ esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *ar * * * This essentially does the same as esp_intr_alloc, but allows specifying a register and mask - * combo. For shared interrupts, the handler is only called if a read from the specified + * combo. For shared interrupts, the handler is only called if a read from the specified * register, ANDed with the mask, returns non-zero. By passing an interrupt status register * address and a fitting mask, this can be used to accelerate interrupt handling in the case * a shared interrupt is triggered; by checking the interrupt statuses first, the code can @@ -171,7 +175,7 @@ esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *ar * choice of interrupts that this routine can choose from. If this value * is 0, it will default to allocating a non-shared interrupt of level * 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared - * interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return + * interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return * from this function with the interrupt disabled. * @param intrstatusreg The address of an interrupt status register * @param intrstatusmask A mask. If a read of address intrstatusreg has any of the bits @@ -197,9 +201,9 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre * Use an interrupt handle to disable the interrupt and release the resources * associated with it. * - * @note - * When the handler shares its source with other handlers, the interrupt status - * bits it's responsible for should be managed properly before freeing it. see + * @note + * When the handler shares its source with other handlers, the interrupt status + * bits it's responsible for should be managed properly before freeing it. see * ``esp_intr_disable`` for more details. * * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus @@ -213,7 +217,7 @@ esp_err_t esp_intr_free(intr_handle_t handle); /** * @brief Get CPU number an interrupt is tied to - * + * * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus * * @return The core number where the interrupt is allocated @@ -222,7 +226,7 @@ int esp_intr_get_cpu(intr_handle_t handle); /** * @brief Get the allocated interrupt for a certain handle - * + * * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus * * @return The interrupt number @@ -231,13 +235,13 @@ int esp_intr_get_intno(intr_handle_t handle); /** * @brief Disable the interrupt associated with the handle - * - * @note + * + * @note * 1. For local interrupts (ESP_INTERNAL_* sources), this function has to be called on the * CPU the interrupt is allocated on. Other interrupts have no such restriction. - * 2. When several handlers sharing a same interrupt source, interrupt status bits, which are + * 2. When several handlers sharing a same interrupt source, interrupt status bits, which are * handled in the handler to be disabled, should be masked before the disabling, or handled - * in other enabled interrupts properly. Miss of interrupt status handling will cause infinite + * in other enabled interrupts properly. Miss of interrupt status handling will cause infinite * interrupt calls and finally system crash. * * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus diff --git a/components/esp32s2beta/intr_alloc.c b/components/esp32s2beta/intr_alloc.c index 415a296d7..78b7c776b 100644 --- a/components/esp32s2beta/intr_alloc.c +++ b/components/esp32s2beta/intr_alloc.c @@ -24,11 +24,10 @@ #include "freertos/task.h" #include #include "esp_err.h" -//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE #include "esp_log.h" #include "esp_intr_alloc.h" #include "esp_attr.h" -#include "esp_intr_alloc.h" +#include "soc/soc.h" #include #include diff --git a/components/esp32s2beta/ld/esp32s2beta.common.ld b/components/esp32s2beta/ld/esp32s2beta.common.ld deleted file mode 100644 index 8195d2320..000000000 --- a/components/esp32s2beta/ld/esp32s2beta.common.ld +++ /dev/null @@ -1,253 +0,0 @@ -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - /* RTC fast memory holds RTC wake stub code, - including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - . = ALIGN(4); - *(.rtc.literal .rtc.text) - *rtc_wake_stub*.o(.literal .text .literal.* .text.*) - } > rtc_iram_seg - - /* RTC slow memory holds RTC wake stub - data/rodata, including from any source file - named rtc_wake_stub*.c - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - *(.rtc.data) - *(.rtc.rodata) - *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*) - _rtc_data_end = ABSOLUTE(.); - } > rtc_slow_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - *rtc_wake_stub*.o(.bss .bss.*) - *rtc_wake_stub*.o(COMMON) - _rtc_bss_end = ABSOLUTE(.); - } > rtc_slow_seg - - /* This section holds data that should not be initialized at power up - and will be retained during deep sleep. The section located in - RTC SLOW Memory area. User data marked with RTC_NOINIT_ATTR will be placed - into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - . = ALIGN(4); - _rtc_noinit_start = ABSOLUTE(.); - *(.rtc_noinit .rtc_noinit.*) - . = ALIGN(4) ; - _rtc_noinit_end = ABSOLUTE(.); - } > rtc_slow_seg - - /* Send .iram0 code to iram */ - .iram0.vectors : - { - /* Vectors go to IRAM */ - _init_start = ABSOLUTE(.); - /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ - . = 0x0; - KEEP(*(.WindowVectors.text)); - . = 0x180; - KEEP(*(.Level2InterruptVector.text)); - . = 0x1c0; - KEEP(*(.Level3InterruptVector.text)); - . = 0x200; - KEEP(*(.Level4InterruptVector.text)); - . = 0x240; - KEEP(*(.Level5InterruptVector.text)); - . = 0x280; - KEEP(*(.DebugExceptionVector.text)); - . = 0x2c0; - KEEP(*(.NMIExceptionVector.text)); - . = 0x300; - KEEP(*(.KernelExceptionVector.text)); - . = 0x340; - KEEP(*(.UserExceptionVector.text)); - . = 0x3C0; - KEEP(*(.DoubleExceptionVector.text)); - . = 0x400; - *(.*Vector.literal) - - *(.UserEnter.literal); - *(.UserEnter.text); - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - _init_end = ABSOLUTE(.); - - /* This goes here, not at top of linker script, so addr2line finds it last, - and uses it in preference to the first symbol in IRAM */ - _iram_start = ABSOLUTE(0); - } > iram0_0_seg - - .iram0.text : - { - /* Code marked as runnning out of IRAM */ - _iram_text_start = ABSOLUTE(.); - *(.iram1 .iram1.*) - *libfreertos.a:(.literal .text .literal.* .text.*) - *libheap.a:multi_heap.o(.literal .text .literal.* .text.*) - *libheap.a:multi_heap_poisoning.o(.literal .text .literal.* .text.*) - *libesp32c.a:panic.o(.literal .text .literal.* .text.*) - *libesp32c.a:core_dump.o(.literal .text .literal.* .text.*) - *libapp_trace.a:(.literal .text .literal.* .text.*) - *libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*) - *librtc.a:(.literal .text .literal.* .text.*) - *libsoc.a:(.literal .text .literal.* .text.*) - *libhal.a:(.literal .text .literal.* .text.*) - *libgcc.a:lib2funcs.o(.literal .text .literal.* .text.*) - *libspi_flash.a:spi_flash_rom_patch.o(.literal .text .literal.* .text.*) - *libgcov.a:(.literal .text .literal.* .text.*) - INCLUDE esp32.spiram.rom-functions-iram.ld - _iram_text_end = ABSOLUTE(.); - } > iram0_0_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - *(.dram1 .dram1.*) - *libesp32c.a:panic.o(.rodata .rodata.*) - *libphy.a:(.rodata .rodata.*) - *libsoc.a:rtc_clk.o(.rodata .rodata.*) - *libapp_trace.a:(.rodata .rodata.*) - *libgcov.a:(.rodata .rodata.*) - *libheap.a:multi_heap.o(.rodata .rodata.*) - *libheap.a:multi_heap_poisoning.o(.rodata .rodata.*) - INCLUDE esp32.spiram.rom-functions-dram.ld - _data_end = ABSOLUTE(.); - . = ALIGN(4); - } > dram0_0_seg - - /*This section holds data that should not be initialized at power up. - The section located in Internal SRAM memory region. The macro _NOINIT - can be used as attribute to place data into this section. - See the esp_attr.h file for more information. - */ - .noinit (NOLOAD): - { - . = ALIGN(4); - _noinit_start = ABSOLUTE(.); - *(.noinit .noinit.*) - . = ALIGN(4) ; - _noinit_end = ABSOLUTE(.); - } > dram0_0_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.share.mem) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - /* The heap starts right after end of this section */ - _heap_start = ABSOLUTE(.); - } > dram0_0_seg - - .flash.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - . = (. + 3) & ~ 3; - __eh_frame = ABSOLUTE(.); - KEEP(*(.eh_frame)) - . = (. + 7) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - /* C++ exception handlers table: */ - __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); - *(.xt_except_desc) - *(.gnu.linkonce.h.*) - __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); - *(.xt_except_desc_end) - *(.dynamic) - *(.gnu.version_d) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _thread_local_start = ABSOLUTE(.); - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); - . = ALIGN(4); - } >drom0_0_seg - - .flash.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - _text_end = ABSOLUTE(.); - _etext = .; - - /* Similar to _iram_start, this symbol goes here so it is - resolved by addr2line in preference to the first symbol in - the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } >iram0_2_seg -} diff --git a/components/esp32s2beta/ld/esp32s2beta.project.ld.in b/components/esp32s2beta/ld/esp32s2beta.project.ld.in index 6b10c8694..597b07e81 100644 --- a/components/esp32s2beta/ld/esp32s2beta.project.ld.in +++ b/components/esp32s2beta/ld/esp32s2beta.project.ld.in @@ -15,9 +15,9 @@ SECTIONS *rtc_wake_stub*.*(.literal .text .literal.* .text.*) _rtc_text_end = ABSOLUTE(.); } > rtc_iram_seg - + /* - This section is required to skip rtc.text area because rtc_iram_seg and + This section is required to skip rtc.text area because rtc_iram_seg and rtc_data_seg are reflect the same address space on different buses. */ .rtc.dummy : @@ -28,8 +28,8 @@ SECTIONS _rtc_dummy_end = ABSOLUTE(.); } > rtc_data_seg - /* This section located in RTC FAST Memory area. - It holds data marked with RTC_FAST_ATTR attribute. + /* This section located in RTC FAST Memory area. + It holds data marked with RTC_FAST_ATTR attribute. See the file "esp_attr.h" for more information. */ .rtc.force_fast : @@ -45,7 +45,7 @@ SECTIONS data/rodata, including from any source file named rtc_wake_stub*.c and the data marked with RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - The memory location of the data is dependent on + The memory location of the data is dependent on CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. */ .rtc.data : @@ -70,11 +70,11 @@ SECTIONS _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location - /* This section holds data that should not be initialized at power up + /* This section holds data that should not be initialized at power up and will be retained during deep sleep. User data marked with RTC_NOINIT_ATTR will be placed - into this section. See the file "esp_attr.h" for more information. - The memory location of the data is dependent on + into this section. See the file "esp_attr.h" for more information. + The memory location of the data is dependent on CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. */ .rtc_noinit (NOLOAD): @@ -86,8 +86,8 @@ SECTIONS _rtc_noinit_end = ABSOLUTE(.); } > rtc_data_location - /* This section located in RTC SLOW Memory area. - It holds data marked with RTC_SLOW_ATTR attribute. + /* This section located in RTC SLOW Memory area. + It holds data marked with RTC_SLOW_ATTR attribute. See the file "esp_attr.h" for more information. */ .rtc.force_slow : @@ -100,17 +100,17 @@ SECTIONS } > rtc_slow_seg /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_slow_end - _rtc_data_start) : (_rtc_force_slow_end - _rtc_force_slow_start); - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_fast_end - _rtc_fast_start) : (_rtc_noinit_end - _rtc_fast_start); - + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), "RTC_SLOW segment data does not fit.") - + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), "RTC_FAST segment data does not fit.") @@ -203,7 +203,7 @@ SECTIONS { . = ALIGN(4); _noinit_start = ABSOLUTE(.); - *(.noinit .noinit.*) + *(.noinit .noinit.*) . = ALIGN(4) ; _noinit_end = ABSOLUTE(.); } > dram0_0_seg @@ -245,7 +245,7 @@ SECTIONS ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") - + .flash.rodata : { _rodata_start = ABSOLUTE(.); diff --git a/components/esp32s2beta/pm_esp32s2beta.c b/components/esp32s2beta/pm_esp32s2beta.c index 64b960c6f..3b14d1a41 100644 --- a/components/esp32s2beta/pm_esp32s2beta.c +++ b/components/esp32s2beta/pm_esp32s2beta.c @@ -34,7 +34,7 @@ #include "esp_private/pm_impl.h" #include "esp_private/pm_trace.h" #include "esp_private/esp_timer_impl.h" -#include "esp32/pm.h" +#include "esp32s2beta/pm.h" /* CCOMPARE update timeout, in CPU cycles. Any value above ~600 cycles will work * for the purpose of detecting a deadlock. @@ -449,6 +449,24 @@ void esp_pm_impl_idle_hook() ESP_PM_TRACE_ENTER(IDLE, core_id); } +void esp_pm_impl_waiti() +{ +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + int core_id = xPortGetCoreID(); + if (s_skipped_light_sleep[core_id]) { + asm("waiti 0"); + /* Interrupt took the CPU out of waiti and s_rtos_lock_handle[core_id] + * is now taken. However since we are back to idle task, we can release + * the lock so that vApplicationSleep can attempt to enter light sleep. + */ + esp_pm_impl_idle_hook(); + s_skipped_light_sleep[core_id] = false; + } +#else + asm("waiti 0"); +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +} + void IRAM_ATTR esp_pm_impl_isr_hook() { int core_id = xPortGetCoreID(); diff --git a/components/esp32s2beta/sleep_modes.c b/components/esp32s2beta/sleep_modes.c index 7820b2d8f..7fd84d918 100644 --- a/components/esp32s2beta/sleep_modes.c +++ b/components/esp32s2beta/sleep_modes.c @@ -25,6 +25,7 @@ #include "esp32s2beta/rom/cache.h" #include "esp32s2beta/rom/rtc.h" #include "esp32s2beta/rom/uart.h" +#include "esp32s2beta/rom/ets_sys.h" #include "soc/cpu.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" diff --git a/components/esp32s2beta/system_api.c b/components/esp32s2beta/system_api.c index 18af5e02f..4a99428d7 100644 --- a/components/esp32s2beta/system_api.c +++ b/components/esp32s2beta/system_api.c @@ -365,3 +365,4 @@ void esp_chip_info(esp_chip_info_t* out_info) out_info->features = CHIP_FEATURE_WIFI_BGN; // FIXME: other features? +} diff --git a/components/esp32s2beta/task_wdt.c b/components/esp32s2beta/task_wdt.c index e3a37d479..b73a30883 100644 --- a/components/esp32s2beta/task_wdt.c +++ b/components/esp32s2beta/task_wdt.c @@ -179,7 +179,7 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic) twdt_config->panic = panic; //Register Interrupt and ISR - ESP_ERROR_CHECK(esp_intr_alloc(ETS_TG0_WDT_LEVEL_INTR_SOURCE, 0, task_wdt_isr, NULL, &twdt_config->intr_handle)) + ESP_ERROR_CHECK(esp_intr_alloc(ETS_TG0_WDT_LEVEL_INTR_SOURCE, 0, task_wdt_isr, NULL, &twdt_config->intr_handle)); //Configure hardware timer periph_module_enable(PERIPH_TIMG0_MODULE); @@ -227,7 +227,7 @@ esp_err_t esp_task_wdt_deinit() TIMERG0.wdt_config0.en=0; //Disable timer TIMERG0.wdt_wprotect=0; //Enable write protection - ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)) //Unregister interrupt + ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)); //Unregister interrupt free(twdt_config); //Free twdt_config twdt_config = NULL; portEXIT_CRITICAL(&twdt_spinlock); @@ -269,7 +269,7 @@ esp_err_t esp_task_wdt_add(TaskHandle_t handle) //If idle task, register the idle hook callback to appropriate core for(int i = 0; i < portNUM_PROCESSORS; i++){ if(handle == xTaskGetIdleTaskHandleForCPU(i)){ - ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_hook_cb, i)) + ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_hook_cb, i)); break; } } diff --git a/components/esp_adc_cal/CMakeLists.txt b/components/esp_adc_cal/CMakeLists.txt index 8bb99092e..1cfe856a1 100644 --- a/components/esp_adc_cal/CMakeLists.txt +++ b/components/esp_adc_cal/CMakeLists.txt @@ -1,3 +1,6 @@ +if(IDF_TARGET STREQUAL "esp32s2beta") + return() +endif() set(COMPONENT_SRCS "esp_adc_cal.c") set(COMPONENT_ADD_INCLUDEDIRS "include") diff --git a/components/esp_common/include/esp_pm.h b/components/esp_common/include/esp_pm.h index 3887e77a9..6bf9f09d9 100644 --- a/components/esp_common/include/esp_pm.h +++ b/components/esp_common/include/esp_pm.h @@ -16,9 +16,12 @@ #include #include #include "esp_err.h" - -// Include SoC-specific definitions. Only ESP32 supported for now. +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/pm.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/pm.h" +#endif #ifdef __cplusplus extern "C" { diff --git a/components/esp_common/src/ets_timer_legacy.c b/components/esp_common/src/ets_timer_legacy.c index 506f2c53c..c08ecf3dd 100644 --- a/components/esp_common/src/ets_timer_legacy.c +++ b/components/esp_common/src/ets_timer_legacy.c @@ -24,7 +24,6 @@ #include "esp_log.h" #include "esp_attr.h" #include "esp_intr_alloc.h" -#include "esp32/rom/ets_sys.h" #include "soc/frc_timer_reg.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -33,6 +32,11 @@ #include "sdkconfig.h" #include "esp_timer.h" #include "esp_private/esp_timer_impl.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif /* We abuse 'timer_arg' field of ETSTimer structure to hold a pointer to esp_timer */ #define ESP_TIMER(p_ets_timer) ((esp_timer_handle_t) (p_ets_timer)->timer_arg) diff --git a/components/esp_event/CMakeLists.txt b/components/esp_event/CMakeLists.txt index d6d58eb77..834ecea54 100644 --- a/components/esp_event/CMakeLists.txt +++ b/components/esp_event/CMakeLists.txt @@ -8,7 +8,7 @@ set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_PRIV_INCLUDEDIRS "private_include") set(COMPONENT_REQUIRES log tcpip_adapter) -if(CONFIG_IDF_TARGET_ESP32) +if(IDF_TARGET STREQUAL "esp32") set(COMPONENT_PRIV_REQUIRES ethernet) endif() diff --git a/components/esp_event/event_send_compat.inc b/components/esp_event/event_send_compat.inc index 42b4daf47..701103b0b 100644 --- a/components/esp_event/event_send_compat.inc +++ b/components/esp_event/event_send_compat.inc @@ -17,7 +17,9 @@ #include "esp_event_legacy.h" #include "esp_wifi_types.h" #include "tcpip_adapter.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp_eth.h" +#endif /** * The purpose of this file is to provide an "esp_event_send_to_default_loop" @@ -87,7 +89,7 @@ esp_err_t esp_event_send_to_default_loop(system_event_t *event) HANDLE_SYS_EVENT_ARG(WIFI, AP_STACONNECTED, sta_connected); HANDLE_SYS_EVENT_ARG(WIFI, AP_STADISCONNECTED, sta_disconnected); HANDLE_SYS_EVENT_ARG(WIFI, AP_PROBEREQRECVED, ap_probereqrecved); - +#if CONFIG_IDF_TARGET_ESP32 /* Ethernet events */ /* Some extra defines to fit the old naming scheme... */ #define ETH_EVENT_ETH_START ETHERNET_EVENT_START @@ -99,7 +101,7 @@ esp_err_t esp_event_send_to_default_loop(system_event_t *event) HANDLE_SYS_EVENT(ETH, ETH_STOP); HANDLE_SYS_EVENT(ETH, ETH_CONNECTED); HANDLE_SYS_EVENT(ETH, ETH_DISCONNECTED); - +#endif /* IP events */ HANDLE_SYS_EVENT_ARG(IP, STA_GOT_IP, got_ip); HANDLE_SYS_EVENT_ARG(IP, ETH_GOT_IP, got_ip); @@ -119,9 +121,9 @@ typedef struct { int err; const char *reason; } wifi_reason_t; - + static const wifi_reason_t wifi_reason[] = -{ +{ {0, "other reason"}, {WIFI_REASON_UNSPECIFIED, "unspecified"}, {WIFI_REASON_AUTH_EXPIRE, "auth expire"}, @@ -150,9 +152,9 @@ static const wifi_reason_t wifi_reason[] = {WIFI_REASON_UNSUPP_RSN_IE_VERSION, "unsupported RSN IE version"}, {WIFI_REASON_INVALID_RSN_IE_CAP, "invalid RSN IE capability"}, {WIFI_REASON_802_1X_AUTH_FAILED, "802.1x auth failed"}, - {WIFI_REASON_CIPHER_SUITE_REJECTED, "cipher suite rejected"} + {WIFI_REASON_CIPHER_SUITE_REJECTED, "cipher suite rejected"} }; - + static const char* wifi_disconnect_reason_to_str(int err) { for (int i=0; i< sizeof(wifi_reason)/sizeof(wifi_reason[0]); i++){ @@ -277,6 +279,7 @@ static void esp_system_event_debug(const system_event_t* event) IP6_ADDR_BLOCK8(addr)); break; } +#if CONFIG_IDF_TARGET_ESP32 case SYSTEM_EVENT_ETH_START: { ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_START"); break; @@ -301,6 +304,7 @@ static void esp_system_event_debug(const system_event_t* event) IP2STR(&got_ip->ip_info.gw)); break; } +#endif default: { ESP_LOGW(TAG, "unexpected system event %d!", event->event_id); break; diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 283aba6a9..73b77702a 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -23,7 +23,7 @@ else() register_component() - if (CONFIG_IDF_TARGET_ESP32) + if (IDF_TARGET STREQUAL "esp32") set(scripts "esp32/ld/esp32.rom.ld" "esp32/ld/esp32.rom.libgcc.ld" @@ -48,14 +48,12 @@ else() target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld") endif() - elseif(CONFIG_IDF_TARGET_ESP32S2BETA) - target_linker_script(${COMPONENT_LIB} - "esp32s2beta/ld/esp32s2beta.rom.ld" - "esp32s2beta/ld/esp32s2beta.rom.nanofmt.ld" - "esp32s2beta/ld/esp32s2beta.rom.spiflash.ld" - "esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld" - "esp32s2beta/ld/esp32s2beta.spiram.rom-functions-dram.ld" - "esp32s2beta/ld/esp32s2beta.spiram.rom-functions-iram.ld") + elseif(IDF_TARGET STREQUAL "esp32s2beta") + set(scripts "esp32s2beta/ld/esp32s2beta.rom.ld" + "esp32s2beta/ld/esp32s2beta.rom.nanofmt.ld" + "esp32s2beta/ld/esp32s2beta.rom.spiflash.ld" + "esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld") + target_linker_script(${COMPONENT_LIB} "${scripts}") endif() endif() diff --git a/components/esp_rom/include/esp32/rom/rtc.h b/components/esp_rom/include/esp32/rom/rtc.h index 6d9d29774..83e621631 100644 --- a/components/esp_rom/include/esp32/rom/rtc.h +++ b/components/esp_rom/include/esp32/rom/rtc.h @@ -21,6 +21,7 @@ #include #include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_rom/include/esp32s2beta/rom/aes.h b/components/esp_rom/include/esp32s2beta/rom/aes.h index 5639fc67b..9350e2511 100644 --- a/components/esp_rom/include/esp32s2beta/rom/aes.h +++ b/components/esp_rom/include/esp32s2beta/rom/aes.h @@ -19,8 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _ROM_AES_H_ -#define _ROM_AES_H_ +#pragma once #include #include @@ -61,5 +60,3 @@ void ets_aes_block(const void *input, void *output); #ifdef __cplusplus } #endif - -#endif /* _ROM_AES_H_ */ diff --git a/components/esp_rom/include/esp32s2beta/rom/ets_sys.h b/components/esp_rom/include/esp32s2beta/rom/ets_sys.h index 73301ba6f..653ca2826 100644 --- a/components/esp_rom/include/esp32s2beta/rom/ets_sys.h +++ b/components/esp_rom/include/esp32s2beta/rom/ets_sys.h @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _ROM_ETS_SYS_H_ -#define _ROM_ETS_SYS_H_ +#pragma once #include #include @@ -608,5 +607,3 @@ typedef enum { #ifdef __cplusplus } #endif - -#endif /* _ROM_ETS_SYS_H_ */ diff --git a/components/esp_rom/include/esp32s2beta/rom/rtc.h b/components/esp_rom/include/esp32s2beta/rom/rtc.h index 89fdb128a..3406eab33 100644 --- a/components/esp_rom/include/esp32s2beta/rom/rtc.h +++ b/components/esp_rom/include/esp32s2beta/rom/rtc.h @@ -21,6 +21,7 @@ #include #include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" #ifdef __cplusplus extern "C" { @@ -174,10 +175,10 @@ void set_rtc_memory_crc(void); /** * @brief Fetch entry from RTC memory and RTC STORE reg * - * @param uint32_t * entry_addr : the address to save entry + * @param uint32_t * entry_addr : the address to save entry * * @param RESET_REASON reset_reason : reset reason this time - * + * * @return None */ void rtc_boot_control(uint32_t * entry_addr, RESET_REASON reset_reason); diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index be99e00d8..5c9fbf2be 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -22,7 +22,9 @@ if(NOT CONFIG_ESP32_NO_BLOBS) set(blobs coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps) foreach(blob ${blobs}) add_library(${blob} STATIC IMPORTED) - set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}/lib${blob}.a) + # set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}/lib${blob}.a) + # ToDo: add lib_esp32s2beta in esp_wifi component + set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_esp32/lib${blob}.a) target_link_libraries(${COMPONENT_LIB} ${blob}) foreach(_blob ${blobs}) diff --git a/components/espcoredump/src/core_dump_uart.c b/components/espcoredump/src/core_dump_uart.c index d3afbe5d0..6b94e75c5 100644 --- a/components/espcoredump/src/core_dump_uart.c +++ b/components/espcoredump/src/core_dump_uart.c @@ -15,8 +15,12 @@ #include "soc/uart_periph.h" #include "soc/gpio_periph.h" #include "driver/gpio.h" -#include "esp32/clk.h" #include "esp_core_dump_priv.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#endif const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_uart"; diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index b4c418a5d..cd3866610 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit b4c418a5d90c94863b44c8661b9332cf229b08b7 +Subproject commit cd386661033d25521b1312cf7fa4699ff4719f77 diff --git a/components/esptool_py/project_include.cmake b/components/esptool_py/project_include.cmake index d6c888f43..b284845f7 100644 --- a/components/esptool_py/project_include.cmake +++ b/components/esptool_py/project_include.cmake @@ -50,7 +50,7 @@ if(CONFIG_SECURE_BOOT_ENABLED AND endif() if(NOT BOOTLOADER_BUILD) - set(ESPTOOLPY_ELF2IMAGE_OPTIONS --elf-sha256-offset 0xb0) + # set(ESPTOOLPY_ELF2IMAGE_OPTIONS --elf-sha256-offset 0xb0) endif() if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT) diff --git a/components/ethernet/CMakeLists.txt b/components/ethernet/CMakeLists.txt index 704d21a7d..8fb148cfe 100644 --- a/components/ethernet/CMakeLists.txt +++ b/components/ethernet/CMakeLists.txt @@ -1,12 +1,14 @@ -set(COMPONENT_SRCS "emac_dev.c" - "emac_main.c" - "eth_phy/phy_common.c" - "eth_phy/phy_lan8720.c" - "eth_phy/phy_tlk110.c" - "eth_phy/phy_ip101.c") -set(COMPONENT_ADD_INCLUDEDIRS "include") +if(IDF_TARGET STREQUAL "esp32") + set(COMPONENT_SRCS "emac_dev.c" + "emac_main.c" + "eth_phy/phy_common.c" + "eth_phy/phy_lan8720.c" + "eth_phy/phy_tlk110.c" + "eth_phy/phy_ip101.c") + set(COMPONENT_ADD_INCLUDEDIRS "include") -set(COMPONENT_REQUIRES) -set(COMPONENT_PRIV_REQUIRES tcpip_adapter esp_event soc) + set(COMPONENT_REQUIRES) + set(COMPONENT_PRIV_REQUIRES tcpip_adapter esp_event soc) -register_component() + register_component() +endif() diff --git a/components/freemodbus/port/porttimer.c b/components/freemodbus/port/porttimer.c index 2859aa016..dc6216a55 100644 --- a/components/freemodbus/port/porttimer.c +++ b/components/freemodbus/port/porttimer.c @@ -45,10 +45,10 @@ #include "port.h" /* ----------------------- Modbus includes ----------------------------------*/ +#include "sdkconfig.h" #include "mb.h" #include "mbport.h" #include "driver/timer.h" -#include "sdkconfig.h" #include "port_serial_slave.h" #ifdef CONFIG_FMB_TIMER_PORT_ENABLED @@ -71,9 +71,17 @@ static void IRAM_ATTR vTimerGroupIsr(void *param) { // Retrieve the interrupt status and the counter value // from the timer that reported the interrupt +#if CONFIG_IDF_TARGET_ESP32 uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st.val; +#endif if (intr_status & BIT(usTimerIndex)) { +#if CONFIG_IDF_TARGET_ESP32 MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + MB_TG[usTimerGroupIndex]->int_clr.val |= BIT(usTimerIndex); +#endif (void)pxMBPortCBTimerExpired(); // Timer callback function MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN; } diff --git a/components/freemodbus/port/porttimer_m.c b/components/freemodbus/port/porttimer_m.c index c2b5b423c..0f268945d 100644 --- a/components/freemodbus/port/porttimer_m.c +++ b/components/freemodbus/port/porttimer_m.c @@ -40,6 +40,7 @@ #include "mb_m.h" #include "mbport.h" #include "port_serial_master.h" +#include "sdkconfig.h" #define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks #define MB_TICK_TIME_US (50) // 50uS = one tick for timer @@ -69,10 +70,22 @@ static void IRAM_ATTR vTimerGroupIsr(void *param) { // Retrieve the interrupt status and the counter value // from the timer that reported the interrupt +#if CONFIG_IDF_TARGET_ESP32 uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st.val; +#endif if (intr_status & BIT(usTimerIndex)) { +#if CONFIG_IDF_TARGET_ESP32 MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + MB_TG[usTimerGroupIndex]->int_clr.val |= BIT(usTimerIndex); +#endif +#if CONFIG_IDF_TARGET_ESP32 MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update = 1; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update.update = 1; +#endif (void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function // Enable alarm MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN; diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index bd3c72db5..884dde32f 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -76,7 +76,7 @@ /* ESP31 and ESP32 are dualcore processors. */ #ifndef CONFIG_FREERTOS_UNICORE #define portNUM_PROCESSORS 2 -#else +#else #define portNUM_PROCESSORS 1 #endif @@ -117,7 +117,11 @@ int xt_clock_freq(void) __attribute__((deprecated)); /* configASSERT behaviour */ #ifndef __ASSEMBLER__ #include /* for abort() */ +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #if defined(CONFIG_FREERTOS_ASSERT_DISABLE) #define configASSERT(a) /* assertions disabled */ @@ -155,7 +159,7 @@ int xt_clock_freq(void) __attribute__((deprecated)); * memory. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 diff --git a/components/freertos/include/freertos/portmacro.h b/components/freertos/include/freertos/portmacro.h index 183d38a4d..7eb9bf476 100644 --- a/components/freertos/include/freertos/portmacro.h +++ b/components/freertos/include/freertos/portmacro.h @@ -349,12 +349,14 @@ static inline unsigned portENTER_CRITICAL_NESTED() { * ESP32 (portMUX assertions would fail). */ static inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { +#ifndef CONFIG_FREERTOS_UNICORE __asm__ __volatile__ ( "WSR %2,SCOMPARE1 \n" "S32C1I %0, %1, 0 \n" :"=r"(*set) :"r"(addr), "r"(compare), "0"(*set) ); +#endif } diff --git a/components/freertos/port.c b/components/freertos/port.c index 04e5efa30..6e99de3c0 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -97,7 +97,6 @@ #include "xtensa_rtos.h" -#include "esp32/rom/ets_sys.h" #include "soc/cpu.h" #include "FreeRTOS.h" @@ -109,6 +108,12 @@ #include "esp_intr_alloc.h" #include "esp_log.h" +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif /* Defined in portasm.h */ extern void _frxt_tick_timer_init(void); diff --git a/components/freertos/queue.c b/components/freertos/queue.c index 1859dbd1d..82e7d988e 100644 --- a/components/freertos/queue.c +++ b/components/freertos/queue.c @@ -78,8 +78,12 @@ #include #include - +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining all the API functions to use the MPU wrappers. That should only be done when diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 91c761664..026945880 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -70,13 +70,17 @@ /* Standard includes. */ #include #include +#include "sdkconfig.h" /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining all the API functions to use the MPU wrappers. That should only be done when task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #include "esp_newlib.h" #include "esp_debug_helpers.h" diff --git a/components/freertos/xtensa_init.c b/components/freertos/xtensa_init.c index c503b7c37..b8cd5f7ff 100644 --- a/components/freertos/xtensa_init.c +++ b/components/freertos/xtensa_init.c @@ -30,11 +30,16 @@ that are implemented in C. #ifdef XT_BOARD -#include +#include "xtensa/xtbsp.h" #endif -#include "xtensa_rtos.h" -#include "esp32/clk.h" +#include "xtensa_rtos.h" +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#endif #ifdef XT_RTOS_TIMER_INT diff --git a/components/freertos/xtensa_intr.c b/components/freertos/xtensa_intr.c index 03979f48a..d3fcea9c7 100644 --- a/components/freertos/xtensa_intr.c +++ b/components/freertos/xtensa_intr.c @@ -33,8 +33,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "freertos/FreeRTOS.h" #include "freertos/xtensa_api.h" #include "freertos/portable.h" - +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #if XCHAL_HAVE_EXCEPTIONS diff --git a/components/heap/multi_heap_platform.h b/components/heap/multi_heap_platform.h index a3a0acc67..19215288a 100644 --- a/components/heap/multi_heap_platform.h +++ b/components/heap/multi_heap_platform.h @@ -16,7 +16,12 @@ #ifdef ESP_PLATFORM #include -#include +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #include /* Because malloc/free can happen inside an ISR context, diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index 21ebbdf23..37dadf2b0 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -18,7 +18,11 @@ #include #include #include "sdkconfig.h" -#include +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #ifdef __cplusplus extern "C" { @@ -154,15 +158,15 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, . /** * @brief Dump a buffer to the log at specified level. - * + * * The dump log shows just like the one below: - * + * * W (195) log_example: 0x3ffb4280 45 53 50 33 32 20 69 73 20 67 72 65 61 74 2c 20 |ESP32 is great, | * W (195) log_example: 0x3ffb4290 77 6f 72 6b 69 6e 67 20 61 6c 6f 6e 67 20 77 69 |working along wi| * W (205) log_example: 0x3ffb42a0 74 68 20 74 68 65 20 49 44 46 2e 00 |th the IDF..| - * + * * It is highly recommend to use terminals with over 102 text width. - * + * * @param tag description tag * @param buffer Pointer to the buffer array * @param buff_len length of buffer in bytes @@ -287,7 +291,7 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, . #endif // BOOTLOADER_BUILD /** runtime macro to output logs at a specified level. - * + * * @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime. * @param level level of the output log. * @param format format of the output log. see ``printf`` diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 3b1fd504e..aef65d2e1 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(idf_target IDF_TARGET) + set(COMPONENT_ADD_INCLUDEDIRS "port/include" "mbedtls/include") set(COMPONENT_SRCS "mbedtls.c") set(COMPONENT_REQUIRES lwip) @@ -79,16 +81,16 @@ set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls}) set(mbedtls_targets mbedtls mbedcrypto mbedx509) # Add port files to mbedtls targets -target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/esp_bignum.c" - "${COMPONENT_DIR}/port/esp_hardware.c" +target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" "${COMPONENT_PATH}/port/esp_sha.c" "${COMPONENT_DIR}/port/esp_sha1.c" "${COMPONENT_DIR}/port/esp_sha256.c" "${COMPONENT_DIR}/port/esp_sha512.c" "${COMPONENT_DIR}/port/mbedtls_debug.c" "${COMPONENT_DIR}/port/net_sockets.c" - "${COMPONENT_DIR}/port/esp32/aes.c" - "${COMPONENT_DIR}/port/esp32/sha.c") + "${COMPONENT_DIR}/port/${idf_target}/aes.c" + "${COMPONENT_DIR}/port/${idf_target}/sha.c" + "${COMPONENT_DIR}/port/${idf_target}/esp_bignum.c") target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_mem.c") foreach(target ${mbedtls_targets}) @@ -101,4 +103,4 @@ target_link_libraries(${COMPONENT_LIB} ${mbedtls_targets}) # Catch usage of deprecated mbedTLS functions when building tests if(mbedtls_test IN_LIST BUILD_TEST_COMPONENTS) add_definitions(-DMBEDTLS_DEPRECATED_WARNING) -endif() \ No newline at end of file +endif() diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index 09ce80c96..f21c94660 100644 --- a/components/mbedtls/component.mk +++ b/components/mbedtls/component.mk @@ -4,7 +4,7 @@ COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include -COMPONENT_SRCDIRS := mbedtls/library port port/esp32 +COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET) COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp32/esp_bignum.c similarity index 100% rename from components/mbedtls/port/esp_bignum.c rename to components/mbedtls/port/esp32/esp_bignum.c diff --git a/components/mbedtls/port/esp32s2beta/aes.c b/components/mbedtls/port/esp32s2beta/aes.c index 9384b12a7..2740b45a2 100644 --- a/components/mbedtls/port/esp32s2beta/aes.c +++ b/components/mbedtls/port/esp32s2beta/aes.c @@ -27,7 +27,7 @@ */ #include #include "mbedtls/aes.h" -#include "hwcrypto/aes.h" +#include "esp32s2beta/aes.h" #include "soc/dport_reg.h" #include "soc/hwcrypto_reg.h" #include diff --git a/components/mbedtls/port/esp32s2beta/esp_bignum.c b/components/mbedtls/port/esp32s2beta/esp_bignum.c new file mode 100644 index 000000000..58fdce67a --- /dev/null +++ b/components/mbedtls/port/esp32s2beta/esp_bignum.c @@ -0,0 +1,613 @@ +/** + * \brief Multi-precision integer library, ESP32C hardware accelerated parts + * + * based on mbedTLS implementation + * + * 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include "mbedtls/bignum.h" +#include "esp32s2beta/rom/bigint.h" +#include "soc/hwcrypto_reg.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_intr.h" +#include "esp_intr_alloc.h" +#include "esp_attr.h" + +#include "soc/dport_reg.h" +#include "soc/periph_defs.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +static const __attribute__((unused)) char *TAG = "bignum"; + +#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ + +#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT) +static SemaphoreHandle_t op_complete_sem; + +static IRAM_ATTR void rsa_complete_isr(void *arg) +{ + BaseType_t higher_woken; + DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); + xSemaphoreGiveFromISR(op_complete_sem, &higher_woken); + if (higher_woken) { + portYIELD_FROM_ISR(); + } +} + +static void rsa_isr_initialise() +{ + if (op_complete_sem == NULL) { + op_complete_sem = xSemaphoreCreateBinary(); + esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, rsa_complete_isr, NULL, NULL); + } +} + +#endif /* CONFIG_MBEDTLS_MPI_USE_INTERRUPT */ + +static _lock_t mpi_lock; + +void esp_mpi_acquire_hardware( void ) +{ + /* newlib locks lazy initialize on ESP-IDF */ + _lock_acquire(&mpi_lock); + + DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_CLK_EN_RSA); + /* also clear reset on digital signature & secure boot, otherwise RSA is held in reset */ + DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_RST_EN_RSA + | DPORT_RST_EN_DIGITAL_SIGNATURE + | DPORT_RST_EN_SECURE_BOOT); + + DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD); + + while(DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) { + } + // Note: from enabling RSA clock to here takes about 1.3us + +#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT + rsa_isr_initialise(); +#endif +} + +void esp_mpi_release_hardware( void ) +{ + DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); + + /* don't reset digital signature unit, as this resets AES also */ + DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA); + DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA); + + _lock_release(&mpi_lock); +} + + +/* Return the number of words actually used to represent an mpi + number. +*/ +static size_t mpi_words(const mbedtls_mpi *mpi) +{ + for (size_t i = mpi->n; i > 0; i--) { + if (mpi->p[i - 1] != 0) { + return i; + } + } + return 0; +} + +/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. + + If num_words is higher than the number of words in the bignum then + these additional words will be zeroed in the memory buffer. + + As this function only writes to DPORT memory, no DPORT_STALL_OTHER_CPU_START() + is required. +*/ +static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) +{ + uint32_t *pbase = (uint32_t *)mem_base; + uint32_t copy_words = num_words < mpi->n ? num_words : mpi->n; + + /* Copy MPI data to memory block registers */ + for (int i = 0; i < copy_words; i++) { + pbase[i] = mpi->p[i]; + } + + /* Zero any remaining memory block data */ + for (int i = copy_words; i < num_words; i++) { + pbase[i] = 0; + } + + /* Note: not executing memw here, can do it before we start a bignum operation */ +} + +/* Read mbedTLS MPI bignum back from hardware memory block. + + Reads num_words words from block. + + Can return a failure result if fails to grow the MPI result. + + Cannot be called inside DPORT_STALL_OTHER_CPU_START() (as may allocate memory). +*/ +static inline int mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) +{ + int ret = 0; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow(x, num_words) ); + + /* Copy data from memory block registers */ + esp_dport_access_read_buffer(x->p, mem_base, num_words); + /* Zero any remaining limbs in the bignum, if the buffer is bigger + than num_words */ + for(size_t i = num_words; i < x->n; i++) { + x->p[i] = 0; + } + + asm volatile ("memw"); + cleanup: + return ret; +} + + +/** + * + * There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1, + * where B^-1(B-1) mod N=1. Actually, only the least significant part of + * N' is needed, hence the definition N0'=N' mod b. We reproduce below the + * simple algorithm from an article by Dusse and Kaliski to efficiently + * find N0' from N0 and b + */ +static mbedtls_mpi_uint modular_inverse(const mbedtls_mpi *M) +{ + int i; + uint64_t t = 1; + uint64_t two_2_i_minus_1 = 2; /* 2^(i-1) */ + uint64_t two_2_i = 4; /* 2^i */ + uint64_t N = M->p[0]; + + for (i = 2; i <= 32; i++) { + if ((mbedtls_mpi_uint) N * t % two_2_i >= two_2_i_minus_1) { + t += two_2_i_minus_1; + } + + two_2_i_minus_1 <<= 1; + two_2_i <<= 1; + } + + return (mbedtls_mpi_uint)(UINT32_MAX - t + 1); +} + +/* Calculate Rinv = RR^2 mod M, where: + * + * R = b^n where b = 2^32, n=num_words, + * R = 2^N (where N=num_bits) + * RR = R^2 = 2^(2*N) (where N=num_bits=num_words*32) + * + * This calculation is computationally expensive (mbedtls_mpi_mod_mpi) + * so caller should cache the result where possible. + * + * DO NOT call this function while holding esp_mpi_acquire_hardware(). + * + */ +static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words) +{ + int ret; + size_t num_bits = num_words * 32; + mbedtls_mpi RR; + mbedtls_mpi_init(&RR); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&RR, num_bits * 2, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(Rinv, &RR, M)); + + cleanup: + mbedtls_mpi_free(&RR); + return ret; +} + + +/* Begin an RSA operation. op_reg specifies which 'START' register + to write to. + + Because the only DPORT operations here are writes, + does not need protecting via DPORT_STALL_OTHER_CPU_START(); +*/ +static inline void start_op(uint32_t op_reg) +{ + /* Clear interrupt status */ + DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); + + /* Note: above REG_WRITE includes a memw, so we know any writes + to the memory blocks are also complete. */ + + DPORT_REG_WRITE(op_reg, 1); +} + +/* Wait for an RSA operation to complete. + + This should NOT be called inside a DPORT_STALL_OTHER_CPU_START(), as it will stall the other CPU for an unacceptably long + period (and - depending on config - may require interrupts enabled). +*/ +static inline void wait_op_complete(uint32_t op_reg) +{ +#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT + if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) { + ESP_LOGE(TAG, "Timed out waiting for RSA operation (op_reg 0x%x int_reg 0x%x)", + op_reg, DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG)); + abort(); /* indicates a fundamental problem with driver */ + } +#else + while(DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1) + { } + + /* clear the interrupt */ + DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); +#endif + +} + +/* Z = (X * Y) mod M + + Not an mbedTLS function +*/ +int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M) +{ + int ret; + size_t m_words = mpi_words(M); + mbedtls_mpi Rinv; + mbedtls_mpi_uint Mprime; + + size_t num_words = MAX(MAX(m_words, mpi_words(X)), mpi_words(Y)); + + if (num_words * 32 > 4096) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } + + /* Calculate and load the first stage montgomery multiplication */ + mbedtls_mpi_init(&Rinv); + MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, m_words)); + Mprime = modular_inverse(M); + + esp_mpi_acquire_hardware(); + + DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); + DPORT_REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime); + + /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ + mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); + mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, &Rinv, num_words); + + /* Execute first stage montgomery multiplication */ + start_op(RSA_MOD_MULT_START_REG); + + wait_op_complete(RSA_MOD_MULT_START_REG); + + mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words); + + esp_mpi_release_hardware(); + + cleanup: + mbedtls_mpi_free(&Rinv); + return ret; +} + +#if defined(MBEDTLS_MPI_EXP_MOD_ALT) + +/* + * Sliding-window exponentiation: Z = X^Y mod M (HAC 14.85) + * + * _Rinv is optional pre-calculated version of Rinv (via calculate_rinv()). + * + * (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) + * + */ +int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, mbedtls_mpi* _Rinv ) +{ + int ret = 0; + size_t x_words = mpi_words(X); + size_t y_words = mpi_words(Y); + size_t m_words = mpi_words(M); + size_t num_words; + + mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */ + mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */ + mbedtls_mpi_uint Mprime; + + /* "all numbers must be the same length", so choose longest number + as cardinal length of operation... + */ + num_words = MAX(m_words, MAX(x_words, y_words)); + + if (num_words * 32 > 4096) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } + + /* Determine RR pointer, either _RR for cached value + or local RR_new */ + if (_Rinv == NULL) { + mbedtls_mpi_init(&Rinv_new); + Rinv = &Rinv_new; + } else { + Rinv = _Rinv; + } + if (Rinv->p == NULL) { + MBEDTLS_MPI_CHK(calculate_rinv(Rinv, M, num_words)); + } + + Mprime = modular_inverse(M); + + esp_mpi_acquire_hardware(); + + DPORT_REG_WRITE(RSA_LENGTH_REG, num_words - 1); + + /* Load M, X, Rinv, M-prime (M-prime is mod 2^32) */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); + mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); + mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); + DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); + + DPORT_REG_WRITE(RSA_CONSTANT_TIME_DISABLE_REG, 1); + DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1); + DPORT_REG_WRITE(RSA_SEARCH_POS_REG, (y_words * 32) - 1); + + start_op(RSA_MODEXP_START_REG); + wait_op_complete(RSA_MODEXP_START_REG); + + DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 0); + DPORT_REG_WRITE(RSA_SEARCH_POS_REG, (m_words * 32) - 1); + + ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words); + + esp_mpi_release_hardware(); + + cleanup: + if (_Rinv == NULL) { + mbedtls_mpi_free(&Rinv_new); + } + + return ret; +} + +#endif /* MBEDTLS_MPI_EXP_MOD_ALT */ + +#if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */ + +static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words); +static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t Y_bits, size_t words_result); + +/* Z = X * Y */ +int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y ) +{ + int ret = 0; + size_t bits_x, bits_y, words_x, words_y, words_mult, words_z; + + /* Count words needed for X & Y in hardware */ + bits_x = mbedtls_mpi_bitlen(X); + bits_y = mbedtls_mpi_bitlen(Y); + + words_x = (bits_x + 7) / 8; + words_y = (bits_y + 7) / 8; + + /* Short-circuit eval if either argument is 0 or 1. + + This is needed as the mpi modular division + argument will sometimes call in here when one + argument is too large for the hardware unit, but the other + argument is zero or one. + + This leaks some timing information, although overall there is a + lot less timing variation than a software MPI approach. + */ + if (bits_x == 0 || bits_y == 0) { + mbedtls_mpi_lset(Z, 0); + return 0; + } + if (bits_x == 1) { + ret = mbedtls_mpi_copy(Z, Y); + Z->s *= X->s; + return ret; + } + if (bits_y == 1) { + ret = mbedtls_mpi_copy(Z, X); + Z->s *= Y->s; + return ret; + } + + words_mult = (words_x > words_y ? words_x : words_y); + + /* Result Z has to have room for double the larger factor */ + words_z = words_mult * 2; + + /* If either factor is over 2048 bits, we can't use the standard hardware multiplier + (it assumes result is double longest factor, and result is max 4096 bits.) + + However, we can fail over to mod_mult for up to 4096 bits of result (modulo + multiplication doesn't have the same restriction, so result is simply the + number of bits in X plus number of bits in in Y.) + */ + if (words_mult * 32 > 2048) { + /* Calculate new length of Z */ + words_z = (bits_x + bits_y + 31) / 32; + if (words_z * 32 <= 4096) { + /* Note: it's possible to use mpi_mult_mpi_overlong + for this case as well, but it's very slightly + slower and requires a memory allocation. + */ + return mpi_mult_mpi_failover_mod_mult(Z, X, Y, words_z); + } else { + /* Still too long for the hardware unit... */ + if(bits_y > bits_x) { + return mpi_mult_mpi_overlong(Z, X, Y, bits_y, words_z); + } else { + return mpi_mult_mpi_overlong(Z, Y, X, bits_x, words_z); + } + } + } + + /* Otherwise, we can use the (faster) multiply hardware unit */ + + esp_mpi_acquire_hardware(); + + /* Copy X (right-extended) & Y (left-extended) to memory block */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, words_mult); + mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + words_mult * 4, Y, words_mult); + /* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block. + This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware(). + */ + + DPORT_REG_WRITE(RSA_M_DASH_REG, 0); + DPORT_REG_WRITE(RSA_LENGTH_REG, (words_z - 1)); + start_op(RSA_MULT_START_REG); + + wait_op_complete(RSA_MULT_START_REG); + + /* Read back the result */ + ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, words_z); + + Z->s = X->s * Y->s; + + esp_mpi_release_hardware(); + + return ret; +} + +/* Special-case of mbedtls_mpi_mult_mpi(), where we use hardware montgomery mod + multiplication to calculate an mbedtls_mpi_mult_mpi result where either + A or B are >2048 bits so can't use the standard multiplication method. + + Result (A bits + B bits) must still be less than 4096 bits. + + This case is simpler than the general case modulo multiply of + esp_mpi_mul_mpi_mod() because we can control the other arguments: + + * Modulus is chosen with M=(2^num_bits - 1) (ie M=R-1), so output + isn't actually modulo anything. + * Mprime and Rinv are therefore predictable as follows: + Mprime = 1 + Rinv = 1 + + (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) +*/ +static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) +{ + int ret = 0; + + /* Load coefficients to hardware */ + esp_mpi_acquire_hardware(); + + /* M = 2^num_words - 1, so block is entirely FF */ + for(int i = 0; i < num_words; i++) { + DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX); + } + + /* Mprime = 1 */ + DPORT_REG_WRITE(RSA_M_DASH_REG, 1); + DPORT_REG_WRITE(RSA_LENGTH_REG, num_words -1); + + /* Load X & Y */ + mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); + mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); + + /* Rinv = 1 */ + DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1); + for(int i = 1; i < num_words; i++) { + DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0); + } + + start_op(RSA_MOD_MULT_START_REG); + wait_op_complete(RSA_MOD_MULT_START_REG); + + mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, num_words); + + esp_mpi_release_hardware(); + + return ret; +} + +/* Deal with the case when X & Y are too long for the hardware unit, by splitting one operand + into two halves. + + Y must be the longer operand + + Slice Y into Yp, Ypp such that: + Yp = lower 'b' bits of Y + Ypp = upper 'b' bits of Y (right shifted) + + Such that + Z = X * Y + Z = X * (Yp + Ypp<p, + .n = limbs_slice, + .s = Y->s + }; + /* Ypp holds upper bits of Y, right shifted (also reuses Y's array contents) */ + const mbedtls_mpi Ypp = { + .p = Y->p + limbs_slice, + .n = limbs_y - limbs_slice, + .s = Y->s + }; + mbedtls_mpi_init(&Ztemp); + + /* Grow Z to result size early, avoid interim allocations */ + mbedtls_mpi_grow(Z, words_result); + + /* Get result Ztemp = Yp * X (need temporary variable Ztemp) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(&Ztemp, X, &Yp) ); + + /* Z = Ypp * Y */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(Z, X, &Ypp) ); + + /* Z = Z << b */ + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(Z, limbs_slice * biL) ); + + /* Z += Ztemp */ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(Z, Z, &Ztemp) ); + + cleanup: + mbedtls_mpi_free(&Ztemp); + + return ret; +} + +#endif /* MBEDTLS_MPI_MUL_MPI_ALT */ + diff --git a/components/mbedtls/port/esp32s2beta/sha.c b/components/mbedtls/port/esp32s2beta/sha.c index e31beaa3c..5c5f2b6da 100644 --- a/components/mbedtls/port/esp32s2beta/sha.c +++ b/components/mbedtls/port/esp32s2beta/sha.c @@ -31,8 +31,8 @@ #include #include -#include "hwcrypto/sha.h" -#include "rom/ets_sys.h" +#include "esp32s2beta/sha.h" +#include "esp32s2beta/rom/ets_sys.h" #include "soc/dport_reg.h" #include "soc/hwcrypto_reg.h" diff --git a/components/mbedtls/port/include/esp32s2beta/aes.h b/components/mbedtls/port/include/esp32s2beta/aes.h index cc0f56086..2c5853322 100644 --- a/components/mbedtls/port/include/esp32s2beta/aes.h +++ b/components/mbedtls/port/include/esp32s2beta/aes.h @@ -25,7 +25,7 @@ #define ESP_AES_H #include "esp_types.h" -#include "rom/aes.h" +#include "esp32s2beta/rom/aes.h" #ifdef __cplusplus extern "C" { diff --git a/components/mbedtls/port/include/esp32s2beta/sha.h b/components/mbedtls/port/include/esp32s2beta/sha.h index 718cf8a9b..b1b4bead2 100644 --- a/components/mbedtls/port/include/esp32s2beta/sha.h +++ b/components/mbedtls/port/include/esp32s2beta/sha.h @@ -14,7 +14,7 @@ #ifndef _ESP_SHA_H_ #define _ESP_SHA_H_ -#include "rom/sha.h" +#include "esp32s2beta/rom/sha.h" #include "esp_types.h" /** @brief Low-level support functions for the hardware SHA engine diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index e88672f82..c8a07bcda 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -3048,13 +3048,13 @@ void _mdns_disable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protoc /** * @brief Dispatch interface changes based on system events */ -static void _mdns_handle_system_event(esp_event_base_t event_base, +static void _mdns_handle_system_event(esp_event_base_t event_base, int32_t event_id, tcpip_adapter_if_t interface) { if (!_mdns_server) { return; } - + tcpip_adapter_dhcp_status_t dcst; if (event_base == WIFI_EVENT) { switch(event_id) { @@ -3079,7 +3079,9 @@ static void _mdns_handle_system_event(esp_event_base_t event_base, default: break; } - } else if (event_base == ETH_EVENT) { + } +#if CONFIG_IDF_TARGET_ESP32 + else if (event_base == ETH_EVENT) { switch (event_id) { case ETHERNET_EVENT_CONNECTED: if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &dcst)) { @@ -3095,15 +3097,19 @@ static void _mdns_handle_system_event(esp_event_base_t event_base, default: break; } - } else if (event_base == IP_EVENT) { + } +#endif + else if (event_base == IP_EVENT) { switch (event_id) { case IP_EVENT_STA_GOT_IP: _mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); _mdns_announce_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true); break; +#if CONFIG_IDF_TARGET_ESP32 case IP_EVENT_ETH_GOT_IP: _mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); break; +#endif case IP_EVENT_GOT_IP6: _mdns_enable_pcb(interface, MDNS_IP_PROTOCOL_V6); _mdns_announce_pcb(interface, MDNS_IP_PROTOCOL_V4, NULL, 0, true); @@ -3722,7 +3728,7 @@ static void _mdns_execute_action(mdns_action_t * action) switch(action->type) { case ACTION_SYSTEM_EVENT: - _mdns_handle_system_event(action->data.sys_event.event_base, + _mdns_handle_system_event(action->data.sys_event.event_base, action->data.sys_event.event_id, action->data.sys_event.interface); break; case ACTION_HOSTNAME_SET: @@ -4117,7 +4123,7 @@ esp_err_t mdns_handle_system_event(void *ctx, system_event_t *event) return ESP_OK; } -static void event_handler(void* arg, esp_event_base_t event_base, +static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { if (!_mdns_server) { @@ -4139,7 +4145,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) { free(action); - } + } } esp_err_t mdns_init() @@ -4168,17 +4174,17 @@ esp_err_t mdns_init() err = ESP_ERR_NO_MEM; goto free_lock; } - if ((err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) { goto free_event_handlers; } if ((err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) { goto free_event_handlers; } +#if CONFIG_IDF_TARGET_ESP32 if ((err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) { goto free_event_handlers; } - +#endif uint8_t i; ip6_addr_t tmp_addr6; tcpip_adapter_ip_info_t if_ip_info; @@ -4208,7 +4214,9 @@ free_all_and_disable_pcbs: free_event_handlers: esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler); esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler); +#if CONFIG_IDF_TARGET_ESP32 esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler); +#endif vQueueDelete(_mdns_server->action_queue); free_lock: vSemaphoreDelete(_mdns_server->lock); @@ -4256,7 +4264,9 @@ void mdns_free() vSemaphoreDelete(_mdns_server->lock); esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler); esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler); +#if CONFIG_IDF_TARGET_ESP32 esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler); +#endif free(_mdns_server); _mdns_server = NULL; } diff --git a/components/mdns/private_include/mdns_networking.h b/components/mdns/private_include/mdns_networking.h index 1d13e308f..174022dfd 100644 --- a/components/mdns/private_include/mdns_networking.h +++ b/components/mdns/private_include/mdns_networking.h @@ -3,7 +3,7 @@ /* * MDNS Server Networking -- private include - * + * */ #include "mdns.h" #include "mdns_private.h" @@ -21,7 +21,9 @@ #include "esp_system.h" #include "esp_timer.h" #include "esp_event.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp_eth.h" +#endif /** diff --git a/components/newlib/time.c b/components/newlib/time.c index 2eb8b4b27..362b02a5f 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -22,20 +22,26 @@ #include #include #include -#include #include "esp_attr.h" #include "esp_intr_alloc.h" -#include "esp32/clk.h" #include "esp_timer.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/frc_timer_reg.h" -#include "esp32/rom/ets_sys.h" #include "freertos/FreeRTOS.h" #include "freertos/xtensa_api.h" #include "freertos/task.h" -#include "sdkconfig.h" #include "limits.h" +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" +#include "esp32/clk.h" +#include "esp32/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#include "esp32s2beta/rom/rtc.h" +#include "esp32s2beta/rom/ets_sys.h" +#endif #if defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 ) #define WITH_RTC 1 diff --git a/components/nvs_flash/include/nvs.h b/components/nvs_flash/include/nvs.h index c6de4abe3..4ae824d47 100644 --- a/components/nvs_flash/include/nvs.h +++ b/components/nvs_flash/include/nvs.h @@ -205,7 +205,7 @@ esp_err_t nvs_set_u32 (nvs_handle_t handle, const char* key, uint32_t value); esp_err_t nvs_set_i64 (nvs_handle_t handle, const char* key, int64_t value); esp_err_t nvs_set_u64 (nvs_handle_t handle, const char* key, uint64_t value); esp_err_t nvs_set_str (nvs_handle_t handle, const char* key, const char* value); -/**@}*/ +/**@}*/ /** * @brief set variable length binary value for given key @@ -282,7 +282,7 @@ esp_err_t nvs_get_i32 (nvs_handle_t handle, const char* key, int32_t* out_value) esp_err_t nvs_get_u32 (nvs_handle_t handle, const char* key, uint32_t* out_value); esp_err_t nvs_get_i64 (nvs_handle_t handle, const char* key, int64_t* out_value); esp_err_t nvs_get_u64 (nvs_handle_t handle, const char* key, uint64_t* out_value); -/**@}*/ +/**@}*/ /** * @brief get value for given key diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index bae7e2fbd..1fe157a43 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -11,10 +11,13 @@ endif() list(APPEND COMPONENT_ADD_INCLUDEDIRS include) if(NOT BOOTLOADER_BUILD) list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c" - "src/lldesc.c src/hal/spi_hal.c" - "src/hal/spi_hal_iram.c" + "src/lldesc.c" "src/soc_include_legacy_warn.c") + if(IDF_TARGET STREQUAL "esp32") + list(APPEND COMPONENT_SRCS "src/hal/spi_hal.c" "src/hal/spi_hal_iram.c") + endif() + set(COMPONENT_ADD_LDFRAGMENTS linker.lf) endif() diff --git a/components/soc/esp32s2beta/gpio_periph.c b/components/soc/esp32s2beta/gpio_periph.c new file mode 100644 index 000000000..79e5c87c8 --- /dev/null +++ b/components/soc/esp32s2beta/gpio_periph.c @@ -0,0 +1,66 @@ +// Copyright 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. + +#include "soc/gpio_periph.h" + +const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { + IO_MUX_GPIO0_REG, + IO_MUX_GPIO1_REG, + IO_MUX_GPIO2_REG, + IO_MUX_GPIO3_REG, + IO_MUX_GPIO4_REG, + IO_MUX_GPIO5_REG, + IO_MUX_GPIO6_REG, + IO_MUX_GPIO7_REG, + IO_MUX_GPIO8_REG, + IO_MUX_GPIO9_REG, + IO_MUX_GPIO10_REG, + IO_MUX_GPIO11_REG, + IO_MUX_GPIO12_REG, + IO_MUX_GPIO13_REG, + IO_MUX_GPIO14_REG, + IO_MUX_GPIO15_REG, + IO_MUX_GPIO16_REG, + IO_MUX_GPIO17_REG, + IO_MUX_GPIO18_REG, + IO_MUX_GPIO19_REG, + IO_MUX_GPIO20_REG, + IO_MUX_GPIO21_REG, + 0, + 0, + 0, + 0, + IO_MUX_GPIO26_REG, + IO_MUX_GPIO27_REG, + IO_MUX_GPIO28_REG, + IO_MUX_GPIO29_REG, + IO_MUX_GPIO30_REG, + IO_MUX_GPIO31_REG, + IO_MUX_GPIO32_REG, + IO_MUX_GPIO33_REG, + IO_MUX_GPIO34_REG, + IO_MUX_GPIO35_REG, + IO_MUX_GPIO36_REG, + IO_MUX_GPIO37_REG, + IO_MUX_GPIO38_REG, + IO_MUX_GPIO39_REG, + IO_MUX_GPIO40_REG, + IO_MUX_GPIO41_REG, + IO_MUX_GPIO42_REG, + IO_MUX_GPIO43_REG, + IO_MUX_GPIO44_REG, + IO_MUX_GPIO45_REG, + IO_MUX_GPIO46_REG, + 0, +}; diff --git a/components/soc/esp32s2beta/include/soc/periph_defs.h b/components/soc/esp32s2beta/include/soc/periph_defs.h index 85c8274cf..5f80e6678 100644 --- a/components/soc/esp32s2beta/include/soc/periph_defs.h +++ b/components/soc/esp32s2beta/include/soc/periph_defs.h @@ -23,11 +23,7 @@ typedef enum { PERIPH_LEDC_MODULE = 0, PERIPH_UART0_MODULE, PERIPH_UART1_MODULE, -#ifdef CONFIG_CHIP_IS_ESP32 - PERIPH_UART2_MODULE, -#else PERIPH_USB_MODULE, -#endif PERIPH_I2C0_MODULE, PERIPH_I2C1_MODULE, PERIPH_I2S0_MODULE, diff --git a/components/soc/esp32s2beta/include/soc/sdio_slave_pins.h b/components/soc/esp32s2beta/include/soc/sdio_slave_pins.h new file mode 100644 index 000000000..d55bf246b --- /dev/null +++ b/components/soc/esp32s2beta/include/soc/sdio_slave_pins.h @@ -0,0 +1,34 @@ +// Copyright 2015-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. + +#ifndef _SOC_SDIO_SLAVE_PINS_H_ +#define _SOC_SDIO_SLAVE_PINS_H_ + +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 12 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 11 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 13 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 14 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 9 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 10 +#define SDIO_SLAVE_SLOT0_FUNC 0 + +#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK 36 +#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD 35 +#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0 37 +#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1 38 +#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2 33 +#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3 34 +#define SDIO_SLAVE_SLOT1_FUNC 3 + +#endif /* _SOC_SDIO_SLAVE_PINS_H_ */ diff --git a/components/soc/esp32s2beta/include/soc/sdmmc_pins.h b/components/soc/esp32s2beta/include/soc/sdmmc_pins.h new file mode 100644 index 000000000..48d5894ab --- /dev/null +++ b/components/soc/esp32s2beta/include/soc/sdmmc_pins.h @@ -0,0 +1,38 @@ +// Copyright 2015-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. + +#ifndef _SOC_SDMMC_PINS_H_ +#define _SOC_SDMMC_PINS_H_ + +#define SDMMC_SLOT0_IOMUX_PIN_NUM_CLK 12 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_CMD 11 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D0 13 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D1 14 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D2 9 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D3 10 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D4 16 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D5 17 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D6 5 +#define SDMMC_SLOT0_IOMUX_PIN_NUM_D7 18 +#define SDMMC_SLOT0_FUNC 0 + +#define SDMMC_SLOT1_IOMUX_PIN_NUM_CLK 36 +#define SDMMC_SLOT1_IOMUX_PIN_NUM_CMD 35 +#define SDMMC_SLOT1_IOMUX_PIN_NUM_D0 37 +#define SDMMC_SLOT1_IOMUX_PIN_NUM_D1 38 +#define SDMMC_SLOT1_IOMUX_PIN_NUM_D2 33 +#define SDMMC_SLOT1_IOMUX_PIN_NUM_D3 34 +#define SDMMC_SLOT1_FUNC 3 + +#endif /* _SOC_SDMMC_PINS_H_ */ diff --git a/components/soc/esp32s2beta/include/soc/soc.h b/components/soc/esp32s2beta/include/soc/soc.h index d349e863b..31702827b 100644 --- a/components/soc/esp32s2beta/include/soc/soc.h +++ b/components/soc/esp32s2beta/include/soc/soc.h @@ -57,6 +57,8 @@ #define PRO_CPU_NUM (0) +#define SOC_MAX_CONTIGUOUS_RAM_SIZE 0x400000 ///< Largest span of contiguous memory (DRAM or IRAM) in the address space + #define DR_REG_SYSTEM_BASE 0x3f4c0000 #define DR_REG_SENSITIVE_BASE 0x3f4c1000 #define DR_REG_INTERRUPT_BASE 0x3f4c2000 @@ -123,7 +125,7 @@ //Registers Operation {{ #define ETS_UNCACHED_ADDR(addr) (addr) -#define ETS_CACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) #ifndef __ASSEMBLER__ #define BIT(nr) (1UL << (nr)) diff --git a/components/soc/esp32s2beta/rtc_periph.c b/components/soc/esp32s2beta/rtc_periph.c new file mode 100644 index 000000000..0849b0303 --- /dev/null +++ b/components/soc/esp32s2beta/rtc_periph.c @@ -0,0 +1,20 @@ +// Copyright 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. + +#include "soc/rtc_periph.h" + +//Reg,Mux,Fun,IE,Up,Down,Rtc_number +const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = { + 0 +}; diff --git a/components/soc/include/soc/can_periph.h b/components/soc/include/soc/can_periph.h index 91d958276..6148c1cee 100644 --- a/components/soc/include/soc/can_periph.h +++ b/components/soc/include/soc/can_periph.h @@ -13,4 +13,10 @@ // limitations under the License. #pragma once +<<<<<<< a7ae5416fbc96f364c1047b2de9ba426677e258b #include "soc/can_struct.h" +======= +#if CONFIG_IDF_TARGET_ESP32 +#include "soc/can_struct.h" +#endif +>>>>>>> build and link hello-world for esp32s2beta diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 43bf49003..41e58876d 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -10,12 +10,14 @@ else() # not BOOTLOADER_BUILD "flash_mmap.c" "flash_ops.c" "partition.c" - "spi_flash_rom_patch.c") + "spi_flash_rom_patch.c" + "${IDF_TARGET}/flash_ops_${IDF_TARGET}.c") set(COMPONENT_REQUIRES app_update) set(COMPONENT_PRIV_REQUIRES bootloader_support soc) endif() set(COMPONENT_ADD_INCLUDEDIRS include) +set(COMPONENT_PRIV_INCLUDEDIRS ".") set(COMPONENT_ADD_LDFRAGMENTS linker.lf) register_component() diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index b27b968ad..ca2fa55e8 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -20,8 +20,13 @@ #include #include #include +#if CONFIG_IDF_TARGET_ESP32 #include #include +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/spi_flash.h" +#include "esp32s2beta/rom/cache.h" +#endif #include #include #include "sdkconfig.h" @@ -31,6 +36,7 @@ #include "esp_spi_flash.h" #include "esp_log.h" +static const char* TAG = "spiflash"; static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state); static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); @@ -62,7 +68,7 @@ void spi_flash_op_unlock() } /* If you're going to modify this, keep in mind that while the flash caches of the pro and app - cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine + cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine with its cache enabled but the other CPUs cache is not enabled yet, you will have problems when accessing psram from the former CPU. */ @@ -133,7 +139,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() } // Kill interrupts that aren't located in IRAM esp_intr_noniram_disable(); - // This CPU executes this routine, with non-IRAM interrupts and the scheduler + // This CPU executes this routine, with non-IRAM interrupts and the scheduler // disabled. The other CPU is spinning in the spi_flash_op_block_func task, also // with non-iram interrupts and the scheduler disabled. None of these CPUs will // touch external RAM or flash this way, so we can safely disable caches. @@ -255,13 +261,19 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os() * function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to * Cache_Flush before Cache_Read_Enable, even if cached data was not modified. */ - +#if CONFIG_IDF_TARGET_ESP32 static const uint32_t cache_mask = DPORT_APP_CACHE_MASK_OPSDRAM | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 | DPORT_APP_CACHE_MASK_IROM0 | DPORT_APP_CACHE_MASK_IRAM1 | DPORT_APP_CACHE_MASK_IRAM0; - +#elif CONFIG_IDF_TARGET_ESP32S2BETA +// static const uint32_t icache_mask = DPORT_PRO_ICACHE_MASK_DROM0 |DPORT_PRO_ICACHE_MASK_IROM0 | +// DPORT_PRO_ICACHE_MASK_IRAM1 | DPORT_PRO_ICACHE_MASK_IRAM0; +// static const uint32_t dcache_mask = DPORT_PRO_DCACHE_MASK_DRAM1 | DPORT_PRO_DCACHE_MASK_DRAM0 | +// DPORT_PRO_DCACHE_MASK_DPORT | DPORT_PRO_DCACHE_MASK_DROM0; +#endif static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state) { +#if CONFIG_IDF_TARGET_ESP32 uint32_t ret = 0; if (cpuid == 0) { ret |= DPORT_GET_PERI_REG_BITS2(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, 0); @@ -269,33 +281,327 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_st ; } DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S); - } else { + } +#if !CONFIG_FREERTOS_UNICORE + else { ret |= DPORT_GET_PERI_REG_BITS2(DPORT_APP_CACHE_CTRL1_REG, cache_mask, 0); while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1) { ; } DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 0, DPORT_APP_CACHE_ENABLE_S); } +#endif *saved_state = ret; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + *saved_state = Cache_Suspend_ICache(); + if (!Cache_Drom0_Using_ICache()) { + *(saved_state + 1) = Cache_Suspend_DCache(); + } +#endif } static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state) { +#if CONFIG_IDF_TARGET_ESP32 if (cpuid == 0) { DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 1, DPORT_PRO_CACHE_ENABLE_S); DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, saved_state, 0); - } else { + } +#if !CONFIG_FREERTOS_UNICORE + else { DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 1, DPORT_APP_CACHE_ENABLE_S); DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL1_REG, cache_mask, saved_state, 0); } +#endif +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(saved_state); + if (!Cache_Drom0_Using_ICache()) { + Cache_Resume_DCache(s_flash_op_cache_state[1]); + } +#endif } IRAM_ATTR bool spi_flash_cache_enabled() { +#if CONFIG_IDF_TARGET_ESP32 bool result = (DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE) != 0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + bool result = (DPORT_REG_GET_BIT(DPORT_PRO_ICACHE_CTRL_REG, DPORT_PRO_ICACHE_ENABLE) != 0); + if (!Cache_Drom0_Using_ICache()) { + result = result && (DPORT_REG_GET_BIT(DPORT_PRO_DCACHE_CTRL_REG, DPORT_PRO_DCACHE_ENABLE) != 0); + } +#endif #if portNUM_PROCESSORS == 2 result = result && (DPORT_REG_GET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE) != 0); #endif return result; } + +#if CONFIG_IDF_TARGET_ESP32S2BETA +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_INSTRUCTION_CACHE_8KB + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_8KB; +#else + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_16KB; +#endif +#if CONFIG_INSTRUCTION_CACHE_4WAYS + cache_ways = CACHE_4WAYS_ASSOC; +#else + cache_ways = CACHE_8WAYS_ASSOC; +#endif +#if CONFIG_INSTRUCTION_CACHE_LINE_16B + cache_line_size = CACHE_LINE_SIZE_16B; +#elif CONFIG_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 \t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16,cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 2 : 64)); + Cache_Suspend_ICache(); + Cache_Set_ICache_Mode(cache_size, cache_ways, cache_line_size); + Cache_Invalidate_ICache_All(); + Cache_Resume_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_INSTRUCTION_CACHE_8KB +#if CONFIG_DATA_CACHE_8KB + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_8KB; +#else + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_DCACHE_HIGH, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_16KB; +#endif +#else +#if CONFIG_DATA_CACHE_8KB + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_8KB; +#else + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_DCACHE_HIGH); + cache_size = CACHE_SIZE_16KB; +#endif +#endif + +#if CONFIG_DATA_CACHE_4WAYS + cache_ways = CACHE_4WAYS_ASSOC; +#else + cache_ways = CACHE_8WAYS_ASSOC; +#endif +#if CONFIG_DATA_CACHE_LINE_16B + cache_line_size = CACHE_LINE_SIZE_16B; +#elif CONFIG_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 \t\t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16, cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 2 : 64)); + Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size); + Cache_Invalidate_DCache_All(); +} + +void esp_switch_rodata_to_dcache(void) +{ + REG_CLR_BIT(DPORT_PRO_DCACHE_CTRL1_REG, DPORT_PRO_DCACHE_MASK_DROM0); + Cache_Drom0_Source_DCache(); + MMU_Drom_ICache_Unmap(); + REG_SET_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_DROM0); + ESP_EARLY_LOGI(TAG, "Switch rodata load path to data cache."); +} + +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(DPORT_PRO_CACHE_WRAP_AROUND_CTRL_REG, DPORT_PRO_CACHE_FLASH_WRAP_AROUND); + if (icache) { + Cache_Resume_ICache(i_autoload); + } + if (dcache) { + Cache_Resume_DCache(d_autoload); + } +} + +#if CONFIG_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(DPORT_PRO_CACHE_WRAP_AROUND_CTRL_REG, DPORT_PRO_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 = true, spiram_support_wrap = true; + if (icache_wrap_enable) { +#if CONFIG_INSTRUCTION_CACHE_LINE_16B + icache_wrap_size = 16; +#elif CONFIG_INSTRUCTION_CACHE_LINE_32B + icache_wrap_size = 32; +#else + icache_wrap_size = 64; +#endif + } + if (dcache_wrap_enable) { +#if CONFIG_DATA_CACHE_LINE_16B + dcache_wrap_size = 16; +#elif CONFIG_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_INSTRUCTION_USE_SPIRAM +extern uint32_t esp_spiram_instruction_access_enabled(); + instruction_use_spiram = esp_spiram_instruction_access_enabled(); +#endif +#if CONFIG_RODATA_USE_SPIRAM +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 (Cache_Drom0_Using_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 (Cache_Drom0_Using_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_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; + } + +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); + } + +#ifdef CONFIG_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."); + spi_flash_enable_wrap(flash_wrap_size); + esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); + } +#if CONFIG_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."); + 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 d482c4da7..fdf48368d 100644 --- a/components/spi_flash/cache_utils.h +++ b/components/spi_flash/cache_utils.h @@ -54,4 +54,12 @@ void spi_flash_enable_interrupts_caches_no_os(); // Returns true if cache was flushed, false otherwise bool spi_flash_check_and_flush_cache(uint32_t start_addr, uint32_t length); +//config cache mode +#ifdef CONFIG_IDF_TARGET_ESP32S2BETA +void esp_config_instruction_cache_mode(void); +void esp_config_data_cache_mode(void); +void esp_switch_rodata_to_dcache(void); +#endif + + #endif //ESP_SPI_FLASH_CACHE_UTILS_H diff --git a/components/spi_flash/component.mk b/components/spi_flash/component.mk index 2ff786e2d..b575ceabb 100644 --- a/components/spi_flash/component.mk +++ b/components/spi_flash/component.mk @@ -1,5 +1,6 @@ COMPONENT_ADD_INCLUDEDIRS := include - +COMPONENT_SRCDIRS := . $(IDF_TARGET) +COMPONENT_PRIV_INCLUDEDIRS := . COMPONENT_ADD_LDFRAGMENTS += linker.lf ifdef IS_BOOTLOADER_BUILD diff --git a/components/spi_flash/esp32/flash_ops_esp32.c b/components/spi_flash/esp32/flash_ops_esp32.c new file mode 100644 index 000000000..b2e158d1a --- /dev/null +++ b/components/spi_flash/esp32/flash_ops_esp32.c @@ -0,0 +1,87 @@ +// Copyright 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. + +#include "esp_spi_flash_chip.h" +#include "cache_utils.h" +#include "rom/spi_flash.h" +#include "rom/cache.h" + +static inline void IRAM_ATTR spi_flash_guard_start() +{ + spi_flash_guard_funcs_t *ops = spi_flash_guard_get(); + if (ops && s_ops->start) { + ops->start(); + } +} + +static inline void IRAM_ATTR spi_flash_guard_end() +{ + spi_flash_guard_funcs_t *ops = spi_flash_guard_get(); + if (ops && s_ops->end) { + ops->end(); + } +} + +esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size) +{ + const uint8_t *ssrc = (const uint8_t *)src; + esp_rom_spiflash_result_t rc; + rc = spi_flash_unlock(); + if (rc != ESP_ROM_SPIFLASH_RESULT_OK) { + return rc; + } + /* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes, + so copy to a temporary buffer - 32 bytes at a time. + + Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of + data to encrypt, and each row is two 16 byte AES blocks + that share a key (as derived from flash address). + */ + uint8_t encrypt_buf[32] __attribute__((aligned(4))); + uint32_t row_size; + for (size_t i = 0; i < size; i += row_size) { + uint32_t row_addr = dest_addr + i; + if (i == 0 && (row_addr % 32) != 0) { + /* writing to second block of a 32 byte row */ + row_size = 16; + row_addr -= 16; + /* copy to second block in buffer */ + memcpy(encrypt_buf + 16, ssrc + i, 16); + /* decrypt the first block from flash, will reencrypt to same bytes */ + spi_flash_read_encrypted(row_addr, encrypt_buf, 16); + } else if (size - i == 16) { + /* 16 bytes left, is first block of a 32 byte row */ + row_size = 16; + /* copy to first block in buffer */ + memcpy(encrypt_buf, ssrc + i, 16); + /* decrypt the second block from flash, will reencrypt to same bytes */ + spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16); + } else { + /* Writing a full 32 byte row (2 blocks) */ + row_size = 32; + memcpy(encrypt_buf, ssrc + i, 32); + } + + spi_flash_guard_start(); + rc = esp_rom_spiflash_write_encrypted(row_addr, (uint32_t *)encrypt_buf, 32); + spi_flash_guard_end(); + if (rc != ESP_ROM_SPIFLASH_RESULT_OK) { + break; + } + } + bzero(encrypt_buf, sizeof(encrypt_buf)); + + return rc; +} + diff --git a/components/spi_flash/esp32s2beta/flash_ops_esp32s2beta.c b/components/spi_flash/esp32s2beta/flash_ops_esp32s2beta.c new file mode 100644 index 000000000..bc02514a8 --- /dev/null +++ b/components/spi_flash/esp32s2beta/flash_ops_esp32s2beta.c @@ -0,0 +1,65 @@ +// Copyright 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. + +#include +#include + +#include "esp_spi_flash.h" +#include "esp_spi_flash_chip.h" +#include "cache_utils.h" +#include "soc/system_reg.h" +#include "soc/soc_memory_layout.h" +#include "esp32s2beta/rom/spi_flash.h" +#include "esp32s2beta/rom/cache.h" + +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; + + 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 + rc = spi_flash_unlock(); + if (rc != ESP_ROM_SPIFLASH_RESULT_OK) { + return rc; + } + + if (ops && ops->start) { + ops->start(); + } + rc = SPI_Encrypt_Write(dest_addr, src, size); + if (ops && ops->end) { + ops->end(); + } + return rc; + } +} diff --git a/components/spi_flash/esp_spi_flash_chip.h b/components/spi_flash/esp_spi_flash_chip.h new file mode 100644 index 000000000..b79e771ba --- /dev/null +++ b/components/spi_flash/esp_spi_flash_chip.h @@ -0,0 +1,29 @@ +// Copyright 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. + +/* Private header with chip-specific routines for SPI flash interaction */ +#pragma once + +#include +#include +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/spi_flash.h" +#endif + +esp_rom_spiflash_result_t spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size); + +esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock(); + diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 76e2d025c..8058251e3 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include #include @@ -32,7 +30,15 @@ #include "esp_flash_encrypt.h" #include "esp_log.h" #include "cache_utils.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/spi_flash.h" +#include "esp32/rom/cache.h" #include "esp32/spiram.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/spi_flash.h" +#include "esp32s2beta/rom/cache.h" +#include "esp32s2beta/spiram.h" +#endif #ifndef NDEBUG // Enable built-in checks in queue.h in debug builds @@ -40,13 +46,29 @@ #endif #include "sys/queue.h" -#define REGIONS_COUNT 4 #define PAGES_PER_REGION 64 -#define INVALID_ENTRY_VAL 0x100 -#define VADDR0_START_ADDR 0x3F400000 +#ifdef CONFIG_IDF_TARGET_ESP32 +#define REGIONS_COUNT 4 +#define IROM0_PAGES_START 64 +#define IROM0_PAGES_END 256 +#define DROM0_PAGES_START 0 +#define DROM0_PAGES_END 64 +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#define REGIONS_COUNT 8 +#define IROM0_PAGES_START (PRO_CACHE_IBUS0_MMU_START / sizeof(uint32_t)) +#define IROM0_PAGES_END (PRO_CACHE_IBUS2_MMU_END / sizeof(uint32_t)) +#define DROM0_PAGES_START (Cache_Drom0_Using_ICache()? PRO_CACHE_IBUS3_MMU_START / sizeof(uint32_t) : PRO_CACHE_DBUS3_MMU_START /sizeof(uint32_t)) +#define DROM0_PAGES_END (Cache_Drom0_Using_ICache()? PRO_CACHE_IBUS3_MMU_END / sizeof(uint32_t) : PRO_CACHE_DBUS3_MMU_END / sizeof(uint32_t)) +#endif +#define MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK +#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 INVALID_ENTRY_VAL DPORT_FLASH_MMU_TABLE_INVALID_VAL +#define VADDR0_START_ADDR SOC_DROM_LOW #define VADDR1_START_ADDR 0x40000000 -#define VADDR1_FIRST_USABLE_ADDR 0x400D0000 -#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + 64) +#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; @@ -70,6 +92,7 @@ static void IRAM_ATTR spi_flash_mmap_init() 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 uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]); if (entry_pro != entry_app) { @@ -77,11 +100,14 @@ static void IRAM_ATTR spi_flash_mmap_init() entry_pro = DPORT_FLASH_MMU_TABLE_INVALID_VAL; DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL; } - if ((entry_pro & INVALID_ENTRY_VAL) == 0 && (i == 0 || i == PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) { +#endif + if ((entry_pro & INVALID_ENTRY_VAL) == 0 && (i == DROM0_PAGES_START || i == PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) { s_mmap_page_refcnt[i] = 1; } else { DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL; +#if !CONFIG_FREERTOS_UNICORE DPORT_APP_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL; +#endif } } DPORT_INTERRUPT_RESTORE(); @@ -91,13 +117,13 @@ static void IRAM_ATTR get_mmu_region(spi_flash_mmap_memory_t memory, int* out_be { if (memory == SPI_FLASH_MMAP_DATA) { // Vaddr0 - *out_begin = 0; - *out_size = 64; + *out_begin = DROM0_PAGES_START; + *out_size = DROM0_PAGES_NUM; *region_addr = VADDR0_START_ADDR; } else { // only part of VAddr1 is usable, so adjust for that *out_begin = PRO_IRAM0_FIRST_USABLE_PAGE; - *out_size = 3 * 64 - *out_begin; + *out_size = IROM0_PAGES_END - *out_begin; *region_addr = VADDR1_FIRST_USABLE_ADDR; } } @@ -121,7 +147,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ return ESP_ERR_NO_MEM; } for (int i = 0; i < page_count; i++) { - pages[i] = phys_page+i; + pages[i] = (phys_page+i) | DPORT_MMU_ACCESS_FLASH; } ret = spi_flash_mmap_pages(pages, page_count, memory, out_ptr, out_handle); free(pages); @@ -140,7 +166,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp return ESP_ERR_INVALID_ARG; } for (int i = 0; i < page_count; i++) { - if (pages[i] < 0 || pages[i]*SPI_FLASH_MMU_PAGE_SIZE >= g_rom_flashchip.chip_size) { + if (pages[i] < 0 || (pages[i] & MMU_ADDR_MASK)*SPI_FLASH_MMU_PAGE_SIZE >= g_rom_flashchip.chip_size) { return ESP_ERR_INVALID_ARG; } } @@ -196,14 +222,25 @@ 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 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 == pages[pageno] && - entry_app == pages[pageno])); + (entry_pro == pages[pageno] +#if !CONFIG_FREERTOS_UNICORE + && entry_app == pages[pageno] +#endif + )); if (s_mmap_page_refcnt[i] == 0) { - if (entry_pro != pages[pageno] || entry_app != pages[pageno]) { + if (entry_pro != pages[pageno] +#if !CONFIG_FREERTOS_UNICORE + || entry_app != pages[pageno] +#endif + ) { DPORT_PRO_FLASH_MMU_TABLE[i] = pages[pageno]; +#if !CONFIG_FREERTOS_UNICORE DPORT_APP_FLASH_MMU_TABLE[i] = pages[pageno]; +#endif need_flush = true; } } @@ -227,10 +264,24 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp */ if (need_flush) { #if CONFIG_ESP32_SPIRAM_SUPPORT +#if CONFIG_IDF_TARGET_ESP32 esp_spiram_writeback_cache(); #endif +#endif +#if CONFIG_IDF_TARGET_ESP32 Cache_Flush(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Invalidate_ICache_All(); + if (!Cache_Drom0_Using_ICache()) { +#if CONFIG_SPIRAM_SUPPORT + Cache_WriteBack_All(); +#endif + Cache_Invalidate_DCache_All(); + } +#endif +#if !CONFIG_FREERTOS_UNICORE Cache_Flush(1); +#endif } spi_flash_enable_interrupts_caches_and_other_cpu(); @@ -254,7 +305,9 @@ 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 DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; +#endif } } LIST_REMOVE(it, entries); @@ -327,16 +380,15 @@ uint32_t spi_flash_cache2phys(const void *cached) if (c >= VADDR1_START_ADDR && c < VADDR1_FIRST_USABLE_ADDR) { /* IRAM address, doesn't map to flash */ return SPI_FLASH_CACHE2PHYS_FAIL; - } - else if (c < VADDR1_FIRST_USABLE_ADDR) { + } else if (c < VADDR1_FIRST_USABLE_ADDR) { /* expect cache is in DROM */ - cache_page = (c - VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE; + cache_page = (c - VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + DROM0_PAGES_START; } else { /* expect cache is in IROM */ - cache_page = (c - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + 64; + cache_page = (c - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START; } - if (cache_page >= 256) { + if (cache_page >= PAGES_LIMIT) { /* cached address was not in IROM or DROM */ return SPI_FLASH_CACHE2PHYS_FAIL; } @@ -345,7 +397,7 @@ uint32_t spi_flash_cache2phys(const void *cached) /* page is not mapped */ return SPI_FLASH_CACHE2PHYS_FAIL; } - uint32_t phys_offs = phys_page * SPI_FLASH_MMU_PAGE_SIZE; + uint32_t phys_offs = (phys_page & MMU_ADDR_MASK)* SPI_FLASH_MMU_PAGE_SIZE; return phys_offs | (c & (SPI_FLASH_MMU_PAGE_SIZE-1)); } @@ -356,15 +408,15 @@ const void *IRAM_ATTR spi_flash_phys2cache(uint32_t phys_offs, spi_flash_mmap_me intptr_t base; if (memory == SPI_FLASH_MMAP_DATA) { - start = 0; - end = 64; + start = DROM0_PAGES_START; + end = DROM0_PAGES_END; base = VADDR0_START_ADDR; - page_delta = 0; + page_delta = DROM0_PAGES_START > IROM0_PAGES_START ? DROM0_PAGES_START : 0; } else { start = PRO_IRAM0_FIRST_USABLE_PAGE; - end = 256; + end = IROM0_PAGES_END; base = VADDR1_START_ADDR; - page_delta = 64; + page_delta = DROM0_PAGES_START > IROM0_PAGES_START ? 0: IROM0_PAGES_START; } spi_flash_disable_interrupts_caches_and_other_cpu(); DPORT_INTERRUPT_DISABLE(); @@ -421,12 +473,14 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length) } if (is_page_mapped_in_cache(page)) { +#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_ESP32_SPIRAM_SUPPORT esp_spiram_writeback_cache(); #endif Cache_Flush(0); #ifndef CONFIG_FREERTOS_UNICORE Cache_Flush(1); +#endif #endif return true; } diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 8aae45f0e..dfb51e7f4 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -30,11 +30,18 @@ #include "esp_ipc.h" #include "esp_attr.h" #include "esp_spi_flash.h" +#include "esp_spi_flash_chip.h" #include "esp_log.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#include "soc/spi_mem_reg.h" +#endif #include "esp_flash_partitions.h" #include "esp_ota_ops.h" #include "cache_utils.h" +#include "soc/spi_periph.h" /* bytes erased by SPIEraseBlock() ROM function */ #define BLOCK_ERASE_SIZE 65536 @@ -184,7 +191,7 @@ static inline void IRAM_ATTR spi_flash_guard_op_unlock() } } -static esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock() +esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock() { static bool unlocked = false; if (!unlocked) { @@ -420,7 +427,6 @@ out: esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size) { CHECK_WRITE_ADDRESS(dest_addr, size); - const uint8_t *ssrc = (const uint8_t *)src; if ((dest_addr % 16) != 0) { return ESP_ERR_INVALID_ARG; } @@ -430,49 +436,7 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, COUNTER_START(); esp_rom_spiflash_result_t rc; - rc = spi_flash_unlock(); - if (rc == ESP_ROM_SPIFLASH_RESULT_OK) { - /* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes, - so copy to a temporary buffer - 32 bytes at a time. - - Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of - data to encrypt, and each row is two 16 byte AES blocks - that share a key (as derived from flash address). - */ - uint8_t encrypt_buf[32] __attribute__((aligned(4))); - uint32_t row_size; - for (size_t i = 0; i < size; i += row_size) { - uint32_t row_addr = dest_addr + i; - if (i == 0 && (row_addr % 32) != 0) { - /* writing to second block of a 32 byte row */ - row_size = 16; - row_addr -= 16; - /* copy to second block in buffer */ - memcpy(encrypt_buf + 16, ssrc + i, 16); - /* decrypt the first block from flash, will reencrypt to same bytes */ - spi_flash_read_encrypted(row_addr, encrypt_buf, 16); - } else if (size - i == 16) { - /* 16 bytes left, is first block of a 32 byte row */ - row_size = 16; - /* copy to first block in buffer */ - memcpy(encrypt_buf, ssrc + i, 16); - /* decrypt the second block from flash, will reencrypt to same bytes */ - spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16); - } else { - /* Writing a full 32 byte row (2 blocks) */ - row_size = 32; - memcpy(encrypt_buf, ssrc + i, 32); - } - - spi_flash_guard_start(); - rc = esp_rom_spiflash_write_encrypted(row_addr, (uint32_t *)encrypt_buf, 32); - spi_flash_guard_end(); - if (rc != ESP_ROM_SPIFLASH_RESULT_OK) { - break; - } - } - bzero(encrypt_buf, sizeof(encrypt_buf)); - } + rc = spi_flash_write_encrypted_chip(dest_addr, src, size); COUNTER_ADD_BYTES(write, size); COUNTER_STOP(write); @@ -689,3 +653,76 @@ void spi_flash_dump_counters() } #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS + +#if CONFIG_IDF_TARGET_ESP32S2BETA +#define SPICACHE SPIMEM0 +#define SPIFLASH SPIMEM1 +#define FLASH_WRAP_CMD 0x77 +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; + uint32_t reg_bkp_usr = SPIFLASH.user.val; + SPIFLASH.user.fwrite_dio = 0; + SPIFLASH.user.fwrite_dual = 0; + SPIFLASH.user.fwrite_qio = 1; + SPIFLASH.user.fwrite_quad = 0; + SPIFLASH.ctrl.fcmd_dual = 0; + SPIFLASH.ctrl.fcmd_quad = 0; + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 1; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD; + SPIFLASH.user1.usr_addr_bitlen = 23; + SPIFLASH.addr = 0; + SPIFLASH.user.usr_miso = 0; + SPIFLASH.user.usr_mosi = 1; + SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7; + SPIFLASH.data_buf[0] = (uint32_t) mode << 4;; + SPIFLASH.cmd.usr = 1; + while(SPIFLASH.cmd.usr != 0) + { } + + SPIFLASH.ctrl.val = reg_bkp_ctrl; + SPIFLASH.user.val = reg_bkp_usr; + return ESP_OK; +} + +esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) +{ + switch(wrap_size) { + case 8: + return spi_flash_wrap_set(FLASH_WRAP_MODE_8B); + case 16: + return spi_flash_wrap_set(FLASH_WRAP_MODE_16B); + case 32: + return spi_flash_wrap_set(FLASH_WRAP_MODE_32B); + case 64: + return spi_flash_wrap_set(FLASH_WRAP_MODE_64B); + default: + return ESP_FAIL; + } +} + +void spi_flash_disable_wrap() +{ + spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); +} + +bool spi_flash_support_wrap_size(uint32_t wrap_size) +{ + if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)){ + return ESP_FAIL; + } + switch(wrap_size) { + case 0: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} +#endif diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 254e40895..dc53ad31d 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -33,10 +33,28 @@ extern "C" { #define SPI_FLASH_MMU_PAGE_SIZE 0x10000 /**< Flash cache MMU mapping page size */ +typedef enum { + FLASH_WRAP_MODE_8B = 0, + FLASH_WRAP_MODE_16B = 2, + FLASH_WRAP_MODE_32B = 4, + FLASH_WRAP_MODE_64B = 6, + FLASH_WRAP_MODE_DISABLE = 1 +} spi_flash_wrap_mode_t; + +/** + * @brief set wrap mode of flash + * + * @param spi_flash_wrap_mode_t mode: wrap mode support disable, 16 32, 64 byte + * + * @return esp_err_t : ESP_OK for successful. + * + */ +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode); + /** * @brief Initialize SPI flash access driver * - * This function must be called exactly once, before any other + * This function must be called exactly once, before any other * spi_flash_* functions are called. * Currently this function is called from startup code. There is * no need to call it from application code. diff --git a/components/spi_flash/spi_flash_rom_patch.c b/components/spi_flash/spi_flash_rom_patch.c index e00452585..295ef44f3 100644 --- a/components/spi_flash/spi_flash_rom_patch.c +++ b/components/spi_flash/spi_flash_rom_patch.c @@ -11,11 +11,16 @@ // 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" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" #include "esp32/rom/gpio.h" #include "esp32/rom/spi_flash.h" -#include "sdkconfig.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#include "esp32s2beta/rom/gpio.h" +#include "esp32s2beta/rom/spi_flash.h" +#endif #include "soc/spi_periph.h" @@ -27,12 +32,18 @@ extern esp_rom_spiflash_chip_t g_rom_spiflash_chip; esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi) { uint32_t status; - +#if CONFIG_IDF_TARGET_ESP32 //wait for spi control ready while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) { } while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) { } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) { + } + while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) { + } +#endif //wait for flash status ready if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_status(spi, &status)) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -69,12 +80,21 @@ esp_rom_spiflash_result_t esp_rom_spiflash_unlock() status &= ESP_ROM_SPIFLASH_QE; esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); +#if CONFIG_IDF_TARGET_ESP32 REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN); while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) { } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN); + while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) { + } +#endif esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); - +#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B); +#endif if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) { return ESP_ROM_SPIFLASH_RESULT_ERR; } @@ -96,7 +116,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_sp esp_rom_spiflash_wait_idle(spi); // Chip erase. +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_CE); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE); +#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); // check erase is finished. @@ -117,7 +141,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_ // sector erase 4Kbytes erase is sector erase. WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff); +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_SE); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE); +#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); esp_rom_spiflash_wait_idle(spi); @@ -132,7 +160,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_s // sector erase 4Kbytes erase is sector erase. WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff); +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_BE); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE); +#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); esp_rom_spiflash_wait_idle(spi); @@ -186,8 +218,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_ } temp_bl = 0; } - +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_PP); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP); +#endif while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 ); esp_rom_spiflash_wait_idle(spi); @@ -218,9 +253,15 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chi while (temp_length > 0) { if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) { //WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN)); +#if CONFIG_IDF_TARGET_ESP32 REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S); WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8); REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S); + WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8); + REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR); +#endif while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0); for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) { @@ -231,8 +272,13 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chi } else { //WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN )); WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8); +#if CONFIG_IDF_TARGET_ESP32 REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S); REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S); + REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR); +#endif while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0); remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1; @@ -253,7 +299,11 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t * if (g_rom_spiflash_dummy_len_plus[1] == 0) { while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_RDSR); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR); +#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask); @@ -283,7 +333,11 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t // update status value by status_value WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WRSR); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR); +#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); esp_rom_spiflash_wait_idle(spi); @@ -297,7 +351,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_ esp_rom_spiflash_wait_idle(spi); //enable write +#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WREN); // enable write operation +#elif CONFIG_IDF_TARGET_ESP32S2BETA + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation +#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); // make sure the flash is ready for writing @@ -310,6 +368,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_ static void spi_cache_mode_switch(uint32_t modebit) { +#if CONFIG_IDF_TARGET_ESP32 if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) { REG_CLR_BIT(SPI_USER_REG(0), SPI_USR_MOSI); REG_SET_BIT(SPI_USER_REG(0), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR); @@ -345,7 +404,43 @@ static void spi_cache_mode_switch(uint32_t modebit) REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN); REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x03); } - +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) { + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xEB); + } else if (modebit & SPI_MEM_FASTRD_MODE) { + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN); + if ((modebit & SPI_MEM_FREAD_QUAD)) { + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x6B); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); + } else if ((modebit & SPI_MEM_FREAD_DIO)) { + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xBB); + } else if ((modebit & SPI_MEM_FREAD_DUAL)) { + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x3B); + } else{ + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x0B); + } + } else { + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); + if (g_rom_spiflash_dummy_len_plus[0] == 0) { + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); + } else { + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1); + } + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x03); + } +#endif } esp_rom_spiflash_result_t esp_rom_spiflash_lock() @@ -374,27 +469,50 @@ esp_rom_spiflash_result_t esp_rom_spiflash_lock() esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode) { uint32_t modebit; - +#if CONFIG_IDF_TARGET_ESP32 while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) { } while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) { } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) { + } + while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) { + } +#endif //clear old mode bit +#if CONFIG_IDF_TARGET_ESP32 CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE); CLEAR_PERI_REG_MASK(SPI_CTRL_REG(0), SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE); + CLEAR_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE); +#endif //configure read mode switch (mode) { +#if CONFIG_IDF_TARGET_ESP32 case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_FREAD_QIO | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_FREAD_QUAD | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_FREAD_DIO | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_FREAD_DUAL | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_FASTRD_MODE; break; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE; break; + case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE; break; + case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE; break; + case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE; break; + case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_MEM_FASTRD_MODE; break; +#endif case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break; default : modebit = 0; } SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit); +#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_MASK(SPI_CTRL_REG(0), modebit); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit); +#endif spi_cache_mode_switch(modebit); return ESP_ROM_SPIFLASH_RESULT_OK; @@ -416,9 +534,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip() esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num) { // flash write is always 1 line currently +#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); - +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); +#endif //check program size if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -437,9 +559,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num) esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num) { // flash write is always 1 line currently +#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); - +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); +#endif //check program size if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -463,9 +589,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t uint8_t i; // flash write is always 1 line currently +#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); - +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); +#endif //check program size if ( (target + len) > (g_rom_spiflash_chip.chip_size)) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -503,6 +633,7 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t return ESP_ROM_SPIFLASH_RESULT_OK; } +#if CONFIG_IDF_TARGET_ESP32 esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len) { esp_rom_spiflash_result_t ret = ESP_ROM_SPIFLASH_RESULT_OK; @@ -528,13 +659,14 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, return ret; } - +#endif esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_addr, int32_t len) { // QIO or SIO, non-QIO regard as SIO uint32_t modebit; modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL); +#if CONFIG_IDF_TARGET_ESP32 if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) { REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI); REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR); @@ -546,17 +678,44 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_ REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI); REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_ADDR); if (modebit & SPI_FREAD_DIO) { +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) { + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI); + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]); + //REG_SET_FIELD(PERIPHS_SPI_SPI_MEM_H_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB); + REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xEB); + } else if (modebit & SPI_MEM_FASTRD_MODE) { + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI); + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); + if (modebit & SPI_MEM_FREAD_DIO) { +#endif if (g_rom_spiflash_dummy_len_plus[1] == 0) { +#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0xBB); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); + REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xBB); +#endif } else { +#if CONFIG_IDF_TARGET_ESP32 REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0xBB); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_MEM_USR_COMMAND_VALUE, 0xBB); +#endif } } else { +#if CONFIG_IDF_TARGET_ESP32 if ((modebit & SPI_FREAD_QUAD)) { //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x6B); REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x6B); @@ -570,8 +729,21 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_ REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if ((modebit & SPI_MEM_FREAD_QUAD)) { + REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x6B); + } else if ((modebit & SPI_MEM_FREAD_DUAL)) { + REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x3B); + } else { + REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x0B); + } + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]); +#endif } } else { +#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI); if (g_rom_spiflash_dummy_len_plus[1] == 0) { REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); @@ -583,6 +755,18 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_ REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN); //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x03); REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x03); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI); + if (g_rom_spiflash_dummy_len_plus[1] == 0) { + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + } else { + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1); + } + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN); + REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x03); +#endif } if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) { diff --git a/components/spiffs/CMakeLists.txt b/components/spiffs/CMakeLists.txt index 17e5a5587..8a186b44a 100644 --- a/components/spiffs/CMakeLists.txt +++ b/components/spiffs/CMakeLists.txt @@ -13,3 +13,7 @@ set(COMPONENT_PRIV_REQUIRES bootloader_support) register_component() +set_source_files_properties( + "spiffs/src/spiffs_nucleus.c" + PROPERTIES COMPILE_FLAGS + -Wno-tautological-compare) diff --git a/components/spiffs/component.mk b/components/spiffs/component.mk index f245a57e1..54b22b5f7 100644 --- a/components/spiffs/component.mk +++ b/components/spiffs/component.mk @@ -3,3 +3,5 @@ COMPONENT_PRIV_INCLUDEDIRS := . spiffs/src COMPONENT_SRCDIRS := . spiffs/src COMPONENT_SUBMODULES := spiffs + +spiffs/src/spiffs_nucleus.o: CFLAGS += -Wno-tautological-compare diff --git a/components/tcpip_adapter/event_handlers.c b/components/tcpip_adapter/event_handlers.c index 3f606067b..c4f2fc7c1 100644 --- a/components/tcpip_adapter/event_handlers.c +++ b/components/tcpip_adapter/event_handlers.c @@ -17,7 +17,9 @@ #include "esp_event.h" #include "esp_wifi.h" #include "esp_private/wifi.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp_eth.h" +#endif #include "esp_err.h" #include "esp_log.h" @@ -41,7 +43,7 @@ static void handle_sta_stop(void *arg, esp_event_base_t base, int32_t event_id, static void handle_sta_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data); static void handle_sta_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data); static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data); - +#if CONFIG_IDF_TARGET_ESP32 static void handle_eth_start(void *arg, esp_event_base_t base, int32_t event_id, void *data); static void handle_eth_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data); static void handle_eth_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data); @@ -97,6 +99,16 @@ static void handle_eth_disconnected(void *arg, esp_event_base_t base, int32_t ev tcpip_adapter_down(TCPIP_ADAPTER_IF_ETH); } +static void handle_eth_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data) +{ + const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data; + ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, + IP2STR(&event->ip_info.ip), + IP2STR(&event->ip_info.netmask), + IP2STR(&event->ip_info.gw)); +} +#endif + static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data) { API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK); @@ -108,14 +120,6 @@ static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id IP2STR(&event->ip_info.gw)); } -static void handle_eth_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data) -{ - const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data; - ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, - IP2STR(&event->ip_info.ip), - IP2STR(&event->ip_info.netmask), - IP2STR(&event->ip_info.gw)); -} static void handle_ap_start(void *arg, esp_event_base_t base, int32_t event_id, void *data) { @@ -261,7 +265,7 @@ esp_err_t tcpip_adapter_clear_default_wifi_handlers() return ESP_OK; } - +#if CONFIG_IDF_TARGET_ESP32 esp_err_t tcpip_adapter_set_default_eth_handlers() { esp_err_t err; @@ -306,3 +310,4 @@ esp_err_t tcpip_adapter_clear_default_eth_handlers() esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip); return ESP_OK; } +#endif diff --git a/components/ulp/include/esp32s2beta/ulp.h b/components/ulp/include/esp32s2beta/ulp.h new file mode 100644 index 000000000..c9ca51101 --- /dev/null +++ b/components/ulp/include/esp32s2beta/ulp.h @@ -0,0 +1,920 @@ +// 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" + +#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 */ +/**@}*/ + +/**@{*/ +#define ESP_ERR_ULP_BASE 0x1200 /*!< Offset for ULP-related error codes */ +#define ESP_ERR_ULP_SIZE_TOO_BIG (ESP_ERR_ULP_BASE + 1) /*!< Program doesn't fit into RTC memory reserved for the ULP */ +#define ESP_ERR_ULP_INVALID_LOAD_ADDR (ESP_ERR_ULP_BASE + 2) /*!< Load address is outside of RTC memory reserved for the ULP */ +#define ESP_ERR_ULP_DUPLICATE_LABEL (ESP_ERR_ULP_BASE + 3) /*!< More than one label with the same number was defined */ +#define ESP_ERR_ULP_UNDEFINED_LABEL (ESP_ERR_ULP_BASE + 4) /*!< Branch instructions references an undefined label */ +#define ESP_ERR_ULP_BRANCH_OUT_OF_RANGE (ESP_ERR_ULP_BASE + 5) /*!< Branch target is out of range of B instruction (try replacing with BX) */ +/**@}*/ + + +/** + * @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. + */ +typedef union { + + 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 */ + +} 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 */ + +/** + * @brief Resolve all macro references in a program and load it into RTC memory + * @param load_addr address where the program should be loaded, expressed in 32-bit words + * @param program ulp_insn_t array with the program + * @param psize size of the program, expressed in 32-bit words + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM if auxiliary temporary structure can not be allocated + * - one of ESP_ERR_ULP_xxx if program is not valid or can not be loaded + */ +esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* program, size_t* psize); + +/** + * @brief Load ULP program binary into RTC memory + * + * ULP program binary should have the following format (all values little-endian): + * + * 1. MAGIC, (value 0x00706c75, 4 bytes) + * 2. TEXT_OFFSET, offset of .text section from binary start (2 bytes) + * 3. TEXT_SIZE, size of .text section (2 bytes) + * 4. DATA_SIZE, size of .data section (2 bytes) + * 5. BSS_SIZE, size of .bss section (2 bytes) + * 6. (TEXT_OFFSET - 12) bytes of arbitrary data (will not be loaded into RTC memory) + * 7. .text section + * 8. .data section + * + * Linker script in components/ulp/ld/esp32.ulp.ld produces ELF files which + * correspond to this format. This linker script produces binaries with load_addr == 0. + * + * @param load_addr address where the program should be loaded, expressed in 32-bit words + * @param program_binary pointer to program binary + * @param program_size size of the program binary + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if load_addr is out of range + * - ESP_ERR_INVALID_SIZE if program_size doesn't match (TEXT_OFFSET + TEXT_SIZE + DATA_SIZE) + * - ESP_ERR_NOT_SUPPORTED if the magic number is incorrect + */ +esp_err_t ulp_load_binary(uint32_t load_addr, const uint8_t* program_binary, size_t program_size); + +/** + * @brief Run the program loaded into RTC memory + * @param entry_point entry point, expressed in 32-bit words + * @return ESP_OK on success + */ +esp_err_t ulp_run(uint32_t entry_point); + +/** + * @brief Set one of ULP wakeup period values + * + * ULP coprocessor starts running the program when the wakeup timer counts up + * to a given value (called period). There are 5 period values which can be + * programmed into SENS_ULP_CP_SLEEP_CYCx_REG registers, x = 0..4. + * By default, wakeup timer will use the period set into SENS_ULP_CP_SLEEP_CYC0_REG, + * i.e. period number 0. ULP program code can use SLEEP instruction to select + * which of the SENS_ULP_CP_SLEEP_CYCx_REG should be used for subsequent wakeups. + * + * However, please note that SLEEP instruction issued (from ULP program) while the system + * is in deep sleep mode does not have effect, and sleep cycle count 0 is used. + * + * @param period_index wakeup period setting number (0 - 4) + * @param period_us wakeup period, us + * @note The ULP FSM requires two clock cycles to wakeup before being able to run the program. + * Then additional 16 cycles are reserved after wakeup waiting until the 8M clock is stable. + * The FSM also requires two more clock cycles to go to sleep after the program execution is halted. + * The minimum wakeup period that may be set up for the ULP + * is equal to the total number of cycles spent on the above internal tasks. + * For a default configuration of the ULP running at 150kHz it makes about 133us. + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if period_index is out of range + */ +esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/ulp.c b/components/ulp/ulp.c index 31a393b86..fb5760ebd 100644 --- a/components/ulp/ulp.c +++ b/components/ulp/ulp.c @@ -15,19 +15,24 @@ #include #include #include - +#include "sdkconfig.h" #include "esp_attr.h" #include "esp_err.h" #include "esp_log.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/clk.h" #include "esp32/ulp.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#include "esp32s2beta/ulp.h" +#endif #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" #include "soc/sens_reg.h" -#include "sdkconfig.h" + typedef struct { uint32_t magic; @@ -112,7 +117,7 @@ esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us) } uint64_t period_us_64 = period_us; uint64_t period_cycles = (period_us_64 << RTC_CLK_CAL_FRACT) / esp_clk_slowclk_cal_get(); - uint64_t min_sleep_period_cycles = ULP_FSM_PREPARE_SLEEP_CYCLES + uint64_t min_sleep_period_cycles = ULP_FSM_PREPARE_SLEEP_CYCLES + ULP_FSM_WAKEUP_SLEEP_CYCLES + REG_GET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT); if (period_cycles < min_sleep_period_cycles) { diff --git a/components/unity/unity_port_esp32.c b/components/unity/unity_port_esp32.c index 9c1370007..1a25bc1a6 100644 --- a/components/unity/unity_port_esp32.c +++ b/components/unity/unity_port_esp32.c @@ -14,9 +14,14 @@ #include #include "unity.h" #include "sdkconfig.h" +#include "soc/cpu.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/clk.h" #include "esp32/rom/uart.h" -#include "soc/cpu.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/clk.h" +#include "esp32s2beta/rom/uart.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 147c54cb7..2bb365a60 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -25,7 +25,11 @@ #include "driver/uart.h" #include "sdkconfig.h" #include "driver/uart_select.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/uart.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/uart.h" +#endif // TODO: make the number of UARTs chip dependent #define UART_NUM 3 @@ -131,7 +135,11 @@ static void uart_tx_char(int fd, int c) while (uart->status.txfifo_cnt >= 127) { ; } +#if CONFIG_IDF_TARGET_ESP32 uart->fifo.rw_byte = c; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uart->ahb_fifo.rw_byte = c; +#endif } static void uart_tx_char_via_driver(int fd, int c) @@ -146,7 +154,11 @@ static int uart_rx_char(int fd) if (uart->status.rxfifo_cnt == 0) { return NONE; } +#if CONFIG_IDF_TARGET_ESP32 return uart->fifo.rw_byte; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + return uart->ahb_fifo.rw_byte; +#endif } static int uart_rx_char_via_driver(int fd) diff --git a/components/wpa_supplicant/include/crypto/includes.h b/components/wpa_supplicant/include/crypto/includes.h index 263078981..2618589cb 100644 --- a/components/wpa_supplicant/include/crypto/includes.h +++ b/components/wpa_supplicant/include/crypto/includes.h @@ -57,8 +57,11 @@ #endif /* CONFIG_NATIVE_WINDOWS */ #else - +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #endif /* !__ets__ */ diff --git a/components/wpa_supplicant/include/wpa/wpa.h b/components/wpa_supplicant/include/wpa/wpa.h index 14ed2175a..f2ab9898d 100644 --- a/components/wpa_supplicant/include/wpa/wpa.h +++ b/components/wpa_supplicant/include/wpa/wpa.h @@ -15,7 +15,7 @@ #ifndef WPA_H #define WPA_H -#include "esp32/rom/ets_sys.h" +// #include "esp32/rom/ets_sys.h" #include "common.h" #include "wpa/defs.h" #include "wpa/wpa_common.h" @@ -95,7 +95,7 @@ struct wpa_sm { void (*wpa_deauthenticate)(u8 reason_code); void (*wpa_neg_complete)(); struct wpa_gtk_data gd; //used for calllback save param - u16 key_info; //used for txcallback param + u16 key_info; //used for txcallback param }; struct l2_ethhdr { @@ -169,7 +169,7 @@ struct l2_ethhdr { * handler if send_eapol() is used. */ -#define KEYENTRY_TABLE_MAP(key_entry_valid) ((key_entry_valid)%5) +#define KEYENTRY_TABLE_MAP(key_entry_valid) ((key_entry_valid)%5) void wpa_sm_set_state(enum wpa_states state); diff --git a/components/wpa_supplicant/include/wps/wps.h b/components/wpa_supplicant/include/wps/wps.h index 425449574..b9a1b1071 100644 --- a/components/wpa_supplicant/include/wps/wps.h +++ b/components/wpa_supplicant/include/wps/wps.h @@ -9,7 +9,11 @@ #ifndef WPS_H #define WPS_H +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #include "wps_defs.h" #include "esp_wifi_types.h" @@ -1057,7 +1061,7 @@ struct wps_sm *wps_sm_get(void); int wps_ssid_save(u8 *ssid, u8 ssid_len); int wps_key_save(char *key, u8 key_len); int wps_station_wps_register_cb(wps_st_cb_t cb); -int wps_station_wps_unregister_cb(void); +int wps_station_wps_unregister_cb(void); int wps_start_pending(void); int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h index ff1ba9bce..95cceb299 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -19,7 +19,7 @@ #include #include #include "esp_err.h" -#include "esp32/rom/ets_sys.h" +// #include "esp32/rom/ets_sys.h" typedef long os_time_t; @@ -188,7 +188,7 @@ char * os_readfile(const char *name, size_t *len); * OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case * these functions need to be implemented in os_*.c file for the target system. */ - + #ifndef os_malloc #define os_malloc(s) malloc((s)) #endif @@ -204,7 +204,7 @@ char * os_readfile(const char *name, size_t *len); #ifndef os_bzero #define os_bzero(s, n) bzero(s, n) -#endif +#endif #ifndef os_strdup diff --git a/components/wpa_supplicant/src/wps/wps_enrollee.c b/components/wpa_supplicant/src/wps/wps_enrollee.c index b3890c4e8..bd1655f96 100644 --- a/components/wpa_supplicant/src/wps/wps_enrollee.c +++ b/components/wpa_supplicant/src/wps/wps_enrollee.c @@ -5,8 +5,11 @@ * This software may be distributed under the terms of the BSD license. * See README for more details. */ - +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/ets_sys.h" +#endif #include "wpa/includes.h" #include "wpa/common.h" diff --git a/components/xtensa/CMakeLists.txt b/components/xtensa/CMakeLists.txt index 31cbb2703..4127650bb 100644 --- a/components/xtensa/CMakeLists.txt +++ b/components/xtensa/CMakeLists.txt @@ -1,5 +1,8 @@ if(NOT BOOTLOADER_BUILD) - set(COMPONENT_SRCS "eri.c" "trax.c") + set(COMPONENT_SRCS "eri.c") + if(IDF_TARGET STREQUAL "esp32") + list(APPEND COMPONENT_SRCS "trax.c") + endif() endif() set(COMPONENT_ADD_INCLUDEDIRS "include" "${IDF_TARGET}/include") diff --git a/tools/cmake/toolchain-esp32s2beta.cmake b/tools/cmake/toolchain-esp32s2beta.cmake index 32a62cc86..3ec83543a 100644 --- a/tools/cmake/toolchain-esp32s2beta.cmake +++ b/tools/cmake/toolchain-esp32s2beta.cmake @@ -1,8 +1,8 @@ set(CMAKE_SYSTEM_NAME Generic) -set(CMAKE_C_COMPILER xtensa-lx7-elf-gcc) -set(CMAKE_CXX_COMPILER xtensa-lx7-elf-g++) -set(CMAKE_ASM_COMPILER xtensa-lx7-elf-gcc) +set(CMAKE_C_COMPILER xtensa-esp32s2-elf-gcc) +set(CMAKE_CXX_COMPILER xtensa-esp32s2-elf-g++) +set(CMAKE_ASM_COMPILER xtensa-esp32s2-elf-gcc) set(CMAKE_EXE_LINKER_FLAGS "-nostdlib" CACHE STRING "Linker Base Flags") set(CMAKE_C_FLAGS "-mlongcalls" CACHE STRING "C Compiler Base Flags")