Merge branch 'feature/esp32c3_small_changes' into 'master'

esp32c3: Merge small target support changes

Closes IDF-2361

See merge request espressif/esp-idf!11714
This commit is contained in:
Angus Gratton 2020-12-24 12:36:12 +08:00
commit 7a40b1695c
43 changed files with 809 additions and 56 deletions

View File

@ -24,10 +24,13 @@
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/cdc_acm.h"
#include "esp32s2/rom/usb/usb_common.h" #include "esp32s2/rom/usb/usb_common.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h"
#endif #endif
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_rom_caps.h"
#ifdef CONFIG_ESP_CONSOLE_UART_NONE #ifdef CONFIG_ESP_CONSOLE_UART_NONE
void bootloader_console_init(void) void bootloader_console_init(void)
@ -42,7 +45,12 @@ void bootloader_console_init(void)
{ {
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM; const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
#if !ESP_ROM_SUPPORT_MULTIPLE_UART
/* esp_rom_install_channel_put is not available unless multiple UARTs are supported */
esp_rom_install_uart_printf(); esp_rom_install_uart_printf();
#else
esp_rom_install_channel_putc(1, esp_rom_uart_putc);
#endif
// Wait for UART FIFO to be empty. // Wait for UART FIFO to be empty.
esp_rom_uart_tx_wait_idle(0); esp_rom_uart_tx_wait_idle(0);

View File

@ -68,16 +68,7 @@ static esp_err_t initialise_flash_encryption(void)
/* Before first flash encryption pass, need to initialise key & crypto config */ /* Before first flash encryption pass, need to initialise key & crypto config */
/* Find out if a key is already set */ /* Find out if a key is already set */
bool has_aes128 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL); bool has_key = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL);
bool has_aes256_1 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1, NULL);
bool has_aes256_2 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2, NULL);
bool has_key = has_aes128 || (has_aes256_1 && has_aes256_2);
if (!has_key && (has_aes256_1 || has_aes256_2)) {
ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set.");
return ESP_ERR_INVALID_STATE;
}
if (has_key) { if (has_key) {
ESP_LOGI(TAG, "Using pre-existing key in efuse"); ESP_LOGI(TAG, "Using pre-existing key in efuse");
@ -85,15 +76,9 @@ static esp_err_t initialise_flash_encryption(void)
ESP_LOGE(TAG, "TODO: Check key is read & write protected"); // TODO ESP_LOGE(TAG, "TODO: Check key is read & write protected"); // TODO
} else { } else {
ESP_LOGI(TAG, "Generating new flash encryption key..."); ESP_LOGI(TAG, "Generating new flash encryption key...");
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES256
const unsigned BLOCKS_NEEDED = 2;
const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1;
const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2;
#else
const unsigned BLOCKS_NEEDED = 1; const unsigned BLOCKS_NEEDED = 1;
const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY; const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY; const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
#endif
if (ets_efuse_count_unused_key_blocks() < BLOCKS_NEEDED) { if (ets_efuse_count_unused_key_blocks() < BLOCKS_NEEDED) {
ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED); ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);

View File

@ -132,7 +132,7 @@ SECTIONS
{ {
_iram_start = ABSOLUTE(.); _iram_start = ABSOLUTE(.);
/* Vectors go to IRAM */ /* Vectors go to IRAM */
_init_start = ABSOLUTE(.); _vector_table = ABSOLUTE(.);
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
. = 0x0; . = 0x0;
KEEP(*(.WindowVectors.text)); KEEP(*(.WindowVectors.text));

View File

@ -0,0 +1,9 @@
if(IDF_TARGET STREQUAL "esp32c3")
idf_component_register(SRC_DIRS .
INCLUDE_DIRS . ${CMAKE_CURRENT_BINARY_DIR}
REQUIRES unity test_utils esp_common
)
idf_build_set_property(COMPILE_DEFINITIONS "-DESP_TIMER_DYNAMIC_OVERFLOW_VAL" APPEND)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_test_dport_xt_highint5")
endif()

View File

@ -0,0 +1,4 @@
#
# Component Makefile (not used for tests, but CI checks test parity between GNU Make & CMake)
#
COMPONENT_CONFIG_ONLY := 1

View File

@ -0,0 +1,80 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_types.h"
#include "esp32c3/clk.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_heap_caps.h"
#include "idf_performance.h"
#include "unity.h"
#include "test_utils.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "sha/sha_dma.h"
/* Note: Most of the SHA functions are called as part of mbedTLS, so
are tested as part of mbedTLS tests. Only esp_sha() is different.
*/
#define TAG "sha_test"
TEST_CASE("Test esp_sha()", "[hw_crypto]")
{
const size_t BUFFER_SZ = 32 * 1024 + 6; // NB: not an exact multiple of SHA block size
int64_t begin, end;
uint32_t us_sha1;
uint8_t sha1_result[20] = { 0 };
void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha1_expected[20] = { 0xc7, 0xbb, 0xd3, 0x74, 0xf2, 0xf6, 0x20, 0x86,
0x61, 0xf4, 0x50, 0xd5, 0xf5, 0x18, 0x44, 0xcc,
0x7a, 0xb7, 0xa5, 0x4a };
begin = esp_timer_get_time();
esp_sha(SHA1, buffer, BUFFER_SZ, sha1_result);
end = esp_timer_get_time();
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, sha1_result, sizeof(sha1_expected));
us_sha1 = end - begin;
ESP_LOGI(TAG, "esp_sha() 32KB SHA1 in %u us", us_sha1);
free(buffer);
TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA1_32KB, "%dus", us_sha1);
}
TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
{
const void* ptr;
spi_flash_mmap_handle_t handle;
uint8_t sha1_espsha[20] = { 0 };
uint8_t sha1_mbedtls[20] = { 0 };
uint8_t sha256_espsha[32] = { 0 };
uint8_t sha256_mbedtls[32] = { 0 };
const size_t LEN = 1024 * 1024;
/* mmap() 1MB of flash, we don't care what it is really */
esp_err_t err = spi_flash_mmap(0x0, LEN, SPI_FLASH_MMAP_DATA, &ptr, &handle);
TEST_ASSERT_EQUAL_HEX32(ESP_OK, err);
TEST_ASSERT_NOT_NULL(ptr);
/* Compare esp_sha() result to the mbedTLS result, should always be the same */
esp_sha(SHA1, ptr, LEN, sha1_espsha);
int r = mbedtls_sha1_ret(ptr, LEN, sha1_mbedtls);
TEST_ASSERT_EQUAL(0, r);
esp_sha(SHA2_256, ptr, LEN, sha256_espsha);
r = mbedtls_sha256_ret(ptr, LEN, sha256_mbedtls, 0);
TEST_ASSERT_EQUAL(0, r);
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_espsha, sha1_mbedtls, sizeof(sha1_espsha), "SHA1 results should match");
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_espsha, sha256_mbedtls, sizeof(sha256_espsha), "SHA256 results should match");
}

View File

@ -0,0 +1,25 @@
#include "unity.h"
#if CONFIG_COMPILER_STACK_CHECK
static void recur_and_smash(void)
{
static int cnt;
volatile uint8_t buf[50];
volatile int num = sizeof(buf)+10;
if (cnt++ < 1) {
recur_and_smash();
}
for (int i = 0; i < num; i++) {
buf[i] = 0;
}
}
TEST_CASE("stack smashing protection", "[stack_check] [ignore]")
{
recur_and_smash();
}
#endif

View File

@ -0,0 +1,25 @@
#include "unity.h"
#if CONFIG_COMPILER_STACK_CHECK
static void recur_and_smash_cxx(void)
{
static int cnt;
volatile uint8_t buf[50];
volatile int num = sizeof(buf)+10;
if (cnt++ < 1) {
recur_and_smash_cxx();
}
for (int i = 0; i < num; i++) {
buf[i] = 0;
}
}
TEST_CASE("stack smashing protection CXX", "[stack_check] [ignore]")
{
recur_and_smash_cxx();
}
#endif

View File

@ -138,7 +138,7 @@ SECTIONS
{ {
_iram_start = ABSOLUTE(.); _iram_start = ABSOLUTE(.);
/* Vectors go to IRAM */ /* Vectors go to IRAM */
_init_start = ABSOLUTE(.); _vector_table = ABSOLUTE(.);
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
. = 0x0; . = 0x0;
KEEP(*(.WindowVectors.text)); KEEP(*(.WindowVectors.text));

View File

@ -134,7 +134,7 @@ SECTIONS
{ {
_iram_start = ABSOLUTE(.); _iram_start = ABSOLUTE(.);
/* Vectors go to IRAM */ /* Vectors go to IRAM */
_init_start = ABSOLUTE(.); _vector_table = ABSOLUTE(.);
. = 0x0; . = 0x0;
KEEP(*(.WindowVectors.text)); KEEP(*(.WindowVectors.text));
. = 0x180; . = 0x180;

View File

@ -94,9 +94,13 @@ menu "Common ESP-related"
bool bool
default y if ESP_CONSOLE_UART_DEFAULT || ESP_CONSOLE_UART_CUSTOM default y if ESP_CONSOLE_UART_DEFAULT || ESP_CONSOLE_UART_CUSTOM
config ESP_CONSOLE_MULTIPLE_UART
bool
default y if !IDF_TARGET_ESP32C3
choice ESP_CONSOLE_UART_NUM choice ESP_CONSOLE_UART_NUM
prompt "UART peripheral to use for console output (0-1)" prompt "UART peripheral to use for console output (0-1)"
depends on ESP_CONSOLE_UART_CUSTOM depends on ESP_CONSOLE_UART_CUSTOM && ESP_CONSOLE_MULTIPLE_UART
default ESP_CONSOLE_UART_CUSTOM_NUM_0 default ESP_CONSOLE_UART_CUSTOM_NUM_0
help help
This UART peripheral is used for console output from the ESP-IDF Bootloader and the app. This UART peripheral is used for console output from the ESP-IDF Bootloader and the app.
@ -116,6 +120,7 @@ menu "Common ESP-related"
config ESP_CONSOLE_UART_NUM config ESP_CONSOLE_UART_NUM
int int
default 0 if ESP_CONSOLE_UART_DEFAULT default 0 if ESP_CONSOLE_UART_DEFAULT
default 0 if !ESP_CONSOLE_MULTIPLE_UART
default 0 if ESP_CONSOLE_UART_CUSTOM_NUM_0 default 0 if ESP_CONSOLE_UART_CUSTOM_NUM_0
default 1 if ESP_CONSOLE_UART_CUSTOM_NUM_1 default 1 if ESP_CONSOLE_UART_CUSTOM_NUM_1
default -1 if !ESP_CONSOLE_UART default -1 if !ESP_CONSOLE_UART
@ -125,6 +130,7 @@ menu "Common ESP-related"
depends on ESP_CONSOLE_UART_CUSTOM depends on ESP_CONSOLE_UART_CUSTOM
range 0 46 range 0 46
default 1 if IDF_TARGET_ESP32 default 1 if IDF_TARGET_ESP32
default 21 if IDF_TARGET_ESP32C3
default 43 default 43
help help
This GPIO is used for console UART TX output in the ESP-IDF Bootloader and the app (including This GPIO is used for console UART TX output in the ESP-IDF Bootloader and the app (including
@ -138,6 +144,7 @@ menu "Common ESP-related"
depends on ESP_CONSOLE_UART_CUSTOM depends on ESP_CONSOLE_UART_CUSTOM
range 0 46 range 0 46
default 3 if IDF_TARGET_ESP32 default 3 if IDF_TARGET_ESP32
default 20 if IDF_TARGET_ESP32C3
default 44 default 44
help help
This GPIO is used for UART RX input in the ESP-IDF Bootloader and the app (including This GPIO is used for UART RX input in the ESP-IDF Bootloader and the app (including

View File

@ -18,6 +18,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
#include "esp_attr.h"
extern void ets_update_cpu_frequency(uint32_t ticks_per_us); extern void ets_update_cpu_frequency(uint32_t ticks_per_us);
@ -36,7 +37,8 @@ void bootloader_clock_configure(void)
REG_WRITE(RTC_CNTL_STORE4_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16)); REG_WRITE(RTC_CNTL_STORE4_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16));
} }
void bootloader_fill_random(void *buffer, size_t length) /* Placed in IRAM since test_apps expects it to be */
void IRAM_ATTR bootloader_fill_random(void *buffer, size_t length)
{ {
uint8_t *buffer_bytes = (uint8_t *)buffer; uint8_t *buffer_bytes = (uint8_t *)buffer;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {

View File

@ -3,8 +3,7 @@ idf_build_get_property(target IDF_TARGET)
idf_component_register(SRCS "patches/esp_rom_crc.c" idf_component_register(SRCS "patches/esp_rom_crc.c"
"patches/esp_rom_sys.c" "patches/esp_rom_sys.c"
"patches/esp_rom_uart.c" "patches/esp_rom_uart.c"
INCLUDE_DIRS include INCLUDE_DIRS include "${target}"
PRIV_INCLUDE_DIRS "${target}"
PRIV_REQUIRES soc hal) PRIV_REQUIRES soc hal)
# Append a target linker script at the target-specific path, # Append a target linker script at the target-specific path,
@ -33,8 +32,7 @@ if(BOOTLOADER_BUILD)
rom_linker_script("spiflash") rom_linker_script("spiflash")
elseif(target STREQUAL "esp32c3") elseif(target STREQUAL "esp32c3")
# currently nothing additional here rom_linker_script("newlib")
endif() endif()
else() # Regular app build else() # Regular app build

View File

@ -1,6 +1,5 @@
COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_ADD_INCLUDEDIRS := include esp32
COMPONENT_SRCDIRS := patches . COMPONENT_SRCDIRS := patches .
COMPONENT_PRIV_INCLUDEDIRS := esp32
#Linker scripts used to link the final application. #Linker scripts used to link the final application.
#Warning: These linker scripts are only used when the normal app is compiled; the bootloader #Warning: These linker scripts are only used when the normal app is compiled; the bootloader

View File

@ -24,6 +24,8 @@ PROVIDE ( esp_rom_uart_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle ); PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char ); PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_uart_rx_string = UartRxString ); PROVIDE ( esp_rom_uart_rx_string = UartRxString );
PROVIDE ( esp_rom_uart_putc = ets_write_char_uart );
PROVIDE ( esp_rom_md5_init = MD5Init ); PROVIDE ( esp_rom_md5_init = MD5Init );
PROVIDE ( esp_rom_md5_update = MD5Update ); PROVIDE ( esp_rom_md5_update = MD5Update );

View File

@ -1728,10 +1728,9 @@ ieee80211_is_tx_allowed = 0x40001860;
ieee80211_output_pending_eb = 0x40001864; ieee80211_output_pending_eb = 0x40001864;
ieee80211_output_process = 0x40001868; ieee80211_output_process = 0x40001868;
ieee80211_set_tx_desc = 0x4000186c; ieee80211_set_tx_desc = 0x4000186c;
sta_input = 0x40001870; rom_sta_input = 0x40001870;
wifi_get_macaddr = 0x40001874; wifi_get_macaddr = 0x40001874;
wifi_rf_phy_disable = 0x40001878; wifi_rf_phy_disable = 0x40001878;
wifi_rf_phy_enable = 0x4000187c;
ic_ebuf_alloc = 0x40001880; ic_ebuf_alloc = 0x40001880;
ieee80211_classify = 0x40001884; ieee80211_classify = 0x40001884;
ieee80211_copy_eb_header = 0x40001888; ieee80211_copy_eb_header = 0x40001888;

View File

@ -2,7 +2,7 @@
ROM functions for hardware AES support. ROM functions for hardware AES support.
It is not recommended to use these functions directly, It is not recommended to use these functions directly,
use the wrapper functions in aes/esp_aes.h instead. use the wrapper functions in esp32/aes.h instead.
*/ */
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD

View File

@ -0,0 +1,25 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void ets_apb_backup_init_lock_func(void(* _apb_backup_lock)(void), void(* _apb_backup_unlock)(void));
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,38 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
// NOTE: From the view of master
#define CMD_HD_WRBUF_REG 0x01
#define CMD_HD_RDBUF_REG 0x02
#define CMD_HD_WRDMA_REG 0x03
#define CMD_HD_RDDMA_REG 0x04
#define CMD_HD_ONEBIT_MODE 0x00
#define CMD_HD_DOUT_MODE 0x10
#define CMD_HD_QOUT_MODE 0x20
#define CMD_HD_DIO_MODE 0x50
#define CMD_HD_QIO_MODE 0xA0
#define CMD_HD_SEG_END_REG 0x05
#define CMD_HD_EN_QPI_REG 0x06
#define CMD_HD_WR_END_REG 0x07
#define CMD_HD_INT0_REG 0x08
#define CMD_HD_INT1_REG 0x09
#define CMD_HD_INT2_REG 0x0A
#define CMD_HD_EX_QPI_REG 0xDD
#define SPI_SLAVE_HD_BUFFER_SIZE 64

View File

@ -140,6 +140,17 @@ esp_err_t esp_sleep_enable_touchpad_wakeup(void);
*/ */
touch_pad_t esp_sleep_get_touchpad_wakeup_status(void); touch_pad_t esp_sleep_get_touchpad_wakeup_status(void);
/**
* @brief Returns true if a GPIO number is valid for use as wakeup source.
*
* @note For SoCs with RTC IO capability, this can be any valid RTC IO input pin.
*
* @param gpio_num Number of the GPIO to test for wakeup source capability
*
* @return True if this GPIO number will be accepted as a sleep wakeup source.
*/
bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num);
/** /**
* @brief Enable wakeup using a pin * @brief Enable wakeup using a pin
* *

View File

@ -98,7 +98,7 @@ extern int _bss_end;
extern int _rtc_bss_start; extern int _rtc_bss_start;
extern int _rtc_bss_end; extern int _rtc_bss_end;
extern int _init_start; extern int _vector_table;
static const char *TAG = "cpu_start"; static const char *TAG = "cpu_start";
@ -131,7 +131,7 @@ void startup_resume_other_cores(void)
void IRAM_ATTR call_start_cpu1(void) void IRAM_ATTR call_start_cpu1(void)
{ {
cpu_hal_set_vecbase(&_init_start); cpu_hal_set_vecbase(&_vector_table);
ets_set_appcpu_boot_addr(0); ets_set_appcpu_boot_addr(0);
@ -261,7 +261,7 @@ void IRAM_ATTR call_start_cpu0(void)
#endif #endif
// Move exception vectors to IRAM // Move exception vectors to IRAM
cpu_hal_set_vecbase(&_init_start); cpu_hal_set_vecbase(&_vector_table);
rst_reas[0] = rtc_get_reset_reason(0); rst_reas[0] = rtc_get_reset_reason(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
@ -321,14 +321,16 @@ void IRAM_ATTR call_start_cpu0(void)
extern void rom_config_data_cache_mode(uint32_t cfg_cache_size, uint8_t cfg_cache_ways, uint8_t cfg_cache_line_size); extern void rom_config_data_cache_mode(uint32_t cfg_cache_size, uint8_t cfg_cache_ways, uint8_t cfg_cache_line_size);
rom_config_data_cache_mode(CONFIG_ESP32S3_DATA_CACHE_SIZE, CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS, CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE); rom_config_data_cache_mode(CONFIG_ESP32S3_DATA_CACHE_SIZE, CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS, CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE);
Cache_Resume_DCache(0); Cache_Resume_DCache(0);
#endif // CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
/* Configure the Cache MMU size for instruction and rodata in flash. */ /* Configure the Cache MMU size for instruction and rodata in flash. */
extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size); extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size);
extern int _rodata_reserved_start; extern int _rodata_reserved_start;
uint32_t rodata_reserved_start_align = (uint32_t)&_rodata_reserved_start & ~(MMU_PAGE_SIZE - 1); uint32_t rodata_reserved_start_align = (uint32_t)&_rodata_reserved_start & ~(MMU_PAGE_SIZE - 1);
uint32_t cache_mmu_irom_size = ((rodata_reserved_start_align - SOC_DROM_LOW) / MMU_PAGE_SIZE) * sizeof(uint32_t); uint32_t cache_mmu_irom_size = ((rodata_reserved_start_align - SOC_DROM_LOW) / MMU_PAGE_SIZE) * sizeof(uint32_t);
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
#endif #endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
bootloader_init_mem(); bootloader_init_mem();
#if CONFIG_SPIRAM_BOOT_INIT #if CONFIG_SPIRAM_BOOT_INIT

View File

@ -0,0 +1,8 @@
set(srcs "clk.c"
"reset_reason.c"
"../../async_memcpy_impl_gdma.c"
"apb_dma.c"
"../../arch/riscv/panic_arch.c")
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs})
target_sources(${COMPONENT_LIB} PRIVATE ${srcs})

View File

@ -0,0 +1,44 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_attr.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "esp32c3/rom/apb_dma.h"
static portMUX_TYPE apb_backup_mutex = portMUX_INITIALIZER_UNLOCKED;
static void IRAM_ATTR apb_backup_lock(void)
{
if (xPortInIsrContext()) {
portENTER_CRITICAL_ISR(&apb_backup_mutex);
} else {
portENTER_CRITICAL(&apb_backup_mutex);
}
}
static void IRAM_ATTR apb_backup_unlock(void)
{
if (xPortInIsrContext()) {
portEXIT_CRITICAL_ISR(&apb_backup_mutex);
} else {
portEXIT_CRITICAL(&apb_backup_mutex);
}
}
void esp_apb_backup_lock_init(void)
{
ets_apb_backup_init_lock_func(apb_backup_lock, apb_backup_unlock);
}

View File

@ -0,0 +1,321 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "esp32c3/clk.h"
#include "esp_clk_internal.h"
#include "esp32c3/rom/ets_sys.h"
#include "esp32c3/rom/uart.h"
#include "esp32c3/rom/rtc.h"
#include "soc/system_reg.h"
#include "soc/dport_access.h"
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_periph.h"
#include "soc/i2s_reg.h"
#include "hal/wdt_hal.h"
#include "driver/periph_ctrl.h"
//#include "xtensa/core-macros.h"
#include "bootloader_clock.h"
#include "soc/syscon_reg.h"
#include "esp_rom_uart.h"
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
* Larger values increase startup delay. Smaller values may cause false positive
* detection (i.e. oscillator runs for a few cycles and then stops).
*/
#define SLOW_CLK_CAL_CYCLES CONFIG_ESP32C3_RTC_CLK_CAL_CYCLES
#define MHZ (1000000)
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
*/
#define MIN_32K_XTAL_CAL_VAL 15000000L
/* Indicates that this 32k oscillator gets input from external oscillator, rather
* than a crystal.
*/
#define EXT_OSC_FLAG BIT(3)
/* This is almost the same as rtc_slow_freq_t, except that we define
* an extra enum member for the external 32k oscillator.
* For convenience, lower 2 bits should correspond to rtc_slow_freq_t values.
*/
typedef enum {
SLOW_CLK_RTC = RTC_SLOW_FREQ_RTC, //!< Internal 90 kHz RC oscillator
SLOW_CLK_32K_XTAL = RTC_SLOW_FREQ_32K_XTAL, //!< External 32 kHz XTAL
SLOW_CLK_8MD256 = RTC_SLOW_FREQ_8MD256, //!< Internal 8 MHz RC oscillator, divided by 256
SLOW_CLK_32K_EXT_OSC = RTC_SLOW_FREQ_32K_XTAL | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin
} slow_clk_sel_t;
static void select_rtc_slow_clk(slow_clk_sel_t slow_clk);
static const char *TAG = "clk";
__attribute__((weak)) void esp_clk_init(void)
{
#if !CONFIG_IDF_ENV_FPGA
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
rtc_init(cfg);
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
rtc_clk_fast_freq_set(RTC_FAST_FREQ_8M);
#endif
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
// If the frequency changes from 90kHz to 32kHz, then the timeout set for the WDT will increase 2.8 times.
// Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec).
// This prevents excessive delay before resetting in case the supply voltage is drawdown.
// (If frequency is changed from 90kHz to 32kHz then WDT timeout will increased to 1.6sec * 90/32 = 4.5 sec).
wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
wdt_hal_feed(&rtc_wdt_ctx);
//Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
#endif
#if defined(CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS)
select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
#elif defined(CONFIG_ESP32C3_RTC_CLK_SRC_EXT_OSC)
select_rtc_slow_clk(SLOW_CLK_32K_EXT_OSC);
#elif defined(CONFIG_ESP32C3_RTC_CLK_SRC_INT_8MD256)
select_rtc_slow_clk(SLOW_CLK_8MD256);
#else
select_rtc_slow_clk(RTC_SLOW_FREQ_RTC);
#endif
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
// After changing a frequency WDT timeout needs to be set for new frequency.
stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
wdt_hal_feed(&rtc_wdt_ctx);
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
#endif
rtc_cpu_freq_config_t old_config, new_config;
rtc_clk_cpu_freq_get_config(&old_config);
//const uint32_t old_freq_mhz = old_config.freq_mhz;
const uint32_t new_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ;
bool res = rtc_clk_cpu_freq_mhz_to_config(new_freq_mhz, &new_config);
assert(res);
// Wait for UART TX to finish, otherwise some UART output will be lost
// when switching APB frequency
esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
rtc_clk_cpu_freq_set_config(&new_config);
// Re calculate the ccount to make time calculation correct.
// TODO ESP32-C3 IDF-2554 apply same adjustment
//XTHAL_SET_CCOUNT( (uint64_t)XTHAL_GET_CCOUNT() * new_freq_mhz / old_freq_mhz );
}
static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
{
rtc_slow_freq_t rtc_slow_freq = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V;
uint32_t cal_val = 0;
/* number of times to repeat 32k XTAL calibration
* before giving up and switching to the internal RC
*/
int retry_32k_xtal = 3;
do {
if (rtc_slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
/* 32k XTAL oscillator needs to be enabled and running before it can
* be used. Hardware doesn't have a direct way of checking if the
* oscillator is running. Here we use rtc_clk_cal function to count
* the number of main XTAL cycles in the given number of 32k XTAL
* oscillator cycles. If the 32k XTAL has not started up, calibration
* will time out, returning 0.
*/
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
if (slow_clk == SLOW_CLK_32K_XTAL) {
rtc_clk_32k_enable(true);
} else if (slow_clk == SLOW_CLK_32K_EXT_OSC) {
rtc_clk_32k_enable_external();
}
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
if (SLOW_CLK_CAL_CYCLES > 0) {
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
if (retry_32k_xtal-- > 0) {
continue;
}
ESP_EARLY_LOGW(TAG, "32 kHz XTAL not found, switching to internal 90 kHz oscillator");
rtc_slow_freq = RTC_SLOW_FREQ_RTC;
}
}
} else if (rtc_slow_freq == RTC_SLOW_FREQ_8MD256) {
rtc_clk_8m_enable(true, true);
}
rtc_clk_slow_freq_set(rtc_slow_freq);
if (SLOW_CLK_CAL_CYCLES > 0) {
/* TODO: 32k XTAL oscillator has some frequency drift at startup.
* Improve calibration routine to wait until the frequency is stable.
*/
cal_val = rtc_clk_cal(RTC_CAL_RTC_MUX, SLOW_CLK_CAL_CYCLES);
} else {
const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL;
cal_val = (uint32_t) (cal_dividend / rtc_clk_slow_freq_get_hz());
}
} while (cal_val == 0);
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
esp_clk_slowclk_cal_set(cal_val);
}
void rtc_clk_select_rtc_slow_clk(void)
{
select_rtc_slow_clk(RTC_SLOW_FREQ_32K_XTAL);
}
/* This function is not exposed as an API at this point.
* All peripheral clocks are default enabled after chip is powered on.
* This function disables some peripheral clocks when cpu starts.
* These peripheral clocks are enabled when the peripherals are initialized
* and disabled when they are de-initialized.
*/
__attribute__((weak)) void esp_perip_clk_init(void)
{
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
uint32_t common_perip_clk1 = 0;
#if CONFIG_FREERTOS_UNICORE
RESET_REASON rst_reas[1];
#else
RESET_REASON rst_reas[2];
#endif
rst_reas[0] = rtc_get_reset_reason(0);
#if !CONFIG_FREERTOS_UNICORE
rst_reas[1] = rtc_get_reset_reason(1);
#endif
/* For reason that only reset CPU, do not disable the clocks
* that have been enabled before reset.
*/
/* For reason that only reset CPU, do not disable the clocks
* that have been enabled before reset.
*/
if ((rst_reas[0] >= TG0WDT_CPU_RESET && rst_reas[0] <= TG0WDT_CPU_RESET && rst_reas[0] != RTCWDT_BROWN_OUT_RESET)
#if !CONFIG_FREERTOS_UNICORE
|| (rst_reas[1] >= TG0WDT_CPU_RESET && rst_reas[1] <= RTCWDT_CPU_RESET)
#endif
) {
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
} else {
common_perip_clk = SYSTEM_WDG_CLK_EN |
SYSTEM_I2S0_CLK_EN |
#if CONFIG_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
#endif
#if CONFIG_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
#endif
#if CONFIG_CONSOLE_UART_NUM != 2
SYSTEM_UART2_CLK_EN |
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_LEDC_CLK_EN |
SYSTEM_TIMERGROUP1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_TWAI_CLK_EN |
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
common_perip_clk1 = 0;
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
SYSTEM_CRYPTO_SHA_CLK_EN |
SYSTEM_CRYPTO_RSA_CLK_EN;
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
SYSTEM_WIFI_CLK_BT_EN_M |
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
SYSTEM_WIFI_CLK_UNUSED_BIT12;
}
//Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state.
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
#if CONFIG_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
#endif
#if CONFIG_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
#endif
#if CONFIG_CONSOLE_UART_NUM != 2
SYSTEM_UART2_CLK_EN |
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_UHCI1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_I2C_EXT1_CLK_EN |
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
common_perip_clk1 = 0;
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
* the current is not reduced when disable I2S clock.
*/
// TOCK(check replacement)
// REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
// REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
/* Disable some peripheral clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
/* Disable hardware crypto clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
/* Disable WiFi/BT/SDIO clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
/* Set WiFi light sleep clock source to RTC slow clock */
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
/* Enable RNG clock. */
periph_module_enable(PERIPH_RNG_MODULE);
}

View File

@ -0,0 +1,119 @@
// 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_system.h"
#include "esp32c3/rom/rtc.h"
#include "esp_private/system_internal.h"
#include "soc/rtc_periph.h"
static void esp_reset_reason_clear_hint(void);
static esp_reset_reason_t s_reset_reason;
static esp_reset_reason_t get_reset_reason(RESET_REASON rtc_reset_reason, esp_reset_reason_t reset_reason_hint)
{
switch (rtc_reset_reason) {
case POWERON_RESET:
return ESP_RST_POWERON;
case RTC_SW_CPU_RESET:
case RTC_SW_SYS_RESET:
if (reset_reason_hint == ESP_RST_PANIC ||
reset_reason_hint == ESP_RST_BROWNOUT ||
reset_reason_hint == ESP_RST_TASK_WDT ||
reset_reason_hint == ESP_RST_INT_WDT) {
return reset_reason_hint;
}
return ESP_RST_SW;
case DEEPSLEEP_RESET:
return ESP_RST_DEEPSLEEP;
case TG0WDT_SYS_RESET:
return ESP_RST_TASK_WDT;
case TG1WDT_SYS_RESET:
return ESP_RST_INT_WDT;
case RTCWDT_SYS_RESET:
case RTCWDT_RTC_RESET:
case SUPER_WDT_RESET:
case RTCWDT_CPU_RESET: /* unused */
case TG0WDT_CPU_RESET: /* unused */
case TG1WDT_CPU_RESET: /* unused */
return ESP_RST_WDT;
case RTCWDT_BROWN_OUT_RESET:
return ESP_RST_BROWNOUT;
case INTRUSION_RESET: /* unused */
default:
return ESP_RST_UNKNOWN;
}
}
static void __attribute__((constructor)) esp_reset_reason_init(void)
{
esp_reset_reason_t hint = esp_reset_reason_get_hint();
s_reset_reason = get_reset_reason(rtc_get_reset_reason(PRO_CPU_NUM),
hint);
if (hint != ESP_RST_UNKNOWN) {
esp_reset_reason_clear_hint();
}
}
esp_reset_reason_t esp_reset_reason(void)
{
return s_reset_reason;
}
/* Reset reason hint is stored in RTC_RESET_CAUSE_REG, a.k.a. RTC_CNTL_STORE6_REG,
* a.k.a. RTC_ENTRY_ADDR_REG. It is safe to use this register both for the
* deep sleep wake stub entry address and for reset reason hint, since wake stub
* is only used for deep sleep reset, and in this case the reason provided by
* rtc_get_reset_reason is unambiguous.
*
* Same layout is used as for RTC_APB_FREQ_REG (a.k.a. RTC_CNTL_STORE5_REG):
* the value is replicated in low and high half-words. In addition to that,
* MSB is set to 1, which doesn't happen when RTC_CNTL_STORE6_REG contains
* deep sleep wake stub address.
*/
#define RST_REASON_BIT 0x80000000
#define RST_REASON_MASK 0x7FFF
#define RST_REASON_SHIFT 16
/* in IRAM, can be called from panic handler */
void IRAM_ATTR esp_reset_reason_set_hint(esp_reset_reason_t hint)
{
assert((hint & (~RST_REASON_MASK)) == 0);
uint32_t val = hint | (hint << RST_REASON_SHIFT) | RST_REASON_BIT;
REG_WRITE(RTC_RESET_CAUSE_REG, val);
}
/* in IRAM, can be called from panic handler */
esp_reset_reason_t IRAM_ATTR esp_reset_reason_get_hint(void)
{
uint32_t reset_reason_hint = REG_READ(RTC_RESET_CAUSE_REG);
uint32_t high = (reset_reason_hint >> RST_REASON_SHIFT) & RST_REASON_MASK;
uint32_t low = reset_reason_hint & RST_REASON_MASK;
if ((reset_reason_hint & RST_REASON_BIT) == 0 || high != low) {
return ESP_RST_UNKNOWN;
}
return (esp_reset_reason_t) low;
}
static void esp_reset_reason_clear_hint(void)
{
REG_WRITE(RTC_RESET_CAUSE_REG, 0);
}

View File

@ -652,12 +652,21 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void)
return pad_num; return pad_num;
} }
bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num)
{
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
return RTC_GPIO_IS_VALID_GPIO(gpio_num);
#else
return GPIO_IS_VALID_GPIO(gpio_num);
#endif
}
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
{ {
if (level < 0 || level > 1) { if (level < 0 || level > 1) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { if (!esp_sleep_is_valid_wakeup_gpio(gpio_num)) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
@ -689,7 +698,7 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode
if ((mask & 1) == 0) { if ((mask & 1) == 0) {
continue; continue;
} }
if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio); ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio);
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
@ -747,7 +756,7 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
// Translate bit map of RTC IO numbers into the bit map of GPIO numbers // Translate bit map of RTC IO numbers into the bit map of GPIO numbers
uint64_t gpio_mask = 0; uint64_t gpio_mask = 0;
for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) {
if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
continue; continue;
} }
int rtc_pin = rtc_io_number_get(gpio); int rtc_pin = rtc_io_number_get(gpio);

View File

@ -141,7 +141,12 @@ TEST_CASE("check if ROM or Flash is used for functions", "[newlib]")
#if defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM) #if defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM)
TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(atoi));
TEST_ASSERT(fn_in_rom(strtol)); TEST_ASSERT(fn_in_rom(strtol));
#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
/* S3 and C3 always use these from ROM */
TEST_ASSERT(fn_in_rom(atoi));
TEST_ASSERT(fn_in_rom(strtol));
#else #else
/* S2 do not have these in ROM */
TEST_ASSERT_FALSE(fn_in_rom(atoi)); TEST_ASSERT_FALSE(fn_in_rom(atoi));
TEST_ASSERT_FALSE(fn_in_rom(strtol)); TEST_ASSERT_FALSE(fn_in_rom(strtol));
#endif // defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM) #endif // defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM)

View File

@ -26,6 +26,8 @@ void another_external_stack_function(void)
shared_stack_sp = (StackType_t *)get_sp(); shared_stack_sp = (StackType_t *)get_sp();
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
TEST_CASE("test printf using shared buffer stack", "[newlib]") TEST_CASE("test printf using shared buffer stack", "[newlib]")
{ {
portSTACK_TYPE *shared_stack = malloc(SHARED_STACK_SIZE); portSTACK_TYPE *shared_stack = malloc(SHARED_STACK_SIZE);
@ -58,3 +60,5 @@ TEST_CASE("test printf using shared buffer stack", "[newlib]")
vSemaphoreDelete(printf_lock); vSemaphoreDelete(printf_lock);
free(shared_stack); free(shared_stack);
} }
#endif

View File

@ -3,3 +3,4 @@ archive: libriscv.a
entries: entries:
interrupt (noflash_text) interrupt (noflash_text)
vectors (noflash_text) vectors (noflash_text)
stdatomic (noflash_text)

View File

@ -162,7 +162,7 @@ TEST_CASE("probe SD, slot 0, 1-bit", "[sd][test_env=UT_T1_SDCARD][ignore]")
#endif #endif
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
//No runners //No runners
static void test_sdspi_init_bus(spi_host_device_t host, int mosi_pin, int miso_pin, int clk_pin, int dma_chan) static void test_sdspi_init_bus(spi_host_device_t host, int mosi_pin, int miso_pin, int clk_pin, int dma_chan)
{ {
@ -375,7 +375,7 @@ TEST_CASE("SDMMC read/write test (eMMC slot 0, 8 line)", "[sd][test_env=EMMC]")
#endif // WITH_EMMC_TEST #endif // WITH_EMMC_TEST
#endif // SDMMC_HOST_SUPPORTED #endif // SDMMC_HOST_SUPPORTED
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
//No runners //No runners
TEST_CASE("SDMMC read/write test (SD slot 1, in SPI mode)", "[sdspi][test_env=UT_T1_SPIMODE]") TEST_CASE("SDMMC read/write test (SD slot 1, in SPI mode)", "[sdspi][test_env=UT_T1_SPIMODE]")
{ {
@ -401,7 +401,7 @@ TEST_CASE("SDMMC read/write test (SD slot 1, in SPI mode)", "[sdspi][test_env=UT
test_sdspi_deinit_bus(dev_config.host_id); test_sdspi_deinit_bus(dev_config.host_id);
sd_test_board_power_off(); sd_test_board_power_off();
} }
#endif //DISABLED_FOR_TARGETS(ESP32S2) #endif //DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
#if SOC_SDMMC_HOST_SUPPORTED #if SOC_SDMMC_HOST_SUPPORTED
TEST_CASE("reads and writes with an unaligned buffer", "[sd][test_env=UT_T1_SDMODE]") TEST_CASE("reads and writes with an unaligned buffer", "[sd][test_env=UT_T1_SDMODE]")
@ -484,7 +484,7 @@ TEST_CASE("CD input works in SD mode", "[sd][test_env=UT_T1_SDMODE]")
} }
#endif #endif
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
//No runners //No runners
TEST_CASE("CD input works in SPI mode", "[sd][test_env=UT_T1_SPIMODE]") TEST_CASE("CD input works in SPI mode", "[sd][test_env=UT_T1_SPIMODE]")
{ {
@ -558,7 +558,7 @@ TEST_CASE("WP input works in SD mode", "[sd][test_env=UT_T1_SDMODE]")
} }
#endif #endif
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
//No runners //No runners
TEST_CASE("WP input works in SPI mode", "[sd][test_env=UT_T1_SPIMODE]") TEST_CASE("WP input works in SPI mode", "[sd][test_env=UT_T1_SPIMODE]")
{ {

View File

@ -6,6 +6,7 @@ set(srcs
"spi_periph.c" "spi_periph.c"
"ledc_periph.c" "ledc_periph.c"
"rmt_periph.c" "rmt_periph.c"
"soc_memory_layout.c"
"sigmadelta_periph.c" "sigmadelta_periph.c"
"soc_memory_layout.c" "soc_memory_layout.c"
"i2s_periph.c" "i2s_periph.c"

View File

@ -122,7 +122,7 @@ static void send_task(void *param)
static inline void start_task(const test_task_param_t *test_task_param) static inline void start_task(const test_task_param_t *test_task_param)
{ {
xTaskCreate(send_task, "send_task", 4*1024, (void *) test_task_param, 5, NULL); xTaskCreate(send_task, "send_task", 8*1024, (void *) test_task_param, 5, NULL);
} }
static void init(int *uart_fd, int *socket_fd) static void init(int *uart_fd, int *socket_fd)
@ -206,6 +206,9 @@ TEST_CASE("UART can do select()", "[vfs]")
deinit(uart_fd, socket_fd); deinit(uart_fd, socket_fd);
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
// TODO ESP32C3 IDF-2457
TEST_CASE("UART can do poll()", "[vfs]") TEST_CASE("UART can do poll()", "[vfs]")
{ {
int uart_fd; int uart_fd;
@ -267,6 +270,9 @@ TEST_CASE("UART can do poll()", "[vfs]")
deinit(uart_fd, socket_fd); deinit(uart_fd, socket_fd);
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
TEST_CASE("socket can do select()", "[vfs]") TEST_CASE("socket can do select()", "[vfs]")
{ {
int uart_fd; int uart_fd;

View File

@ -325,14 +325,14 @@ TEST_CASE("Can use termios for UART", "[vfs]")
TEST_ASSERT_EQUAL(230423, baudrate); TEST_ASSERT_EQUAL(230423, baudrate);
tios.c_cflag |= BOTHER; tios.c_cflag |= BOTHER;
tios.c_ispeed = tios.c_ospeed = 213; tios.c_ispeed = tios.c_ospeed = 42321;
TEST_ASSERT_EQUAL(0, tcsetattr(uart_fd, TCSANOW, &tios)); TEST_ASSERT_EQUAL(0, tcsetattr(uart_fd, TCSANOW, &tios));
TEST_ASSERT_EQUAL(0, tcgetattr(uart_fd, &tios_result)); TEST_ASSERT_EQUAL(0, tcgetattr(uart_fd, &tios_result));
TEST_ASSERT_EQUAL(BOTHER, tios_result.c_cflag & BOTHER); TEST_ASSERT_EQUAL(BOTHER, tios_result.c_cflag & BOTHER);
TEST_ASSERT_EQUAL(213, tios_result.c_ispeed); TEST_ASSERT_EQUAL(42321, tios_result.c_ispeed);
TEST_ASSERT_EQUAL(213, tios_result.c_ospeed); TEST_ASSERT_EQUAL(42321, tios_result.c_ospeed);
TEST_ASSERT_EQUAL(ESP_OK, uart_get_baudrate(UART_NUM_1, &baudrate)); TEST_ASSERT_EQUAL(ESP_OK, uart_get_baudrate(UART_NUM_1, &baudrate));
TEST_ASSERT_EQUAL(213, baudrate); TEST_ASSERT_EQUAL(42321, baudrate);
memset(&tios_result, 0xFF, sizeof(struct termios)); memset(&tios_result, 0xFF, sizeof(struct termios));
} }

View File

@ -114,6 +114,7 @@ static vfs_semihost_ctx_t s_semhost_ctx[CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS];
static inline int generic_syscall(int sys_nr, int arg1, int arg2, int arg3, int arg4, int* ret_errno) static inline int generic_syscall(int sys_nr, int arg1, int arg2, int arg3, int arg4, int* ret_errno)
{ {
#if !CONFIG_IDF_TARGET_ESP32C3 // TODO ESP32-C3 reenable semihost in C3 IDF-2287
int host_ret, host_errno; int host_ret, host_errno;
if (!esp_cpu_in_ocd_debug_mode()) { if (!esp_cpu_in_ocd_debug_mode()) {
@ -134,6 +135,10 @@ static inline int generic_syscall(int sys_nr, int arg1, int arg2, int arg3, int
:"a2","a3","a4","a5","a6"); :"a2","a3","a4","a5","a6");
*ret_errno = host_errno; *ret_errno = host_errno;
return host_ret; return host_ret;
#else
return 0;
#endif
} }
inline bool ctx_is_unused(const vfs_semihost_ctx_t* ctx) inline bool ctx_is_unused(const vfs_semihost_ctx_t* ctx)

View File

@ -291,6 +291,7 @@ static ssize_t uart_read(int fd, void* data, size_t size)
static int uart_fstat(int fd, struct stat * st) static int uart_fstat(int fd, struct stat * st)
{ {
assert(fd >=0 && fd < 3); assert(fd >=0 && fd < 3);
st->st_blksize = BUFSIZ;
st->st_mode = S_IFCHR; st->st_mode = S_IFCHR;
return 0; return 0;
} }

View File

@ -1,7 +1,3 @@
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "esp32c3")
return() # TODO ESP32-C3 IDF-2180
endif()
idf_component_register(SRCS "Partition.cpp" idf_component_register(SRCS "Partition.cpp"
"SPI_Flash.cpp" "SPI_Flash.cpp"
"WL_Ext_Perf.cpp" "WL_Ext_Perf.cpp"

View File

@ -13,6 +13,8 @@
#include "esp32s2/clk.h" #include "esp32s2/clk.h"
#elif CONFIG_IDF_TARGET_ESP32S3 #elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/clk.h" #include "esp32s3/clk.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/clk.h"
#endif #endif
#include "soc/cpu.h" #include "soc/cpu.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"

View File

@ -1,5 +1,7 @@
idf_build_get_property(target IDF_TARGET) idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "esp32c3")
return()
endif()
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
# bootloader only needs headers from this component # bootloader only needs headers from this component
set(priv_requires soc) set(priv_requires soc)

View File

@ -210,7 +210,7 @@ static int deep_sleep(int argc, char **argv)
} }
if (deep_sleep_args.wakeup_gpio_num->count) { if (deep_sleep_args.wakeup_gpio_num->count) {
int io_num = deep_sleep_args.wakeup_gpio_num->ival[0]; int io_num = deep_sleep_args.wakeup_gpio_num->ival[0];
if (!rtc_gpio_is_valid_gpio(io_num)) { if (!esp_sleep_is_valid_wakeup_gpio(io_num)) {
ESP_LOGE(TAG, "GPIO %d is not an RTC IO", io_num); ESP_LOGE(TAG, "GPIO %d is not an RTC IO", io_num);
return 1; return 1;
} }

View File

@ -1,4 +1,4 @@
CONFIG_IDF_TARGET="esp32s2"
# Enable ULP # Enable ULP
CONFIG_ESP32S2_ULP_COPROC_ENABLED=y CONFIG_ESP32S2_ULP_COPROC_ENABLED=y
CONFIG_ESP32S2_ULP_COPROC_RISCV=y CONFIG_ESP32S2_ULP_COPROC_RISCV=y

View File

@ -0,0 +1,9 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_C_FLAGS "-march=rv32imc" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-march=rv32imc" CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc --specs=nosys.specs" CACHE STRING "Linker Base Flags")

View File

@ -0,0 +1 @@
rsource "../../../Kconfig.extra"