Skip to content

Commit d1e8549

Browse files
committed
Merge branch 'feat/p4_rev3_isp_awb_wbg_v5.5' into 'release/v5.5'
isp: awb white balance gain feature and subwindow feature support on P4 ECO5 (v5.5) See merge request espressif/esp-idf!42799
2 parents e66fc82 + 3fff202 commit d1e8549

File tree

21 files changed

+465
-66
lines changed

21 files changed

+465
-66
lines changed

components/esp_driver_isp/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ if(CONFIG_SOC_ISP_LSC_SUPPORTED)
4242
list(APPEND srcs "src/isp_lsc.c")
4343
endif()
4444

45+
if(CONFIG_SOC_ISP_WBG_SUPPORTED)
46+
list(APPEND srcs "src/isp_wbg.c")
47+
endif()
48+
4549
if(NOT ${target} STREQUAL "linux")
4650
list(APPEND requires esp_mm)
4751
endif()

components/esp_driver_isp/include/driver/isp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@
2424
#include "driver/isp_hist.h"
2525
#include "driver/isp_lsc.h"
2626
#include "driver/isp_sharpen.h"
27+
#include "driver/isp_wbg.h"

components/esp_driver_isp/include/driver/isp_awb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

components/esp_driver_isp/include/driver/isp_types.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -39,14 +39,25 @@ typedef struct {
3939
int luminance[ISP_AF_WINDOW_NUM]; ///< Luminance, it refers how luminant an image is
4040
} isp_af_result_t;
4141

42+
/**
43+
* @brief ISP AWB subwindow result
44+
*/
45+
typedef struct {
46+
uint32_t white_patch_num[ISP_AWB_WINDOW_X_NUM][ISP_AWB_WINDOW_Y_NUM]; ///< white patch number that counted by AWB in the subwindow
47+
uint32_t sum_r[ISP_AWB_WINDOW_X_NUM][ISP_AWB_WINDOW_Y_NUM]; ///< The sum of R channel of these white patches
48+
uint32_t sum_g[ISP_AWB_WINDOW_X_NUM][ISP_AWB_WINDOW_Y_NUM]; ///< The sum of G channel of these white patches
49+
uint32_t sum_b[ISP_AWB_WINDOW_X_NUM][ISP_AWB_WINDOW_Y_NUM]; ///< The sum of B channel of these white patches
50+
} isp_awb_subwin_stat_result_t;
51+
4252
/**
4353
* @brief ISP AWB result
4454
*/
4555
typedef struct {
46-
uint32_t white_patch_num; ///< white patch number that counted by AWB in the window
47-
uint32_t sum_r; ///< The sum of R channel of these white patches
48-
uint32_t sum_g; ///< The sum of G channel of these white patches
49-
uint32_t sum_b; ///< The sum of B channel of these white patches
56+
uint32_t white_patch_num; ///< white patch number that counted by AWB in the window
57+
uint32_t sum_r; ///< The sum of R channel of these white patches
58+
uint32_t sum_g; ///< The sum of G channel of these white patches
59+
uint32_t sum_b; ///< The sum of B channel of these white patches
60+
isp_awb_subwin_stat_result_t subwin_result; ///< The AWB subwindow statistics result
5061
} isp_awb_stat_result_t;
5162

5263
/**
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdint.h>
10+
#include "esp_err.h"
11+
#include "driver/isp_types.h"
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
/*---------------------------------------------------------------
18+
WBG (White Balance Gain)
19+
---------------------------------------------------------------*/
20+
/**
21+
* @brief ISP BLC configurations
22+
*/
23+
typedef struct {
24+
//for future proof
25+
} esp_isp_wbg_config_t;
26+
27+
/**
28+
* @brief ISP WBG configuration
29+
*
30+
* @note After calling this API, WBG doesn't take into effect until `esp_isp_wbg_enable` is called
31+
*
32+
* @param[in] isp_proc Processor handle
33+
* @param[in] config WBG configurations
34+
*
35+
* @return
36+
* - ESP_OK On success
37+
* - ESP_ERR_INVALID_STATE Not allowed to be called under current state
38+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
39+
* - ESP_ERR_NOT_SUPPORTED Not supported
40+
*/
41+
esp_err_t esp_isp_wbg_configure(isp_proc_handle_t isp_proc, const esp_isp_wbg_config_t *config);
42+
43+
/**
44+
* @brief Enable ISP WBG function
45+
*
46+
* @param[in] isp_proc Processor handle
47+
*
48+
* @return
49+
* - ESP_OK On success
50+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
51+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
52+
*/
53+
esp_err_t esp_isp_wbg_enable(isp_proc_handle_t isp_proc);
54+
55+
/**
56+
* @brief Set AWB white balance gain
57+
*
58+
* @param[in] isp_proc Processor handle
59+
* @param[in] gain WBG white balance gain
60+
* @return
61+
* - ESP_OK On success
62+
* - ESP_ERR_INVALID_ARG Null pointer
63+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
64+
*/
65+
esp_err_t esp_isp_wbg_set_wb_gain(isp_proc_handle_t isp_proc, isp_wbg_gain_t gain);
66+
67+
/**
68+
* @brief Disable ISP WBG function
69+
*
70+
* @param[in] isp_proc Processor handle
71+
*
72+
* @return
73+
* - ESP_OK On success
74+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
75+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
76+
*/
77+
esp_err_t esp_isp_wbg_disable(isp_proc_handle_t isp_proc);
78+
79+
#ifdef __cplusplus
80+
}
81+
#endif

components/esp_driver_isp/include/esp_private/isp_private.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -9,6 +9,7 @@
99
#include <stdint.h>
1010
#include <stdbool.h>
1111
#include <esp_types.h>
12+
#include <stdatomic.h>
1213
#include "sdkconfig.h"
1314
#include "esp_attr.h"
1415
#include "esp_log.h"
@@ -27,8 +28,12 @@
2728
#include "soc/isp_periph.h"
2829
#endif
2930

31+
// Helper macros for atomic operations to ensure Clang compatibility
3032
#ifdef __cplusplus
31-
extern "C" {
33+
#include <atomic>
34+
#define ISP_ATOMIC_TYPE(T) std::atomic<T>
35+
#else
36+
#define ISP_ATOMIC_TYPE(T) _Atomic T
3237
#endif
3338

3439
#if CONFIG_ISP_ISR_IRAM_SAFE || CONFIG_ISP_CTRL_FUNC_IN_IRAM
@@ -39,6 +44,10 @@ extern "C" {
3944
#define ISP_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
4045
#endif
4146

47+
#ifdef __cplusplus
48+
extern "C" {
49+
#endif
50+
4251
typedef enum {
4352
ISP_FSM_INIT, // Controller is initialized, but not enabled
4453
ISP_FSM_ENABLE, // Controller is enabled, but is not running
@@ -59,7 +68,7 @@ typedef struct isp_processor_t {
5968
int csi_brg_id;
6069
void *csi_brg_hw;
6170
#endif
62-
isp_fsm_t isp_fsm;
71+
ISP_ATOMIC_TYPE(isp_fsm_t) isp_fsm;
6372
portMUX_TYPE spinlock;
6473
color_space_pixel_format_t in_color_format;
6574
color_space_pixel_format_t out_color_format;
@@ -72,12 +81,15 @@ typedef struct isp_processor_t {
7281
isp_awb_ctlr_t awb_ctlr;
7382
isp_ae_ctlr_t ae_ctlr;
7483
isp_hist_ctlr_t hist_ctlr;
75-
isp_fsm_t bf_fsm;
76-
isp_fsm_t demosaic_fsm;
77-
isp_fsm_t sharpen_fsm;
78-
isp_fsm_t color_fsm;
79-
isp_fsm_t lsc_fsm;
80-
isp_fsm_t blc_fsm;
84+
ISP_ATOMIC_TYPE(isp_fsm_t) bf_fsm;
85+
ISP_ATOMIC_TYPE(isp_fsm_t) blc_fsm;
86+
ISP_ATOMIC_TYPE(isp_fsm_t) ccm_fsm;
87+
ISP_ATOMIC_TYPE(isp_fsm_t) color_fsm;
88+
ISP_ATOMIC_TYPE(isp_fsm_t) demosaic_fsm;
89+
ISP_ATOMIC_TYPE(isp_fsm_t) gamma_fsm;
90+
ISP_ATOMIC_TYPE(isp_fsm_t) lsc_fsm;
91+
ISP_ATOMIC_TYPE(isp_fsm_t) sharpen_fsm;
92+
ISP_ATOMIC_TYPE(isp_fsm_t) wbg_fsm;
8193
esp_isp_evt_cbs_t cbs;
8294
void *user_data;
8395

components/esp_driver_isp/src/isp_awb.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -239,6 +239,26 @@ bool IRAM_ATTR esp_isp_awb_isr(isp_proc_handle_t proc, uint32_t awb_events)
239239
.sum_b = isp_ll_awb_get_accumulated_b_value(proc->hal.hw),
240240
},
241241
};
242+
243+
// Get subwindow statistics
244+
for (int x = 0; x < ISP_AWB_WINDOW_X_NUM; x++) {
245+
for (int y = 0; y < ISP_AWB_WINDOW_Y_NUM; y++) {
246+
int subwindow_id = x * ISP_AWB_WINDOW_Y_NUM + y;
247+
248+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_WHITE_PATCH_CNT, subwindow_id, ISP_LL_LUT_AWB);
249+
edata.awb_result.subwin_result.white_patch_num[x][y] = isp_ll_lut_awb_get_subwindow_white_patch_cnt(proc->hal.hw);
250+
251+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_ACCUMULATED_R, subwindow_id, ISP_LL_LUT_AWB);
252+
edata.awb_result.subwin_result.sum_r[x][y] = isp_ll_lut_awb_get_subwindow_accumulated_r(proc->hal.hw);
253+
254+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_ACCUMULATED_G, subwindow_id, ISP_LL_LUT_AWB);
255+
edata.awb_result.subwin_result.sum_g[x][y] = isp_ll_lut_awb_get_subwindow_accumulated_g(proc->hal.hw);
256+
257+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_ACCUMULATED_B, subwindow_id, ISP_LL_LUT_AWB);
258+
edata.awb_result.subwin_result.sum_b[x][y] = isp_ll_lut_awb_get_subwindow_accumulated_b(proc->hal.hw);
259+
}
260+
}
261+
242262
// Invoke the callback if the callback is registered
243263
if (awb_ctlr->cbs.on_statistics_done) {
244264
need_yield |= awb_ctlr->cbs.on_statistics_done(awb_ctlr, &edata, awb_ctlr->user_data);

components/esp_driver_isp/src/isp_bf.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -49,21 +49,21 @@ esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t
4949
esp_err_t esp_isp_bf_enable(isp_proc_handle_t proc)
5050
{
5151
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
52-
ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "bf is enabled already");
52+
isp_fsm_t expected_fsm = ISP_FSM_INIT;
53+
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&proc->bf_fsm, &expected_fsm, ISP_FSM_ENABLE), ESP_ERR_INVALID_STATE, TAG, "bf is enabled already");
5354

5455
isp_ll_bf_enable(proc->hal.hw, true);
55-
proc->bf_fsm = ISP_FSM_ENABLE;
5656

5757
return ESP_OK;
5858
}
5959

6060
esp_err_t esp_isp_bf_disable(isp_proc_handle_t proc)
6161
{
6262
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
63-
ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "bf isn't enabled yet");
63+
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
64+
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&proc->bf_fsm, &expected_fsm, ISP_FSM_INIT), ESP_ERR_INVALID_STATE, TAG, "bf isn't enabled yet");
6465

6566
isp_ll_bf_enable(proc->hal.hw, false);
66-
proc->bf_fsm = ISP_FSM_INIT;
6767

6868
return ESP_OK;
6969
}

components/esp_driver_isp/src/isp_blc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ esp_err_t esp_isp_blc_configure(isp_proc_handle_t isp_proc, const esp_isp_blc_co
6464
esp_err_t esp_isp_blc_enable(isp_proc_handle_t isp_proc)
6565
{
6666
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
67-
ESP_RETURN_ON_FALSE(isp_proc->blc_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "blc is enabled already");
67+
isp_fsm_t expected_fsm = ISP_FSM_INIT;
68+
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&isp_proc->blc_fsm, &expected_fsm, ISP_FSM_ENABLE), ESP_ERR_INVALID_STATE, TAG, "blc is enabled already");
6869

6970
// Enable BLC module
7071
isp_ll_blc_enable(isp_proc->hal.hw, true);
71-
isp_proc->blc_fsm = ISP_FSM_ENABLE;
7272

7373
ESP_LOGD(TAG, "BLC enabled");
7474
return ESP_OK;
@@ -77,7 +77,7 @@ esp_err_t esp_isp_blc_enable(isp_proc_handle_t isp_proc)
7777
esp_err_t esp_isp_blc_set_correction_offset(isp_proc_handle_t isp_proc, esp_isp_blc_offset_t *offset)
7878
{
7979
ESP_RETURN_ON_FALSE(isp_proc && offset, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
80-
ESP_RETURN_ON_FALSE(isp_proc->blc_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "blc isn't enabled yet");
80+
ESP_RETURN_ON_FALSE(atomic_load(&isp_proc->blc_fsm) == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "blc isn't enabled yet");
8181

8282
// Set correction offset for each channel
8383
isp_ll_blc_set_correction_offset(isp_proc->hal.hw, offset->top_left_chan_offset, offset->top_right_chan_offset, offset->bottom_left_chan_offset, offset->bottom_right_chan_offset);
@@ -92,11 +92,11 @@ esp_err_t esp_isp_blc_set_correction_offset(isp_proc_handle_t isp_proc, esp_isp_
9292
esp_err_t esp_isp_blc_disable(isp_proc_handle_t isp_proc)
9393
{
9494
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
95-
ESP_RETURN_ON_FALSE(isp_proc->blc_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "blc isn't enabled yet");
95+
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
96+
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&isp_proc->blc_fsm, &expected_fsm, ISP_FSM_INIT), ESP_ERR_INVALID_STATE, TAG, "blc isn't enabled yet");
9697

9798
// Disable BLC module
9899
isp_ll_blc_enable(isp_proc->hal.hw, false);
99-
isp_proc->blc_fsm = ISP_FSM_INIT;
100100

101101
ESP_LOGD(TAG, "BLC disabled");
102102
return ESP_OK;

components/esp_driver_isp/src/isp_ccm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config
3434
esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc)
3535
{
3636
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
37+
isp_fsm_t expected_fsm = ISP_FSM_INIT;
38+
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&proc->ccm_fsm, &expected_fsm, ISP_FSM_ENABLE), ESP_ERR_INVALID_STATE, TAG, "ccm is enabled already");
3739

3840
portENTER_CRITICAL(&proc->spinlock);
3941
isp_ll_ccm_enable(proc->hal.hw, true);
@@ -45,6 +47,8 @@ esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc)
4547
esp_err_t esp_isp_ccm_disable(isp_proc_handle_t proc)
4648
{
4749
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
50+
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
51+
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&proc->ccm_fsm, &expected_fsm, ISP_FSM_INIT), ESP_ERR_INVALID_STATE, TAG, "ccm isn't enabled yet");
4852

4953
portENTER_CRITICAL(&proc->spinlock);
5054
isp_ll_ccm_enable(proc->hal.hw, false);

0 commit comments

Comments
 (0)