-
Notifications
You must be signed in to change notification settings - Fork 7k
/
sleep_event.c
92 lines (82 loc) · 3.16 KB
/
sleep_event.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <string.h>
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "esp_private/sleep_event.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_check.h"
#include "freertos/FreeRTOS.h"
static __attribute__((unused)) const char *TAG = "sleep_event";
#if CONFIG_ESP_SLEEP_EVENT_CALLBACKS
esp_sleep_event_cbs_config_t g_sleep_event_cbs_config;
static portMUX_TYPE s_sleep_event_mutex = portMUX_INITIALIZER_UNLOCKED;
esp_err_t esp_sleep_register_event_callback(esp_sleep_event_cb_index_t event_id, const esp_sleep_event_cb_config_t *event_cb_conf) {
if (event_cb_conf == NULL || event_id >= SLEEP_EVENT_CB_INDEX_NUM) {
return ESP_ERR_INVALID_ARG;
}
esp_sleep_event_cb_config_t *new_config = (esp_sleep_event_cb_config_t *)heap_caps_malloc(sizeof(esp_sleep_event_cb_config_t), MALLOC_CAP_INTERNAL);
if (new_config == NULL) {
return ESP_ERR_NO_MEM; /* Memory allocation failed */
}
portENTER_CRITICAL(&s_sleep_event_mutex);
esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]);
while (*current_ptr != NULL) {
if (((*current_ptr)->cb) == (event_cb_conf->cb)) {
free(new_config);
portEXIT_CRITICAL(&s_sleep_event_mutex);
return ESP_FAIL;
}
current_ptr = &((*current_ptr)->next);
}
*new_config = *event_cb_conf;
while (*current_ptr != NULL && (*current_ptr)->prior <= new_config->prior) {
current_ptr = &((*current_ptr)->next);
}
new_config->next = *current_ptr;
*current_ptr = new_config;
portEXIT_CRITICAL(&s_sleep_event_mutex);
return ESP_OK;
}
esp_err_t esp_sleep_unregister_event_callback(esp_sleep_event_cb_index_t event_id, esp_sleep_event_cb_t cb) {
if (cb == NULL || event_id >= SLEEP_EVENT_CB_INDEX_NUM) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL(&s_sleep_event_mutex);
esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]);
while (*current_ptr != NULL) {
if (((*current_ptr)->cb) == cb) {
esp_sleep_event_cb_config_t *temp = *current_ptr;
*current_ptr = (*current_ptr)->next;
free(temp);
break;
}
current_ptr = &((*current_ptr)->next);
}
portEXIT_CRITICAL(&s_sleep_event_mutex);
return ESP_OK;
}
#endif
void IRAM_ATTR esp_sleep_execute_event_callbacks(esp_sleep_event_cb_index_t event_id, void *ext_arg)
{
#if CONFIG_ESP_SLEEP_EVENT_CALLBACKS
if (event_id >= SLEEP_EVENT_CB_INDEX_NUM) {
ESP_EARLY_LOGW(TAG, "event_id out of range");
return;
}
esp_sleep_event_cb_config_t *current = g_sleep_event_cbs_config.sleep_event_cb_config[event_id];
while (current != NULL) {
if (current->cb != NULL) {
if (ESP_OK != (*current->cb)(current->user_arg, ext_arg)) {
ESP_EARLY_LOGW(TAG, "esp_sleep_execute_event_callbacks has an err, current->cb = %p", current->cb);
}
}
current = current->next;
}
#endif
}