Merge branch 'master' into feature/esp32s2beta_update

This commit is contained in:
Angus Gratton
2019-08-16 19:06:34 +10:00
committed by Angus Gratton
157 changed files with 4014 additions and 1316 deletions

View File

@@ -4,6 +4,34 @@ menu "ESP32-specific"
# not working so we just hide all items here
visible if IDF_TARGET_ESP32
choice ESP32_REV_MIN
prompt "Minimum Supported ESP32 Revision"
default ESP32_REV_MIN_0
help
Minimum revision that ESP-IDF would support.
ESP-IDF performs different strategy on different esp32 revision.
config ESP32_REV_MIN_0
bool "Rev 0"
config ESP32_REV_MIN_1
bool "Rev 1"
config ESP32_REV_MIN_2
bool "Rev 2"
config ESP32_REV_MIN_3
bool "Rev 3"
endchoice
config ESP32_REV_MIN
int
default 0 if ESP32_REV_MIN_0
default 1 if ESP32_REV_MIN_1
default 2 if ESP32_REV_MIN_2
default 3 if ESP32_REV_MIN_3
config ESP32_DPORT_WORKAROUND
bool
default "y" if !FREERTOS_UNICORE && ESP32_REV_MIN < 2
choice ESP32_DEFAULT_CPU_FREQ_MHZ
prompt "CPU frequency"
default ESP32_DEFAULT_CPU_FREQ_160

View File

@@ -204,7 +204,7 @@ void IRAM_ATTR call_start_cpu0(void)
abort();
}
ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1);
esp_flash_enc_mode_t mode;
mode = esp_get_flash_encryption_mode();
if (mode == ESP_FLASH_ENC_MODE_DEVELOPMENT) {
@@ -408,6 +408,16 @@ void start_cpu0_default(void)
esp_flash_app_init();
esp_err_t flash_ret = esp_flash_init_default_chip();
assert(flash_ret == ESP_OK);
uint8_t revision = esp_efuse_get_chip_ver();
ESP_LOGI(TAG, "Chip Revision: %d", revision);
if (revision > CONFIG_ESP32_REV_MIN) {
ESP_LOGW(TAG, "Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.");
} else if(revision != CONFIG_ESP32_REV_MIN) {
ESP_LOGE(TAG, "ESP-IDF can't support this chip revision. Modify minimum supported revision in menuconfig");
abort();
}
#ifdef CONFIG_PM_ENABLE
esp_pm_impl_init();
#ifdef CONFIG_PM_DFS_INIT_AUTO

View File

@@ -16,7 +16,7 @@
* DPORT access is used for do protection when dual core access DPORT internal register and APB register via DPORT simultaneously
* This function will be initialize after FreeRTOS startup.
* When cpu0 want to access DPORT register, it should notify cpu1 enter in high-priority interrupt for be mute. When cpu1 already in high-priority interrupt,
* cpu0 can access DPORT register. Currently, cpu1 will wait for cpu0 finish access and exit high-priority interrupt.
* cpu0 can access DPORT register. Currently, cpu1 will wait for cpu0 finish access and exit high-priority interrupt.
*/
#include <stdint.h>
@@ -116,7 +116,7 @@ void IRAM_ATTR esp_dport_access_stall_other_cpu_end(void)
{
#ifndef CONFIG_FREERTOS_UNICORE
int cpu_id = xPortGetCoreID();
if (dport_core_state[0] == DPORT_CORE_STATE_IDLE
|| dport_core_state[1] == DPORT_CORE_STATE_IDLE) {
return;
@@ -249,7 +249,7 @@ void IRAM_ATTR esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address
*/
uint32_t IRAM_ATTR esp_dport_access_reg_read(uint32_t reg)
{
#if defined(BOOTLOADER_BUILD) || defined(CONFIG_FREERTOS_UNICORE) || !defined(ESP_PLATFORM)
#if defined(BOOTLOADER_BUILD) || !defined(CONFIG_ESP32_DPORT_WORKAROUND) || !defined(ESP_PLATFORM)
return _DPORT_REG_READ(reg);
#else
uint32_t apb;
@@ -295,7 +295,7 @@ uint32_t IRAM_ATTR esp_dport_access_reg_read(uint32_t reg)
*/
uint32_t IRAM_ATTR esp_dport_access_sequence_reg_read(uint32_t reg)
{
#if defined(BOOTLOADER_BUILD) || defined(CONFIG_FREERTOS_UNICORE) || !defined(ESP_PLATFORM)
#if defined(BOOTLOADER_BUILD) || !defined(CONFIG_ESP32_DPORT_WORKAROUND) || !defined(ESP_PLATFORM)
return _DPORT_REG_READ(reg);
#else
uint32_t apb;

View File

@@ -33,7 +33,7 @@ uint32_t esp_dport_access_sequence_reg_read(uint32_t reg);
//only call in case of panic().
void esp_dport_access_int_abort(void);
#if defined(BOOTLOADER_BUILD) || defined(CONFIG_FREERTOS_UNICORE) || !defined(ESP_PLATFORM)
#if defined(BOOTLOADER_BUILD) || !defined(CONFIG_ESP32_DPORT_WORKAROUND) || !defined(ESP_PLATFORM)
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()

View File

@@ -30,10 +30,11 @@
#include "driver/timer.h"
#include "driver/periph_ctrl.h"
#include "esp_int_wdt.h"
#include "hal/timer_ll.h"
#if CONFIG_ESP_INT_WDT
#define TG1_WDT_TICK_US 500
#define WDT_INT_NUM 24
@@ -48,11 +49,15 @@ static void IRAM_ATTR tick_hook(void) {
} else {
//Only feed wdt if app cpu also ticked.
if (int_wdt_app_cpu_ticked) {
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config2=CONFIG_ESP_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt
TIMERG1.wdt_config3=CONFIG_ESP_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset
TIMERG1.wdt_feed=1;
TIMERG1.wdt_wprotect=0;
timer_ll_wdt_set_protect(&TIMERG1, false);
//Set timeout before interrupt
timer_ll_wdt_set_timeout(&TIMERG1, 0,
CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US);
//Set timeout before reset
timer_ll_wdt_set_timeout(&TIMERG1, 1,
2*CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US);
timer_ll_wdt_feed(&TIMERG1);
timer_ll_wdt_set_protect(&TIMERG1, true);
int_wdt_app_cpu_ticked=false;
}
}
@@ -60,33 +65,36 @@ static void IRAM_ATTR tick_hook(void) {
#else
static void IRAM_ATTR tick_hook(void) {
if (xPortGetCoreID()!=0) return;
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config2=CONFIG_ESP_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt
TIMERG1.wdt_config3=CONFIG_ESP_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset
TIMERG1.wdt_feed=1;
TIMERG1.wdt_wprotect=0;
timer_ll_wdt_set_protect(&TIMERG1, false);
//Set timeout before interrupt
timer_ll_wdt_set_timeout(&TIMERG1, 0, CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US);
//Set timeout before reset
timer_ll_wdt_set_timeout(&TIMERG1, 1, 2*CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US);
timer_ll_wdt_feed(&TIMERG1);
timer_ll_wdt_set_protect(&TIMERG1, true);
}
#endif
void esp_int_wdt_init(void) {
periph_module_enable(PERIPH_TIMG1_MODULE);
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS
TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS
TIMERG1.wdt_config0.level_int_en=1;
TIMERG1.wdt_config0.stg0=TIMG_WDT_STG_SEL_INT; //1st stage timeout: interrupt
TIMERG1.wdt_config0.stg1=TIMG_WDT_STG_SEL_RESET_SYSTEM; //2nd stage timeout: reset system
TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS
//The timer configs initially are set to 5 seconds, to make sure the CPU can start up. The tick hook sets
//it to their actual value.
TIMERG1.wdt_config2=10000;
TIMERG1.wdt_config3=10000;
TIMERG1.wdt_config0.en=1;
TIMERG1.wdt_feed=1;
TIMERG1.wdt_wprotect=0;
TIMERG1.int_clr_timers.wdt=1;
timer_group_intr_enable(TIMER_GROUP_1, TIMG_WDT_INT_ENA_M);
timer_ll_wdt_set_protect(&TIMERG1, false);
timer_ll_wdt_init(&TIMERG1);
timer_ll_wdt_set_tick(&TIMERG1, TG1_WDT_TICK_US); //Prescaler: wdt counts in ticks of TG1_WDT_TICK_US
//1st stage timeout: interrupt
timer_ll_wdt_set_timeout_behavior(&TIMERG1, 0, TIMER_WDT_INT);
timer_ll_wdt_set_timeout(&TIMERG1, 0, 5*1000*1000/TG1_WDT_TICK_US);
//2nd stage timeout: reset system
timer_ll_wdt_set_timeout_behavior(&TIMERG1, 1, TIMER_WDT_RESET_SYSTEM);
timer_ll_wdt_set_timeout(&TIMERG1, 1, 5*1000*1000/TG1_WDT_TICK_US);
timer_ll_wdt_set_enable(&TIMERG1, true);
timer_ll_wdt_feed(&TIMERG1);
timer_ll_wdt_set_protect(&TIMERG1, true);
timer_ll_intr_status_clear(&TIMERG1, TIMER_INTR_WDT);
timer_group_intr_enable(TIMER_GROUP_1, TIMER_INTR_WDT);
}
void esp_int_wdt_cpu_init(void)

View File

@@ -44,6 +44,8 @@
#include "esp_private/system_internal.h"
#include "sdkconfig.h"
#include "esp_ota_ops.h"
#include "driver/timer.h"
#include "hal/timer_ll.h"
#if CONFIG_SYSVIEW_ENABLE
#include "SEGGER_RTT.h"
#endif
@@ -311,7 +313,7 @@ void panicHandler(XtExcFrame *frame)
disableAllWdts();
if (frame->exccause == PANIC_RSN_INTWDT_CPU0 ||
frame->exccause == PANIC_RSN_INTWDT_CPU1) {
TIMERG1.int_clr_timers.wdt = 1;
timer_group_clr_intr_sta_in_isr(TIMER_GROUP_1, TIMER_INTR_WDT);
}
#if CONFIG_ESP32_APPTRACE_ENABLE
#if CONFIG_SYSVIEW_ENABLE
@@ -401,19 +403,21 @@ static void illegal_instruction_helper(XtExcFrame *frame)
*/
static void reconfigureAllWdts(void)
{
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed = 1;
TIMERG0.wdt_config0.sys_reset_length = 7; //3.2uS
TIMERG0.wdt_config0.cpu_reset_length = 7; //3.2uS
TIMERG0.wdt_config0.stg0 = TIMG_WDT_STG_SEL_RESET_SYSTEM; //1st stage timeout: reset system
TIMERG0.wdt_config1.clk_prescale = 80 * 500; //Prescaler: wdt counts in ticks of 0.5mS
TIMERG0.wdt_config2 = 2000; //1 second before reset
TIMERG0.wdt_config0.en = 1;
TIMERG0.wdt_wprotect = 0;
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_feed(&TIMERG0);
timer_ll_wdt_init(&TIMERG0);
timer_ll_wdt_set_tick(&TIMERG0, TG0_WDT_TICK_US); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US
//1st stage timeout: reset system
timer_ll_wdt_set_timeout_behavior(&TIMERG0, 0, TIMER_WDT_RESET_SYSTEM);
//1 second before reset
timer_ll_wdt_set_timeout(&TIMERG0, 0, 1000*1000/TG0_WDT_TICK_US);
timer_ll_wdt_set_enable(&TIMERG0, true);
timer_ll_wdt_set_protect(&TIMERG0, true);
//Disable wdt 1
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
timer_ll_wdt_set_protect(&TIMERG1, false);
timer_ll_wdt_set_enable(&TIMERG1, false);
timer_ll_wdt_set_protect(&TIMERG1, true);
}
/*
@@ -421,14 +425,16 @@ static void reconfigureAllWdts(void)
*/
static inline void disableAllWdts(void)
{
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_set_enable(&TIMERG0, false);
timer_ll_wdt_set_protect(&TIMERG0, true);
timer_ll_wdt_set_protect(&TIMERG1, false);
timer_ll_wdt_set_enable(&TIMERG1, false);
timer_ll_wdt_set_protect(&TIMERG1, true);
}
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
static void esp_panic_dig_reset(void) __attribute__((noreturn));
static void esp_panic_dig_reset(void)
@@ -444,6 +450,7 @@ static void esp_panic_dig_reset(void)
;
}
}
#endif
static void putEntry(uint32_t pc, uint32_t sp)
{

View File

@@ -508,6 +508,7 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_mode_t
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
} else if (rd_mode_reg & SPI_FREAD_DIO_M) {
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN_V, SPI0_R_DIO_ADDR_BITSLEN, SPI_USR_ADDR_BITLEN_S);
} else if (rd_mode_reg & (SPI_FREAD_QUAD_M | SPI_FREAD_DUAL_M)) {
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
} else {

View File

@@ -38,6 +38,7 @@
#include "esp_private/system_internal.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "hal/timer_ll.h"
static const char* TAG = "system_api";
@@ -204,7 +205,7 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
ESP_LOGW(TAG, "incorrect mac type");
break;
}
return ESP_OK;
}
@@ -281,12 +282,13 @@ void IRAM_ATTR esp_restart_noos(void)
esp_dport_access_int_abort();
// Disable TG0/TG1 watchdogs
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect=0;
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect=0;
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_set_enable(&TIMERG0, false);
timer_ll_wdt_set_protect(&TIMERG0, true);
timer_ll_wdt_set_protect(&TIMERG1, false);
timer_ll_wdt_set_enable(&TIMERG1, false);
timer_ll_wdt_set_protect(&TIMERG1, true);
// Flush any data left in UART FIFOs
uart_tx_wait_idle(0);
@@ -307,10 +309,10 @@ void IRAM_ATTR esp_restart_noos(void)
WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30);
// Reset wifi/bluetooth/ethernet/sdio (bb/mac)
DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG,
DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG,
DPORT_BB_RST | DPORT_FE_RST | DPORT_MAC_RST |
DPORT_BT_RST | DPORT_BTMAC_RST | DPORT_SDIO_RST |
DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST |
DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST |
DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST);
DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0);
@@ -366,35 +368,27 @@ const char* esp_get_idf_version(void)
return IDF_VER;
}
static void get_chip_info_esp32(esp_chip_info_t* out_info)
void esp_chip_info(esp_chip_info_t* out_info)
{
uint32_t reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
uint32_t efuse_rd3 = REG_READ(EFUSE_BLK0_RDATA3_REG);
memset(out_info, 0, sizeof(*out_info));
out_info->model = CHIP_ESP32;
if ((reg & EFUSE_RD_CHIP_VER_REV1_M) != 0) {
out_info->revision = 1;
}
if ((reg & EFUSE_RD_CHIP_VER_DIS_APP_CPU_M) == 0) {
out_info->revision = esp_efuse_get_chip_ver();
if ((efuse_rd3 & EFUSE_RD_CHIP_VER_DIS_APP_CPU_M) == 0) {
out_info->cores = 2;
} else {
out_info->cores = 1;
}
out_info->features = CHIP_FEATURE_WIFI_BGN;
if ((reg & EFUSE_RD_CHIP_VER_DIS_BT_M) == 0) {
if ((efuse_rd3 & EFUSE_RD_CHIP_VER_DIS_BT_M) == 0) {
out_info->features |= CHIP_FEATURE_BT | CHIP_FEATURE_BLE;
}
int package = (reg & EFUSE_RD_CHIP_VER_PKG_M) >> EFUSE_RD_CHIP_VER_PKG_S;
int package = (efuse_rd3 & EFUSE_RD_CHIP_VER_PKG_M) >> EFUSE_RD_CHIP_VER_PKG_S;
if (package == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 ||
package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 ||
package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
out_info->features |= CHIP_FEATURE_EMB_FLASH;
}
}
void esp_chip_info(esp_chip_info_t* out_info)
{
// Only ESP32 is supported now, in the future call one of the
// chip-specific functions based on sdkconfig choice
return get_chip_info_esp32(out_info);
}

View File

@@ -34,6 +34,8 @@
#include "driver/periph_ctrl.h"
#include "esp_task_wdt.h"
#include "esp_private/system_internal.h"
#include "hal/timer_ll.h"
static const char *TAG = "task_wdt";
@@ -107,9 +109,9 @@ static twdt_task_t *find_task_in_twdt_list(TaskHandle_t handle, bool *all_reset)
static void reset_hw_timer(void)
{
//All tasks have reset; time to reset the hardware timer.
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed=1;
TIMERG0.wdt_wprotect=0;
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_feed(&TIMERG0);
timer_ll_wdt_set_protect(&TIMERG0, true);
//Clear all has_reset flags in list
for (twdt_task_t *task = twdt_config->list; task != NULL; task = task->next){
task->has_reset=false;
@@ -137,11 +139,11 @@ static void task_wdt_isr(void *arg)
twdt_task_t *twdttask;
const char *cpu;
//Reset hardware timer so that 2nd stage timeout is not reached (will trigger system reset)
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed=1;
TIMERG0.wdt_wprotect=0;
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_feed(&TIMERG0);
timer_ll_wdt_set_protect(&TIMERG0, true);
//Acknowledge interrupt
TIMERG0.int_clr_timers.wdt=1;
timer_group_clr_intr_sta_in_isr(TIMER_GROUP_0, TIMER_INTR_WDT);
//We are taking a spinlock while doing I/O (ESP_EARLY_LOGE) here. Normally, that is a pretty
//bad thing, possibly (temporarily) hanging up the 2nd core and stopping FreeRTOS. In this case,
//something bad already happened and reporting this is considered more important
@@ -198,32 +200,33 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic)
//Configure hardware timer
periph_module_enable(PERIPH_TIMG0_MODULE);
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //Disable write protection
TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS
TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS
TIMERG0.wdt_config0.level_int_en=1;
TIMERG0.wdt_config0.stg0=TIMG_WDT_STG_SEL_INT; //1st stage timeout: interrupt
TIMERG0.wdt_config0.stg1=TIMG_WDT_STG_SEL_RESET_SYSTEM; //2nd stage timeout: reset system
TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS
TIMERG0.wdt_config2=twdt_config->timeout*2000; //Set timeout before interrupt
TIMERG0.wdt_config3=twdt_config->timeout*4000; //Set timeout before reset
TIMERG0.wdt_config0.en=1;
TIMERG0.wdt_feed=1;
TIMERG0.wdt_wprotect=0; //Enable write protection
}else{ //twdt_config previously initialized
timer_ll_wdt_set_protect(&TIMERG0, false); //Disable write protection
timer_ll_wdt_init(&TIMERG0);
timer_ll_wdt_set_tick(&TIMERG0, TG0_WDT_TICK_US); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US
//1st stage timeout: interrupt
timer_ll_wdt_set_timeout_behavior(&TIMERG0, 0, TIMER_WDT_INT);
timer_ll_wdt_set_timeout(&TIMERG0, 0, twdt_config->timeout*1000*1000/TG0_WDT_TICK_US);
//2nd stage timeout: reset system
timer_ll_wdt_set_timeout_behavior(&TIMERG0, 1, TIMER_WDT_RESET_SYSTEM);
timer_ll_wdt_set_timeout(&TIMERG0, 1, 2*twdt_config->timeout*1000*1000/TG0_WDT_TICK_US);
timer_ll_wdt_set_enable(&TIMERG0, true);
timer_ll_wdt_feed(&TIMERG0);
timer_ll_wdt_set_protect(&TIMERG0, true); //Enable write protection
} else { //twdt_config previously initialized
//Reconfigure task wdt
twdt_config->panic = panic;
twdt_config->timeout = timeout;
//Reconfigure hardware timer
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //Disable write protection
TIMERG0.wdt_config0.en=0; //Disable timer
TIMERG0.wdt_config2=twdt_config->timeout*2000; //Set timeout before interrupt
TIMERG0.wdt_config3=twdt_config->timeout*4000; //Set timeout before reset
TIMERG0.wdt_config0.en=1; //Renable timer
TIMERG0.wdt_feed=1; //Reset timer
TIMERG0.wdt_wprotect=0; //Enable write protection
timer_ll_wdt_set_protect(&TIMERG0, false); //Disable write protection
timer_ll_wdt_set_enable(&TIMERG0, false); //Disable timer
//Set timeout before interrupt
timer_ll_wdt_set_timeout(&TIMERG0, 0, twdt_config->timeout*1000*1000/TG0_WDT_TICK_US);
//Set timeout before reset
timer_ll_wdt_set_timeout(&TIMERG0, 1, 2*twdt_config->timeout*1000*1000/TG0_WDT_TICK_US);
timer_ll_wdt_set_enable(&TIMERG0, true); //Renable timer
timer_ll_wdt_feed(&TIMERG0); //Reset timer
timer_ll_wdt_set_protect(&TIMERG0, true); //Enable write protection
}
portEXIT_CRITICAL(&twdt_spinlock);
return ESP_OK;
@@ -238,9 +241,9 @@ esp_err_t esp_task_wdt_deinit(void)
ASSERT_EXIT_CRIT_RETURN((twdt_config->list == NULL), ESP_ERR_INVALID_STATE);
//Disable hardware timer
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //Disable write protection
TIMERG0.wdt_config0.en=0; //Disable timer
TIMERG0.wdt_wprotect=0; //Enable write protection
timer_ll_wdt_set_protect(&TIMERG0, false); //Disable write protection
timer_ll_wdt_set_enable(&TIMERG0, false); //Disable timer
timer_ll_wdt_set_protect(&TIMERG0, true); //Enable write protection
ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)); //Unregister interrupt
free(twdt_config); //Free twdt_config

View File

@@ -55,24 +55,20 @@ static void timer_isr(void *arg)
int timer_idx = (int)arg;
count[timer_idx]++;
if (timer_idx==0) {
TIMERG0.int_clr_timers.t0 = 1;
TIMERG0.hw_timer[0].update=1;
TIMERG0.hw_timer[0].config.alarm_en = 1;
timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0);
timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0);
}
if (timer_idx==1) {
TIMERG0.int_clr_timers.t1 = 1;
TIMERG0.hw_timer[1].update=1;
TIMERG0.hw_timer[1].config.alarm_en = 1;
timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_1);
timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_1);
}
if (timer_idx==2) {
TIMERG1.int_clr_timers.t0 = 1;
TIMERG1.hw_timer[0].update=1;
TIMERG1.hw_timer[0].config.alarm_en = 1;
timer_group_intr_clr_in_isr(TIMER_GROUP_1, TIMER_0);
timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_0);
}
if (timer_idx==3) {
TIMERG1.int_clr_timers.t1 = 1;
TIMERG1.hw_timer[1].update=1;
TIMERG1.hw_timer[1].config.alarm_en = 1;
timer_group_intr_clr_in_isr(TIMER_GROUP_1, TIMER_1);
timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_1);
}
// ets_printf("int %d\n", timer_idx);
}
@@ -280,7 +276,7 @@ TEST_CASE("allocate 2 handlers for a same source and remove the later one","[esp
r=esp_intr_alloc(ETS_SPI2_INTR_SOURCE, ESP_INTR_FLAG_SHARED, int_handler2, &ctx, &handle2);
TEST_ESP_OK(r);
SPI2.slave.trans_inten = 1;
printf("trigger first time.\n");
SPI2.slave.trans_done = 1;

View File

@@ -280,11 +280,12 @@ static void timer_group_test_first_stage(void)
//Start timer
timer_start(TIMER_GROUP_0, TIMER_0);
//Waiting for timer_group to generate an interrupt
while( !TIMERG0.int_raw.t0 && loop_cnt++ < 100) {
while( !(timer_group_intr_get_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0) &&
loop_cnt++ < 100) {
vTaskDelay(200);
}
//TIMERG0.int_raw.t0 == 1 means an interruption has occurred
TEST_ASSERT_EQUAL(1, TIMERG0.int_raw.t0);
TEST_ASSERT(timer_group_intr_get_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0);
esp_restart();
}