From 3f5cab42b2326a57d726261825e8411e495c9cf8 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Wed, 16 Apr 2025 12:00:42 +0800 Subject: [PATCH] feat(bod): Add a simple callback function for brownout detector, Closes https://github.com/espressif/esp-idf/pull/15661 --- .../esp_hw_support/power_supply/brownout.c | 19 ++++++++++ .../power_supply/include/esp_brownout.h | 37 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 components/esp_hw_support/power_supply/include/esp_brownout.h diff --git a/components/esp_hw_support/power_supply/brownout.c b/components/esp_hw_support/power_supply/brownout.c index d2b73df4d8..adcc15336d 100644 --- a/components/esp_hw_support/power_supply/brownout.c +++ b/components/esp_hw_support/power_supply/brownout.c @@ -26,6 +26,9 @@ #include "esp_rom_uart.h" #include "hal/uart_ll.h" #include "soc/power_supply_periph.h" +#include "esp_brownout.h" +#include "esp_check.h" +#include "esp_memory_utils.h" #if defined(CONFIG_ESP_BROWNOUT_DET_LVL) #define BROWNOUT_DET_LVL CONFIG_ESP_BROWNOUT_DET_LVL @@ -35,6 +38,8 @@ static __attribute__((unused)) DRAM_ATTR const char TAG[] = "BOD"; +static brownout_callback_t s_brownout_callback = NULL; + #if CONFIG_ESP_BROWNOUT_USE_INTR IRAM_ATTR static void rtc_brownout_isr_handler(void *arg) { @@ -44,6 +49,10 @@ IRAM_ATTR static void rtc_brownout_isr_handler(void *arg) */ brownout_ll_intr_clear(); + if (s_brownout_callback) { + s_brownout_callback(); + } + // Stop the other core. #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE const uint32_t core_id = esp_cpu_get_core_id(); @@ -123,3 +132,13 @@ void esp_brownout_disable(void) rtc_isr_deregister(rtc_brownout_isr_handler, NULL); #endif // CONFIG_ESP_BROWNOUT_USE_INTR } + +esp_err_t esp_brownout_register_callback(brownout_callback_t callback) +{ + if (callback != NULL) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callback), ESP_ERR_INVALID_ARG, TAG, "brownout callback is not in IRAM"); + } + s_brownout_callback = callback; + + return ESP_OK; +} diff --git a/components/esp_hw_support/power_supply/include/esp_brownout.h b/components/esp_hw_support/power_supply/include/esp_brownout.h new file mode 100644 index 0000000000..7d1cee1742 --- /dev/null +++ b/components/esp_hw_support/power_supply/include/esp_brownout.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #pragma once + + #include "esp_err.h" + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @brief Type definition for a brownout callback function. + * + * This type defines a callback function that will be invoked when a brownout + * condition is detected. + * + * @note The callback function is executed in an brownout interrupt context, so it + * must be designed to execute quickly and must not call blocking functions. + */ +typedef void (*brownout_callback_t)(void); + +/** + * @brief Register a callback to be called during brownout interrupt. + * + * @note The callback in brownout must be put in IRAM. + * + * @param callback The callback function to register. Set NULL to unregister the callback. + */ +esp_err_t esp_brownout_register_callback(brownout_callback_t callback); + +#ifdef __cplusplus +} +#endif