forked from espressif/esp-idf
feat(isp): ISP dispatched ISRs together
This commit is contained in:
@@ -21,7 +21,7 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
isp_ae_sample_point_t sample_point; ///< The input data source, ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC: AE input data after demosaic, ISP_AE_SAMPLE_POINT_AFTER_GAMMA: AE input data after gamma
|
isp_ae_sample_point_t sample_point; ///< The input data source, ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC: AE input data after demosaic, ISP_AE_SAMPLE_POINT_AFTER_GAMMA: AE input data after gamma
|
||||||
isp_window_t window; ///< The sampling windows of AE
|
isp_window_t window; ///< The sampling windows of AE
|
||||||
int intr_priority; ///< The interrupt priority, range 0~7, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) otherwise the larger the higher, 7 is NMI
|
int intr_priority; ///< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3)
|
||||||
} esp_isp_ae_config_t;
|
} esp_isp_ae_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -21,7 +21,7 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
isp_window_t window[ISP_AF_WINDOW_NUM]; ///< The sampling windows of AF
|
isp_window_t window[ISP_AF_WINDOW_NUM]; ///< The sampling windows of AF
|
||||||
int edge_thresh; ///< Edge threshold, definition higher than this value will be counted as a valid pixel for calculating AF result
|
int edge_thresh; ///< Edge threshold, definition higher than this value will be counted as a valid pixel for calculating AF result
|
||||||
int intr_priority; ///< The interrupt priority, range 0~7, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) otherwise the larger the higher, 7 is NMI
|
int intr_priority; ///< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3)
|
||||||
} esp_isp_af_config_t;
|
} esp_isp_af_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,6 +28,7 @@ typedef struct {
|
|||||||
bool has_line_end_packet; ///< Enable line end packet
|
bool has_line_end_packet; ///< Enable line end packet
|
||||||
uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line
|
uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line
|
||||||
uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame
|
uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame
|
||||||
|
int intr_priority; ///< The interrupt priority, range 0~3
|
||||||
} esp_isp_processor_cfg_t;
|
} esp_isp_processor_cfg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -32,10 +32,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ISP_ISR_IRAM_SAFE
|
#if CONFIG_ISP_ISR_IRAM_SAFE
|
||||||
#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_IRAM)
|
#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_IRAM)
|
||||||
#define ISP_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
#define ISP_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
||||||
#else
|
#else
|
||||||
#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_INTRDISABLED)
|
#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED)
|
||||||
#define ISP_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
#define ISP_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -67,9 +67,34 @@ typedef struct isp_processor_t {
|
|||||||
isp_awb_ctlr_t awb_ctlr;
|
isp_awb_ctlr_t awb_ctlr;
|
||||||
isp_fsm_t bf_fsm;
|
isp_fsm_t bf_fsm;
|
||||||
isp_ae_ctlr_t ae_ctlr;
|
isp_ae_ctlr_t ae_ctlr;
|
||||||
|
/* ISR */
|
||||||
|
intr_handle_t intr_hdl;
|
||||||
|
int intr_priority;
|
||||||
|
int isr_ref_counts;
|
||||||
|
struct {
|
||||||
|
uint32_t af_isr_added: 1;
|
||||||
|
uint32_t ae_isr_added: 1;
|
||||||
|
uint32_t awb_isr_added: 1;
|
||||||
|
} isr_users;
|
||||||
|
|
||||||
} isp_processor_t;
|
} isp_processor_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ISP_SUBMODULE_AF,
|
||||||
|
ISP_SUBMODULE_AE,
|
||||||
|
ISP_SUBMODULE_AWB,
|
||||||
|
} isp_submodule_t;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
INTR
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule);
|
||||||
|
esp_err_t esp_isp_deregister_isr(isp_proc_handle_t proc, isp_submodule_t submodule);
|
||||||
|
bool esp_isp_af_isr(isp_proc_handle_t proc, uint32_t af_events);
|
||||||
|
bool esp_isp_ae_isr(isp_proc_handle_t proc, uint32_t ae_events);
|
||||||
|
bool esp_isp_awb_isr(isp_proc_handle_t proc, uint32_t awb_events);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -31,10 +31,6 @@ typedef struct isp_ae_controller_t {
|
|||||||
void *user_data;
|
void *user_data;
|
||||||
} isp_ae_controller_t;
|
} isp_ae_controller_t;
|
||||||
|
|
||||||
extern portMUX_TYPE fsm_spinlock;
|
|
||||||
|
|
||||||
static void s_isp_ae_default_isr(void *arg);
|
|
||||||
|
|
||||||
/*---------------------------------------------
|
/*---------------------------------------------
|
||||||
AE
|
AE
|
||||||
----------------------------------------------*/
|
----------------------------------------------*/
|
||||||
@@ -69,10 +65,10 @@ static void s_isp_ae_free_controller(isp_ae_ctlr_t ae_ctlr)
|
|||||||
esp_intr_free(ae_ctlr->intr_handle);
|
esp_intr_free(ae_ctlr->intr_handle);
|
||||||
}
|
}
|
||||||
if (ae_ctlr->evt_que) {
|
if (ae_ctlr->evt_que) {
|
||||||
vQueueDelete(ae_ctlr->evt_que);
|
vQueueDeleteWithCaps(ae_ctlr->evt_que);
|
||||||
}
|
}
|
||||||
if (ae_ctlr->stat_lock) {
|
if (ae_ctlr->stat_lock) {
|
||||||
vSemaphoreDelete(ae_ctlr->stat_lock);
|
vSemaphoreDeleteWithCaps(ae_ctlr->stat_lock);
|
||||||
}
|
}
|
||||||
free(ae_ctlr);
|
free(ae_ctlr);
|
||||||
}
|
}
|
||||||
@@ -105,10 +101,9 @@ esp_err_t esp_isp_new_ae_controller(isp_proc_handle_t isp_proc, const esp_isp_ae
|
|||||||
ESP_GOTO_ON_ERROR(s_isp_claim_ae_controller(isp_proc, ae_ctlr), err1, TAG, "no available controller");
|
ESP_GOTO_ON_ERROR(s_isp_claim_ae_controller(isp_proc, ae_ctlr), err1, TAG, "no available controller");
|
||||||
|
|
||||||
// Register the AE ISR
|
// Register the AE ISR
|
||||||
uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(isp_proc->hal.hw);
|
int intr_priority = (ae_config->intr_priority > 0 && ae_config->intr_priority <= 3) ? BIT(ae_config->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
||||||
int intr_priority = ae_config->intr_priority > 0 && ae_config->intr_priority <= 7 ? BIT(ae_config->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
ESP_GOTO_ON_ERROR(intr_priority != isp_proc->intr_priority, err2, TAG, "intr_priority error");
|
||||||
ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(isp_hw_info.instances[isp_proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | intr_priority, intr_st_reg_addr, ISP_LL_EVENT_AE_MASK,
|
ESP_GOTO_ON_ERROR(esp_isp_register_isr(ae_ctlr->isp_proc, ISP_SUBMODULE_AE), err2, TAG, "fail to register ISR");
|
||||||
s_isp_ae_default_isr, ae_ctlr, &ae_ctlr->intr_handle), err2, TAG, "allocate interrupt failed");
|
|
||||||
|
|
||||||
isp_ll_ae_set_sample_point(isp_proc->hal.hw, ae_config->sample_point);
|
isp_ll_ae_set_sample_point(isp_proc->hal.hw, ae_config->sample_point);
|
||||||
isp_ll_ae_enable(isp_proc->hal.hw, false);
|
isp_ll_ae_enable(isp_proc->hal.hw, false);
|
||||||
@@ -132,8 +127,11 @@ esp_err_t esp_isp_del_ae_controller(isp_ae_ctlr_t ae_ctlr)
|
|||||||
ESP_RETURN_ON_FALSE(ae_ctlr && ae_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE(ae_ctlr && ae_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
ESP_RETURN_ON_FALSE(ae_ctlr->isp_proc->ae_ctlr == ae_ctlr, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
ESP_RETURN_ON_FALSE(ae_ctlr->isp_proc->ae_ctlr == ae_ctlr, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
||||||
ESP_RETURN_ON_FALSE(ae_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
ESP_RETURN_ON_FALSE(ae_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
||||||
s_isp_declaim_ae_controller(ae_ctlr);
|
|
||||||
|
|
||||||
|
// Deregister the AE ISR
|
||||||
|
ESP_RETURN_ON_FALSE(esp_isp_deregister_isr(ae_ctlr->isp_proc, ISP_SUBMODULE_AE) == ESP_OK, ESP_FAIL, TAG, "fail to deregister ISR");
|
||||||
|
|
||||||
|
s_isp_declaim_ae_controller(ae_ctlr);
|
||||||
s_isp_ae_free_controller(ae_ctlr);
|
s_isp_ae_free_controller(ae_ctlr);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -143,17 +141,14 @@ esp_err_t esp_isp_ae_controller_enable(isp_ae_ctlr_t ae_ctlr)
|
|||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(ae_ctlr && ae_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE(ae_ctlr && ae_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
ESP_RETURN_ON_FALSE(ae_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
ESP_RETURN_ON_FALSE(ae_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
||||||
esp_err_t ret = ESP_OK;
|
|
||||||
ESP_GOTO_ON_ERROR(esp_intr_enable(ae_ctlr->intr_handle), err, TAG, "failed to enable the AE interrupt");
|
|
||||||
isp_ll_ae_clk_enable(ae_ctlr->isp_proc->hal.hw, true);
|
isp_ll_ae_clk_enable(ae_ctlr->isp_proc->hal.hw, true);
|
||||||
isp_ll_enable_intr(ae_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AE_MASK, true);
|
isp_ll_enable_intr(ae_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AE_MASK, true);
|
||||||
isp_ll_ae_enable(ae_ctlr->isp_proc->hal.hw, true);
|
isp_ll_ae_enable(ae_ctlr->isp_proc->hal.hw, true);
|
||||||
xSemaphoreGive(ae_ctlr->stat_lock);
|
xSemaphoreGive(ae_ctlr->stat_lock);
|
||||||
|
|
||||||
return ret;
|
ae_ctlr->fsm = ISP_FSM_ENABLE;
|
||||||
err:
|
return ESP_OK;
|
||||||
ae_ctlr->fsm = ISP_FSM_INIT;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_isp_ae_controller_disable(isp_ae_ctlr_t ae_ctlr)
|
esp_err_t esp_isp_ae_controller_disable(isp_ae_ctlr_t ae_ctlr)
|
||||||
@@ -195,9 +190,7 @@ esp_err_t esp_isp_ae_controller_get_oneshot_statistics(isp_ae_ctlr_t ae_ctlr, in
|
|||||||
// Re-enable the env detector after manual statistics.
|
// Re-enable the env detector after manual statistics.
|
||||||
isp_ll_ae_env_detector_set_thresh(ae_ctlr->isp_proc->hal.hw, ae_ctlr->low_thresh, ae_ctlr->high_thresh);
|
isp_ll_ae_env_detector_set_thresh(ae_ctlr->isp_proc->hal.hw, ae_ctlr->low_thresh, ae_ctlr->high_thresh);
|
||||||
|
|
||||||
portENTER_CRITICAL(&fsm_spinlock);
|
|
||||||
ae_ctlr->fsm = ISP_FSM_ENABLE;
|
ae_ctlr->fsm = ISP_FSM_ENABLE;
|
||||||
portEXIT_CRITICAL(&fsm_spinlock);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
xSemaphoreGive(ae_ctlr->stat_lock);
|
xSemaphoreGive(ae_ctlr->stat_lock);
|
||||||
@@ -208,7 +201,6 @@ err:
|
|||||||
esp_err_t esp_isp_ae_controller_start_continuous_statistics(isp_ae_ctlr_t ae_ctlr)
|
esp_err_t esp_isp_ae_controller_start_continuous_statistics(isp_ae_ctlr_t ae_ctlr)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE_ISR(ae_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE_ISR(ae_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
ESP_RETURN_ON_FALSE_ISR(ae_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state");
|
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
if (xSemaphoreTake(ae_ctlr->stat_lock, 0) == pdFALSE) {
|
if (xSemaphoreTake(ae_ctlr->stat_lock, 0) == pdFALSE) {
|
||||||
ESP_LOGW(TAG, "statistics lock is not acquired, controller is busy");
|
ESP_LOGW(TAG, "statistics lock is not acquired, controller is busy");
|
||||||
@@ -216,9 +208,7 @@ esp_err_t esp_isp_ae_controller_start_continuous_statistics(isp_ae_ctlr_t ae_ctl
|
|||||||
}
|
}
|
||||||
ESP_GOTO_ON_FALSE(ae_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "controller isn't in enable state");
|
ESP_GOTO_ON_FALSE(ae_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "controller isn't in enable state");
|
||||||
|
|
||||||
portENTER_CRITICAL(&fsm_spinlock);
|
|
||||||
ae_ctlr->fsm = ISP_FSM_START;
|
ae_ctlr->fsm = ISP_FSM_START;
|
||||||
portEXIT_CRITICAL(&fsm_spinlock);
|
|
||||||
|
|
||||||
isp_ll_ae_manual_update(ae_ctlr->isp_proc->hal.hw);
|
isp_ll_ae_manual_update(ae_ctlr->isp_proc->hal.hw);
|
||||||
|
|
||||||
@@ -231,11 +221,8 @@ esp_err_t esp_isp_ae_controller_stop_continuous_statistics(isp_ae_ctlr_t ae_ctlr
|
|||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE_ISR(ae_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE_ISR(ae_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
ESP_RETURN_ON_FALSE_ISR(ae_ctlr->fsm == ISP_FSM_START, ESP_ERR_INVALID_STATE, TAG, "controller isn't in continuous state");
|
ESP_RETURN_ON_FALSE_ISR(ae_ctlr->fsm == ISP_FSM_START, ESP_ERR_INVALID_STATE, TAG, "controller isn't in continuous state");
|
||||||
isp_ll_ae_env_detector_set_thresh(ae_ctlr->isp_proc->hal.hw, ae_ctlr->low_thresh, ae_ctlr->high_thresh);
|
|
||||||
|
|
||||||
portENTER_CRITICAL(&fsm_spinlock);
|
|
||||||
ae_ctlr->fsm = ISP_FSM_ENABLE;
|
ae_ctlr->fsm = ISP_FSM_ENABLE;
|
||||||
portEXIT_CRITICAL(&fsm_spinlock);
|
|
||||||
xSemaphoreGive(ae_ctlr->stat_lock);
|
xSemaphoreGive(ae_ctlr->stat_lock);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -297,12 +284,9 @@ esp_err_t esp_isp_ae_controller_set_env_detector_threshold(isp_ae_ctlr_t ae_ctlr
|
|||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
INTR
|
INTR
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
static void IRAM_ATTR s_isp_ae_default_isr(void *arg)
|
bool IRAM_ATTR esp_isp_ae_isr(isp_proc_handle_t proc, uint32_t ae_events)
|
||||||
{
|
{
|
||||||
isp_ae_ctlr_t ae_ctlr = (isp_ae_ctlr_t)arg;
|
isp_ae_ctlr_t ae_ctlr = proc->ae_ctlr;
|
||||||
isp_proc_handle_t proc = ae_ctlr->isp_proc;
|
|
||||||
|
|
||||||
uint32_t ae_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AE_MASK);
|
|
||||||
|
|
||||||
bool need_yield = false;
|
bool need_yield = false;
|
||||||
esp_isp_ae_env_detector_evt_data_t edata = {};
|
esp_isp_ae_env_detector_evt_data_t edata = {};
|
||||||
@@ -343,8 +327,5 @@ static void IRAM_ATTR s_isp_ae_default_isr(void *arg)
|
|||||||
need_yield |= ae_ctlr->cbs.on_env_change(ae_ctlr, &edata, ae_ctlr->user_data);
|
need_yield |= ae_ctlr->cbs.on_env_change(ae_ctlr, &edata, ae_ctlr->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return need_yield;
|
||||||
if (need_yield) {
|
|
||||||
portYIELD_FROM_ISR();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,6 @@ typedef struct isp_af_controller_t {
|
|||||||
void *user_data;
|
void *user_data;
|
||||||
} isp_af_controller_t;
|
} isp_af_controller_t;
|
||||||
|
|
||||||
static void s_isp_af_default_isr(void *arg);
|
|
||||||
|
|
||||||
/*---------------------------------------------
|
/*---------------------------------------------
|
||||||
AF
|
AF
|
||||||
----------------------------------------------*/
|
----------------------------------------------*/
|
||||||
@@ -72,7 +70,7 @@ static void s_isp_af_free_controller(isp_af_ctlr_t af_ctlr)
|
|||||||
esp_intr_free(af_ctlr->intr_handle);
|
esp_intr_free(af_ctlr->intr_handle);
|
||||||
}
|
}
|
||||||
if (af_ctlr->evt_que) {
|
if (af_ctlr->evt_que) {
|
||||||
vQueueDelete(af_ctlr->evt_que);
|
vQueueDeleteWithCaps(af_ctlr->evt_que);
|
||||||
}
|
}
|
||||||
free(af_ctlr);
|
free(af_ctlr);
|
||||||
}
|
}
|
||||||
@@ -114,10 +112,9 @@ esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af
|
|||||||
ESP_GOTO_ON_ERROR(s_isp_claim_af_controller(isp_proc, af_ctlr), err1, TAG, "no available controller");
|
ESP_GOTO_ON_ERROR(s_isp_claim_af_controller(isp_proc, af_ctlr), err1, TAG, "no available controller");
|
||||||
|
|
||||||
// Register the AF ISR
|
// Register the AF ISR
|
||||||
uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(isp_proc->hal.hw);
|
int intr_priority = (af_config->intr_priority > 0 && af_config->intr_priority <= 3) ? BIT(af_config->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
||||||
int intr_priority = af_config->intr_priority > 0 && af_config->intr_priority <= 7 ? BIT(af_config->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
ESP_GOTO_ON_ERROR(intr_priority != isp_proc->intr_priority, err2, TAG, "intr_priority error");
|
||||||
ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(isp_hw_info.instances[isp_proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | intr_priority, intr_st_reg_addr, ISP_LL_EVENT_AF_MASK,
|
ESP_GOTO_ON_ERROR(esp_isp_register_isr(af_ctlr->isp_proc, ISP_SUBMODULE_AF), err2, TAG, "fail to register ISR");
|
||||||
s_isp_af_default_isr, af_ctlr, &af_ctlr->intr_handle), err2, TAG, "allocate interrupt failed");
|
|
||||||
|
|
||||||
isp_ll_af_enable_auto_update(isp_proc->hal.hw, false);
|
isp_ll_af_enable_auto_update(isp_proc->hal.hw, false);
|
||||||
isp_ll_af_enable(isp_proc->hal.hw, false);
|
isp_ll_af_enable(isp_proc->hal.hw, false);
|
||||||
@@ -153,6 +150,10 @@ esp_err_t esp_isp_del_af_controller(isp_af_ctlr_t af_ctlr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_RETURN_ON_FALSE(exist, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
ESP_RETURN_ON_FALSE(exist, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
||||||
|
|
||||||
|
// Deregister the AF ISR
|
||||||
|
ESP_RETURN_ON_FALSE(esp_isp_deregister_isr(af_ctlr->isp_proc, ISP_SUBMODULE_AF) == ESP_OK, ESP_FAIL, TAG, "fail to deregister ISR");
|
||||||
|
|
||||||
s_isp_declaim_af_controller(af_ctlr);
|
s_isp_declaim_af_controller(af_ctlr);
|
||||||
s_isp_af_free_controller(af_ctlr);
|
s_isp_af_free_controller(af_ctlr);
|
||||||
|
|
||||||
@@ -164,7 +165,6 @@ esp_err_t esp_isp_af_controller_enable(isp_af_ctlr_t af_ctlr)
|
|||||||
ESP_RETURN_ON_FALSE(af_ctlr && af_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE(af_ctlr && af_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
ESP_RETURN_ON_FALSE(af_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
ESP_RETURN_ON_FALSE(af_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
||||||
|
|
||||||
esp_intr_enable(af_ctlr->intr_handle);
|
|
||||||
isp_ll_af_clk_enable(af_ctlr->isp_proc->hal.hw, true);
|
isp_ll_af_clk_enable(af_ctlr->isp_proc->hal.hw, true);
|
||||||
isp_ll_enable_intr(af_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AF_MASK, true);
|
isp_ll_enable_intr(af_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AF_MASK, true);
|
||||||
isp_ll_af_enable(af_ctlr->isp_proc->hal.hw, true);
|
isp_ll_af_enable(af_ctlr->isp_proc->hal.hw, true);
|
||||||
@@ -284,12 +284,9 @@ esp_err_t esp_isp_af_controller_set_env_detector_threshold(isp_af_ctlr_t af_ctrl
|
|||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
INTR
|
INTR
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
static void IRAM_ATTR s_isp_af_default_isr(void *arg)
|
bool IRAM_ATTR esp_isp_af_isr(isp_proc_handle_t proc, uint32_t af_events)
|
||||||
{
|
{
|
||||||
isp_af_ctlr_t af_ctrlr = (isp_af_ctlr_t)arg;
|
isp_af_ctlr_t af_ctrlr = proc->af_ctlr[0];
|
||||||
isp_proc_handle_t proc = af_ctrlr->isp_proc;
|
|
||||||
|
|
||||||
uint32_t af_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AF_MASK);
|
|
||||||
|
|
||||||
bool need_yield = false;
|
bool need_yield = false;
|
||||||
esp_isp_af_env_detector_evt_data_t edata = {};
|
esp_isp_af_env_detector_evt_data_t edata = {};
|
||||||
@@ -323,8 +320,5 @@ static void IRAM_ATTR s_isp_af_default_isr(void *arg)
|
|||||||
need_yield |= af_ctrlr->cbs.on_env_change(af_ctrlr, &edata, af_ctrlr->user_data);
|
need_yield |= af_ctrlr->cbs.on_env_change(af_ctrlr, &edata, af_ctrlr->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return need_yield;
|
||||||
if (need_yield) {
|
|
||||||
portYIELD_FROM_ISR();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@ typedef struct isp_awb_controller_t {
|
|||||||
isp_fsm_t fsm;
|
isp_fsm_t fsm;
|
||||||
portMUX_TYPE spinlock;
|
portMUX_TYPE spinlock;
|
||||||
intr_handle_t intr_handle;
|
intr_handle_t intr_handle;
|
||||||
int intr_priority;
|
|
||||||
isp_proc_handle_t isp_proc;
|
isp_proc_handle_t isp_proc;
|
||||||
QueueHandle_t evt_que;
|
QueueHandle_t evt_que;
|
||||||
SemaphoreHandle_t stat_lock;
|
SemaphoreHandle_t stat_lock;
|
||||||
@@ -28,8 +27,6 @@ typedef struct isp_awb_controller_t {
|
|||||||
|
|
||||||
static const char *TAG = "ISP_AWB";
|
static const char *TAG = "ISP_AWB";
|
||||||
|
|
||||||
static void s_isp_awb_default_isr(void *arg);
|
|
||||||
|
|
||||||
/*---------------------------------------------
|
/*---------------------------------------------
|
||||||
AWB
|
AWB
|
||||||
----------------------------------------------*/
|
----------------------------------------------*/
|
||||||
@@ -64,10 +61,10 @@ static void s_isp_awb_free_controller(isp_awb_ctlr_t awb_ctlr)
|
|||||||
esp_intr_free(awb_ctlr->intr_handle);
|
esp_intr_free(awb_ctlr->intr_handle);
|
||||||
}
|
}
|
||||||
if (awb_ctlr->evt_que) {
|
if (awb_ctlr->evt_que) {
|
||||||
vQueueDelete(awb_ctlr->evt_que);
|
vQueueDeleteWithCaps(awb_ctlr->evt_que);
|
||||||
}
|
}
|
||||||
if (awb_ctlr->stat_lock) {
|
if (awb_ctlr->stat_lock) {
|
||||||
vSemaphoreDelete(awb_ctlr->stat_lock);
|
vSemaphoreDeleteWithCaps(awb_ctlr->stat_lock);
|
||||||
}
|
}
|
||||||
free(awb_ctlr);
|
free(awb_ctlr);
|
||||||
}
|
}
|
||||||
@@ -109,11 +106,11 @@ esp_err_t esp_isp_new_awb_controller(isp_proc_handle_t isp_proc, const esp_isp_a
|
|||||||
|
|
||||||
// Claim an AWB controller
|
// Claim an AWB controller
|
||||||
ESP_GOTO_ON_ERROR(s_isp_claim_awb_controller(isp_proc, awb_ctlr), err1, TAG, "no available controller");
|
ESP_GOTO_ON_ERROR(s_isp_claim_awb_controller(isp_proc, awb_ctlr), err1, TAG, "no available controller");
|
||||||
|
|
||||||
// Register the AWB ISR
|
// Register the AWB ISR
|
||||||
uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(isp_proc->hal.hw);
|
int intr_priority = (awb_cfg->intr_priority > 0 && awb_cfg->intr_priority <= 3) ? BIT(awb_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
||||||
awb_ctlr->intr_priority = awb_cfg->intr_priority > 0 && awb_cfg->intr_priority <= 3 ? BIT(awb_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
ESP_GOTO_ON_ERROR(intr_priority != isp_proc->intr_priority, err2, TAG, "intr_priority error");
|
||||||
ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(isp_hw_info.instances[isp_proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | awb_ctlr->intr_priority, intr_st_reg_addr, ISP_LL_EVENT_AWB_MASK,
|
ESP_GOTO_ON_ERROR(esp_isp_register_isr(awb_ctlr->isp_proc, ISP_SUBMODULE_AWB), err2, TAG, "fail to register ISR");
|
||||||
s_isp_awb_default_isr, awb_ctlr, &awb_ctlr->intr_handle), err2, TAG, "allocate interrupt failed");
|
|
||||||
|
|
||||||
// Configure the hardware
|
// Configure the hardware
|
||||||
isp_ll_awb_enable(isp_proc->hal.hw, false);
|
isp_ll_awb_enable(isp_proc->hal.hw, false);
|
||||||
@@ -137,6 +134,8 @@ esp_err_t esp_isp_del_awb_controller(isp_awb_ctlr_t awb_ctlr)
|
|||||||
ESP_RETURN_ON_FALSE(awb_ctlr && awb_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE(awb_ctlr && awb_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
ESP_RETURN_ON_FALSE(awb_ctlr->isp_proc->awb_ctlr == awb_ctlr, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
ESP_RETURN_ON_FALSE(awb_ctlr->isp_proc->awb_ctlr == awb_ctlr, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
||||||
ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state");
|
||||||
|
|
||||||
|
ESP_RETURN_ON_FALSE(esp_isp_deregister_isr(awb_ctlr->isp_proc, ISP_SUBMODULE_AWB) == ESP_OK, ESP_FAIL, TAG, "fail to deregister ISR");
|
||||||
s_isp_declaim_awb_controller(awb_ctlr);
|
s_isp_declaim_awb_controller(awb_ctlr);
|
||||||
|
|
||||||
isp_ll_awb_enable_algorithm_mode(awb_ctlr->isp_proc->hal.hw, false);
|
isp_ll_awb_enable_algorithm_mode(awb_ctlr->isp_proc->hal.hw, false);
|
||||||
@@ -148,9 +147,6 @@ esp_err_t esp_isp_del_awb_controller(isp_awb_ctlr_t awb_ctlr)
|
|||||||
esp_err_t esp_isp_awb_controller_reconfig(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_config_t *awb_cfg)
|
esp_err_t esp_isp_awb_controller_reconfig(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_config_t *awb_cfg)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(awb_ctlr && awb_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE(awb_ctlr && awb_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
int intr_priority = awb_cfg->intr_priority > 0 && awb_cfg->intr_priority <= 3 ? BIT(awb_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
|
||||||
ESP_RETURN_ON_FALSE(intr_priority == awb_ctlr->intr_priority, ESP_ERR_INVALID_ARG, TAG, "can't change interrupt priority after initialized");
|
|
||||||
|
|
||||||
return s_esp_isp_awb_config_hardware(awb_ctlr->isp_proc, awb_cfg);
|
return s_esp_isp_awb_config_hardware(awb_ctlr->isp_proc, awb_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,14 +157,10 @@ esp_err_t esp_isp_awb_controller_enable(isp_awb_ctlr_t awb_ctlr)
|
|||||||
awb_ctlr->fsm = ISP_FSM_ENABLE;
|
awb_ctlr->fsm = ISP_FSM_ENABLE;
|
||||||
|
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
ESP_GOTO_ON_ERROR(esp_intr_enable(awb_ctlr->intr_handle), err, TAG, "failed to enable the AWB interrupt");
|
|
||||||
isp_ll_awb_clk_enable(awb_ctlr->isp_proc->hal.hw, true);
|
isp_ll_awb_clk_enable(awb_ctlr->isp_proc->hal.hw, true);
|
||||||
isp_ll_enable_intr(awb_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AWB_MASK, true);
|
isp_ll_enable_intr(awb_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AWB_MASK, true);
|
||||||
xSemaphoreGive(awb_ctlr->stat_lock);
|
xSemaphoreGive(awb_ctlr->stat_lock);
|
||||||
|
|
||||||
return ret;
|
|
||||||
err:
|
|
||||||
awb_ctlr->fsm = ISP_FSM_INIT;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,13 +237,8 @@ esp_err_t esp_isp_awb_controller_stop_continuous_statistics(isp_awb_ctlr_t awb_c
|
|||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
INTR
|
INTR
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
static void IRAM_ATTR s_isp_awb_default_isr(void *arg)
|
bool IRAM_ATTR esp_isp_awb_isr(isp_proc_handle_t proc, uint32_t awb_events)
|
||||||
{
|
{
|
||||||
isp_awb_ctlr_t awb_ctlr = (isp_awb_ctlr_t)arg;
|
|
||||||
isp_proc_handle_t proc = awb_ctlr->isp_proc;
|
|
||||||
|
|
||||||
uint32_t awb_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AWB_MASK);
|
|
||||||
|
|
||||||
bool need_yield = false;
|
bool need_yield = false;
|
||||||
|
|
||||||
if (awb_events & ISP_LL_EVENT_AWB_FDONE) {
|
if (awb_events & ISP_LL_EVENT_AWB_FDONE) {
|
||||||
@@ -279,10 +266,7 @@ static void IRAM_ATTR s_isp_awb_default_isr(void *arg)
|
|||||||
isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, true);
|
isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return need_yield;
|
||||||
if (need_yield) {
|
|
||||||
portYIELD_FROM_ISR();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_isp_awb_register_event_callbacks(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_cbs_t *cbs, void *user_data)
|
esp_err_t esp_isp_awb_register_event_callbacks(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_cbs_t *cbs, void *user_data)
|
||||||
|
@@ -89,6 +89,8 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_
|
|||||||
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");
|
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");
|
||||||
ESP_GOTO_ON_FALSE((proc_config->clk_hz > 0 && proc_config->clk_hz <= clk_src_freq_hz), ESP_ERR_INVALID_ARG, err, TAG, "clk hz not supported");
|
ESP_GOTO_ON_FALSE((proc_config->clk_hz > 0 && proc_config->clk_hz <= clk_src_freq_hz), ESP_ERR_INVALID_ARG, err, TAG, "clk hz not supported");
|
||||||
|
|
||||||
|
proc->intr_priority = (proc_config->intr_priority > 0 && proc_config->intr_priority <= 3) ? BIT(proc_config->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
||||||
|
|
||||||
uint32_t out_clk_freq_hz = 0;
|
uint32_t out_clk_freq_hz = 0;
|
||||||
hal_utils_clk_div_t clk_div = {};
|
hal_utils_clk_div_t clk_div = {};
|
||||||
hal_utils_clk_info_t clk_info = {
|
hal_utils_clk_info_t clk_info = {
|
||||||
@@ -102,7 +104,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_
|
|||||||
if (out_clk_freq_hz != proc_config->clk_hz) {
|
if (out_clk_freq_hz != proc_config->clk_hz) {
|
||||||
ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32"Hz", out_clk_freq_hz);
|
ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32"Hz", out_clk_freq_hz);
|
||||||
}
|
}
|
||||||
|
;
|
||||||
isp_hal_init(&proc->hal, proc->proc_id);
|
isp_hal_init(&proc->hal, proc->proc_id);
|
||||||
PERIPH_RCC_ATOMIC() {
|
PERIPH_RCC_ATOMIC() {
|
||||||
isp_ll_select_clk_source(proc->hal.hw, clk_src);
|
isp_ll_select_clk_source(proc->hal.hw, clk_src);
|
||||||
@@ -186,3 +188,137 @@ esp_err_t esp_isp_disable(isp_proc_handle_t proc)
|
|||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
INTR
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
static void IRAM_ATTR s_isp_isr_dispatcher(void *arg)
|
||||||
|
{
|
||||||
|
isp_processor_t *proc = (isp_processor_t *)arg;
|
||||||
|
bool need_yield = false;
|
||||||
|
|
||||||
|
//Check and clear hw events
|
||||||
|
uint32_t af_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AF_MASK);
|
||||||
|
uint32_t awb_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AWB_MASK);
|
||||||
|
uint32_t ae_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AE_MASK);
|
||||||
|
|
||||||
|
bool do_dispatch = false;
|
||||||
|
//Deal with hw events
|
||||||
|
if (af_events) {
|
||||||
|
portENTER_CRITICAL_ISR(&proc->spinlock);
|
||||||
|
do_dispatch = proc->isr_users.af_isr_added;
|
||||||
|
portEXIT_CRITICAL_ISR(&proc->spinlock);
|
||||||
|
|
||||||
|
if (do_dispatch) {
|
||||||
|
need_yield |= esp_isp_af_isr(proc, af_events);
|
||||||
|
}
|
||||||
|
do_dispatch = false;
|
||||||
|
}
|
||||||
|
if (awb_events) {
|
||||||
|
portENTER_CRITICAL_ISR(&proc->spinlock);
|
||||||
|
do_dispatch = proc->isr_users.awb_isr_added;
|
||||||
|
portEXIT_CRITICAL_ISR(&proc->spinlock);
|
||||||
|
|
||||||
|
if (do_dispatch) {
|
||||||
|
need_yield |= esp_isp_awb_isr(proc, awb_events);
|
||||||
|
}
|
||||||
|
do_dispatch = false;
|
||||||
|
}
|
||||||
|
if (ae_events) {
|
||||||
|
portENTER_CRITICAL_ISR(&proc->spinlock);
|
||||||
|
do_dispatch = proc->isr_users.ae_isr_added;
|
||||||
|
portEXIT_CRITICAL_ISR(&proc->spinlock);
|
||||||
|
|
||||||
|
if (do_dispatch) {
|
||||||
|
need_yield |= esp_isp_ae_isr(proc, ae_events);
|
||||||
|
}
|
||||||
|
do_dispatch = false;
|
||||||
|
}
|
||||||
|
if (need_yield) {
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_FAIL;
|
||||||
|
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
|
||||||
|
bool do_alloc = false;
|
||||||
|
portENTER_CRITICAL(&proc->spinlock);
|
||||||
|
proc->isr_ref_counts++;
|
||||||
|
if (proc->isr_ref_counts == 1) {
|
||||||
|
assert(!proc->intr_hdl);
|
||||||
|
do_alloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (submodule) {
|
||||||
|
case ISP_SUBMODULE_AF:
|
||||||
|
proc->isr_users.af_isr_added = true;
|
||||||
|
break;
|
||||||
|
case ISP_SUBMODULE_AWB:
|
||||||
|
proc->isr_users.awb_isr_added = true;
|
||||||
|
break;
|
||||||
|
case ISP_SUBMODULE_AE:
|
||||||
|
proc->isr_users.ae_isr_added = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "no intr source");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
esp_intr_enable(proc->intr_hdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_isp_deregister_isr(isp_proc_handle_t proc, isp_submodule_t submodule)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_FAIL;
|
||||||
|
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
|
||||||
|
bool do_free = false;
|
||||||
|
portENTER_CRITICAL(&proc->spinlock);
|
||||||
|
proc->isr_ref_counts--;
|
||||||
|
assert(proc->isr_ref_counts >= 0);
|
||||||
|
if (proc->isr_ref_counts == 0) {
|
||||||
|
assert(proc->intr_hdl);
|
||||||
|
do_free = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (submodule) {
|
||||||
|
case ISP_SUBMODULE_AF:
|
||||||
|
proc->isr_users.af_isr_added = false;
|
||||||
|
break;
|
||||||
|
case ISP_SUBMODULE_AWB:
|
||||||
|
proc->isr_users.awb_isr_added = false;
|
||||||
|
break;
|
||||||
|
case ISP_SUBMODULE_AE:
|
||||||
|
proc->isr_users.ae_isr_added = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL(&proc->spinlock);
|
||||||
|
|
||||||
|
if (do_free) {
|
||||||
|
esp_intr_disable(proc->intr_hdl);
|
||||||
|
ret = esp_intr_free(proc->intr_hdl);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
@@ -187,7 +187,7 @@ TEST_CASE("ISP AE driver basic function", "[isp]")
|
|||||||
isp_ae_ctlr_t ae_ctlr = NULL;
|
isp_ae_ctlr_t ae_ctlr = NULL;
|
||||||
/* Default parameters from helper macro */
|
/* Default parameters from helper macro */
|
||||||
esp_isp_ae_config_t ae_config = {
|
esp_isp_ae_config_t ae_config = {
|
||||||
.ae_sample_point = ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC,
|
.sample_point = ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC,
|
||||||
};
|
};
|
||||||
isp_ae_result_t ae_res = {};
|
isp_ae_result_t ae_res = {};
|
||||||
/* Create the ae controller */
|
/* Create the ae controller */
|
||||||
@@ -230,7 +230,7 @@ TEST_CASE("ISP AE controller exhausted allocation", "[isp]")
|
|||||||
TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc));
|
TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||||||
|
|
||||||
esp_isp_ae_config_t ae_config = {
|
esp_isp_ae_config_t ae_config = {
|
||||||
.ae_sample_point = ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC,
|
.sample_point = ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC,
|
||||||
};
|
};
|
||||||
isp_ae_ctlr_t ae_ctrlr[SOC_ISP_AE_CTLR_NUMS + 1] = {};
|
isp_ae_ctlr_t ae_ctrlr[SOC_ISP_AE_CTLR_NUMS + 1] = {};
|
||||||
for (int i = 0; i < SOC_ISP_AE_CTLR_NUMS; i++) {
|
for (int i = 0; i < SOC_ISP_AE_CTLR_NUMS; i++) {
|
||||||
|
Reference in New Issue
Block a user