From 13ddee015b98ce330ace56562dcda44a84596ca4 Mon Sep 17 00:00:00 2001 From: armando Date: Mon, 16 Mar 2026 10:25:12 +0800 Subject: [PATCH] feat(isp): added isp error interrupts --- .../include/esp_private/isp_private.h | 1 + components/esp_driver_isp/src/isp_core.c | 42 +++++++++++++++---- components/hal/esp32p4/include/hal/isp_ll.h | 13 ++++++ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/components/esp_driver_isp/include/esp_private/isp_private.h b/components/esp_driver_isp/include/esp_private/isp_private.h index 5701d9ef599..3bc3dda446c 100644 --- a/components/esp_driver_isp/include/esp_private/isp_private.h +++ b/components/esp_driver_isp/include/esp_private/isp_private.h @@ -119,6 +119,7 @@ typedef enum { ISP_SUBMODULE_AWB, ISP_SUBMODULE_SHARPEN, ISP_SUBMODULE_HIST, + ISP_SUBMODULE_GENERAL, } isp_submodule_t; /*--------------------------------------------------------------- diff --git a/components/esp_driver_isp/src/isp_core.c b/components/esp_driver_isp/src/isp_core.c index 2fb6510d091..c00afdfff5b 100644 --- a/components/esp_driver_isp/src/isp_core.c +++ b/components/esp_driver_isp/src/isp_core.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,6 +85,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ isp_processor_t *proc = heap_caps_calloc(1, sizeof(isp_processor_t), ISP_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(proc, ESP_ERR_NO_MEM, TAG, "no mem"); + proc->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; //claim a processor, then do assignment ESP_GOTO_ON_ERROR(s_isp_claim_processor(proc), err, TAG, "no available isp processor"); @@ -92,6 +93,8 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ ESP_GOTO_ON_ERROR(mipi_csi_brg_claim(MIPI_CSI_BRG_USER_SHARE, &proc->csi_brg_id), err, TAG, "csi bridge is in use already"); #endif + ESP_GOTO_ON_ERROR(esp_isp_register_isr(proc, ISP_SUBMODULE_GENERAL), err, TAG, "fail to register ISR"); + isp_clk_src_t clk_src = !proc_config->clk_src ? ISP_CLK_SRC_DEFAULT : proc_config->clk_src; uint32_t clk_src_freq_hz = 0; ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz), err, TAG, "clock source setting fail"); @@ -129,7 +132,6 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ atomic_init(&proc->lsc_fsm, ISP_FSM_INIT); atomic_init(&proc->sharpen_fsm, ISP_FSM_INIT); atomic_init(&proc->wbg_fsm, ISP_FSM_INIT); - proc->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; //Input & Output color format color_space_pixel_format_t in_color_format = { @@ -151,6 +153,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ } isp_ll_clk_enable(proc->hal.hw, true); + isp_ll_enable_intr(proc->hal.hw, ISP_LL_EVENT_ERROR_MASK, true); isp_ll_set_input_data_source(proc->hal.hw, proc_config->input_data_source); isp_ll_enable_line_start_packet_exist(proc->hal.hw, proc_config->has_line_start_packet); isp_ll_enable_line_end_packet_exist(proc->hal.hw, proc_config->has_line_end_packet); @@ -192,6 +195,9 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ return ESP_OK; err: + if (proc->intr_hdl) { + esp_isp_deregister_isr(proc, ISP_SUBMODULE_GENERAL); + } free(proc); return ret; @@ -208,6 +214,9 @@ esp_err_t esp_isp_del_processor(isp_proc_handle_t proc) ESP_RETURN_ON_ERROR(mipi_csi_brg_declaim(proc->csi_brg_id), TAG, "declaim csi bridge fail"); #endif ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(proc->clk_src), false), TAG, "clock source disable failed"); + if (proc->intr_hdl) { + esp_isp_deregister_isr(proc, ISP_SUBMODULE_GENERAL); + } free(proc); return ESP_OK; @@ -275,6 +284,7 @@ static void IRAM_ATTR s_isp_isr_dispatcher(void *arg) uint32_t ae_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AE_MASK); uint32_t sharp_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_SHARP_MASK); uint32_t hist_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_HIST_MASK); + uint32_t error_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_ERROR_MASK); bool do_dispatch = false; //Deal with hw events @@ -328,6 +338,23 @@ static void IRAM_ATTR s_isp_isr_dispatcher(void *arg) } do_dispatch = false; } + + if ((error_events & ISP_LL_EVENT_DATA_TYPE_ERR) || (error_events & ISP_LL_EVENT_DATA_TYPE_SETTING_ERR)) { + ESP_EARLY_LOGE(TAG, "data type error"); + } + if ((error_events & ISP_LL_EVENT_ASYNC_FIFO_OVF) || (error_events & ISP_LL_EVENT_BUF_FULL)) { + ESP_EARLY_LOGE(TAG, "fifo overflow"); + } + if ((error_events & ISP_LL_EVENT_HVNUM_SETTING_ERR) || (error_events & ISP_LL_EVENT_MIPI_HNUM_UNMATCH)) { + ESP_EARLY_LOGE(TAG, "hnum / vnum setting error"); + } + if (error_events & ISP_LL_EVENT_GAMMA_XCOORD_ERR) { + ESP_EARLY_LOGE(TAG, "gamma xcoord error"); + } + if (error_events & ISP_LL_EVENT_CROP_ERR) { + ESP_EARLY_LOGE(TAG, "crop error"); + } + if (need_yield) { portYIELD_FROM_ISR(); } @@ -363,16 +390,13 @@ esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule proc->isr_users.hist_isr_added = true; break; default: - assert(false); + break; } portEXIT_CRITICAL(&proc->spinlock); if (do_alloc) { - - uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(proc->hal.hw); - uint32_t intr_st_mask = ISP_LL_EVENT_AF_MASK | ISP_LL_EVENT_AE_MASK | ISP_LL_EVENT_AWB_MASK | ISP_LL_EVENT_HIST_MASK; - ret = esp_intr_alloc_intrstatus(isp_hw_info.instances[proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | proc->intr_priority, intr_st_reg_addr, intr_st_mask, - s_isp_isr_dispatcher, (void *)proc, &proc->intr_hdl); + ret = esp_intr_alloc(isp_hw_info.instances[proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | proc->intr_priority, + s_isp_isr_dispatcher, (void *)proc, &proc->intr_hdl); if (ret != ESP_OK) { ESP_LOGE(TAG, "no intr source"); return ret; @@ -414,7 +438,7 @@ esp_err_t esp_isp_deregister_isr(isp_proc_handle_t proc, isp_submodule_t submodu proc->isr_users.hist_isr_added = false; break; default: - assert(false); + break; } portEXIT_CRITICAL(&proc->spinlock); diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 2dc04840afd..bd62901d644 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -71,6 +71,18 @@ extern "C" { #define ISP_LL_EVENT_WBG_FRAME (1<<30) #define ISP_LL_EVENT_CROP_ERR (1<<31) +/*--------------------------------------------------------------- + Error Events +---------------------------------------------------------------*/ +#define ISP_LL_EVENT_DATA_TYPE_ERR (1<<0) +#define ISP_LL_EVENT_ASYNC_FIFO_OVF (1<<1) +#define ISP_LL_EVENT_BUF_FULL (1<<2) +#define ISP_LL_EVENT_HVNUM_SETTING_ERR (1<<3) +#define ISP_LL_EVENT_DATA_TYPE_SETTING_ERR (1<<4) +#define ISP_LL_EVENT_MIPI_HNUM_UNMATCH (1<<5) +#define ISP_LL_EVENT_GAMMA_XCOORD_ERR (1<<7) +#define ISP_LL_EVENT_CROP_ERR (1<<31) + #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 #define ISP_LL_EVENT_ALL_MASK (0xFFFFFFFF) #else @@ -82,6 +94,7 @@ extern "C" { #define ISP_LL_EVENT_SHARP_MASK (ISP_LL_EVENT_SHARP_FRAME) #define ISP_LL_EVENT_HIST_MASK (ISP_LL_EVENT_HIST_FDONE) #define ISP_LL_EVENT_COLOR_MASK (ISP_LL_EVENT_COLOR_FRAME) +#define ISP_LL_EVENT_ERROR_MASK (ISP_LL_EVENT_DATA_TYPE_ERR | ISP_LL_EVENT_ASYNC_FIFO_OVF | ISP_LL_EVENT_BUF_FULL | ISP_LL_EVENT_HVNUM_SETTING_ERR | ISP_LL_EVENT_DATA_TYPE_SETTING_ERR | ISP_LL_EVENT_MIPI_HNUM_UNMATCH | ISP_LL_EVENT_GAMMA_XCOORD_ERR | ISP_LL_EVENT_CROP_ERR) /*--------------------------------------------------------------- AF