Compare commits

..

No commits in common. "2bde2d8e309c6b5a56ab135a3d09394dd52e4599" and "41c2b799ad02f18b0306e95b357c092a031f8288" have entirely different histories.

193 changed files with 936 additions and 2920 deletions

View File

@ -60,9 +60,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU for multiarch builds
uses: docker/setup-qemu-action@v3
with:
image: tonistiigi/binfmt:qemu-v7.0.0-28
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push

View File

@ -76,8 +76,4 @@ void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -490,15 +490,6 @@ config BTDM_BLE_VS_QA_SUPPORT
help
This enables BLE vendor HCI command and event for QA.
config BTDM_CTRL_CONTROLLER_DEBUG_MODE_1
bool "Enable Bluetooth controller debugging mode 1 (for internal use only)" if n
default n
depends on BT_ENABLED
help
Enables specific debugging features for the Bluetooth controller.
This option is strictly for internal debugging purposes and should not be enabled in production environments,
as it may impact performance and stability.
config BTDM_RESERVE_DRAM
hex
default 0xdb5c if BT_ENABLED

@ -1 +1 @@
Subproject commit 6093909e01930f8cda6f60510f8a412c6d1814e8
Subproject commit 35fb599d3733f50254c056171edebcaa3c57d06b

View File

@ -723,6 +723,8 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
} else {
APPL_TRACE_ERROR("%s, malloc failed", __func__);
}
} else {
APPL_TRACE_ERROR("%s, incorrect length", __func__);
}
(*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
if (cb_data.req_data.value != NULL) {
@ -731,7 +733,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
}
}
} else {
APPL_TRACE_ERROR("Not a registered service attribute ID: 0x%04x",
APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
p_msg->api_indicate.attr_id);
}
}
@ -921,7 +923,7 @@ void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
**
** Function bta_gatts_show_local_database
**
** Description print local service database
** Description print loacl service database
**
** Returns none.
**

View File

@ -18,7 +18,7 @@
/******************************************************************************
*
* This is the public interface file for the simultaneous advanced
* This is the public interface file for the simulatenous advanced
* audio/video streaming (AV) source and sink of BTA, Broadcom's Bluetooth
* application layer for mobile phones.
*
@ -35,10 +35,6 @@
#if (BTA_AR_INCLUDED == TRUE)
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
** Constants and data types
*****************************************************************************/

View File

@ -23,9 +23,6 @@
#include "stack/a2d_sbc.h"
#if (BTC_AV_INCLUDED == TRUE)
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
** Constants and data types
*****************************************************************************/

View File

@ -4003,6 +4003,7 @@ static void btm_ble_stop_discover(void)
if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
/* Clear the inquiry callback if set */
btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
btm_cb.ble_ctr_cb.inq_var.state &= ~BTM_BLE_SCANNING;
/* stop discovery now */
if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) {

View File

@ -200,7 +200,7 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status,
*p++ = GATT_RSP_READ_MULTI;
p_buf->len = 1;
/* Now walk through the buffers putting the data into the response in order */
/* Now walk through the buffers puting the data into the response in order */
list_t *list = NULL;
const list_node_t *node = NULL;
if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
@ -321,7 +321,7 @@ static BOOLEAN process_read_multi_var_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS sta
*p++ = GATT_RSP_READ_MULTI_VAR;
p_buf->len = 1;
/* Now walk through the buffers putting the data into the response in order */
/* Now walk through the buffers puting the data into the response in order */
list_t *list = NULL;
const list_node_t *node = NULL;
if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
@ -735,7 +735,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
handle_len = 4 + p_uuid->len;
}
/* get the length byte in the response */
/* get the length byte in the repsonse */
if (p_msg->offset == 0) {
*p ++ = op_code + 1;
p_msg->len ++;
@ -788,7 +788,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
** buffer.
**
** Returns TRUE: if data filled successfully.
** FALSE: packet full.
** FALSE: packet full, or format mismatch.
**
*******************************************************************************/
static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len,
@ -831,9 +831,10 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg,
gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid);
p += LEN_UUID_128;
} else {
// UUID format mismatch in sequential attributes
// A new request will be sent with the starting handle of the next attribute
GATT_TRACE_ERROR("format mismatch");
status = GATT_NO_RESOURCES;
break;
/* format mismatch */
}
p_msg->len += info_pair_len[p_msg->offset - 1];
len -= info_pair_len[p_msg->offset - 1];
@ -888,7 +889,7 @@ static tGATT_STATUS gatts_validate_packet_format(UINT8 op_code, UINT16 *p_len,
/* parse uuid now */
if (gatt_parse_uuid_from_cmd (p_uuid_filter, uuid_len, &p) == FALSE ||
p_uuid_filter->len == 0) {
GATT_TRACE_DEBUG("UUID filter does not exist");
GATT_TRACE_DEBUG("UUID filter does not exsit");
reason = GATT_INVALID_PDU;
} else {
len -= p_uuid_filter->len;
@ -1041,7 +1042,7 @@ static void gatts_process_find_info(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
**
** Function gatts_process_mtu_req
**
** Description This function is called to process exchange MTU request.
** Description This function is called to process excahnge MTU request.
** Only used on LE.
**
** Returns void
@ -1054,7 +1055,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
BT_HDR *p_buf;
UINT16 conn_id;
/* BR/EDR connection, send error response */
/* BR/EDR conenction, send error response */
if (p_tcb->att_lcid != L2CAP_ATT_CID) {
gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, FALSE);
} else if (len < GATT_MTU_REQ_MIN_LEN) {
@ -1080,7 +1081,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
attp_send_sr_msg (p_tcb, p_buf);
/* Notify all registered application with new MTU size. Us a transaction ID */
/* of 0, as no response is allowed from applications */
/* of 0, as no response is allowed from applcations */
for (i = 0; i < GATT_MAX_APPS; i ++) {
if (gatt_cb.cl_rcb[i].in_use ) {
@ -1447,7 +1448,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand
}
if ((prepare_record->error_code_app == GATT_SUCCESS)
// update prepare write status for execute write request
// update prepare write status for excute write request
&& (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) {
prepare_record->error_code_app = status;
}
@ -1854,7 +1855,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
break;
case GATT_REQ_FIND_INFO: /* discover char descriptor */
case GATT_REQ_FIND_INFO: /* discover char descrptor */
gatts_process_find_info(p_tcb, op_code, len, p_data);
break;

View File

@ -1058,15 +1058,6 @@ config BT_NIMBLE_HOST_QUEUE_CONG_CHECK
or application layer handling adv packets is slow, it will cause the controller memory
to run out. if enabled, adv packets will be lost when host queue is congested.
config BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT
bool "Gatt-proc preemption protect check"
depends on BT_NIMBLE_ENABLED
default n
help
When BLE and Wireless protocol/IEEE 802.15.4 operate in coexistence, BLE preemption
can disrupt the GATT context,causing the service discovery callback to not be invoked.
A temporary list is maintained to preserve the GATT context and use it in case of preemption.
menu "Host-controller Transport"
config BT_NIMBLE_TRANSPORT_UART
bool "Enable Uart Transport"

@ -1 +1 @@
Subproject commit 553fe4598c6585b2288e6b255604a63b1e6f8485
Subproject commit c42b505ac5442da027d0cb7738a4a1850a09edc7

View File

@ -1942,14 +1942,6 @@
#endif
#endif
#ifndef MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT
#ifdef CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT
#define MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT
#else
#define MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT (0)
#endif
#endif
#ifndef MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN
#ifdef CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN
#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN

View File

@ -205,16 +205,6 @@ the adv packet will be discarded until the memory is restored. */
#define BTDM_BLE_CHAN_ASS_EN (0)
#endif
#if CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1
#define BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 (1 << 1)
#else
#define BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 0
#endif
#ifndef BTDM_CTRL_CONTROLLER_DEBUG_FLAG
#define BTDM_CTRL_CONTROLLER_DEBUG_FLAG (BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 | CONTROLLER_ADV_LOST_DEBUG_BIT)
#endif
#if defined(CONFIG_BTDM_BLE_PING_EN)
#define BTDM_BLE_PING_EN (CONFIG_BTDM_BLE_PING_EN)
#else
@ -234,7 +224,7 @@ the adv packet will be discarded until the memory is restored. */
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
.controller_debug_flag = BTDM_CTRL_CONTROLLER_DEBUG_FLAG, \
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
.mode = BTDM_CONTROLLER_MODE_EFF, \
.ble_max_conn = CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF, \
.bt_max_acl_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF, \

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -23,7 +23,6 @@
#include "hal/gpio_hal.h"
#include "esp_rom_gpio.h"
#include "esp_private/esp_gpio_reserve.h"
#include "esp_private/io_mux.h"
#if (SOC_RTCIO_PIN_COUNT > 0)
#include "hal/rtc_io_hal.h"
@ -633,11 +632,6 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
#if SOC_RTCIO_WAKE_SUPPORTED
if (rtc_gpio_is_valid_gpio(gpio_num)) {
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
// LP_IO Wake-up function does not depend on LP_IO Matrix, but uses its clock to
// sample the wake-up signal, we need to enable the LP_IO clock here.
io_mux_enable_lp_io_clock(gpio_num, true);
#endif
ret = rtc_gpio_wakeup_enable(gpio_num, intr_type);
}
#endif
@ -663,9 +657,6 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num)
#if SOC_RTCIO_WAKE_SUPPORTED
if (rtc_gpio_is_valid_gpio(gpio_num)) {
ret = rtc_gpio_wakeup_disable(gpio_num);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, false);
#endif
}
#endif
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
@ -993,9 +984,6 @@ esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t int
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, true);
#endif
gpio_hal_deepsleep_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type);
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num);
@ -1014,9 +1002,6 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num)
gpio_hal_deepsleep_wakeup_disable(gpio_context.gpio_hal, gpio_num);
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num);
#endif
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, false);
#endif
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
return ESP_OK;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,8 +8,6 @@
#include "esp_log.h"
#include "esp_err.h"
#include "esp_check.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/io_mux.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
@ -47,9 +45,6 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
RTCIO_ENTER_CRITICAL();
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, true);
#endif
rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_RTC);
RTCIO_EXIT_CRITICAL();
@ -62,10 +57,6 @@ esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
RTCIO_ENTER_CRITICAL();
// Select Gpio as Digital Gpio
rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_force_disable_lp_io_clock(gpio_num);
#endif
RTCIO_EXIT_CRITICAL();
return ESP_OK;

View File

@ -423,12 +423,8 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
spi_hal_timing_conf_t temp_timing_conf;
int freq;
esp_err_t ret = spi_hal_cal_clock_conf(&timing_param, &freq, &temp_timing_conf);
SPI_CHECK(ret == ESP_OK, "assigned clock speed not supported", ret);
temp_timing_conf.clock_source = clk_src;
temp_timing_conf.rx_sample_point = dev_config->sample_point;
if (temp_timing_conf.rx_sample_point == SPI_SAMPLING_POINT_PHASE_1) {
SPI_CHECK(spi_ll_master_is_rx_std_sample_supported(), "SPI_SAMPLING_POINT_PHASE_1 is not supported on this chip", ESP_ERR_NOT_SUPPORTED);
}
SPI_CHECK(ret == ESP_OK, "assigned clock speed not supported", ret);
//Allocate memory for device
dev = malloc(sizeof(spi_device_t));
@ -517,15 +513,6 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
#if SOC_SPI_SUPPORT_CLK_RC_FAST
if (handle->cfg.clock_source == SPI_CLK_SRC_RC_FAST) {
// If no transactions from other device, acquire the bus to switch module clock to `SPI_CLK_SRC_DEFAULT`
// because `SPI_CLK_SRC_RC_FAST` will be disabled then, which block following transactions
if (handle->host->cur_cs == DEV_NUM_MAX) {
spi_device_acquire_bus(handle, portMAX_DELAY);
SPI_MASTER_PERI_CLOCK_ATOMIC() {
spi_ll_set_clk_source(handle->host->hal.hw, SPI_CLK_SRC_DEFAULT);
}
spi_device_release_bus(handle);
}
periph_rtc_dig_clk8m_disable();
}
#endif

View File

@ -77,7 +77,6 @@ typedef struct {
delay before the MISO is ready on the line. Leave at 0 unless you know you need a delay. For better timing
performance at high frequency (over 8MHz), it's suggest to have the right value.
*/
spi_sampling_point_t sample_point; ///< Sample point tuning of spi master receiving bit.
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time

View File

@ -1,5 +1,5 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -111,18 +111,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
assert(cal_temp_size == 9);
uint32_t cal_temp = 0;
esp_err_t err = esp_efuse_read_field_blob(cal_temp_efuse, &cal_temp, cal_temp_size);
if (err != ESP_OK) {
*tsens_cal = 0.0;
return err;
}
// BIT(8) stands for sign: 1: negative, 0: positive
*tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
// Currently calibration is not supported on ESP32-C2, IDF-5236
*tsens_cal = 0.0;
return ESP_OK;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -132,18 +132,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
assert(cal_temp_size == 9);
uint32_t cal_temp = 0;
esp_err_t err = esp_efuse_read_field_blob(cal_temp_efuse, &cal_temp, cal_temp_size);
if (err != ESP_OK) {
*tsens_cal = 0.0;
return err;
}
// BIT(8) stands for sign: 1: negative, 0: positive
*tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
// Currently calibration is not supported on ESP32-C6, IDF-5236
*tsens_cal = 0;
return ESP_OK;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -124,18 +124,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
assert(cal_temp_size == 9);
uint32_t cal_temp = 0;
esp_err_t err = esp_efuse_read_field_blob(cal_temp_efuse, &cal_temp, cal_temp_size);
if (err != ESP_OK) {
*tsens_cal = 0.0;
return err;
}
// BIT(8) stands for sign: 1: negative, 0: positive
*tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
// Currently calibration is not supported on ESP32-H2, IDF-5236
*tsens_cal = 0;
return ESP_OK;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -35,6 +35,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t*
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
//TODO: IDF-7482
*tsens_cal = 0;
return ESP_ERR_NOT_SUPPORTED;
}

View File

@ -434,10 +434,7 @@ cleanup:
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
#ifndef CONFIG_TARGET_ETH_PHY_DEVICE_W5500
// only unregister events if the device != W5500, since w5500 doesn't support loopback and we don't register the event
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
#endif
TEST_ESP_OK(esp_event_loop_delete_default());
extra_cleanup();
vEventGroupDelete(eth_event_group);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,7 +22,7 @@
/* ---------------------------- Definitions --------------------------------- */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
// LOOP @<address, name> rx:<received events no.> dr:<dropped events no.>
// LOOP @<address, name> rx:<recieved events no.> dr:<dropped events no.>
#define LOOP_DUMP_FORMAT "LOOP @%p,%s rx:%" PRIu32 " dr:%" PRIu32 "\n"
// handler @<address> ev:<base, id> inv:<times invoked> time:<runtime>
#define HANDLER_DUMP_FORMAT " HANDLER @%p ev:%s,%s inv:%" PRIu32 " time:%lld us\n"
@ -38,7 +38,6 @@
static const char* TAG = "event";
static const char* esp_event_any_base = "any";
static const char* esp_event_handler_cleanup = "cleanup";
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
static SLIST_HEAD(esp_event_loop_instance_list_t, esp_event_loop_instance) s_event_loops =
@ -137,14 +136,29 @@ static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_n
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, data_ptr);
#else
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, post.data.ptr);
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, post.data);
#endif
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
diff = esp_timer_get_time() - start;
handler->invoked++;
handler->time += diff;
xSemaphoreTake(loop->profiling_mutex, portMAX_DELAY);
// At this point handler may be already unregistered.
// This happens in "handler instance can unregister itself" test case.
// To prevent memory corruption error it's necessary to check if pointer is still valid.
esp_event_loop_node_t* loop_node;
esp_event_handler_node_t* handler_node;
SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) {
SLIST_FOREACH(handler_node, &(loop_node->handlers), next) {
if(handler_node == handler) {
handler->invoked++;
handler->time += diff;
}
}
}
xSemaphoreGive(loop->profiling_mutex);
#endif
}
@ -349,8 +363,8 @@ static esp_err_t base_node_remove_handler(esp_event_base_node_t* base_node, int3
if (SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(base_node->id_nodes), it, esp_event_id_node, next);
free(it);
return ESP_OK;
}
return ESP_OK;
}
}
}
@ -374,8 +388,8 @@ static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_
if (SLIST_EMPTY(&(it->handlers)) && SLIST_EMPTY(&(it->id_nodes))) {
SLIST_REMOVE(&(loop_node->base_nodes), it, esp_event_base_node, next);
free(it);
return ESP_OK;
}
return ESP_OK;
}
}
}
@ -384,23 +398,6 @@ static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_
return ESP_ERR_NOT_FOUND;
}
static esp_err_t loop_remove_handler(esp_event_remove_handler_context_t* ctx)
{
esp_event_loop_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(ctx->loop->loop_nodes), next, temp) {
esp_err_t res = loop_node_remove_handler(it, ctx->event_base, ctx->event_id, ctx->handler_ctx, ctx->legacy);
if (res == ESP_OK) {
if (SLIST_EMPTY(&(it->base_nodes)) && SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(ctx->loop->loop_nodes), it, esp_event_loop_node, next);
free(it);
}
return ESP_OK;
}
}
return ESP_ERR_NOT_FOUND;
}
static void handler_instances_remove_all(esp_event_handler_nodes_t* handlers)
{
esp_event_handler_node_t *it, *temp;
@ -438,112 +435,17 @@ static void loop_node_remove_all_handler(esp_event_loop_node_t* loop_node)
static void inline __attribute__((always_inline)) post_instance_delete(esp_event_post_instance_t* post)
{
#if CONFIG_ESP_EVENT_POST_FROM_ISR
if (post->data_allocated)
#endif
{
if (post->data_allocated && post->data.ptr) {
free(post->data.ptr);
}
#else
if (post->data) {
free(post->data);
}
#endif
memset(post, 0, sizeof(*post));
}
static esp_err_t find_and_unregister_handler(esp_event_remove_handler_context_t* ctx)
{
esp_event_handler_node_t *handler_to_unregister = NULL;
esp_event_handler_node_t *handler;
esp_event_loop_node_t *loop_node;
esp_event_base_node_t *base_node;
esp_event_id_node_t *id_node;
SLIST_FOREACH(loop_node, &(ctx->loop->loop_nodes), next) {
// Execute loop level handlers
SLIST_FOREACH(handler, &(loop_node->handlers), next) {
if (ctx->legacy) {
if (handler->handler_ctx->handler == ctx->handler_ctx->handler) {
handler_to_unregister = handler;
break;
}
} else {
if (handler->handler_ctx == ctx->handler_ctx) {
handler_to_unregister = handler;
break;
}
}
}
if (handler_to_unregister != NULL) {
break;
}
SLIST_FOREACH(base_node, &(loop_node->base_nodes), next) {
if (base_node->base == ctx->event_base) {
// Execute base level handlers
SLIST_FOREACH(handler, &(base_node->handlers), next) {
if (ctx->legacy) {
if (handler->handler_ctx->handler == ctx->handler_ctx->handler) {
handler_to_unregister = handler;
break;
}
} else {
if (handler->handler_ctx == ctx->handler_ctx) {
handler_to_unregister = handler;
break;
}
}
}
if (handler_to_unregister != NULL) {
break;
}
SLIST_FOREACH(id_node, &(base_node->id_nodes), next) {
if (id_node->id == ctx->event_id) {
// Execute id level handlers
SLIST_FOREACH(handler, &(id_node->handlers), next) {
if (ctx->legacy) {
if (handler->handler_ctx->handler == ctx->handler_ctx->handler) {
handler_to_unregister = handler;
break;
}
} else {
if (handler->handler_ctx == ctx->handler_ctx) {
handler_to_unregister = handler;
break;
}
}
}
}
}
}
}
}
if (handler_to_unregister == NULL) {
/* handler not found in the lists, return */
return ESP_ERR_NOT_FOUND;
}
if (handler_to_unregister->unregistered) {
/* the handler was found in a list but has already be marked
* as unregistered. It means an event was already created to
* remove from the list. return OK but do nothing */
return ESP_OK;
}
/* handler found in the lists and not already marked as unregistered. Mark it as unregistered
* and post an event to remove it from the lists */
handler_to_unregister->unregistered = true;
if (ctx->legacy) {
/* in case of legacy code, we have to copy the handler_ctx content since it was created in the calling function */
esp_event_handler_instance_context_t *handler_ctx_copy = calloc(1, sizeof(esp_event_handler_instance_context_t));
if (!handler_ctx_copy) {
return ESP_ERR_NO_MEM;
}
handler_ctx_copy->arg = ctx->handler_ctx->arg;
handler_ctx_copy->handler = ctx->handler_ctx->handler;
ctx->handler_ctx = handler_ctx_copy;
}
return esp_event_post_to(ctx->loop, esp_event_handler_cleanup, 0, ctx, sizeof(esp_event_remove_handler_context_t), portMAX_DELAY);
}
/* ---------------------------- Public API --------------------------------- */
esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop)
@ -579,6 +481,14 @@ esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, es
goto on_err;
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
loop->profiling_mutex = xSemaphoreCreateMutex();
if (loop->profiling_mutex == NULL) {
ESP_LOGE(TAG, "create event loop profiling mutex failed");
goto on_err;
}
#endif
SLIST_INIT(&(loop->loop_nodes));
// Create the loop task if requested
@ -624,6 +534,12 @@ on_err:
vSemaphoreDelete(loop->mutex);
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
if (loop->profiling_mutex != NULL) {
vSemaphoreDelete(loop->profiling_mutex);
}
#endif
free(loop);
return err;
@ -650,25 +566,10 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
int64_t remaining_ticks = ticks_to_run;
#endif
while (xQueueReceive(loop->queue, &post, remaining_ticks) == pdTRUE) {
while(xQueueReceive(loop->queue, &post, ticks_to_run) == pdTRUE) {
// The event has already been unqueued, so ensure it gets executed.
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
// check if the event retrieve from the queue is the internal event that is
// triggered when a handler needs to be removed..
if (post.base == esp_event_handler_cleanup) {
assert(post.data.ptr != NULL);
esp_event_remove_handler_context_t* ctx = (esp_event_remove_handler_context_t*)post.data.ptr;
loop_remove_handler(ctx);
// if the handler unregistration request came from legacy code,
// we have to free handler_ctx pointer since it points to memory
// allocated by esp_event_handler_unregister_with_internal
if (ctx->legacy) {
free(ctx->handler_ctx);
}
}
loop->running_task = xTaskGetCurrentTaskHandle();
bool exec = false;
@ -681,30 +582,24 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
SLIST_FOREACH_SAFE(loop_node, &(loop->loop_nodes), next, temp_node) {
// Execute loop level handlers
SLIST_FOREACH_SAFE(handler, &(loop_node->handlers), next, temp_handler) {
if (!handler->unregistered) {
handler_execute(loop, handler, post);
exec |= true;
}
handler_execute(loop, handler, post);
exec |= true;
}
SLIST_FOREACH_SAFE(base_node, &(loop_node->base_nodes), next, temp_base) {
if (base_node->base == post.base) {
// Execute base level handlers
SLIST_FOREACH_SAFE(handler, &(base_node->handlers), next, temp_handler) {
if (!handler->unregistered) {
handler_execute(loop, handler, post);
exec |= true;
}
handler_execute(loop, handler, post);
exec |= true;
}
SLIST_FOREACH_SAFE(id_node, &(base_node->id_nodes), next, temp_id_node) {
if (id_node->id == post.id) {
// Execute id level handlers
SLIST_FOREACH_SAFE(handler, &(id_node->handlers), next, temp_handler) {
if (!handler->unregistered) {
handler_execute(loop, handler, post);
exec |= true;
}
handler_execute(loop, handler, post);
exec |= true;
}
// Skip to next base node
break;
@ -751,10 +646,14 @@ esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop)
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
SemaphoreHandle_t loop_mutex = loop->mutex;
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
SemaphoreHandle_t loop_profiling_mutex = loop->profiling_mutex;
#endif
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
xSemaphoreTake(loop->profiling_mutex, portMAX_DELAY);
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_REMOVE(&s_event_loops, loop, esp_event_loop_instance, next);
portEXIT_CRITICAL(&s_event_loops_spinlock);
@ -784,6 +683,10 @@ esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop)
free(loop);
// Free loop mutex before deleting
xSemaphoreGiveRecursive(loop_mutex);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
xSemaphoreGive(loop_profiling_mutex);
vSemaphoreDelete(loop_profiling_mutex);
#endif
vSemaphoreDelete(loop_mutex);
return ESP_OK;
@ -883,21 +786,24 @@ esp_err_t esp_event_handler_unregister_with_internal(esp_event_loop_handle_t eve
}
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_remove_handler_context_t remove_handler_ctx = {loop, event_base, event_id, handler_ctx, legacy};
/* remove the handler if the mutex is taken successfully.
* otherwise it will be removed from the list later */
esp_err_t res = ESP_FAIL;
if (xSemaphoreTake(loop->mutex, 0) == pdTRUE) {
res = loop_remove_handler(&remove_handler_ctx);
xSemaphoreGive(loop->mutex);
} else {
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
res = find_and_unregister_handler(&remove_handler_ctx);
xSemaphoreGiveRecursive(loop->mutex);
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
esp_event_loop_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(loop->loop_nodes), next, temp) {
esp_err_t res = loop_node_remove_handler(it, event_base, event_id, handler_ctx, legacy);
if (res == ESP_OK && SLIST_EMPTY(&(it->base_nodes)) && SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(loop->loop_nodes), it, esp_event_loop_node, next);
free(it);
break;
}
}
return res;
xSemaphoreGiveRecursive(loop->mutex);
return ESP_OK;
}
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
@ -941,10 +847,12 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
}
memcpy(event_data_copy, event_data, event_data_size);
post.data.ptr = event_data_copy;
#if CONFIG_ESP_EVENT_POST_FROM_ISR
post.data.ptr = event_data_copy;
post.data_allocated = true;
post.data_set = true;
#else
post.data = event_data_copy;
#endif
}
post.base = event_base;
@ -986,7 +894,7 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_received, 1);
atomic_fetch_add(&loop->events_recieved, 1);
#endif
return ESP_OK;
@ -1034,7 +942,7 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_ba
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_received, 1);
atomic_fetch_add(&loop->events_recieved, 1);
#endif
return ESP_OK;
@ -1063,13 +971,13 @@ esp_err_t esp_event_dump(FILE* file)
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_FOREACH(loop_it, &s_event_loops, next) {
uint32_t events_received, events_dropped;
uint32_t events_recieved, events_dropped;
events_received = atomic_load(&loop_it->events_received);
events_recieved = atomic_load(&loop_it->events_recieved);
events_dropped = atomic_load(&loop_it->events_dropped);
PRINT_DUMP_INFO(dst, sz, LOOP_DUMP_FORMAT, loop_it, loop_it->task != NULL ? loop_it->name : "none",
events_received, events_dropped);
PRINT_DUMP_INFO(dst, sz, LOOP_DUMP_FORMAT, loop_it, loop_it->task != NULL ? loop_it->name : "none" ,
events_recieved, events_dropped);
int sz_bak = sz;

View File

@ -1,8 +1,16 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// 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.
#ifndef ESP_EVENT_INTERNAL_H_
#define ESP_EVENT_INTERNAL_H_
@ -31,7 +39,6 @@ typedef struct esp_event_handler_node {
int64_t time; /**< total runtime of this handler across all calls */
#endif
SLIST_ENTRY(esp_event_handler_node) next; /**< next event handler in the list */
bool unregistered;
} esp_event_handler_node_t;
typedef SLIST_HEAD(esp_event_handler_instances, esp_event_handler_node) esp_event_handler_nodes_t;
@ -77,24 +84,21 @@ typedef struct esp_event_loop_instance {
esp_event_loop_nodes_t loop_nodes; /**< set of linked lists containing the
registered handlers for the loop */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_uint_least32_t events_received; /**< number of events successfully posted to the loop */
atomic_uint_least32_t events_recieved; /**< number of events successfully posted to the loop */
atomic_uint_least32_t events_dropped; /**< number of events dropped due to queue being full */
SemaphoreHandle_t profiling_mutex; /**< mutex used for profiliing */
SLIST_ENTRY(esp_event_loop_instance) next; /**< next event loop in the list */
#endif
} esp_event_loop_instance_t;
typedef struct esp_event_remove_handler_context_t {
esp_event_loop_instance_t* loop; /**< Instance of the event loop from which the handler has to be removed */
esp_event_base_t event_base; /**< The event base identification of the handler that has to be removed */
int32_t event_id; /**< The event identification value of the handler that has to be removed */
esp_event_handler_instance_context_t* handler_ctx; /**< The handler context of the handler that has to be removed */
bool legacy; /**< Set to true when the handler unregistration request was made from legacy code */
} esp_event_remove_handler_context_t;
#if CONFIG_ESP_EVENT_POST_FROM_ISR
typedef union esp_event_post_data {
uint32_t val;
void *ptr;
} esp_event_post_data_t;
#else
typedef void* esp_event_post_data_t;
#endif
/// Event posted to the event queue
typedef struct esp_event_post_instance {

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -8,7 +8,6 @@
#include <stdio.h>
#include <string.h>
#include "inttypes.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -1572,167 +1571,3 @@ TEST_CASE("default event loop: registering event handler instance without instan
TEST_ESP_OK(esp_event_loop_delete_default());
}
#if CONFIG_ESP_EVENT_LOOP_PROFILING
static void handler_all(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
}
static void handler_base(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
}
static void handler_id(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
}
/* This test executes the following steps:
* 1) register handler_id for a event id A and event base B,
* 2) register handler_base for a given event base,
* 3) register handler_all for on the loop level,
* 4) post an event (A, B),
* 5) call esp_event_dump and make sure by parsing the string IN PYTEST ENVIRONMENT that
* all handlers profiling data is printed
* 6) unregister the handlers successfully */
TEST_CASE("profiling reports valid values", "[event][default]")
{
TEST_ESP_OK(esp_event_loop_create_default());
/* register handler for event base 1 and event id 1 */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id, NULL));
/* register handler for event base 1 and all event ids */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, ESP_EVENT_ANY_ID, handler_base, NULL));
/* register handler for all event bases and all event ids */
TEST_ESP_OK(esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, handler_all, NULL));
/* post an event on event base 1, event id 1 */
TEST_ESP_OK(esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000)));
/* post an event 1 from base 1 and check the dump.
* - 3 handlers invoked, exec time is not 0 */
esp_event_dump(stdout);
/* unregister handlers */
TEST_ESP_OK(esp_event_handler_unregister(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, handler_all));
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, ESP_EVENT_ANY_ID, handler_base));
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id));
/* delete loop */
TEST_ESP_OK(esp_event_loop_delete_default());
}
static void handler_id2(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("event received: base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
/* self unregistering handler */
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id2));
/* register a new handler on id level */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id, NULL));
}
/* This test executes the following steps:
* 1) register handler_id2 for a given event id and event base,
* 2) post an event to trigger the handler_id2,
* 3) unregister the handler_id2 during the execution of the handler_id2 and register
* handler_id instead.
* 4) call esp_event_dump and make sure by parsing the string IN PYTEST ENVIRONMENT that
* 1 handler profiling data is printed
* 5) unregister the handler_id successfully */
TEST_CASE("esp_event_dump does not show self unregistered handler", "[event][default]")
{
TEST_ESP_OK(esp_event_loop_create_default());
/* register handler for event base 1 and event id 1 */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id2, NULL));
/* post an event on event base 1, event id 1 */
TEST_ESP_OK(esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000)));
/* post an event 1 from base 1 and check the dump.
* - 1 handler invoked 0 times, exec time is 0 us */
esp_event_dump(stdout);
/* unregister handler id */
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id));
/* delete loop */
TEST_ESP_OK(esp_event_loop_delete_default());
}
static SemaphoreHandle_t s_event_mutex;
static StaticSemaphore_t s_event_mutex_buf;
static size_t s_handler_triggered = 0;
static void self_unregistering_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
xSemaphoreTake(s_event_mutex, portMAX_DELAY);
/* self unregistering handler */
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, self_unregistering_handler));
s_handler_triggered++;
xSemaphoreGive(s_event_mutex);
}
/* This test makes sure that once a handler is unregistered, it is never called again.
* This test follows the update in esp event unregistration process where a handler can
* be marked as unregistered but not removed directly from the list it belongs to.
* The test creates a handler triggered by a specific combination of event base / event id
* and generates 2 consecutive events that should trigger the handler. The handler unregisters
* itself. Make sure that the second event does not trigger the handler again.
*
* Both event posts need to be queued before the unregistration happens, to make sure that event if
* the handler is still present in the handlers lists when the second event triggers, it will not
* be called. To make sure of that, the execution of the handler is blocked by a mutex released from
* test after the 2 events are posted. */
TEST_CASE("self unregistered handlers are never called again after they return", "[event][default]")
{
s_event_mutex = xSemaphoreCreateMutexStatic(&s_event_mutex_buf);
TEST_ASSERT_NOT_NULL(s_event_mutex);
esp_err_t ret = esp_event_loop_create_default();
printf("esp_event_loop_create_default %d\n", ret);
TEST_ESP_OK(ret);
/* register handler for event base 1 and event id 1 */
ret = esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, self_unregistering_handler, NULL);
printf("esp_event_handler_register %d\n", ret);
TEST_ESP_OK(ret);
/* take the mutex to block the execution of the self_unregistering_handler */
xSemaphoreTake(s_event_mutex, portMAX_DELAY);
/* post 2 times the event on event base 1, event id 1 */
ret = esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000));
printf("esp_event_post %d\n", ret);
TEST_ESP_OK(ret);
ret = esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000));
printf("esp_event_post %d\n", ret);
TEST_ESP_OK(ret);
/* release the mutex to execute the self_unregistering_handler */
xSemaphoreGive(s_event_mutex);
/* make sure the handler was called only once */
TEST_ASSERT(s_handler_triggered == 1);
/* delete mutex */
vSemaphoreDelete(s_event_mutex);
/* reset the static variable in case the test gets called once more */
s_handler_triggered = 0;
/* delete loop */
ret = esp_event_loop_delete_default();
printf("esp_event_loop_delete_default %d\n", ret);
TEST_ESP_OK(ret);
}
#endif // CONFIG_ESP_EVENT_LOOP_PROFILING

View File

@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@ -42,28 +43,3 @@ def test_esp_event_posix_simulator(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests.')
dut.write('*')
dut.expect(r'\d{2} Tests 0 Failures 0 Ignored', timeout=120)
@pytest.mark.esp32
@pytest.mark.generic
def test_esp_event_profiling(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests.')
dut.write('"profiling reports valid values"')
# look for all references of handlers invoked at least 1 time
# with an execution time superior to 0 us
matches = dut.expect(r'HANDLER .+ inv:[1-9][0-9]{0,} time:[1-9][0-9]{0,} us', timeout=2)
matches_arr = matches.group().split(b'\r\n')
assert (len(matches_arr) == 3)
dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120)
dut.expect_exact("Enter next test, or 'enter' to see menu")
dut.write('"esp_event_dump does not show self unregistered handler"')
# look for 1 handlers never invoked
matches = dut.expect(r'HANDLER .+ inv:0 time:0 us', timeout=2)
matches_arr = matches.group().split(b'\r\n')
assert (len(matches_arr) == 1)
dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120)
dut.expect_exact("Enter next test, or 'enter' to see menu")
dut.write('"self unregistered handlers are never called again after they return"')
dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120)

View File

@ -1,3 +0,0 @@
# This configuration checks the event loop if posting from ISR is disabled
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_POST_EVENTS_FROM_ISR=n

View File

@ -1,17 +0,0 @@
menu "ESP HID"
config ESPHID_TASK_SIZE_BT
int "Task stack size for ESP HID BR/EDR"
range 2048 10240
default 2048
help
This is the stack size for the BT HID task.
Default is 2048 bytes.
config ESPHID_TASK_SIZE_BLE
int "Task stack size for ESP HID BLE"
range 2048 10240
default 4096
help
This is the stack size for the BLE HID task.
Default is 4096 bytes.
endmenu

View File

@ -1,8 +1,16 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
@ -86,19 +94,6 @@ extern "C" {
#define ESP_HID_CCC_NOTIFICATIONS_ENABLED 0x01 // Notifications enabled
#define ESP_HID_CCC_INDICATIONS_ENABLED 0x02 // Indications enabled
/* HID Task Size configuration */
#ifdef CONFIG_ESPHID_TASK_SIZE_BT
#define BT_HID_DEVICE_TASK_SIZE_BT CONFIG_ESPHID_TASK_SIZE_BT
#else
#define BT_HID_DEVICE_TASK_SIZE_BT 2048
#endif
#ifdef CONFIG_ESPHID_TASK_SIZE_BLE
#define BT_HID_DEVICE_TASK_SIZE_BLE CONFIG_ESPHID_TASK_SIZE_BLE
#else
#define BT_HID_DEVICE_TASK_SIZE_BLE 4096
#endif
/* HID Transports */
typedef enum {
ESP_HID_TRANSPORT_BT,
@ -208,8 +203,8 @@ esp_hid_report_map_t *esp_hid_parse_report_map(const uint8_t *hid_rm, size_t hid
void esp_hid_free_report_map(esp_hid_report_map_t *map);
/**
* @brief Calculate the HID Device usage type from the BLE Appearance
* @param appearance : BLE Appearance value
* @brief Calculate the HID Device usage type from the BLE Apperance
* @param appearance : BLE Apperance value
*
* @return: the hid usage type
*/

View File

@ -976,7 +976,7 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf
.queue_size = 5,
.task_name = "ble_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = BT_HID_DEVICE_TASK_SIZE_BLE,
.task_stack_size = 4096,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_dev->event_loop_handle);

View File

@ -810,7 +810,7 @@ esp_err_t esp_bt_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_confi
.queue_size = 5,
.task_name = "bt_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = BT_HID_DEVICE_TASK_SIZE_BT,
.task_stack_size = 2048,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_hidd_param.dev->event_loop_handle);

View File

@ -1,17 +1,13 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_err.h"
#include "soc/clk_tree_defs.h"
#include "soc/gpio_num.h"
#include "soc/soc_caps.h"
#include "soc/io_mux_reg.h"
#ifdef __cplusplus
extern "C" {
@ -30,26 +26,6 @@ extern "C" {
*/
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
typedef struct {
uint8_t rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM];
uint32_t rtc_io_using_mask;
} rtc_io_status_t;
/**
* Enable/Disable LP_IO peripheral clock.
* @param gpio_num GPIO number
* @param enable true to enable the clock / false to disable the clock
*/
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable);
/**
* Force disable one LP_IO to clock dependency
* @param gpio_num GPIO number
*/
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -168,13 +168,9 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void);
/**
* @brief Enable wakeup by timer
* @param time_in_us time before wakeup, in microseconds
* @note The valid `time_in_us` value depends on the bit width of the lp_timer/rtc_timer counter and the
* current slow clock source selection (Refer RTC clock source configuration in menuconfig).
* Valid values should be positive values less than RTC slow clock period * (2 ^ RTC timer bitwidth).
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if value is out of range.
* - ESP_ERR_INVALID_ARG if value is out of range (TBD)
*/
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);
@ -415,10 +411,8 @@ esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_
*
* This function enables an IO pin to wake up the chip from deep sleep.
*
* @note 1.This function does not modify pin configuration. The pins are configured
* inside `esp_deep_sleep_start`, immediately before entering sleep mode.
* 2.This function is also applicable to waking up the lightsleep when the peripheral
* power domain is powered off, see PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP in menuconfig.
* @note This function does not modify pin configuration. The pins are
* configured inside esp_deep_sleep_start, immediately before entering sleep mode.
*
* @note You don't need to worry about pull-up or pull-down resistors before
* using this function because the ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS
@ -453,12 +447,7 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee
* wakeup level, for each GPIO which is used for wakeup.
* Then call this function to enable wakeup feature.
*
* @note 1. On ESP32, GPIO wakeup source can not be used together with touch or ULP wakeup sources.
* 2. If PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is enabled (if target supported),
* this API is unavailable since the GPIO module is powered down during sleep.
* You can use `esp_deep_sleep_enable_gpio_wakeup` instead, or use EXT1 wakeup source
* by `esp_sleep_enable_ext1_wakeup_io` to achieve the same function.
* (Only GPIOs which have RTC functionality can be used)
* @note On ESP32, GPIO wakeup source can not be used together with touch or ULP wakeup sources.
*
* @return
* - ESP_OK on success
@ -474,9 +463,7 @@ esp_err_t esp_sleep_enable_gpio_wakeup(void);
* Wakeup from light sleep takes some time, so not every character sent
* to the UART can be received by the application.
*
* @note 1. ESP32 does not support wakeup from UART2.
* 2. If PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is enabled (if target supported),
* this API is unavailable since the UART module is powered down during sleep.
* @note ESP32 does not support wakeup from UART2.
*
* @param uart_num UART port to wake up from
* @return

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -235,12 +235,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
}
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
void rtc_sleep_low_init(uint32_t slowclk_period)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
/* Read back 'reject' status when waking from light or deep sleep */

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -145,9 +145,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -193,12 +193,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
void rtc_sleep_low_init(uint32_t slowclk_period)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -159,9 +159,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -244,12 +244,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
void rtc_sleep_low_init(uint32_t slowclk_period)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -162,9 +162,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -237,9 +237,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -236,9 +236,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -198,9 +198,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,67 +1,13 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_attr.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() \
for (int _rc_cnt = 1; \
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--)
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{
// IO MUX clock source is not selectable
return ESP_OK;
}
extern portMUX_TYPE rtc_spinlock;
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static rtc_io_status_t s_rtc_io_status = {
.rtc_io_enabled_cnt = { 0 },
.rtc_io_using_mask = 0
};
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
}
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++;
} else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) {
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--;
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
}
}
RTCIO_RCC_ATOMIC() {
if (s_rtc_io_status.rtc_io_using_mask == 0) {
rtcio_ll_enable_io_clock(false);
} else {
rtcio_ll_enable_io_clock(true);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -249,11 +249,11 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
void rtc_sleep_low_init(uint32_t slowclk_period)
{
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
}
/* Read back 'reject' status when waking from light or deep sleep */

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -227,9 +227,9 @@ uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,67 +1,13 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_attr.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() \
for (int _rc_cnt = 1; \
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--)
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{
// IO MUX clock source is not selectable
return ESP_OK;
}
extern portMUX_TYPE rtc_spinlock;
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static rtc_io_status_t s_rtc_io_status = {
.rtc_io_enabled_cnt = { 0 },
.rtc_io_using_mask = 0
};
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
}
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++;
} else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) {
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--;
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
}
}
RTCIO_RCC_ATOMIC() {
if (s_rtc_io_status.rtc_io_using_mask == 0) {
rtcio_ll_enable_io_clock(false);
} else {
rtcio_ll_enable_io_clock(true);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}

View File

@ -19,7 +19,6 @@
#include "esp_hw_log.h"
#include "hal/clk_tree_ll.h"
#include "hal/regi2c_ctrl_ll.h"
#include "hal/rtc_io_ll.h"
#include "esp_private/regi2c_ctrl.h"
#include "soc/regi2c_dig_reg.h"
#include "soc/sens_reg.h"
@ -66,7 +65,7 @@ void rtc_clk_32k_enable(bool enable)
void rtc_clk_32k_enable_external(void)
{
PIN_INPUT_ENABLE(IO_MUX_GPIO15_REG);
rtcio_ll_enable_io_clock(true);
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN);
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, RTC_CNTL_X32P_HOLD);
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -256,12 +256,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
void rtc_sleep_low_init(uint32_t slowclk_period)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -161,9 +161,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -12,13 +12,10 @@
#include "esp_attr.h"
#include "esp_memory_utils.h"
#include "esp_sleep.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_timer_private.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/sleep_event.h"
#include "esp_private/system_internal.h"
#include "esp_private/io_mux.h"
#include "esp_log.h"
#include "esp_newlib.h"
#include "esp_timer.h"
@ -877,7 +874,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
rtc_sleep_init(config);
// Set state machine time for light sleep
rtc_sleep_low_init(s_config.rtc_clk_cal_period, deep_sleep);
if (!deep_sleep) {
rtc_sleep_low_init(s_config.rtc_clk_cal_period);
}
#endif
// Configure timer wakeup
@ -1489,10 +1488,6 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void)
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
{
if (time_in_us > ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ ) {
return ESP_ERR_INVALID_ARG;
}
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
s_config.sleep_duration = time_in_us;
return ESP_OK;
@ -1611,9 +1606,6 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
static void ext0_wakeup_prepare(void)
{
int rtc_gpio_num = s_config.ext0_rtc_gpio_num;
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
rtcio_ll_enable_io_clock(true);
#endif
rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level);
rtcio_hal_function_select(rtc_gpio_num, RTCIO_LL_FUNC_RTC);
rtcio_hal_input_enable(rtc_gpio_num);
@ -1743,9 +1735,6 @@ static void ext1_wakeup_prepare(void)
if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) {
continue;
}
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
rtcio_ll_enable_io_clock(true);
#endif
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
// Route pad to RTC
rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_RTC);
@ -1817,9 +1806,6 @@ static void gpio_deep_sleep_wakeup_prepare(void)
if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
continue;
}
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
rtcio_ll_enable_io_clock(true);
#endif
#if CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS
if (s_config.gpio_trigger_mode & BIT(gpio_idx)) {
ESP_ERROR_CHECK(gpio_pullup_dis(gpio_idx));
@ -1868,9 +1854,6 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee
esp_err_t esp_sleep_enable_gpio_wakeup(void)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
ESP_LOGW(TAG, "%s wakeup source is not available if the peripheral power domain is powered down in sleep", "GPIO");
#endif
#if CONFIG_IDF_TARGET_ESP32
if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
@ -1883,9 +1866,6 @@ esp_err_t esp_sleep_enable_gpio_wakeup(void)
esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
ESP_LOGW(TAG, "%s wakeup source is not available if the peripheral power domain is powered down in sleep", "UART");
#endif
if (uart_num == UART_NUM_0) {
s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
} else if (uart_num == UART_NUM_1) {

View File

@ -351,7 +351,7 @@ IRAM_ATTR esp_err_t esp_mmu_paddr_find_caps(const esp_paddr_t paddr, mmu_mem_cap
}
//now we are only traversing the actual dynamically allocated blocks, dummy_head and dummy_tail are excluded already
if (paddr >= mem_block->paddr_start && paddr < mem_block->paddr_end) {
if (mem_block->paddr_start == paddr) {
found = true;
found_block = mem_block;
break;

View File

@ -50,23 +50,3 @@ TEST_CASE("Can dump mapped block stats", "[mmu]")
TEST_ESP_OK(esp_mmu_unmap(ptr1));
TEST_ESP_OK(esp_mmu_unmap(ptr2));
}
TEST_CASE("Can find paddr caps by any paddr offset", "[mmu]")
{
const esp_partition_t *part = s_get_partition();
ESP_LOGI(TAG, "found partition '%s' at offset 0x%"PRIx32" with size 0x%"PRIx32, part->label, part->address, part->size);
void *ptr0 = NULL;
TEST_ESP_OK(esp_mmu_map(part->address, TEST_BLOCK_SIZE, MMU_TARGET_FLASH0, MMU_MEM_CAP_READ, 0, &ptr0));
mmu_mem_caps_t caps = 0;
TEST_ESP_OK(esp_mmu_paddr_find_caps(part->address, &caps));
ESP_LOGI(TAG, "caps: 0x%x", caps);
TEST_ASSERT(caps == MMU_MEM_CAP_READ);
TEST_ESP_OK(esp_mmu_paddr_find_caps(part->address + 0x100, &caps));
ESP_LOGI(TAG, "caps: 0x%x", caps);
TEST_ASSERT(caps == MMU_MEM_CAP_READ);
TEST_ESP_OK(esp_mmu_unmap(ptr0));
}

View File

@ -144,17 +144,12 @@ menu "Power Management"
depends on SOC_PAU_SUPPORTED
default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252)
help
If enabled, digital peripherals will try to powered down in light sleep, then all related peripherals will
not be available during sleep, including wake-up sources from the peripherals (For detailed availability
information, see the note of the corresponding wakeup source enable function).
The chip will automatically save/restore register context during sleep/wakeup to make the upper layer
user unaware of the peripheral powerdown during sleep. Enabling this option will increase static RAM and
heap usage but will also significantly reduce power.
consumption during lightsleep, the actual memory cost depends on the peripherals you have initialized,
for specific power consumption data in this mode, please refer to Electrical Characteristics section
in the chip datasheet.
(In order to save/restore the context of the necessary hardware for FreeRTOS to run, it will need
at least 4.55 KB free heap at sleep time. Otherwise sleep will not power down the peripherals.)
If enabled, digital peripherals will be powered down in light sleep, it will reduce sleep
current consumption by about 100 uA. Chip will save/restore register context at sleep/wake
time to keep the system running. Enabling this option will increase static RAM and heap usage,
the actual cost depends on the peripherals you have initialized. In order to save/restore the
context of the necessary hardware for FreeRTOS to run, it will need at least 4.55 KB free heap
at sleep time. Otherwise sleep will not power down the peripherals.
Note1: Please use this option with caution, the current IDF does not support the retention of
all peripherals. When the digital peripherals are powered off and a sleep and wake-up is completed,
@ -169,14 +164,6 @@ menu "Power Management"
of freertos to not be compensated correctly when returning from sleep and cause the system to crash.
To avoid this, you can increase FREERTOS_IDLE_TIME_BEFORE_SLEEP threshold in menuconfig.
Note3: Enabling this option does not necessarily mean that the peripheral power domain will be
turned down during sleep. The control priority of `esp_sleep_pd_config` is higher than this option,
user code can still prevent the peripheral power domain from powering down during sleep by
`esp_sleep_pd_config(ESP_PD_DOMAIN_TOP, ESP_PD_OPTION_ON)`. In addition, whether the peripheral power
domain is powered down during sleep also depends on the sleep working strategy selected by the driver.
If any module belonging to the peripheral power domain chooses not to be powered down during sleep,
then the peripheral power domain will not be powered off either.
config PM_UPDATE_CCOMPARE_HLI_WORKAROUND
bool
default y if PM_ENABLE && BTDM_CTRL_HLI

View File

@ -21,13 +21,14 @@
extern uint32_t rom_Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped);
uint32_t Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped)
{
uint32_t page0_before_count = *page0_mapped;
uint32_t flash_pages = 0;
flash_pages = rom_Cache_Count_Flash_Pages(bus, page0_mapped);
/* No page mapped to page0 yet, in this condition, the rom api will return
/* No page mapped to page0, in this condition, the rom api will return
* unexpected value + 1.
*/
if (*page0_mapped == 0) {
if (page0_before_count == *page0_mapped) {
flash_pages--;
}
return flash_pages;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,6 +18,8 @@
#define SPI_IDX 1
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
#if CONFIG_IDF_TARGET_ESP32
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
@ -103,12 +105,6 @@ __attribute__((__unused__)) esp_rom_spiflash_result_t esp_rom_spiflash_clear_bp(
}
esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void) __attribute__((alias("esp_rom_spiflash_clear_bp")));
#endif // CONFIG_IDF_TARGET_ESP32
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
#if CONFIG_IDF_TARGET_ESP32
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi);
//only support spi1

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -92,14 +92,6 @@ bool esp_usb_console_write_available(void);
*/
esp_err_t esp_usb_console_set_cb(esp_usb_console_cb_t rx_cb, esp_usb_console_cb_t tx_cb, void* arg);
/**
* @brief Call the USB interrupt handler while any interrupts
* are pending, but not more than a few times. Non-static to
* allow placement into IRAM by ldgen.
*
*/
void esp_usb_console_poll_interrupts(void); // [refactor-todo] Remove when implementing IDF-12175
#ifdef __cplusplus
}
#endif

View File

@ -13,7 +13,6 @@
#include "esp_log.h"
#include "esp_chip_info.h"
#include "esp_app_format.h"
#include "esp_efuse.h"
#include "esp_private/cache_err_int.h"
@ -752,26 +751,18 @@ void IRAM_ATTR call_start_cpu0(void)
// Read the application binary image header. This will also decrypt the header if the image is encrypted.
__attribute__((unused)) esp_image_header_t fhdr = {0};
#if CONFIG_APP_BUILD_TYPE_RAM
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO;
fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2;
fhdr.spi_size = ESP_IMAGE_FLASH_SIZE_4MB;
bootloader_flash_unlock();
#endif
#else
// We can access the image header through the cache by reading from the memory-mapped virtual DROM start offset
uint32_t fhdr_src_addr = (uint32_t)(&_rodata_reserved_start) - sizeof(esp_image_header_t) - sizeof(esp_image_segment_header_t);
hal_memcpy(&fhdr, (void *) fhdr_src_addr, sizeof(fhdr));
if (fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
ESP_EARLY_LOGE(TAG, "Invalid app image header");
abort();
}
// This assumes that DROM is the first segment in the application binary, i.e. that we can read
// the binary header through cache by accessing SOC_DROM_LOW address.
hal_memcpy(&fhdr, (void *) SOC_DROM_LOW, sizeof(fhdr));
#endif // CONFIG_APP_BUILD_TYPE_RAM
#endif // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#if CONFIG_IDF_TARGET_ESP32

View File

@ -19,7 +19,6 @@
#include "soc/rtc.h" // for wakeup trigger defines
#include "soc/rtc_periph.h" // for read rtc registers directly (cause)
#include "soc/soc.h" // for direct register read macros
#include "esp_clk_tree.h"
#include "esp_newlib.h"
#include "test_utils.h"
#include "sdkconfig.h"
@ -27,7 +26,6 @@
#include "esp_rom_sys.h"
#include "esp_timer.h"
#include "esp_private/esp_clk.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/uart_private.h"
#include "esp_random.h"
#include "nvs_flash.h"
@ -59,10 +57,6 @@ static void deep_sleep_task(void *arg)
static void do_deep_sleep_from_app_cpu(void)
{
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_sleep_enable_timer_wakeup(UINT64_MAX));
uint64_t lp_timer_max_allowed_time_in_us = ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ;
TEST_ASSERT_EQUAL(ESP_OK, esp_sleep_enable_timer_wakeup(lp_timer_max_allowed_time_in_us));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_sleep_enable_timer_wakeup(lp_timer_max_allowed_time_in_us + 1));
esp_sleep_enable_timer_wakeup(2000000);
xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1);

View File

@ -1,92 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/errno.h>
#include "unity.h"
#include "esp_private/usb_console.h"
#include "esp_vfs_cdcacm.h"
static void flush_write(void)
{
fflush(stdout);
fsync(fileno(stdout));
}
static void test_setup(const char* func_name, const size_t func_name_size)
{
/* write the name of the test back to the pytest environment to start the test */
write(fileno(stdout), func_name, func_name_size);
write(fileno(stdout), "\n", 1);
flush_write();
}
static bool wait_for_read_ready(FILE *stream)
{
int fd = fileno(stream);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
/* call select to wait for either a read ready or an except to happen */
int nread = select(fd + 1, &read_fds, NULL, NULL, NULL);
if ((nread >= 0) && (FD_ISSET(fd, &read_fds))) {
return true;
} else {
return false;
}
}
static void test_usb_cdc_read_non_blocking(void)
{
test_setup(__func__, sizeof(__func__));
const size_t max_read_bytes = 16;
char read_data_buffer[max_read_bytes];
memset(read_data_buffer, 0x00, max_read_bytes);
/* reset errno to 0 for the purpose of the test to make sure it is no
* longer set to EWOULDBLOCK later in the test. */
errno = 0;
/* make sure to read in non blocking mode */
int stdin_fd = fileno(stdin);
int flags = fcntl(stdin_fd, F_GETFL);
flags |= O_NONBLOCK;
int res = fcntl(stdin_fd, F_SETFL, flags);
TEST_ASSERT(res == 0);
/* call read when no data is available for reading.
* expected result:
* - read returns -1 and errno has been set to EWOULDBLOCK */
int nread = read(stdin_fd, read_data_buffer, max_read_bytes);
TEST_ASSERT(nread == -1);
TEST_ASSERT(errno == EWOULDBLOCK);
/* reset errno to 0 for the purpose of the test to make sure it is no
* longer set to EWOULDBLOCK later in the test. */
errno = 0;
/* call read X number of bytes when less than X number of
* bytes are available for reading (Y bytes).
* expected result:
* - read returns at least 1 bytes errno is not set to EWOULDBLOCK */
char message_8[] = "send_bytes\n";
write(fileno(stdout), message_8, sizeof(message_8));
flush_write();
const bool is_ready = wait_for_read_ready(stdin);
TEST_ASSERT(is_ready);
nread = read(stdin_fd, read_data_buffer, max_read_bytes);
TEST_ASSERT(nread >= 1);
TEST_ASSERT(errno != EWOULDBLOCK);
}
void app_main(void)
{
test_usb_cdc_read_non_blocking();
}

View File

@ -1,20 +0,0 @@
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.usb_device
@pytest.mark.parametrize(
'port, flash_port, config',
[
pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'release'),
],
indirect=True,)
@pytest.mark.parametrize('test_message', ['test123456789!@#%^&*'])
def test_usb_cdc_vfs_default(dut: Dut, test_message: str) -> None:
# test run: test_usb_cdc_read_non_blocking
dut.expect_exact('test_usb_cdc_read_non_blocking', timeout=2)
dut.expect_exact('send_bytes', timeout=2)
dut.write('abcdefgh')

@ -1 +1 @@
Subproject commit 1b54a5565502faaacc257d7d94fcff482bcb6d83
Subproject commit 7d365e96bafc85d2d2a8ddbfe2a022907d81c5fe

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -200,28 +200,15 @@ static int elf_add_segment(core_dump_elf_t *self,
return data_len;
}
/*
* Example Note Segment
* +================================================================+
* | Offset | +0 | +1 | +2 | +3 | Description |
* +----------------------------------------------------------------+
* | 0 | 0x05 | 0x00 | 0x00 | 0x00 | namesz = 5 |
* | 4 | 0x06 | 0x00 | 0x00 | 0x00 | descsz = 6 |
* | 8 | 0x01 | 0x00 | 0x00 | 0x00 | type = 1 |
* | 12 | 'C' | 'O' | 'R' | 'E' | name ("CORE") |
* | 16 | 0x00 | pad | pad | pad | NULL + padding |
* | 20 | 0x1 | 0x2 | 0x3 | 0x4 | desc (6 bytes) |
* | 24 | 0x5 | 0x6 | pad | pad | desc + padding |
* +================================================================+
*/
static int elf_write_note_header(core_dump_elf_t *self, const char* name, uint32_t data_sz, uint32_t type)
static int elf_write_note_header(core_dump_elf_t *self,
const char* name, uint32_t name_len, uint32_t data_sz, uint32_t type)
{
// temporary aligned buffer for note name
static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 };
elf_note note_hdr = { 0 };
size_t name_len = strlcpy(name_buffer, name, sizeof(name_buffer));
note_hdr.n_namesz = name_len + 1; /* name_buffer must be null terminated */
memcpy(name_buffer, name, name_len);
note_hdr.n_namesz = ALIGN_UP(name_len + 1, 4);
note_hdr.n_descsz = data_sz;
note_hdr.n_type = type;
// write note header
@ -229,7 +216,7 @@ static int elf_write_note_header(core_dump_elf_t *self, const char* name, uint32
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
"Write ELF note header failure (%d)", err);
// write note name
err = esp_core_dump_write_data(&self->write_data, name_buffer, ALIGN_UP(note_hdr.n_namesz, 4));
err = esp_core_dump_write_data(&self->write_data, name_buffer, note_hdr.n_namesz);
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
"Write ELF note name failure (%d)", err);
@ -243,17 +230,18 @@ static int elf_write_note(core_dump_elf_t *self,
uint32_t data_sz)
{
esp_err_t err = ESP_FAIL;
uint32_t name_len = strlen(name) + 1; // get name length including terminator
uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator
uint32_t data_len = ALIGN_UP(data_sz, 4);
ELF_CHECK_ERR((name_len <= ELF_NOTE_NAME_MAX_SIZE), 0,
"Segment note name is too long %d.", name_len);
uint32_t note_size = ALIGN_UP(name_len, 4) + ALIGN_UP(data_sz, 4) + sizeof(elf_note);
uint32_t note_size = ALIGN_UP(name_len + data_len + sizeof(elf_note), 4);
// write segment data during second pass
if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, "Invalid data pointer %x.", (uint32_t)data);
err = elf_write_note_header(self, name, data_sz, type);
err = elf_write_note_header(self, name, strlen(name), data_sz, type);
if (err != ESP_OK) {
return err;
}
@ -262,8 +250,8 @@ static int elf_write_note(core_dump_elf_t *self,
// which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary.
err = esp_core_dump_write_data(&self->write_data, data, data_sz);
if (err == ESP_OK) {
const int pad_size = ALIGN_UP(data_sz, 4) - data_sz;
if (pad_size > 0) {
int pad_size = data_len - data_sz;
if (pad_size != 0) {
uint8_t pad_bytes[3] = {0};
ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size);
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
@ -555,7 +543,7 @@ static void elf_write_core_dump_note_cb(void *opaque, const char *data)
static int elf_add_wdt_panic_details(core_dump_elf_t *self)
{
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); /* len includes the null terminator */
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME) - 1;
core_dump_elf_opaque_t param = {
.self = self,
.total_size = 0,
@ -569,25 +557,27 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self)
self->note_data_size = param.total_size;
} else if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
esp_err_t err = elf_write_note_header(self,
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
self->note_data_size,
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
name_len,
self->note_data_size,
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
if (err != ESP_OK) {
return err;
}
esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, &param, NULL);
ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err);
const int pad_size = ALIGN_UP(self->note_data_size, 4) - self->note_data_size;
if (pad_size > 0) {
const uint32_t mod = self->note_data_size & 3;
if (mod != 0) {
uint8_t pad_bytes[3] = {0};
uint32_t pad_size = 4 - mod;
ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size);
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err);
}
}
return ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note);
return ALIGN_UP(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4);
}
#endif //CONFIG_ESP_TASK_WDT_EN
@ -849,17 +839,17 @@ static void esp_core_dump_parse_note_section(uint8_t *coredump_data, elf_note_co
size_t consumed_note_sz = 0;
while (consumed_note_sz < ph->p_memsz) {
const elf_note *note = (const elf_note *)(coredump_data + ph->p_offset + consumed_note_sz);
for (size_t idx = 0; idx < size; ++idx) {
if (target_notes[idx].n_type == note->n_type) {
char *nm = (char *)&note[1];
target_notes[idx].n_ptr = nm + ALIGN_UP(note->n_namesz, 4);
for (size_t idx = 0; idx < size; ++idx) {
if (target_notes[idx].n_type == note->n_type) {
char *nm = (char *)&note[1];
target_notes[idx].n_ptr = nm + note->n_namesz;
target_notes[idx].n_descsz = note->n_descsz;
ESP_COREDUMP_LOGD("%d bytes target note (%X) found in the note section",
note->n_descsz, note->n_type);
break;
}
}
consumed_note_sz += ALIGN_UP(note->n_namesz, 4) + ALIGN_UP(note->n_descsz, 4) + sizeof(elf_note);
note->n_descsz, note->n_type);
break;
}
}
consumed_note_sz += ALIGN_UP(note->n_namesz + note->n_descsz + sizeof(elf_note), 4);
}
}
}

View File

@ -249,7 +249,7 @@ static esp_err_t esp_core_dump_get_regs_from_stack(void* stack_addr,
for (int i = 0; i < XT_SOL_AR_NUM; i++) {
regs->ar[i] = stack_arr[XT_SOL_AR_START + i];
}
regs->pc = (regs->pc & 0x3fffffff);
if (regs->pc & 0x80000000) {
regs->pc = (regs->pc & 0x3fffffff);
}

View File

@ -251,13 +251,13 @@ function(esptool_py_partition_needs_encryption retencrypted partition_name)
# - DATA 0x01
# Subtypes:
# - ota 0x00
# - nvs_keys 0x04
# If the partition is an app, an OTA or an NVS keys partition, then it should
# - nvs 0x02
# If the partition is an app, an OTA or an NVS partition, then it should
# be encrypted
if(
(${type} EQUAL 0) OR
(${type} EQUAL 1 AND ${subtype} EQUAL 0) OR
(${type} EQUAL 1 AND ${subtype} EQUAL 4)
(${type} EQUAL 1 AND ${subtype} EQUAL 2)
)
set(encrypted TRUE)
endif()

View File

@ -607,25 +607,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -663,7 +644,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(SPI1.clock) reg = {.val = 0};
typeof(SPI1.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -696,25 +696,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -752,7 +733,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -698,25 +698,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -754,7 +735,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -690,25 +690,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -746,7 +727,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -61,9 +61,14 @@ static inline void modem_syscon_ll_enable_modem_sec_clock(modem_syscon_dev_t *hw
}
__attribute__((always_inline))
static inline void modem_syscon_ll_enable_ble_timer_clock(modem_syscon_dev_t *hw, bool en)
static inline void modem_syscon_ll_enable_ble_timer_apb(modem_syscon_dev_t *hw, bool en)
{
hw->clk_conf.clk_ble_timer_apb_en = en;
}
__attribute__((always_inline))
static inline void modem_syscon_ll_enable_ble_timer_clock(modem_syscon_dev_t *hw, bool en)
{
hw->clk_conf.clk_ble_timer_en = en;
}

View File

@ -20,13 +20,11 @@
#include "esp_types.h"
#include "soc/spi_periph.h"
#include "soc/spi_struct.h"
#include "soc/chip_revision.h"
#include "soc/pcr_struct.h"
#include "soc/lldesc.h"
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/efuse_hal.h"
#include "hal/spi_types.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
@ -691,26 +689,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
* This config take effect only when SPI_CLK (pre-div before periph) div >=2
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
hw->clock.clk_edge_sel = (sample_point == SPI_SAMPLING_POINT_PHASE_1);
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102);
}
/**
* Set the clock for master by stored value.
*
@ -748,7 +726,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -707,25 +707,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -763,7 +744,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -112,7 +112,7 @@ static inline intptr_t memprot_ll_peri1_rtcslow_get_fault_address(void)
static inline bool memprot_ll_peri1_rtcslow_is_intr_mine(void)
{
if (memprot_ll_peri1_is_assoc_intr()) {
if (memprot_ll_dram0_is_assoc_intr()) {
uint32_t faulting_address = (uint32_t)memprot_ll_peri1_rtcslow_get_fault_address();
return faulting_address >= PERI1_RTCSLOW_ADDRESS_LOW && faulting_address <= PERI1_RTCSLOW_ADDRESS_HIGH;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,7 +13,6 @@
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include "soc/rtc_io_struct.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_periph.h"
@ -26,7 +25,7 @@ extern "C" {
#endif
typedef enum {
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */
RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
} rtcio_ll_func_t;
@ -52,16 +51,6 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, 0x3, func, rtc_io_desc[rtcio_num].func);
}
/**
* @brief Enable/Disable LP IOMUX clock.
*
* @param enable true to enable the clock / false to disable the clock
*/
static inline void rtcio_ll_enable_io_clock(bool enable)
{
SENS.sar_io_mux_conf.iomux_clk_gate_en = enable;
}
/**
* @brief Select the rtcio function.
*
@ -72,12 +61,14 @@ static inline void rtcio_ll_enable_io_clock(bool enable)
static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
{
if (func == RTCIO_LL_FUNC_RTC) {
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
//0:RTC FUNCTION 1,2,3:Reserved
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
SENS.sar_io_mux_conf.iomux_clk_gate_en = 0;
}
}
@ -290,7 +281,8 @@ static inline void rtcio_ll_force_unhold_all(void)
*/
static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type)
{
RTCIO.pin[rtcio_num].wakeup_enable = 1;
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
RTCIO.pin[rtcio_num].int_type = type;
}
@ -301,6 +293,7 @@ static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t ty
*/
static inline void rtcio_ll_wakeup_disable(int rtcio_num)
{
SENS.sar_io_mux_conf.iomux_clk_gate_en = 0;
RTCIO.pin[rtcio_num].wakeup_enable = 0;
RTCIO.pin[rtcio_num].int_type = RTCIO_LL_WAKEUP_DISABLE;
}

View File

@ -681,25 +681,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -737,7 +718,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,7 +13,6 @@
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include "soc/rtc_io_struct.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_periph.h"
@ -43,16 +42,6 @@ typedef enum {
RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */
} rtcio_ll_out_mode_t;
/**
* @brief Enable/Disable LP IOMUX clock.
*
* @param enable true to enable the clock / false to disable the clock
*/
static inline void rtcio_ll_enable_io_clock(bool enable)
{
SENS.sar_peri_clk_gate_conf.iomux_clk_en = enable;
}
/**
* @brief Select a RTC IOMUX function for the RTC IO
*
@ -78,12 +67,14 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
if (rtcio_num == rtc_io_num_map[USB_INT_PHY0_DM_GPIO_NUM] || rtcio_num == rtc_io_num_map[USB_INT_PHY0_DP_GPIO_NUM]) {
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
}
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 1;
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
//0:RTC FUNCTION 1,2,3:Reserved
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 0;
// USB Serial JTAG pad re-enable won't be done here (it requires both DM and DP pins not in rtc function)
// Instead, USB_SERIAL_JTAG_USB_PAD_ENABLE needs to be guaranteed to be set in usb_serial_jtag driver
}
@ -316,7 +307,8 @@ static inline void rtcio_ll_force_unhold_all(void)
*/
static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type)
{
RTCIO.pin[rtcio_num].wakeup_enable = 1;
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 1;
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
RTCIO.pin[rtcio_num].int_type = type;
}

View File

@ -717,25 +717,6 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -773,7 +754,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg = {.val = 0};
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -72,7 +72,6 @@ typedef struct {
spi_clock_source_t clock_source; ///< Clock source of each device used by LL layer
int timing_dummy; ///< Extra dummy needed to compensate the timing
int timing_miso_delay; ///< Extra miso delay clocks to compensate the timing
spi_sampling_point_t rx_sample_point;///< Sample data follow standard SPI timing in master mode
} spi_hal_timing_conf_t;
/**

View File

@ -76,15 +76,8 @@ typedef enum {
SPI_CMD_HD_INT2 = BIT(9),
} spi_command_t;
/**
* @brief SPI master RX sample point mode configuration
*/
typedef enum {
SPI_SAMPLING_POINT_PHASE_0, ///< Data sampling point at 50% cycle delayed then standard timing, (default).
SPI_SAMPLING_POINT_PHASE_1, ///< Data sampling point follows standard SPI timing in master mode
} spi_sampling_point_t;
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
//alias for different chips, deprecated for the chips after esp32s2
#ifdef CONFIG_IDF_TARGET_ESP32
#define SPI_HOST SPI1_HOST
@ -96,6 +89,7 @@ typedef enum {
#define FSPI_HOST SPI2_HOST
#define HSPI_HOST SPI3_HOST
#endif
/** @endcond */
#ifdef __cplusplus

View File

@ -52,7 +52,6 @@ void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
#endif
spi_ll_master_set_pos_cs(hw, dev->cs_pin_id, dev->positive_cs);
spi_ll_master_set_clock_by_reg(hw, &dev->timing_conf.clock_reg);
spi_ll_master_set_rx_timing_mode(hw, dev->timing_conf.rx_sample_point);
//Configure bit order
spi_ll_set_rx_lsbfirst(hw, dev->rx_lsbfirst);
spi_ll_set_tx_lsbfirst(hw, dev->tx_lsbfirst);

View File

@ -2,7 +2,6 @@
archive: liblog.a
entries:
log:esp_log_write (noflash)
log:esp_log_writev (noflash)
log_freertos:esp_log_timestamp (noflash)
log_freertos:esp_log_early_timestamp (noflash)
log_freertos:esp_log_impl_lock (noflash)

View File

@ -1,9 +1,3 @@
components/nvs_flash/host_test:
enable:
- if: IDF_TARGET == "linux"
components/nvs_flash/test_apps:
disable_test:
- if: IDF_TARGET not in ["esp32", "esp32c3"]
temporary: true
reason: NVS flash test on one Xtensa and one RISCV target is enough

View File

@ -3,23 +3,24 @@
# esp-idf NVS partition generation tool. Tool helps in generating NVS-compatible
# partition binary, with key-value pair entries provided via a CSV file.
#
# SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
#
import argparse
import array
import binascii
import codecs
import csv
import datetime
import distutils.dir_util
import os
import random
import struct
import sys
import textwrap
import zlib
import distutils.dir_util
from io import open
try:
from cryptography.hazmat.backends import default_backend
@ -890,7 +891,7 @@ def generate_key(args):
encr_key_bytes = e_key + t_key
key_len = len(encr_key_bytes)
key = encr_key_bytes.hex()
key = f"{int.from_bytes(encr_key_bytes, 'big'):x}"
keys_buf[0:key_len] = encr_key_bytes
crc_data = keys_buf[0:key_len]

View File

@ -10,8 +10,7 @@ CONFIGS_NVS_ENCR_FLASH_ENC = [
]
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.supported_targets
@pytest.mark.generic
@pytest.mark.parametrize('config', ['default'], indirect=True)
def test_nvs_flash(dut: IdfDut) -> None:

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,7 +9,6 @@
#include "esp_netif.h"
#include "esp_netif_types.h"
#include "esp_openthread.h"
#include "esp_openthread_spinel.h"
#include "openthread/instance.h"
#ifdef __cplusplus
@ -61,6 +60,42 @@ esp_err_t esp_openthread_border_router_deinit(void);
*/
esp_netif_t *esp_openthread_get_backbone_netif(void);
/**
* @brief Registers the callback for RCP failure.
*
*/
void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler);
/**
* @brief Registers the callback for spinel compatibility error.
*
* @note This function must be called before esp_openthread_init.
*
* @param[in] callback The callback.
*
*/
void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback);
/**
* @brief Deinitializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if fail to deinitialize RCP
*
*/
esp_err_t esp_openthread_rcp_deinit(void);
/**
* @brief Initializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_FAIL if fail to initialize RCP
*
*/
esp_err_t esp_openthread_rcp_init(void);
/**
* @brief Sets the meshcop(e) instance name.
*

View File

@ -1,71 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "esp_openthread_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Registers the callback for RCP failure.
*
*/
void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler);
/**
* @brief Registers the callback for spinel compatibility error.
*
* @note This function should be called before esp_openthread_init.
*
* @param[in] callback The callback.
*
*/
void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback);
/**
* @brief Deinitializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if fail to deinitialize RCP
*
*/
esp_err_t esp_openthread_rcp_deinit(void);
/**
* @brief Initializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_FAIL if fail to initialize RCP
*
*/
esp_err_t esp_openthread_rcp_init(void);
/**
* @brief Set the RCP version string.
*
* @note This function should be called before esp_openthread_init. When the RCP version string is not an empty string,
* compatibility checks will be performed during the initialization of the ESP OpenThread radio spinel.
* The `esp_openthread_compatibility_error_callback` will be triggered if the desired RCP version does not match
* the actual version running on the RCP. If needed, a NULL parameter can be passed to clear the version string.
*
* @param[in] version_str The pointer to RCP version string.
*
* @return
* - ESP_OK on success
* - ESP_FAIL if fail to set RCP version string
*
*/
esp_err_t esp_openthread_rcp_version_set(const char *version_str);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -198,16 +198,8 @@ typedef struct {
esp_openthread_port_config_t port_config; /*!< The port configuration */
} esp_openthread_platform_config_t;
/**
* @brief The OpenThread rcp failure handler
*
*/
typedef void (*esp_openthread_rcp_failure_handler)(void);
/**
* @brief The OpenThread compatibility error callback
*
*/
typedef void (*esp_openthread_compatibility_error_callback)(void);
#ifdef __cplusplus

View File

@ -494,6 +494,16 @@
#define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000)
#endif
#if CONFIG_EXTERNAL_COEX_ENABLE
/**
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
*
* Enables compilation of vendor specific code for Spinel
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 1
#endif
#endif
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART || CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
#if CONFIG_OPENTHREAD_LINK_METRICS

View File

@ -25,9 +25,6 @@
#include "openthread/platform/time.h"
#include "platform/exit_code.h"
#include "spinel_driver.hpp"
#include <cstring>
#define OT_SPINEL_RCP_VERSION_MAX_SIZE 100
using ot::Spinel::RadioSpinel;
using esp::openthread::SpinelInterfaceAdapter;
@ -59,7 +56,34 @@ static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL
static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL;
static char s_internal_rcp_version[OT_SPINEL_RCP_VERSION_MAX_SIZE] = {'\0'};
#if CONFIG_EXTERNAL_COEX_ENABLE
#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3)
static esp_ieee802154_coex_config_t s_coex_config = {
.idle = IEEE802154_IDLE,
.txrx = IEEE802154_LOW,
.txrx_at = IEEE802154_MIDDLE,
};
static void esp_openthread_restore_coex_config(void *context)
{
esp_openthread_set_coex_config(s_coex_config);
}
static esp_err_t esp_openthread_radio_spinel_coex_config_init(void)
{
s_radio.SetVendorRestorePropertiesCallback(esp_openthread_restore_coex_config, esp_openthread_get_instance());
esp_ieee802154_coex_config_t coex_config;
uint16_t coex_config_len = 0;
ESP_RETURN_ON_ERROR(s_radio.Get(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &coex_config, &coex_config_len),
OT_PLAT_LOG_TAG, "Fail to get coex config");
ESP_RETURN_ON_FALSE(coex_config_len == sizeof(esp_ieee802154_coex_config_t), ESP_FAIL, OT_PLAT_LOG_TAG,
"Fail to get coex config");
s_coex_config = coex_config;
return ESP_OK;
}
#endif
static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config)
{
@ -112,18 +136,11 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf
"Spinel interface init failed");
#endif
s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid);
if (strlen(s_internal_rcp_version) > 0) {
const char *running_rcp_version = s_spinel_driver.GetVersion();
if (strcmp(s_internal_rcp_version, running_rcp_version) != 0) {
if (s_compatibility_error_callback) {
s_compatibility_error_callback();
} else {
ESP_LOGW(OT_PLAT_LOG_TAG, "The running rcp does not match the provided rcp");
}
}
}
s_radio.SetCompatibilityErrorCallback(ot_spinel_compatibility_error_callback, esp_openthread_get_instance());
s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps, /*RCP_time_sync=*/true);
#if CONFIG_EXTERNAL_COEX_ENABLE
ESP_RETURN_ON_ERROR(esp_openthread_radio_spinel_coex_config_init(), OT_PLAT_LOG_TAG, "Coex config init failed");
#endif
#if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed");
#endif
@ -168,24 +185,12 @@ esp_err_t esp_openthread_rcp_init(void)
radiospinel_workflow);
}
esp_err_t esp_openthread_rcp_version_set(const char *version_str)
{
if (version_str == NULL) {
memset(s_internal_rcp_version, 0, OT_SPINEL_RCP_VERSION_MAX_SIZE);
return ESP_OK;
}
ESP_RETURN_ON_FALSE(strlen(version_str) > 0 && strlen(version_str) < OT_SPINEL_RCP_VERSION_MAX_SIZE, ESP_FAIL, OT_PLAT_LOG_TAG, "Invalid rcp version");
strcpy(s_internal_rcp_version, version_str);
return ESP_OK;
}
void esp_openthread_radio_deinit(void)
{
s_radio.Deinit();
s_spinel_driver.Deinit();
s_spinel_interface.GetSpinelInterface().Disable();
esp_openthread_platform_workflow_unregister(radiospinel_workflow);
s_compatibility_error_callback = NULL;
}
esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop)
@ -510,3 +515,39 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
// Refer to `GetRadioChannelMask(bool aPreferred)`: FALSE to get supported channel mask
return s_radio.GetRadioChannelMask(false);
}
#if CONFIG_EXTERNAL_COEX_ENABLE
void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config)
{
otError err = s_radio.Set(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &s_coex_config, sizeof(esp_ieee802154_coex_config_t));
ESP_RETURN_ON_FALSE(err == OT_ERROR_NONE, , OT_PLAT_LOG_TAG, "Fail to set coex config");
s_coex_config = config;
}
esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void)
{
return s_coex_config;
}
namespace ot {
namespace Spinel {
otError RadioSpinel::VendorHandleValueIs(spinel_prop_key_t aPropKey)
{
otError error = OT_ERROR_NONE;
switch (aPropKey)
{
default:
ESP_LOGW(OT_PLAT_LOG_TAG, "Not Implemented!");
error = OT_ERROR_NOT_FOUND;
break;
}
return error;
}
} // namespace Spinel
} // namespace ot
#endif

View File

@ -63,7 +63,7 @@ static void handle_ot_netdata_change(void)
static void handle_ot_role_change(otInstance* instance)
{
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE) && OPENTHREAD_RADIO_NATIVE)
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE && OPENTHREAD_RADIO_NATIVE) || CONFIG_EXTERNAL_COEX_ENABLE)
otLinkModeConfig linkmode = otThreadGetLinkMode(instance);
esp_ieee802154_coex_config_t config = esp_openthread_get_coex_config();
config.txrx = (linkmode.mRxOnWhenIdle) ? IEEE802154_LOW : IEEE802154_MIDDLE;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -64,12 +64,11 @@ esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *conf
#ifndef CONFIG_ESP_CONSOLE_UART
// If UART console is used, UART vfs devices should be registered during startup.
// Otherwise we need to register them here.
char uart_path[16];
snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", config->port);
bool is_uart_registered = (access(uart_path, F_OK) == 0);
if (!is_uart_registered) {
// If UART vfs devices are registered, we will failed to open the directory
DIR *uart_dir = opendir("/dev/uart");
if (!uart_dir) {
esp_vfs_dev_uart_register();
} else {
closedir(uart_dir);
}
#endif
ESP_RETURN_ON_ERROR(uart_param_config(config->port, &config->uart_config), OT_PLAT_LOG_TAG,

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -266,8 +266,8 @@ otError SpiSpinelInterface::WaitForFrame(uint64_t timeout_us)
otError SpiSpinelInterface::HardwareReset(void)
{
if (mRcpFailureHandler) {
mRcpFailureHandler();
ConductSPITransaction(true, 0, 0); // clear
mRcpFailureHandler();
}
return OT_ERROR_NONE;
}

View File

@ -667,14 +667,6 @@ config SOC_TIMER_GROUP_SUPPORT_APB
bool
default y
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_TOUCH_VERSION_1
bool
default y

View File

@ -571,9 +571,8 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode.
*
* @param slowclk_period re-calibrated slow clock period
* @param dslp true if initialize for deepsleep request
*/
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
void rtc_sleep_low_init(uint32_t slowclk_period);
#define RTC_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup

View File

@ -317,10 +317,6 @@
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
#define SOC_TIMER_GROUP_SUPPORT_APB (1)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
#define SOC_TOUCH_VERSION_1 (1) /*!<Hardware version of touch sensor */
#define SOC_TOUCH_SENSOR_NUM (10)

View File

@ -559,14 +559,6 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 1
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -603,9 +603,8 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode.
*
* @param slowclk_period re-calibrated slow clock period
* @param dslp true if initialize for deepsleep request
*/
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
void rtc_sleep_low_init(uint32_t slowclk_period);
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup

View File

@ -265,10 +265,6 @@
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (1U)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -803,14 +803,6 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -648,9 +648,8 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode.
*
* @param slowclk_period re-calibrated slow clock period
* @param dslp true if initialize for deepsleep request
*/
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
void rtc_sleep_low_init(uint32_t slowclk_period);
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup

Some files were not shown because too many files have changed in this diff Show More