mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
Compare commits
103 Commits
41c2b799ad
...
2bde2d8e30
Author | SHA1 | Date | |
---|---|---|---|
|
2bde2d8e30 | ||
|
33a97b8ea1 | ||
|
4e30b88527 | ||
|
511423cd2e | ||
|
f038c00a5b | ||
|
12901ff20b | ||
|
1e6a700601 | ||
|
f70b9ed99e | ||
|
590682f8c5 | ||
|
d661664106 | ||
|
8385f47948 | ||
|
499dd676a9 | ||
|
b60bf2c552 | ||
|
dc1e3c7265 | ||
|
fa7be7cb3d | ||
|
bd186a3fb0 | ||
|
07f409ec8a | ||
|
895e05db19 | ||
|
d309e7c38a | ||
|
ba66243885 | ||
|
95c55f68b5 | ||
|
86210328a7 | ||
|
6312c5eebe | ||
|
f7c0a60a32 | ||
|
37b089ee8d | ||
|
6e1423736e | ||
|
f1b3eab741 | ||
|
1beb0bcd79 | ||
|
e6f49c0480 | ||
|
602fe5b9f4 | ||
|
2af2884ebd | ||
|
d08c883ec3 | ||
|
75a735fdc7 | ||
|
5670a06d83 | ||
|
b8e6e5389d | ||
|
7b100e98b7 | ||
|
5e577dcd5a | ||
|
7de62b3c09 | ||
|
e2dd6f8a6f | ||
|
015e4f1b49 | ||
|
c1ef20b7f4 | ||
|
172e5a317a | ||
|
4459b5f44a | ||
|
11686940ae | ||
|
28ebdd472d | ||
|
d6c2868bcd | ||
|
2dd257d162 | ||
|
90120f30e1 | ||
|
548c6a2f38 | ||
|
9c4b822ab1 | ||
|
dc00dd37dc | ||
|
0efea66c6d | ||
|
b2c8dcacb0 | ||
|
d09f48c97b | ||
|
0fcca4ec3c | ||
|
4f8f92aa2d | ||
|
6eaf8815db | ||
|
339b829126 | ||
|
aff8ad355b | ||
|
6ed9e39ffa | ||
|
84a162aba7 | ||
|
671dc31a32 | ||
|
084cb924f2 | ||
|
60b8013bc3 | ||
|
475ef1bb53 | ||
|
1c93d41325 | ||
|
5e81eb6cf7 | ||
|
72c86ba35c | ||
|
691f9131fc | ||
|
72527f85ea | ||
|
af002606a7 | ||
|
be13df1104 | ||
|
d096dc7cbe | ||
|
bdef0e0cb4 | ||
|
9a1eef2ccc | ||
|
b216535f73 | ||
|
19531e2166 | ||
|
7aa691aaff | ||
|
f5363a3f7a | ||
|
771bbf2f63 | ||
|
bf50c0c197 | ||
|
caca62543b | ||
|
fddc0baced | ||
|
bcf635dcd5 | ||
|
55f1ac37cc | ||
|
791003ea7f | ||
|
91e0e36ffe | ||
|
cacc13873d | ||
|
567469dd27 | ||
|
6465aef894 | ||
|
0938688e9b | ||
|
d1a02e1854 | ||
|
0c69545f30 | ||
|
98285d819b | ||
|
44f09c470b | ||
|
c11e4ad3c4 | ||
|
d9c471d054 | ||
|
0214e29fc3 | ||
|
b83535a889 | ||
|
07425e242c | ||
|
e65cf7ea2a | ||
|
65a616197f | ||
|
333d4fee6f |
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@ -60,7 +60,9 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Set up QEMU for multiarch builds
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
image: tonistiigi/binfmt:qemu-v7.0.0-28
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Build and push
|
||||
|
@ -76,4 +76,8 @@ 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
|
||||
|
@ -490,6 +490,15 @@ 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 35fb599d3733f50254c056171edebcaa3c57d06b
|
||||
Subproject commit 6093909e01930f8cda6f60510f8a412c6d1814e8
|
@ -723,8 +723,6 @@ 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) {
|
||||
@ -733,7 +731,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
|
||||
APPL_TRACE_ERROR("Not a registered service attribute ID: 0x%04x",
|
||||
p_msg->api_indicate.attr_id);
|
||||
}
|
||||
}
|
||||
@ -923,7 +921,7 @@ void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
**
|
||||
** Function bta_gatts_show_local_database
|
||||
**
|
||||
** Description print loacl service database
|
||||
** Description print local service database
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the public interface file for the simulatenous advanced
|
||||
* This is the public interface file for the simultaneous advanced
|
||||
* audio/video streaming (AV) source and sink of BTA, Broadcom's Bluetooth
|
||||
* application layer for mobile phones.
|
||||
*
|
||||
@ -35,6 +35,10 @@
|
||||
|
||||
#if (BTA_AR_INCLUDED == TRUE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include "stack/a2d_sbc.h"
|
||||
|
||||
#if (BTC_AV_INCLUDED == TRUE)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
@ -4003,7 +4003,6 @@ 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)) {
|
||||
|
@ -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 puting the data into the response in order */
|
||||
/* Now walk through the buffers putting 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 puting the data into the response in order */
|
||||
/* Now walk through the buffers putting 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 repsonse */
|
||||
/* get the length byte in the response */
|
||||
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, or format mismatch.
|
||||
** FALSE: packet full.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len,
|
||||
@ -831,10 +831,9 @@ 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 {
|
||||
GATT_TRACE_ERROR("format mismatch");
|
||||
status = GATT_NO_RESOURCES;
|
||||
// UUID format mismatch in sequential attributes
|
||||
// A new request will be sent with the starting handle of the next attribute
|
||||
break;
|
||||
/* format mismatch */
|
||||
}
|
||||
p_msg->len += info_pair_len[p_msg->offset - 1];
|
||||
len -= info_pair_len[p_msg->offset - 1];
|
||||
@ -889,7 +888,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 exsit");
|
||||
GATT_TRACE_DEBUG("UUID filter does not exist");
|
||||
reason = GATT_INVALID_PDU;
|
||||
} else {
|
||||
len -= p_uuid_filter->len;
|
||||
@ -1042,7 +1041,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 excahnge MTU request.
|
||||
** Description This function is called to process exchange MTU request.
|
||||
** Only used on LE.
|
||||
**
|
||||
** Returns void
|
||||
@ -1055,7 +1054,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 conenction, send error response */
|
||||
/* BR/EDR connection, 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) {
|
||||
@ -1081,7 +1080,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 applcations */
|
||||
/* of 0, as no response is allowed from applications */
|
||||
|
||||
for (i = 0; i < GATT_MAX_APPS; i ++) {
|
||||
if (gatt_cb.cl_rcb[i].in_use ) {
|
||||
@ -1448,7 +1447,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 excute write request
|
||||
// update prepare write status for execute write request
|
||||
&& (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) {
|
||||
prepare_record->error_code_app = status;
|
||||
}
|
||||
@ -1855,7 +1854,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 descrptor */
|
||||
case GATT_REQ_FIND_INFO: /* discover char descriptor */
|
||||
gatts_process_find_info(p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
|
@ -1058,6 +1058,15 @@ 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 c42b505ac5442da027d0cb7738a4a1850a09edc7
|
||||
Subproject commit 553fe4598c6585b2288e6b255604a63b1e6f8485
|
@ -1942,6 +1942,14 @@
|
||||
#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
|
||||
|
@ -205,6 +205,16 @@ 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
|
||||
@ -224,7 +234,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 = CONTROLLER_ADV_LOST_DEBUG_BIT, \
|
||||
.controller_debug_flag = BTDM_CTRL_CONTROLLER_DEBUG_FLAG, \
|
||||
.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, \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -23,6 +23,7 @@
|
||||
#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"
|
||||
@ -632,6 +633,11 @@ 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
|
||||
@ -657,6 +663,9 @@ 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);
|
||||
@ -984,6 +993,9 @@ 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);
|
||||
@ -1002,6 +1014,9 @@ 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;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,6 +8,8 @@
|
||||
#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"
|
||||
@ -45,6 +47,9 @@ 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();
|
||||
|
||||
@ -57,6 +62,10 @@ 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;
|
||||
|
@ -423,8 +423,12 @@ 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);
|
||||
temp_timing_conf.clock_source = clk_src;
|
||||
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);
|
||||
}
|
||||
|
||||
//Allocate memory for device
|
||||
dev = malloc(sizeof(spi_device_t));
|
||||
@ -513,6 +517,15 @@ 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
|
||||
|
@ -77,6 +77,7 @@ 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
||||
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
|
||||
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
|
||||
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_NONE=y
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -111,7 +111,18 @@ 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)
|
||||
{
|
||||
// Currently calibration is not supported on ESP32-C2, IDF-5236
|
||||
*tsens_cal = 0.0;
|
||||
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;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -132,7 +132,18 @@ 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)
|
||||
{
|
||||
// Currently calibration is not supported on ESP32-C6, IDF-5236
|
||||
*tsens_cal = 0;
|
||||
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;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -124,7 +124,18 @@ 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)
|
||||
{
|
||||
// Currently calibration is not supported on ESP32-H2, IDF-5236
|
||||
*tsens_cal = 0;
|
||||
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;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -35,7 +35,6 @@ 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;
|
||||
}
|
||||
|
@ -434,7 +434,10 @@ 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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2018-2025 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:<recieved events no.> dr:<dropped events no.>
|
||||
// LOOP @<address, name> rx:<received 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,6 +38,7 @@
|
||||
|
||||
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 =
|
||||
@ -136,29 +137,14 @@ 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);
|
||||
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, post.data.ptr);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
|
||||
diff = esp_timer_get_time() - start;
|
||||
|
||||
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);
|
||||
handler->invoked++;
|
||||
handler->time += diff;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -363,8 +349,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -388,8 +374,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -398,6 +384,23 @@ 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;
|
||||
@ -435,17 +438,112 @@ 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 && post->data.ptr) {
|
||||
if (post->data_allocated)
|
||||
#endif
|
||||
{
|
||||
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)
|
||||
@ -481,14 +579,6 @@ 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
|
||||
@ -534,12 +624,6 @@ 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;
|
||||
@ -566,10 +650,25 @@ 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, ticks_to_run) == pdTRUE) {
|
||||
while (xQueueReceive(loop->queue, &post, remaining_ticks) == 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;
|
||||
@ -582,24 +681,30 @@ 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) {
|
||||
handler_execute(loop, handler, post);
|
||||
exec |= true;
|
||||
if (!handler->unregistered) {
|
||||
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) {
|
||||
handler_execute(loop, handler, post);
|
||||
exec |= true;
|
||||
if (!handler->unregistered) {
|
||||
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) {
|
||||
handler_execute(loop, handler, post);
|
||||
exec |= true;
|
||||
if (!handler->unregistered) {
|
||||
handler_execute(loop, handler, post);
|
||||
exec |= true;
|
||||
}
|
||||
}
|
||||
// Skip to next base node
|
||||
break;
|
||||
@ -646,14 +751,10 @@ 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);
|
||||
@ -683,10 +784,6 @@ 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;
|
||||
@ -786,24 +883,21 @@ 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};
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
|
||||
xSemaphoreGiveRecursive(loop->mutex);
|
||||
|
||||
return ESP_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
@ -847,12 +941,10 @@ 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);
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
post.data.ptr = event_data_copy;
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
post.data_allocated = true;
|
||||
post.data_set = true;
|
||||
#else
|
||||
post.data = event_data_copy;
|
||||
#endif
|
||||
}
|
||||
post.base = event_base;
|
||||
@ -894,7 +986,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_recieved, 1);
|
||||
atomic_fetch_add(&loop->events_received, 1);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
@ -942,7 +1034,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_recieved, 1);
|
||||
atomic_fetch_add(&loop->events_received, 1);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
@ -971,13 +1063,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_recieved, events_dropped;
|
||||
uint32_t events_received, events_dropped;
|
||||
|
||||
events_recieved = atomic_load(&loop_it->events_recieved);
|
||||
events_received = atomic_load(&loop_it->events_received);
|
||||
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_recieved, events_dropped);
|
||||
PRINT_DUMP_INFO(dst, sz, LOOP_DUMP_FORMAT, loop_it, loop_it->task != NULL ? loop_it->name : "none",
|
||||
events_received, events_dropped);
|
||||
|
||||
int sz_bak = sz;
|
||||
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ESP_EVENT_INTERNAL_H_
|
||||
#define ESP_EVENT_INTERNAL_H_
|
||||
@ -39,6 +31,7 @@ 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;
|
||||
@ -84,21 +77,24 @@ 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_recieved; /**< number of events successfully posted to the loop */
|
||||
atomic_uint_least32_t events_received; /**< 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;
|
||||
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
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;
|
||||
|
||||
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 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "inttypes.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -1571,3 +1572,167 @@ 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
|
||||
|
@ -1,6 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
@ -43,3 +42,28 @@ 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)
|
||||
|
3
components/esp_event/test_apps/sdkconfig.ci.no_isr_post
Normal file
3
components/esp_event/test_apps/sdkconfig.ci.no_isr_post
Normal file
@ -0,0 +1,3 @@
|
||||
# This configuration checks the event loop if posting from ISR is disabled
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
CONFIG_POST_EVENTS_FROM_ISR=n
|
17
components/esp_hid/Kconfig
Normal file
17
components/esp_hid/Kconfig
Normal file
@ -0,0 +1,17 @@
|
||||
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
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -94,6 +86,19 @@ 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,
|
||||
@ -203,8 +208,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 Apperance
|
||||
* @param appearance : BLE Apperance value
|
||||
* @brief Calculate the HID Device usage type from the BLE Appearance
|
||||
* @param appearance : BLE Appearance value
|
||||
*
|
||||
* @return: the hid usage type
|
||||
*/
|
||||
|
@ -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 = 4096,
|
||||
.task_stack_size = BT_HID_DEVICE_TASK_SIZE_BLE,
|
||||
.task_core_id = tskNO_AFFINITY
|
||||
};
|
||||
ret = esp_event_loop_create(&event_task_args, &s_dev->event_loop_handle);
|
||||
|
@ -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 = 2048,
|
||||
.task_stack_size = BT_HID_DEVICE_TASK_SIZE_BT,
|
||||
.task_core_id = tskNO_AFFINITY
|
||||
};
|
||||
ret = esp_event_loop_create(&event_task_args, &s_hidd_param.dev->event_loop_handle);
|
||||
|
@ -1,13 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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" {
|
||||
@ -26,6 +30,26 @@ 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -168,9 +168,13 @@ 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 (TBD)
|
||||
* - ESP_ERR_INVALID_ARG if value is out of range.
|
||||
*/
|
||||
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);
|
||||
|
||||
@ -411,8 +415,10 @@ 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 This function does not modify pin configuration. The pins are
|
||||
* configured inside esp_deep_sleep_start, immediately before entering sleep mode.
|
||||
* @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 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
|
||||
@ -447,7 +453,12 @@ 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 On ESP32, GPIO wakeup source can not be used together with touch or ULP wakeup sources.
|
||||
* @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)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
@ -463,7 +474,9 @@ 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 ESP32 does not support wakeup from UART2.
|
||||
* @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.
|
||||
*
|
||||
* @param uart_num UART port to wake up from
|
||||
* @return
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 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)
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
|
||||
{
|
||||
// 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, 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);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Read back 'reject' status when waking from light or deep sleep */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 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)
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
|
||||
{
|
||||
// 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, 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);
|
||||
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);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 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)
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
|
||||
{
|
||||
// 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, 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);
|
||||
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);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,67 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 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)
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
|
||||
{
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
/* Read back 'reject' status when waking from light or deep sleep */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,67 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#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"
|
||||
@ -65,7 +66,7 @@ void rtc_clk_32k_enable(bool enable)
|
||||
void rtc_clk_32k_enable_external(void)
|
||||
{
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO15_REG);
|
||||
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN);
|
||||
rtcio_ll_enable_io_clock(true);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, RTC_CNTL_X32P_HOLD);
|
||||
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 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)
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
|
||||
{
|
||||
// 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, 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);
|
||||
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);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 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);
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,13 @@
|
||||
#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"
|
||||
@ -874,9 +877,7 @@ 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
|
||||
if (!deep_sleep) {
|
||||
rtc_sleep_low_init(s_config.rtc_clk_cal_period);
|
||||
}
|
||||
rtc_sleep_low_init(s_config.rtc_clk_cal_period, deep_sleep);
|
||||
#endif
|
||||
|
||||
// Configure timer wakeup
|
||||
@ -1488,6 +1489,10 @@ 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;
|
||||
@ -1606,6 +1611,9 @@ 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);
|
||||
@ -1735,6 +1743,9 @@ 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);
|
||||
@ -1806,6 +1817,9 @@ 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));
|
||||
@ -1854,6 +1868,9 @@ 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");
|
||||
@ -1866,6 +1883,9 @@ 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) {
|
||||
|
@ -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 (mem_block->paddr_start == paddr) {
|
||||
if (paddr >= mem_block->paddr_start && paddr < mem_block->paddr_end) {
|
||||
found = true;
|
||||
found_block = mem_block;
|
||||
break;
|
||||
|
@ -50,3 +50,23 @@ 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));
|
||||
}
|
||||
|
@ -144,12 +144,17 @@ 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 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.
|
||||
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.)
|
||||
|
||||
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,
|
||||
@ -164,6 +169,14 @@ 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
|
||||
|
@ -21,14 +21,13 @@
|
||||
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, in this condition, the rom api will return
|
||||
/* No page mapped to page0 yet, in this condition, the rom api will return
|
||||
* unexpected value + 1.
|
||||
*/
|
||||
if (page0_before_count == *page0_mapped) {
|
||||
if (*page0_mapped == 0) {
|
||||
flash_pages--;
|
||||
}
|
||||
return flash_pages;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -18,8 +18,6 @@
|
||||
|
||||
#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;
|
||||
@ -105,6 +103,12 @@ __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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -92,6 +92,14 @@ 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
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#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"
|
||||
@ -751,18 +752,26 @@ 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 && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
#if CONFIG_APP_BUILD_TYPE_RAM
|
||||
#if !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();
|
||||
#else
|
||||
// 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 && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
#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();
|
||||
}
|
||||
|
||||
|
||||
#endif // CONFIG_APP_BUILD_TYPE_RAM
|
||||
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
@ -19,6 +19,7 @@
|
||||
#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"
|
||||
@ -26,6 +27,7 @@
|
||||
#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"
|
||||
@ -57,6 +59,10 @@ 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);
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
# 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 7d365e96bafc85d2d2a8ddbfe2a022907d81c5fe
|
||||
Subproject commit 1b54a5565502faaacc257d7d94fcff482bcb6d83
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -200,15 +200,28 @@ static int elf_add_segment(core_dump_elf_t *self,
|
||||
return data_len;
|
||||
}
|
||||
|
||||
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)
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
// temporary aligned buffer for note name
|
||||
static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 };
|
||||
elf_note note_hdr = { 0 };
|
||||
|
||||
memcpy(name_buffer, name, name_len);
|
||||
note_hdr.n_namesz = ALIGN_UP(name_len + 1, 4);
|
||||
size_t name_len = strlcpy(name_buffer, name, sizeof(name_buffer));
|
||||
note_hdr.n_namesz = name_len + 1; /* name_buffer must be null terminated */
|
||||
note_hdr.n_descsz = data_sz;
|
||||
note_hdr.n_type = type;
|
||||
// write note header
|
||||
@ -216,7 +229,7 @@ static int elf_write_note_header(core_dump_elf_t *self,
|
||||
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, note_hdr.n_namesz);
|
||||
err = esp_core_dump_write_data(&self->write_data, name_buffer, ALIGN_UP(note_hdr.n_namesz, 4));
|
||||
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
|
||||
"Write ELF note name failure (%d)", err);
|
||||
|
||||
@ -230,18 +243,17 @@ static int elf_write_note(core_dump_elf_t *self,
|
||||
uint32_t data_sz)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator
|
||||
uint32_t data_len = ALIGN_UP(data_sz, 4);
|
||||
uint32_t name_len = strlen(name) + 1; // get name length including terminator
|
||||
|
||||
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 + data_len + sizeof(elf_note), 4);
|
||||
uint32_t note_size = ALIGN_UP(name_len, 4) + ALIGN_UP(data_sz, 4) + sizeof(elf_note);
|
||||
|
||||
// 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, strlen(name), data_sz, type);
|
||||
err = elf_write_note_header(self, name, data_sz, type);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@ -250,8 +262,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) {
|
||||
int pad_size = data_len - data_sz;
|
||||
if (pad_size != 0) {
|
||||
const int pad_size = ALIGN_UP(data_sz, 4) - 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);
|
||||
@ -543,7 +555,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) - 1;
|
||||
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); /* len includes the null terminator */
|
||||
core_dump_elf_opaque_t param = {
|
||||
.self = self,
|
||||
.total_size = 0,
|
||||
@ -557,27 +569,25 @@ 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,
|
||||
name_len,
|
||||
self->note_data_size,
|
||||
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
|
||||
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
|
||||
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, ¶m, NULL);
|
||||
ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err);
|
||||
const uint32_t mod = self->note_data_size & 3;
|
||||
if (mod != 0) {
|
||||
const int pad_size = ALIGN_UP(self->note_data_size, 4) - self->note_data_size;
|
||||
if (pad_size > 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(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4);
|
||||
return ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note);
|
||||
}
|
||||
#endif //CONFIG_ESP_TASK_WDT_EN
|
||||
|
||||
@ -839,17 +849,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 *)¬e[1];
|
||||
target_notes[idx].n_ptr = nm + note->n_namesz;
|
||||
for (size_t idx = 0; idx < size; ++idx) {
|
||||
if (target_notes[idx].n_type == note->n_type) {
|
||||
char *nm = (char *)¬e[1];
|
||||
target_notes[idx].n_ptr = nm + ALIGN_UP(note->n_namesz, 4);
|
||||
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 + note->n_descsz + sizeof(elf_note), 4);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -251,13 +251,13 @@ function(esptool_py_partition_needs_encryption retencrypted partition_name)
|
||||
# - DATA 0x01
|
||||
# Subtypes:
|
||||
# - ota 0x00
|
||||
# - nvs 0x02
|
||||
# If the partition is an app, an OTA or an NVS partition, then it should
|
||||
# - nvs_keys 0x04
|
||||
# If the partition is an app, an OTA or an NVS keys 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 2)
|
||||
(${type} EQUAL 1 AND ${subtype} EQUAL 4)
|
||||
)
|
||||
set(encrypted TRUE)
|
||||
endif()
|
||||
|
@ -607,6 +607,25 @@ 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.
|
||||
*
|
||||
@ -644,7 +663,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;
|
||||
typeof(SPI1.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -696,6 +696,25 @@ 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.
|
||||
*
|
||||
@ -733,7 +752,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -698,6 +698,25 @@ 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.
|
||||
*
|
||||
@ -735,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -690,6 +690,25 @@ 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.
|
||||
*
|
||||
@ -727,7 +746,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -60,15 +60,10 @@ static inline void modem_syscon_ll_enable_modem_sec_clock(modem_syscon_dev_t *hw
|
||||
hw->clk_conf.clk_modem_sec_apb_en = en;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
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_apb_en = en;
|
||||
hw->clk_conf.clk_ble_timer_en = en;
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,13 @@
|
||||
#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" {
|
||||
@ -689,6 +691,26 @@ 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.
|
||||
*
|
||||
@ -726,7 +748,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -707,6 +707,25 @@ 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.
|
||||
*
|
||||
@ -744,7 +763,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 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_dram0_is_assoc_intr()) {
|
||||
if (memprot_ll_peri1_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;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -13,6 +13,7 @@
|
||||
#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"
|
||||
@ -25,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */
|
||||
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
|
||||
RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
|
||||
} rtcio_ll_func_t;
|
||||
|
||||
@ -51,6 +52,16 @@ 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.
|
||||
*
|
||||
@ -61,14 +72,12 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,8 +290,7 @@ 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)
|
||||
{
|
||||
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
|
||||
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
|
||||
RTCIO.pin[rtcio_num].wakeup_enable = 1;
|
||||
RTCIO.pin[rtcio_num].int_type = type;
|
||||
}
|
||||
|
||||
@ -293,7 +301,6 @@ 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;
|
||||
}
|
||||
|
@ -681,6 +681,25 @@ 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.
|
||||
*
|
||||
@ -718,7 +737,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -13,6 +13,7 @@
|
||||
#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"
|
||||
@ -42,6 +43,16 @@ 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
|
||||
*
|
||||
@ -67,14 +78,12 @@ 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
|
||||
}
|
||||
@ -307,8 +316,7 @@ 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)
|
||||
{
|
||||
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 1;
|
||||
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
|
||||
RTCIO.pin[rtcio_num].wakeup_enable = 1;
|
||||
RTCIO.pin[rtcio_num].int_type = type;
|
||||
}
|
||||
|
||||
|
@ -717,6 +717,25 @@ 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 +773,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;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
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.
|
||||
|
@ -72,6 +72,7 @@ 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;
|
||||
|
||||
/**
|
||||
|
@ -76,8 +76,15 @@ typedef enum {
|
||||
SPI_CMD_HD_INT2 = BIT(9),
|
||||
} spi_command_t;
|
||||
|
||||
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
|
||||
/**
|
||||
* @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
|
||||
@ -89,7 +96,6 @@ typedef enum {
|
||||
#define FSPI_HOST SPI2_HOST
|
||||
#define HSPI_HOST SPI3_HOST
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -52,6 +52,7 @@ 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);
|
||||
|
@ -2,6 +2,7 @@
|
||||
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)
|
||||
|
@ -1,3 +1,9 @@
|
||||
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
|
||||
|
@ -3,24 +3,23 @@
|
||||
# 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-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2018-2025 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
|
||||
from io import open
|
||||
|
||||
import distutils.dir_util
|
||||
|
||||
try:
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
@ -891,7 +890,7 @@ def generate_key(args):
|
||||
|
||||
encr_key_bytes = e_key + t_key
|
||||
key_len = len(encr_key_bytes)
|
||||
key = f"{int.from_bytes(encr_key_bytes, 'big'):x}"
|
||||
key = encr_key_bytes.hex()
|
||||
|
||||
keys_buf[0:key_len] = encr_key_bytes
|
||||
crc_data = keys_buf[0:key_len]
|
||||
|
@ -10,7 +10,8 @@ CONFIGS_NVS_ENCR_FLASH_ENC = [
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['default'], indirect=True)
|
||||
def test_nvs_flash(dut: IdfDut) -> None:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -9,6 +9,7 @@
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_types.h"
|
||||
#include "esp_openthread.h"
|
||||
#include "esp_openthread_spinel.h"
|
||||
#include "openthread/instance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -60,42 +61,6 @@ 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.
|
||||
*
|
||||
|
71
components/openthread/include/esp_openthread_spinel.h
Normal file
71
components/openthread/include/esp_openthread_spinel.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -198,8 +198,16 @@ 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
|
||||
|
@ -494,16 +494,6 @@
|
||||
#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
|
||||
|
@ -25,6 +25,9 @@
|
||||
#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;
|
||||
@ -56,34 +59,7 @@ static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL
|
||||
|
||||
static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL;
|
||||
|
||||
#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 char s_internal_rcp_version[OT_SPINEL_RCP_VERSION_MAX_SIZE] = {'\0'};
|
||||
|
||||
static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config)
|
||||
{
|
||||
@ -136,11 +112,18 @@ 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
|
||||
@ -185,12 +168,24 @@ 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)
|
||||
@ -515,39 +510,3 @@ 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
|
||||
|
@ -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 && OPENTHREAD_RADIO_NATIVE) || CONFIG_EXTERNAL_COEX_ENABLE)
|
||||
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE) && OPENTHREAD_RADIO_NATIVE)
|
||||
otLinkModeConfig linkmode = otThreadGetLinkMode(instance);
|
||||
esp_ieee802154_coex_config_t config = esp_openthread_get_coex_config();
|
||||
config.txrx = (linkmode.mRxOnWhenIdle) ? IEEE802154_LOW : IEEE802154_MIDDLE;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -64,11 +64,12 @@ 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.
|
||||
DIR *uart_dir = opendir("/dev/uart");
|
||||
if (!uart_dir) {
|
||||
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
|
||||
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,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 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) {
|
||||
ConductSPITransaction(true, 0, 0); // clear
|
||||
mRcpFailureHandler();
|
||||
ConductSPITransaction(true, 0, 0); // clear
|
||||
}
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
@ -667,6 +667,14 @@ 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
|
||||
|
@ -571,8 +571,9 @@ 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);
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
|
||||
|
||||
#define RTC_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
|
||||
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup
|
||||
|
@ -317,6 +317,10 @@
|
||||
#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)
|
||||
|
@ -559,6 +559,14 @@ 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
|
||||
|
@ -603,8 +603,9 @@ 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);
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
|
||||
|
||||
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
|
||||
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup
|
||||
|
@ -265,6 +265,10 @@
|
||||
#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)
|
||||
|
||||
|
@ -803,6 +803,14 @@ 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
|
||||
|
@ -648,8 +648,9 @@ 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);
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
|
||||
|
||||
#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
Loading…
x
Reference in New Issue
Block a user