sleep_event.c 3.2 KB

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