From f154ade586c80b6ad256f6945de8184d2a519b23 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 +++++++++++++++---- .../esp_hal_cam/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 76d6956a640..076ef6ab894 100644 --- a/components/esp_driver_isp/include/esp_private/isp_private.h +++ b/components/esp_driver_isp/include/esp_private/isp_private.h @@ -117,6 +117,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 0fcbba95188..9fa525086f1 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"); + INIT_CRIT_SECTION_LOCK_RUNTIME(&proc->spinlock); //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); - INIT_CRIT_SECTION_LOCK_RUNTIME(&proc->spinlock); //Input & Output color format isp_color_t in_color_format = proc_config->input_data_color_type; @@ -148,6 +150,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); @@ -189,6 +192,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; @@ -205,6 +211,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; @@ -272,6 +281,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 @@ -325,6 +335,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(); } @@ -360,16 +387,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; } esp_os_exit_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; @@ -411,7 +435,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; } esp_os_exit_critical(&proc->spinlock); diff --git a/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h b/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h index 0483315aac9..c1fb28f0c15 100644 --- a/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h +++ b/components/esp_hal_cam/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