Skip to content

Commit c8029ac

Browse files
committed
feat(isp): support AWB driver setting wbgain and subwindow feature
1 parent 82d8f9f commit c8029ac

File tree

8 files changed

+224
-20
lines changed

8 files changed

+224
-20
lines changed

components/esp_driver_isp/include/driver/isp_awb.h

Lines changed: 13 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
*/
@@ -164,6 +164,18 @@ esp_err_t esp_isp_awb_controller_start_continuous_statistics(isp_awb_ctlr_t awb_
164164
*/
165165
esp_err_t esp_isp_awb_controller_stop_continuous_statistics(isp_awb_ctlr_t awb_ctlr);
166166

167+
/**
168+
* @brief Set AWB white balance gain
169+
*
170+
* @param[in] awb_ctlr AWB controller handle
171+
* @param[in] gain AWB white balance gain
172+
* @return
173+
* - ESP_OK On success
174+
* - ESP_ERR_INVALID_ARG Null pointer
175+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
176+
*/
177+
esp_err_t esp_isp_awb_controller_set_wb_gain(isp_awb_ctlr_t awb_ctlr, isp_awb_gain_t gain);
178+
167179
/**
168180
* @brief Event data of callbacks
169181
*/

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
/**

components/esp_driver_isp/src/isp_awb.c

Lines changed: 39 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
*/
@@ -111,6 +111,10 @@ esp_err_t esp_isp_new_awb_controller(isp_proc_handle_t isp_proc, const esp_isp_a
111111
isp_ll_awb_enable(isp_proc->hal.hw, false);
112112
isp_ll_awb_set_clk_ctrl_mode(isp_proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO);
113113
isp_ll_awb_enable_algorithm_mode(isp_proc->hal.hw, true);
114+
#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3
115+
isp_ll_awb_set_wb_gain_clk_ctrl_mode(isp_proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO);
116+
isp_ll_awb_enable_wb_gain(isp_proc->hal.hw, true);
117+
#endif
114118
ESP_GOTO_ON_ERROR(s_esp_isp_awb_config_hardware(isp_proc, awb_cfg), err2, TAG, "configure awb hardware failed");
115119

116120
*ret_hdl = awb_ctlr;
@@ -135,6 +139,9 @@ esp_err_t esp_isp_del_awb_controller(isp_awb_ctlr_t awb_ctlr)
135139
s_isp_declaim_awb_controller(awb_ctlr);
136140

137141
isp_ll_awb_enable_algorithm_mode(awb_ctlr->isp_proc->hal.hw, false);
142+
#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3
143+
isp_ll_awb_enable_wb_gain(awb_ctlr->isp_proc->hal.hw, false);
144+
#endif
138145
s_isp_awb_free_controller(awb_ctlr);
139146

140147
return ESP_OK;
@@ -221,6 +228,17 @@ esp_err_t esp_isp_awb_controller_stop_continuous_statistics(isp_awb_ctlr_t awb_c
221228
return ESP_OK;
222229
}
223230

231+
#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3
232+
esp_err_t esp_isp_awb_controller_set_wb_gain(isp_awb_ctlr_t awb_ctlr, isp_awb_gain_t gain)
233+
{
234+
ESP_RETURN_ON_FALSE(awb_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
235+
ESP_RETURN_ON_FALSE(atomic_load(&awb_ctlr->fsm) != ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller not in init state");
236+
isp_ll_awb_set_wb_gain(awb_ctlr->isp_proc->hal.hw, gain);
237+
238+
return ESP_OK;
239+
}
240+
#endif //#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3
241+
224242
/*---------------------------------------------------------------
225243
INTR
226244
---------------------------------------------------------------*/
@@ -239,6 +257,26 @@ bool IRAM_ATTR esp_isp_awb_isr(isp_proc_handle_t proc, uint32_t awb_events)
239257
.sum_b = isp_ll_awb_get_accumulated_b_value(proc->hal.hw),
240258
},
241259
};
260+
261+
// Get subwindow statistics
262+
for (int x = 0; x < ISP_AWB_WINDOW_X_NUM; x++) {
263+
for (int y = 0; y < ISP_AWB_WINDOW_Y_NUM; y++) {
264+
int subwindow_id = x * ISP_AWB_WINDOW_Y_NUM + y;
265+
266+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_WHITE_PATCH_CNT, subwindow_id, ISP_LL_LUT_AWB);
267+
edata.awb_result.subwin_result.white_patch_num[x][y] = isp_ll_lut_awb_get_subwindow_white_patch_cnt(proc->hal.hw);
268+
269+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_ACCUMULATED_R, subwindow_id, ISP_LL_LUT_AWB);
270+
edata.awb_result.subwin_result.sum_r[x][y] = isp_ll_lut_awb_get_subwindow_accumulated_r(proc->hal.hw);
271+
272+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_ACCUMULATED_G, subwindow_id, ISP_LL_LUT_AWB);
273+
edata.awb_result.subwin_result.sum_g[x][y] = isp_ll_lut_awb_get_subwindow_accumulated_g(proc->hal.hw);
274+
275+
isp_ll_lut_awb_set_cmd(proc->hal.hw, ISP_LL_LUT_AWB_ACCUMULATED_B, subwindow_id, ISP_LL_LUT_AWB);
276+
edata.awb_result.subwin_result.sum_b[x][y] = isp_ll_lut_awb_get_subwindow_accumulated_b(proc->hal.hw);
277+
}
278+
}
279+
242280
// Invoke the callback if the callback is registered
243281
if (awb_ctlr->cbs.on_statistics_done) {
244282
need_yield |= awb_ctlr->cbs.on_statistics_done(awb_ctlr, &edata, awb_ctlr->user_data);

components/esp_driver_isp/src/isp_lsc.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
*/
@@ -76,10 +76,10 @@ esp_err_t esp_isp_lsc_configure(isp_proc_handle_t isp_proc, const esp_isp_lsc_co
7676
for (int y = 0; y < num_grids_y; y++) {
7777
for (int x = 0; x < num_grids_x; x++) {
7878
int i = y * num_grids_x + x;
79-
isp_ll_lut_set_wdata_r_gr(isp_proc->hal.hw, config->gain_array->gain_r[i], config->gain_array->gain_gr[i]);
80-
isp_ll_lut_set_cmd(isp_proc->hal.hw, true, false, i, ISP_LL_LUT_LSC);
81-
isp_ll_lut_set_wdata_gb_b(isp_proc->hal.hw, config->gain_array->gain_gb[i], config->gain_array->gain_b[i]);
82-
isp_ll_lut_set_cmd(isp_proc->hal.hw, true, true, i, ISP_LL_LUT_LSC);
79+
isp_ll_lut_lsc_set_wdata_r_gr(isp_proc->hal.hw, config->gain_array->gain_r[i], config->gain_array->gain_gr[i]);
80+
isp_ll_lut_lsc_set_cmd(isp_proc->hal.hw, true, false, i, ISP_LL_LUT_LSC);
81+
isp_ll_lut_lsc_set_wdata_gb_b(isp_proc->hal.hw, config->gain_array->gain_gb[i], config->gain_array->gain_b[i]);
82+
isp_ll_lut_lsc_set_cmd(isp_proc->hal.hw, true, true, i, ISP_LL_LUT_LSC);
8383
}
8484
}
8585

components/hal/esp32p4/include/hal/isp_ll.h

Lines changed: 121 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "hal/config.h"
1616
#include "hal/isp_types.h"
1717
#include "hal/color_types.h"
18+
#include "hal/config.h"
1819
#include "soc/isp_struct.h"
1920
#include "soc/hp_sys_clkrst_struct.h"
2021
#include "soc/clk_tree_defs.h"
@@ -67,11 +68,14 @@ extern "C" {
6768
#define ISP_LL_EVENT_YUV2RGB_FRAME (1<<26)
6869
#define ISP_LL_EVENT_TAIL_IDI_FRAME (1<<27)
6970
#define ISP_LL_EVENT_HEADER_IDI_FRAME (1<<28)
71+
#define ISP_LL_EVENT_CROP_FRAME (1<<29)
72+
#define ISP_LL_EVENT_WBG_FRAME (1<<30)
73+
#define ISP_LL_EVENT_CROP_ERR (1<<31)
7074

7175
#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF)
7276
#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV)
7377
#define ISP_LL_EVENT_AE_MASK (ISP_LL_EVENT_AE_FDONE | ISP_LL_EVENT_AE_ENV)
74-
#define ISP_LL_EVENT_AWB_MASK (ISP_LL_EVENT_AWB_FDONE)
78+
#define ISP_LL_EVENT_AWB_MASK (ISP_LL_EVENT_AWB_FDONE | ISP_LL_EVENT_WBG_FRAME)
7579
#define ISP_LL_EVENT_SHARP_MASK (ISP_LL_EVENT_SHARP_FRAME)
7680
#define ISP_LL_EVENT_HIST_MASK (ISP_LL_EVENT_HIST_FDONE)
7781
#define ISP_LL_EVENT_COLOR_MASK (ISP_LL_EVENT_COLOR_FRAME)
@@ -172,8 +176,19 @@ typedef union {
172176
typedef enum {
173177
ISP_LL_LUT_LSC, ///< LUT for LSC
174178
ISP_LL_LUT_DPC, ///< LUT for DPC
179+
ISP_LL_LUT_AWB, ///< LUT for AWB
175180
} isp_ll_lut_t;
176181

182+
/**
183+
* @brief ISP LUT AWB type
184+
*/
185+
typedef enum {
186+
ISP_LL_LUT_AWB_WHITE_PATCH_CNT, ///< White patch count
187+
ISP_LL_LUT_AWB_ACCUMULATED_R, ///< Accumulated R
188+
ISP_LL_LUT_AWB_ACCUMULATED_G, ///< Accumulated G
189+
ISP_LL_LUT_AWB_ACCUMULATED_B, ///< Accumulated B
190+
} isp_ll_lut_awb_t;
191+
177192
/**
178193
* @brief ISP pipeline clock control mode
179194
*/
@@ -1366,15 +1381,15 @@ static inline void isp_ll_lsc_set_xtablesize(isp_dev_t *hw, uint8_t xtablesize)
13661381
LUT
13671382
---------------------------------------------------------------*/
13681383
/**
1369-
* @brief Select ISP LUT
1384+
* @brief Select ISP LUT for LSC usage
13701385
*
13711386
* @param[in] hw Hardware instance address
13721387
* @param[in] is_write Is write or not
13731388
* @param[in] is_gb_b Is gb_b or not
13741389
* @param[in] addr LUT addr
13751390
* @param[in] lut ISP LUT
13761391
*/
1377-
static inline void isp_ll_lut_set_cmd(isp_dev_t *hw, bool is_write, bool is_gb_b, uint32_t addr, isp_ll_lut_t lut)
1392+
static inline void isp_ll_lut_lsc_set_cmd(isp_dev_t *hw, bool is_write, bool is_gb_b, uint32_t addr, isp_ll_lut_t lut)
13781393
{
13791394
uint32_t val = 0;
13801395
val |= is_write ? (1 << 16) : 0;
@@ -1391,7 +1406,7 @@ static inline void isp_ll_lut_set_cmd(isp_dev_t *hw, bool is_write, bool is_gb_b
13911406
* @param[in] gb_gain gb gain
13921407
* @param[in] b_gain b gain
13931408
*/
1394-
static inline void isp_ll_lut_set_wdata_gb_b(isp_dev_t *hw, isp_lsc_gain_t gb_gain, isp_lsc_gain_t b_gain)
1409+
static inline void isp_ll_lut_lsc_set_wdata_gb_b(isp_dev_t *hw, isp_lsc_gain_t gb_gain, isp_lsc_gain_t b_gain)
13951410
{
13961411
hw->lut_wdata.lut_wdata = (gb_gain.val & 0x3ff) << 10 | (b_gain.val & 0x3ff);
13971412
}
@@ -1403,11 +1418,75 @@ static inline void isp_ll_lut_set_wdata_gb_b(isp_dev_t *hw, isp_lsc_gain_t gb_ga
14031418
* @param[in] r_gain r gain
14041419
* @param[in] gr_gain gr gain
14051420
*/
1406-
static inline void isp_ll_lut_set_wdata_r_gr(isp_dev_t *hw, isp_lsc_gain_t r_gain, isp_lsc_gain_t gr_gain)
1421+
static inline void isp_ll_lut_lsc_set_wdata_r_gr(isp_dev_t *hw, isp_lsc_gain_t r_gain, isp_lsc_gain_t gr_gain)
14071422
{
14081423
hw->lut_wdata.lut_wdata = (r_gain.val & 0x3ff) << 10 | (gr_gain.val & 0x3ff);
14091424
}
14101425

1426+
/**
1427+
* @brief Set AWB LUT command
1428+
*
1429+
* @param[in] hw Hardware instance address
1430+
* @param[in] type ISP LUT AWB type
1431+
* @param[in] addr AWB sub window ID
1432+
*/
1433+
static inline void isp_ll_lut_awb_set_cmd(isp_dev_t *hw, isp_ll_lut_awb_t type, uint32_t sub_window_id, isp_ll_lut_t lut)
1434+
{
1435+
HAL_ASSERT(sub_window_id <= 25);
1436+
uint32_t val = 0;
1437+
val |= 0x2000 + 4 * sub_window_id + type;
1438+
val |= lut << 12;
1439+
hw->lut_cmd.val = val;
1440+
}
1441+
1442+
/**
1443+
* @brief Get AWB statistics of subwindow white patch count
1444+
*
1445+
* @param[in] hw Hardware instance address
1446+
*
1447+
* @return White patch number
1448+
*/
1449+
static inline uint32_t isp_ll_lut_awb_get_subwindow_white_patch_cnt(isp_dev_t *hw)
1450+
{
1451+
return hw->lut_rdata.lut_rdata;
1452+
}
1453+
1454+
/**
1455+
* @brief Get AWB statistics of subwindow accumulated R
1456+
*
1457+
* @param[in] hw Hardware instance address
1458+
*
1459+
* @return Accumulated R
1460+
*/
1461+
static inline uint32_t isp_ll_lut_awb_get_subwindow_accumulated_r(isp_dev_t *hw)
1462+
{
1463+
return hw->lut_rdata.lut_rdata;
1464+
}
1465+
1466+
/**
1467+
* @brief Get AWB statistics of subwindow accumulated G
1468+
*
1469+
* @param[in] hw Hardware instance address
1470+
*
1471+
* @return Accumulated G
1472+
*/
1473+
static inline uint32_t isp_ll_lut_awb_get_subwindow_accumulated_g(isp_dev_t *hw)
1474+
{
1475+
return hw->lut_rdata.lut_rdata;
1476+
}
1477+
1478+
/**
1479+
* @brief Get AWB statistics of subwindow accumulated B
1480+
*
1481+
* @param[in] hw Hardware instance address
1482+
*
1483+
* @return Accumulated B
1484+
*/
1485+
static inline uint32_t isp_ll_lut_awb_get_subwindow_accumulated_b(isp_dev_t *hw)
1486+
{
1487+
return hw->lut_rdata.lut_rdata;
1488+
}
1489+
14111490
/*---------------------------------------------------------------
14121491
INTR
14131492
---------------------------------------------------------------*/
@@ -1636,6 +1715,43 @@ static inline uint32_t isp_ll_awb_get_accumulated_b_value(isp_dev_t *hw)
16361715
return hw->awb0_acc_b.awb0_acc_b;
16371716
}
16381717

1718+
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
1719+
/**
1720+
* @brief Enable AWB white balance gain
1721+
*
1722+
* @param[in] hw Hardware instance address
1723+
* @param[in] enable Enable / Disable
1724+
*/
1725+
static inline void isp_ll_awb_enable_wb_gain(isp_dev_t *hw, bool enable)
1726+
{
1727+
hw->cntl.wbg_en = enable;
1728+
}
1729+
1730+
/**
1731+
* @brief Set AWB white balance gain clock control mode
1732+
*
1733+
* @param[in] hw Hardware instance address
1734+
* @param[in] mode 'isp_ll_pipeline_clk_ctrl_t`
1735+
*/
1736+
static inline void isp_ll_awb_set_wb_gain_clk_ctrl_mode(isp_dev_t *hw, isp_ll_pipeline_clk_ctrl_t mode)
1737+
{
1738+
hw->clk_en.clk_wbg_force_on = mode;
1739+
}
1740+
1741+
/**
1742+
* @brief Set AWB white balance gain
1743+
*
1744+
* @param[in] hw Hardware instance address
1745+
* @param[in] gain AWB white balance gain
1746+
*/
1747+
static inline void isp_ll_awb_set_wb_gain(isp_dev_t *hw, isp_awb_gain_t gain)
1748+
{
1749+
hw->wbg_coef_r.wbg_r = gain.gain_r;
1750+
hw->wbg_coef_g.wbg_g = gain.gain_g;
1751+
hw->wbg_coef_b.wbg_b = gain.gain_b;
1752+
}
1753+
#endif //#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
1754+
16391755
/*---------------------------------------------------------------
16401756
Demosaic
16411757
---------------------------------------------------------------*/

components/hal/include/hal/isp_types.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -125,6 +125,14 @@ typedef enum {
125125
AWB
126126
---------------------------------------------------------------*/
127127

128+
#if SOC_ISP_AWB_WINDOW_X_NUMS
129+
#define ISP_AWB_WINDOW_X_NUM SOC_ISP_AWB_WINDOW_X_NUMS // The AWB window number for sampling
130+
#define ISP_AWB_WINDOW_Y_NUM SOC_ISP_AWB_WINDOW_Y_NUMS // The AWB window number for sampling
131+
#else
132+
#define ISP_AWB_WINDOW_X_NUM 0
133+
#define ISP_AWB_WINDOW_Y_NUM 0
134+
#endif
135+
128136
/**
129137
* @brief ISP AWB sample point in the ISP pipeline
130138
*/
@@ -133,12 +141,21 @@ typedef enum {
133141
ISP_AWB_SAMPLE_POINT_AFTER_CCM, ///< Sample AWB data after CCM (Color Correction Matrix)
134142
} isp_awb_sample_point_t;
135143

144+
/**
145+
* @brief ISP AWB gain
146+
*/
147+
typedef struct {
148+
uint32_t gain_r; ///< White balance gain for R channel
149+
uint32_t gain_g; ///< White balance gain for G channel
150+
uint32_t gain_b; ///< White balance gain for B channel
151+
} isp_awb_gain_t;
152+
136153
/*---------------------------------------------------------------
137154
BF
138155
---------------------------------------------------------------*/
139156
#if SOC_ISP_BF_SUPPORTED
140-
#define ISP_BF_TEMPLATE_X_NUMS SOC_ISP_BF_TEMPLATE_X_NUMS // BF template x field nums
141-
#define ISP_BF_TEMPLATE_Y_NUMS SOC_ISP_BF_TEMPLATE_Y_NUMS // BF template y field nums
157+
#define ISP_BF_TEMPLATE_X_NUMS SOC_ISP_BF_TEMPLATE_X_NUMS ///< BF template x field nums
158+
#define ISP_BF_TEMPLATE_Y_NUMS SOC_ISP_BF_TEMPLATE_Y_NUMS ///< BF template y field nums
142159
#else
143160
#define ISP_BF_TEMPLATE_X_NUMS 0
144161
#define ISP_BF_TEMPLATE_Y_NUMS 0

0 commit comments

Comments
 (0)