luckfox-pico-sdk/sysdrv/source/mcu/rt-thread/applications/battery-ipc/fast_ae.c
luckfox-eng29 8f34c2760d project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between
the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door
for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more
usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp:
Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for
compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem.
sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device
tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately.
sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick
boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades.
sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for
fastboot.

Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
2024-10-14 09:47:04 +08:00

1803 lines
68 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Copyright (c) 2022 Rockchip Electronic Co.,Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @version V0.0.1
*
* Change Logs:
* Date Author Notes
* 2022-07-07 ISP Team first implementation
*
******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <rtthread.h>
#include "fast_ae.h"
#include "rkaiq_parse_iq.h"
//#include "rkaiq_calib.h"
#include "rk_meta.h"
#include "board.h"
#include "board_cam.h"
#include "sensor_init_info.h"
#include "sensor_iq_info.h"
#include "sensor_2a_common.h"
#include "drivers/rt_drv_pwm.h"
#include "rk_meta_app_param.h"
#include "als/drv_als.h"
#define FASTAE_DEBUG 0
#define FASTAE_INFO(...) \
do { \
rk_kprintf("[FASTAE]: "); \
rk_kprintf(__VA_ARGS__); \
}while(0)
#if FASTAE_DEBUG
#define FASTAE_DBG(...) \
do { \
rk_kprintf("[FASTAE]: "); \
rk_kprintf(__VA_ARGS__); \
}while(0)
#else
#define FASTAE_DBG(...)
#endif
#define FASTAE_ERR(...) \
do { \
rk_kprintf("[FASTAE]: "); \
rk_kprintf(__VA_ARGS__); \
}while(0)
#define SET_EXP_ON_VS
#define EXP_VAL_LOG_NUM 8
#define EXP_INVALID_VAL 0x7FFFFFFF
struct expval_log
{
uint32_t set_to_sensor;
uint32_t frame_id;
FIXED exposure;
struct rk_camera_exp_val exp;
};
struct iq_config
{
rt_thread_t stat_tid;
rt_thread_t exp_tid;
uint32_t stat_exit;
uint32_t exp_exit;
rt_sem_t stat_exitsem;
rt_sem_t exp_exitsem;
rt_device_t isp;
rt_device_t sensor;
rt_sem_t exp_sem;
rt_mutex_t exp_mutex;
struct expval_log expval;
struct expval_log explog[EXP_VAL_LOG_NUM];
uint32_t explog_wid;
uint32_t frame_id;
uint32_t skip_stat_num;
uint32_t skip_stat_idx;
uint32_t exp_dly;
uint32_t is_match;
uint32_t is_over_range;
uint32_t conv_num;
};
static struct shared_data *gShare;
static struct shared_data *gShare_next_camera;
static struct iq_config *gConfig = RT_NULL;
static struct expval_log gInitExp;
static CamCalibDbV2Context_t g_main_calib = {0};
static CamCalibDbV2Context_t g_secondary_calib = {0};
static struct fastae_init_info g_fastae_init = {0};
static struct sensor_init_cfg g_sensor_init = {0};
static struct sensor_init_cfg g_secondary_sensor_init = {0};
static struct app_param_info g_app_param = {0};
static CamCalibDbProj_t *g_main_camproj = RT_NULL;
static CamCalibDbProj_t *g_secondary_camproj = RT_NULL;
static int32_t *g_is_bw_night = RT_NULL;
static int g_is_ie_effect;
static int g_fastae_max_run_frame = 20;
static bool g_ae_md = false;
static int g_day_or_night = DayORNight_STATUS_INVALID;
static rk_aiq_iq_bin_mode_t g_iq_bin_mode;
#ifdef RT_USING_RK_AOV
static bool g_use_conv_exp = false;
#endif
extern struct config_param g_param;
int32_t set_night_mode
(
struct fastae_init_info *fastae_init,
struct sensor_init_cfg *sensor_init
);
int32_t ircut_switch(struct sensor_init_cfg *sensor_init, IR_STATUS_t on_or_off)
{
if (on_or_off == IR_STATUS_CUT_OFF)
{
cam_cfg_gpio_func(sensor_init->ircut_a.gpio_index, sensor_init->ircut_a.gpio_func);
cam_cfg_gpio_func(sensor_init->ircut_b.gpio_index, sensor_init->ircut_b.gpio_func);
}
else if (on_or_off == IR_STATUS_CUT_ON)
{
cam_cfg_gpio_func(sensor_init->ircut_a.gpio_index, sensor_init->ircut_b.gpio_func);//exchange a&b
cam_cfg_gpio_func(sensor_init->ircut_b.gpio_index, sensor_init->ircut_a.gpio_func);
}
return 0;
}
int32_t soft_lux_night_mode(struct iq_config *config, struct fastae_info *ae_inf)
{
if (g_fastae_init.night_mode == NIGHT_IR_ON || g_fastae_init.night_mode == NIGHT_WHITE_ON)
{
return 0;
}
if (ae_inf->day_or_night == DayORNight_STATUS_NIGHT)
{
g_day_or_night = DayORNight_STATUS_NIGHT;
ae_inf->day_or_night = DayORNight_STATUS_INVALID;
if (g_fastae_init.night_mode == NIGHT_IR_AUTO)
{
g_is_ie_effect = 1;
*g_is_bw_night = BW_MODE;
ircut_switch(&g_sensor_init, IR_STATUS_CUT_ON);
}
else
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(&g_sensor_init, IR_STATUS_CUT_OFF);
}
set_night_mode(&g_fastae_init, &g_sensor_init);
}
else
{
g_day_or_night = DayORNight_STATUS_DAY;
ae_inf->day_or_night = DayORNight_STATUS_INVALID;
*g_is_bw_night = COLOR_MODE;
ircut_switch(&g_sensor_init, IR_STATUS_CUT_OFF);
}
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)g_is_bw_night, sizeof(*g_is_bw_night));
if (g_is_ie_effect)
{
//cancel the 1_st frame awb
struct rkisp_params_buffer isp_params = { 0 };
isp_params.params.awbgain.gb = 256;
isp_params.params.awbgain.gr = 256;
isp_params.params.awbgain.b = 256;
isp_params.params.awbgain.r = 256;
isp_params.module_cfg_update = ISP_MODULE_AWBGAIN;
set_params(config->isp, &isp_params);
//bw night mode, enable IE
gShare->cfg.module_ens |= ISP3X_MODULE_IE;
gShare->cfg.module_en_update |= ISP3X_MODULE_IE;
gShare->cfg.module_cfg_update |= ISP3X_MODULE_IE;
gShare->cfg.others.ie_cfg.effect = g_is_ie_effect;
}
return 0;
}
static rt_err_t sensor_vs_cb(rt_device_t dev, rt_size_t size)
{
if (gConfig)
{
gConfig->frame_id = (uint32_t)size;
#ifdef SET_EXP_ON_VS
rt_sem_release(gConfig->exp_sem);
#endif
FASTAE_DBG("frm_id %d\n", gConfig->frame_id);
}
return 0;
}
static void set_exposure(struct iq_config *config, bool set_to_sensor, FIXED new_exposure,
struct rk_camera_exp_val *reg_exp)
{
rt_mutex_take(config->exp_mutex, RT_WAITING_FOREVER);
config->expval.set_to_sensor = set_to_sensor;
config->expval.exposure = new_exposure;
rt_memcpy(&config->expval.exp, reg_exp, sizeof(*reg_exp));
rt_mutex_release(config->exp_mutex);
if (set_to_sensor == false)
{
rt_sem_release(config->exp_sem);
}
else
{
#ifndef SET_EXP_ON_VS
rt_sem_release(config->exp_sem);
#endif
}
}
static void map_secondary_ae()
{
// 1. CTRL IRCUT
if (*g_is_bw_night == BW_MODE)
ircut_switch(&g_secondary_sensor_init, IR_STATUS_CUT_ON);
else
ircut_switch(&g_secondary_sensor_init, IR_STATUS_CUT_OFF);
// 2. PARSE AE PARAMS
struct fastae_init_info *fastae_sec_init = rt_calloc(1, sizeof(struct fastae_init_info));
if (!fastae_sec_init)
{
FASTAE_ERR("%s alloc failed!\n", __func__);
return ;
}
fastae_sec_init->is_hdr = (g_app_param.cam2_hdr > NO_HDR) ? true : false;
if (*g_is_bw_night == BW_MODE) {
int ret = 0;
ret = rkaiq_get_night_calib(g_secondary_camproj, &g_secondary_calib, g_app_param.cam_hdr);
if (ret)
FASTAE_INFO(">>> no need to load night calib scene\n");
else
FASTAE_INFO(">>> reload night calib scene\n");
}
parse_ae_params(&g_secondary_calib, fastae_sec_init, g_iq_bin_mode);
// 3. INIT SENSOR CONFIG
rt_device_t sensor_secondary;
struct rk_camera_exp_info exp_info = {0};
sensor_secondary = rt_device_find(RK_ISP_ASSIST_SUBDEV_NAME);
if (sensor_secondary == RT_NULL)
{
FASTAE_ERR("can't find %s device!\n", RK_ISP_ASSIST_SUBDEV_NAME);
return ;
}
rt_device_control(sensor_secondary, RK_DEVICE_CTRL_CAMERA_GET_EXP_INF, &exp_info);
/*
fastae_sec_init->fps = exp_info.pix_clk / (exp_info.hts * exp_info.vts);
fastae_sec_init->hts = exp_info.hts;
fastae_sec_init->vts = exp_info.vts;
*/
fastae_sec_init->fps_aiq = exp_info.dst_pix_clk / (exp_info.dst_hts * exp_info.dst_vts);
fastae_sec_init->hts_aiq = exp_info.dst_hts;
fastae_sec_init->vts_aiq = exp_info.dst_vts;
//g_param.secondary_sensor.dst_vts = exp_info.dst_vts;
FASTAE_INFO(">>> fps/hts/vts: SecAIQ=[%d, %d, %d]\n", fastae_sec_init->fps_aiq, fastae_sec_init->hts_aiq, fastae_sec_init->vts_aiq);
// 4. CONFIG AE PARAMS
FastAeSecInit(fastae_sec_init);
rt_free(fastae_sec_init);
// 5. CALC MAP EXPOSURE
struct fastae_info ae_sec_inf = {0};
ae_sec_inf.exp_aiq.time[0] = gShare->exp_time[0];
ae_sec_inf.exp_aiq.gain[0] = gShare->exp_gain[0];
ae_sec_inf.exp_aiq.isp_gain[0] = gShare->exp_isp_dgain[0];
ae_sec_inf.exp_aiq.time[1] = gShare->exp_time[1];
ae_sec_inf.exp_aiq.gain[1] = gShare->exp_gain[1];
ae_sec_inf.exp_aiq.isp_gain[1] = gShare->exp_isp_dgain[1];
FastAeMainMapSec(&ae_sec_inf);
g_param.secondary_sensor.dst_vts = ae_sec_inf.dst_vts;
if (gShare_next_camera->hdr_mode == NO_HDR)
{
FASTAE_INFO("SecAiqExp: T=%d.%04d,G=%d.%04d,ispG=%d.%04d,regT=%d,regG=%d,dcg=%d\n",
FIX2INT(ae_sec_inf.exp_aiq.time[0]), FIX2FRA(ae_sec_inf.exp_aiq.time[0]),
FIX2INT(ae_sec_inf.exp_aiq.gain[0]), FIX2FRA(ae_sec_inf.exp_aiq.gain[0]),
FIX2INT(ae_sec_inf.exp_aiq.isp_gain[0]), FIX2FRA(ae_sec_inf.exp_aiq.isp_gain[0]),
ae_sec_inf.reg_exp_aiq.reg_time[0], ae_sec_inf.reg_exp_aiq.reg_gain[0],
ae_sec_inf.reg_exp_aiq.dcg_mode[0]);
}
else
{
FASTAE_INFO("SecAiqExp: sFrame: T=%d.%04d,G=%d.%04d,ispG=%d.%04d,regT=%d,regG=%d,dcg=%d\n",
FIX2INT(ae_sec_inf.exp_aiq.time[0]), FIX2FRA(ae_sec_inf.exp_aiq.time[0]),
FIX2INT(ae_sec_inf.exp_aiq.gain[0]), FIX2FRA(ae_sec_inf.exp_aiq.gain[0]),
FIX2INT(ae_sec_inf.exp_aiq.isp_gain[0]), FIX2FRA(ae_sec_inf.exp_aiq.isp_gain[0]),
ae_sec_inf.reg_exp_aiq.reg_time[0], ae_sec_inf.reg_exp_aiq.reg_gain[0],
ae_sec_inf.reg_exp_aiq.dcg_mode[0]);
FASTAE_INFO("SecAiqExp: lFrame: T=%d.%04d,G=%d.%04d,ispG=%d.%04d,regT=%d,regG=%d,dcg=%d\n",
FIX2INT(ae_sec_inf.exp_aiq.time[1]), FIX2FRA(ae_sec_inf.exp_aiq.time[1]),
FIX2INT(ae_sec_inf.exp_aiq.gain[1]), FIX2FRA(ae_sec_inf.exp_aiq.gain[1]),
FIX2INT(ae_sec_inf.exp_aiq.isp_gain[1]), FIX2FRA(ae_sec_inf.exp_aiq.isp_gain[1]),
ae_sec_inf.reg_exp_aiq.reg_time[1], ae_sec_inf.reg_exp_aiq.reg_gain[1],
ae_sec_inf.reg_exp_aiq.dcg_mode[1]);
}
gShare_next_camera->exp_time[0] = ae_sec_inf.exp_aiq.time[0];
gShare_next_camera->exp_gain[0] = ae_sec_inf.exp_aiq.gain[0];
gShare_next_camera->exp_isp_dgain[0] = ae_sec_inf.exp_aiq.isp_gain[0];
gShare_next_camera->exp_time_reg[0] = ae_sec_inf.reg_exp_aiq.reg_time[0];
gShare_next_camera->exp_gain_reg[0] = ae_sec_inf.reg_exp_aiq.reg_gain[0];
gShare_next_camera->dcg_mode[0] = ae_sec_inf.reg_exp_aiq.dcg_mode[0];
gShare_next_camera->exp_time[1] = ae_sec_inf.exp_aiq.time[1];
gShare_next_camera->exp_gain[1] = ae_sec_inf.exp_aiq.gain[1];
gShare_next_camera->exp_isp_dgain[1] = ae_sec_inf.exp_aiq.isp_gain[1];
gShare_next_camera->exp_time_reg[1] = ae_sec_inf.reg_exp_aiq.reg_time[1];
gShare_next_camera->exp_gain_reg[1] = ae_sec_inf.reg_exp_aiq.reg_gain[1];
gShare_next_camera->dcg_mode[1] = ae_sec_inf.reg_exp_aiq.dcg_mode[1];
}
static void calculate_ae(struct iq_config *config, struct rkisp_stats_buffer *luma_buf, FIXED *last_exposure, FIXED *isp_dgain)
{
struct fastae_info ae_inf = {0};
if (config->is_match || config->is_over_range)
{
#ifdef RT_USING_RK_AOV
if (luma_buf->frame_id == 2)
config->conv_num = 2;
else
config->conv_num++;
#endif
return;
}
ae_inf.stats = luma_buf;
ae_inf.current_exposure = *last_exposure;
#ifdef RT_USING_RK_AOV
ae_inf.use_old_exp = g_use_conv_exp;
#endif
//record the initial state of ir!
if (*g_is_bw_night == BW_MODE && g_fastae_init.night_mode == NIGHT_IR_AUTO)
ae_inf.ir_state = IR_STATUS_CUT_ON;
else
ae_inf.ir_state = IR_STATUS_CUT_OFF;
FastAeRun(&ae_inf);
if (ae_inf.day_or_night)
// day_or_night only works on NIGHT_WHITE(IR)_AUTO for ALS_TYPE_NONE
soft_lux_night_mode(config, &ae_inf);
gShare->exp_time[0] = ae_inf.exp_aiq.time[0];
gShare->exp_gain[0] = ae_inf.exp_aiq.gain[0];
gShare->exp_isp_dgain[0] = ae_inf.exp_aiq.isp_gain[0];
gShare->exp_time_reg[0] = ae_inf.reg_exp_aiq.reg_time[0];
gShare->exp_gain_reg[0] = ae_inf.reg_exp_aiq.reg_gain[0];
gShare->dcg_mode[0] = ae_inf.reg_exp_aiq.dcg_mode[0];
isp_dgain[0] = ae_inf.exp.isp_gain[0];
gShare->exp_time[1] = ae_inf.exp_aiq.time[1];
gShare->exp_gain[1] = ae_inf.exp_aiq.gain[1];
gShare->exp_isp_dgain[1] = ae_inf.exp_aiq.isp_gain[1];
gShare->exp_time_reg[1] = ae_inf.reg_exp_aiq.reg_time[1];
gShare->exp_gain_reg[1] = ae_inf.reg_exp_aiq.reg_gain[1];
gShare->dcg_mode[1] = ae_inf.reg_exp_aiq.dcg_mode[1];
isp_dgain[1] = ae_inf.exp.isp_gain[1];
g_param.sensor.dst_vts = ae_inf.dst_vts;
if (ae_inf.is_match || ae_inf.is_over_range)
{
if (gShare->hdr_mode == NO_HDR)
{
FASTAE_INFO("MainAiqExp: T=%d.%04d,G=%d.%04d,ispG=%d.%04d,regT=%d,regG=%d,dcg=%d\n",
FIX2INT(ae_inf.exp_aiq.time[0]), FIX2FRA(ae_inf.exp_aiq.time[0]),
FIX2INT(ae_inf.exp_aiq.gain[0]), FIX2FRA(ae_inf.exp_aiq.gain[0]),
FIX2INT(ae_inf.exp_aiq.isp_gain[0]), FIX2FRA(ae_inf.exp_aiq.isp_gain[0]),
ae_inf.reg_exp_aiq.reg_time[0], ae_inf.reg_exp_aiq.reg_gain[0], ae_inf.reg_exp_aiq.dcg_mode[0]);
}
else
{
FASTAE_INFO("MainAiqExp: sFrame: T=%d.%04d,G=%d.%04d,ispG=%d.%04d,regT=%d,regG=%d,dcg=%d\n",
FIX2INT(ae_inf.exp_aiq.time[0]), FIX2FRA(ae_inf.exp_aiq.time[0]),
FIX2INT(ae_inf.exp_aiq.gain[0]), FIX2FRA(ae_inf.exp_aiq.gain[0]),
FIX2INT(ae_inf.exp_aiq.isp_gain[0]), FIX2FRA(ae_inf.exp_aiq.isp_gain[0]),
ae_inf.reg_exp_aiq.reg_time[0], ae_inf.reg_exp_aiq.reg_gain[0], ae_inf.reg_exp_aiq.dcg_mode[0]);
FASTAE_INFO("MainAiqExp: lFrame: T=%d.%04d,G=%d.%04d,ispG=%d.%04d,regT=%d,regG=%d,dcg=%d\n",
FIX2INT(ae_inf.exp_aiq.time[1]), FIX2FRA(ae_inf.exp_aiq.time[1]),
FIX2INT(ae_inf.exp_aiq.gain[1]), FIX2FRA(ae_inf.exp_aiq.gain[1]),
FIX2INT(ae_inf.exp_aiq.isp_gain[1]), FIX2FRA(ae_inf.exp_aiq.isp_gain[1]),
ae_inf.reg_exp_aiq.reg_time[1], ae_inf.reg_exp_aiq.reg_gain[1], ae_inf.reg_exp_aiq.dcg_mode[1]);
}
#ifdef RT_USING_RK_AOV
if (luma_buf->frame_id == 1)
{
config->conv_num = 2;
int iso = FIX2INT(FIX_MUL(ae_inf.exp.gain[0], ae_inf.exp.isp_gain[0])) * 50;
int meanluma = FIX2INT(ae_inf.mean_luma) << 4; // 8bit to 12bit
struct fastae_md_param md_param = {0};
md_param.width = gShare->width;
md_param.height = gShare->height;
md_param.last_hidif = g_fastae_init.last_hidif;
md_param.last_lodif = g_fastae_init.last_lodif;
if(g_iq_bin_mode == FULL_IQ_BIN_MODE || g_iq_bin_mode == INVALID_IQ_BIN_MODE) {
CamCalibDbV2Context_t* calib = &g_main_calib;
CalibDbV2_BayerTnrV23_t *bayertnr_calib =
(CalibDbV2_BayerTnrV23_t *)(CALIBDBV2_GET_MODULE_PTR((void *)(calib), bayertnr_v23));
get_tnr_sigma(&bayertnr_calib->CalibPara, 0, iso, meanluma, &md_param);
} else if(g_iq_bin_mode == SIM_IQ_BIN_MODE) {
get_tnr_sigma(&g_main_calib.baytnr_calib.CalibPara, 0, iso, meanluma, &md_param);
}
uint8_t ret = FastAeMd(g_fastae_init.conv_ae_stats, &luma_buf->stats, md_param);
g_ae_md = (ret == 1) ? true : false;
}
// motion detection, judge whether update 2a result
if (g_ae_md == true)
{
struct meta_head *metahead_p = (struct meta_head *)(RT_USING_META_DDR_ADRESS);
struct ae_awb_init_cfg *ae_awb = (struct ae_awb_init_cfg *)(metahead_p->load + AE_TABLE_OFFSET);
ae_awb->rtt_res.exp = ae_inf.new_exposure;
ae_awb->rtt_res.reg_time = ae_inf.reg_exp.reg_time[0];
ae_awb->rtt_res.reg_gain = ae_inf.reg_exp.reg_gain[0];
ae_awb->rtt_res.dcg_mode = ae_inf.reg_exp.dcg_mode[0];
for (int i = 0; i < AE_GRID_STATS - 1; i++)
{
ae_awb->rtt_res.ae_stats[i] = ((uint32_t)luma_buf->stats.rawae1.data[2 * i].channelg_xy & 0xffff) |
((uint32_t)luma_buf->stats.rawae1.data[2 * i + 1].channelg_xy << 16) ;
}
ae_awb->rtt_res.ae_stats[AE_GRID_STATS - 1] = luma_buf->stats.rawae1.data[ISP_RAWAEBIG_MEAN_NUM - 1].channelg_xy;
ae_awb->rtt_res.day_or_night = g_day_or_night;
//clear last result
ae_awb->rtt_res.last_hidif_0 = 0;
ae_awb->rtt_res.last_hidif_1 = 0;
ae_awb->rtt_res.last_lodif_0 = 0;
ae_awb->rtt_res.last_lodif_1 = 0;
}
else
{
struct meta_head *metahead_p = (struct meta_head *)(RT_USING_META_DDR_ADRESS);
struct ae_awb_init_cfg *ae_awb = (struct ae_awb_init_cfg *)(metahead_p->load + AE_TABLE_OFFSET);
ae_awb->rtt_res.last_hidif_0 = luma_buf->stats.baytnr.sum_hidif_0;
ae_awb->rtt_res.last_hidif_1 = luma_buf->stats.baytnr.sum_hidif_1;
ae_awb->rtt_res.last_lodif_0 = luma_buf->stats.baytnr.sum_lodif_0;
ae_awb->rtt_res.last_lodif_1 = luma_buf->stats.baytnr.sum_lodif_1;
}
set_exposure(config, true, ae_inf.new_exposure, &ae_inf.reg_exp);
#endif
config->is_match = ae_inf.is_match;
config->is_over_range = ae_inf.is_over_range;
FASTAE_DBG("ae is %s\n", config->is_match > 0 ? "match" : "over range");
return;
}
if (ae_inf.current_exposure != ae_inf.new_exposure)
set_exposure(config, true, ae_inf.new_exposure, &ae_inf.reg_exp);
}
static void calculate_awb(struct iq_config *config, struct rkisp_params_buffer *isp_params, struct rkisp_stats_buffer *stats_buf, FIXED isp_dgain)
{
// CALC FAST AWB
if (g_is_ie_effect != 1)
{
//struct rkisp_params_buffer isp_params = { 0 };
calc_wbgain(&isp_params->params.awbgain, &stats_buf->stats.rawawb);
isp_params->params.awbgain.r = MAX(1 << 8, ((FIXED)isp_params->params.awbgain.r * isp_dgain) >> 16);
isp_params->params.awbgain.gr = MAX(1 << 8, ((FIXED)isp_params->params.awbgain.gr * isp_dgain) >> 16);
isp_params->params.awbgain.gb = MAX(1 << 8, ((FIXED)isp_params->params.awbgain.gb * isp_dgain) >> 16);
isp_params->params.awbgain.b = MAX(1 << 8, ((FIXED)isp_params->params.awbgain.b * isp_dgain) >> 16);
//cancel the 1~5_st frame awb in soft_lux when last_state is gray
if (*g_is_bw_night == BW_MODE)
{
isp_params->params.awbgain.gb = (256 * isp_dgain) >> 16;
isp_params->params.awbgain.gr = (256 * isp_dgain) >> 16;
isp_params->params.awbgain.b = (256 * isp_dgain) >> 16;
isp_params->params.awbgain.r = (256 * isp_dgain) >> 16;
}
}
else
{
isp_params->params.awbgain.gb = (256 * isp_dgain) >> 16;
isp_params->params.awbgain.gr = (256 * isp_dgain) >> 16;
isp_params->params.awbgain.b = (256 * isp_dgain) >> 16;
isp_params->params.awbgain.r = (256 * isp_dgain) >> 16;
}
isp_params->module_cfg_update |= ISP_MODULE_AWBGAIN;
set_params(config->isp, isp_params);
#ifdef RT_USING_RK_AOV
if (g_ae_md)
{
struct meta_head *metahead_p = (struct meta_head *)(RT_USING_META_DDR_ADRESS);
struct ae_awb_init_cfg *ae_awb = (struct ae_awb_init_cfg *)(metahead_p->load + AE_TABLE_OFFSET);
ae_awb->rtt_res.awb_gain = (isp_params->params.awbgain.r & 0xffff) | (isp_params->params.awbgain.b << FIXEDPREC & 0xffff0000);
ae_awb->rtt_res.isp_dgain = isp_dgain;
}
#endif
FASTAE_DBG("calcwbgain: 0x%x 0x%x 0x%x 0x%x,ispdgain=0x%x\n",
isp_params->params.awbgain.r, isp_params->params.awbgain.gr,
isp_params->params.awbgain.gb, isp_params->params.awbgain.b, isp_dgain);
}
static void exp_thread(void *arg)
{
struct expval_log *expval;
struct iq_config *config = arg;
uint32_t explog_wid;
rt_device_set_rx_indicate(config->isp, sensor_vs_cb);
while (!config->exp_exit)
{
expval = NULL;
rt_sem_take(config->exp_sem, RT_WAITING_FOREVER);
if (config->exp_exit)
break;
rt_mutex_take(config->exp_mutex, RT_WAITING_FOREVER);
if (config->expval.exp.reg_time[0] && config->expval.exp.reg_gain[0])
{
explog_wid = (config->explog_wid + 1) % EXP_VAL_LOG_NUM;
config->explog_wid = explog_wid;
expval = &config->explog[explog_wid];
rt_memcpy(expval, &config->expval, sizeof(*expval));
rt_memset(&config->expval, 0, sizeof(*expval));
expval->frame_id = EXP_INVALID_VAL;
}
rt_mutex_release(config->exp_mutex);
if (expval)
{
if (expval->set_to_sensor)
rt_device_control(config->sensor,
RK_DEVICE_CTRL_CAMERA_SET_EXP_VAL,
&expval->exp);
expval->frame_id = config->frame_id;
FASTAE_DBG("%d: reg: %x, %x, %x, %x, %x, %x\n", expval->frame_id,
expval->exp.reg_time[0], expval->exp.reg_gain[0],
expval->exp.reg_time[1], expval->exp.reg_gain[1],
expval->exp.reg_time[2], expval->exp.reg_gain[2]);
}
}
FASTAE_DBG("exp thread exit\n");
rt_sem_release(config->exp_exitsem);
}
static void stat_thread(void *arg)
{
struct iq_config *config = arg;
struct rkisp_stats_buffer *stats_buf;
struct rk_camera_exp_info exp_info;
uint32_t rid, i, frm_id, fnd_flg, exp_dly;
bool first_exp;
FIXED last_exposure = 0, isp_dgain[3] = {FIX_ONE, FIX_ONE, FIX_ONE};
stats_buf = rt_calloc(1, sizeof(struct rkisp_stats_buffer));
if (!stats_buf)
{
FASTAE_ERR("%s alloc failed\n", __func__);
return ;
}
rt_memset(&exp_info, 0, sizeof(exp_info));
rt_device_control(config->sensor,
RK_DEVICE_CTRL_CAMERA_GET_EXP_INF,
&exp_info);
if (exp_info.time_valid_delay != exp_info.gain_valid_delay)
{
FASTAE_ERR("sensor: time_valid_delay is not equal to gain_valid_delay\n");
return;
}
exp_dly = exp_info.time_valid_delay;
config->exp_dly = exp_dly;
// config first exp
set_exposure(config, false, gInitExp.exposure, &gInitExp.exp);
struct rkisp_params_buffer isp_params = { 0 };
first_exp = true;
while (!config->stat_exit)
{
rt_device_control(config->isp,
RK_DEVICE_CTRL_ISP_GET_STATS,
stats_buf);
#ifdef RT_USING_RK_AOV
isp_params.module_cfg_update |= ISP32_MODULE_BAY3D;
isp_params.params.bay3d.is_first = false;
set_params(config->isp, &isp_params);
gShare->frame_num = stats_buf->frame_id;
FASTAE_DBG("stats tick:%u seq:%d type:0x%x, ae:0x%x 0x%x 0x%x awb:0x%x 0x%x 0x%x\n",
rt_tick_get(),
stats_buf->frame_id, stats_buf->meas_type,
stats_buf->stats.rawae1.data[0].channelg_xy,
stats_buf->stats.rawae1.data[0].channelb_xy,
stats_buf->stats.rawae1.data[0].channelr_xy,
stats_buf->stats.rawawb.rgain_nor,
stats_buf->stats.rawawb.bgain_nor,
stats_buf->stats.rawawb.wp_num_nor);
#else
FASTAE_DBG("stats tick:%u seq:%d type:0x%x, ae:0x%x 0x%x 0x%x awb:0x%x 0x%x 0x%x\n",
rt_tick_get(),
stats_buf->frame_id, stats_buf->meas_type,
stats_buf->stats.rawae1.data[0].channelg_xy,
stats_buf->stats.rawae1.data[0].channelb_xy,
stats_buf->stats.rawae1.data[0].channelr_xy,
stats_buf->stats.rawawb.rgain_nor,
stats_buf->stats.rawawb.bgain_nor,
stats_buf->stats.rawawb.wp_num_nor);
#endif
if (gShare->hdr_mode == NO_HDR)
{
if (first_exp)
isp_dgain[0] = MAX(g_fastae_init.start_isp_gain[0], isp_dgain[0]);
else
isp_dgain[0] = MAX(0x10000, isp_dgain[0]);
calculate_awb(config, &isp_params, stats_buf, isp_dgain[0]);
}
else
{
if (first_exp)
isp_dgain[1] = MAX(g_fastae_init.start_isp_gain[1], isp_dgain[1]);
else
isp_dgain[1] = MAX(0x10000, isp_dgain[1]);
calculate_awb(config, &isp_params, stats_buf, isp_dgain[1]);
}
if (config->stat_exit)
break;
if (first_exp)
{
first_exp = false;
config->skip_stat_num = 0;
config->skip_stat_idx = 0;
last_exposure = gInitExp.exposure;
calculate_ae(config, stats_buf, &last_exposure, isp_dgain);
#ifdef RT_USING_RK_AOV
//first frame, use the same
if (!((config->is_match || config->is_over_range) && g_use_conv_exp))
{
g_ae_md = true;
struct meta_head *metahead_p = (struct meta_head *)(RT_USING_META_DDR_ADRESS);
struct ae_awb_init_cfg *ae_awb = (struct ae_awb_init_cfg *)(metahead_p->load + AE_TABLE_OFFSET);
//clear last result
ae_awb->rtt_res.last_hidif_0 = 0;
ae_awb->rtt_res.last_hidif_1 = 0;
ae_awb->rtt_res.last_lodif_0 = 0;
ae_awb->rtt_res.last_lodif_1 = 0;
if (g_sensor_init.als_type == ALS_TYPE_NONE && g_use_conv_exp)
{
//return to the original state, IRCUT no need to change, led light should be turned off
if (g_app_param.night_mode == NIGHT_WHITE_AUTO || g_app_param.night_mode == NIGHT_WHITE_AUTO)
{
g_is_ie_effect = 0;
*g_is_bw_night = COLOR_MODE;
struct rt_device_pwm *pwm_dev;
if (g_app_param.night_mode == NIGHT_WHITE_AUTO)
{
const char *pPWMDevice = cam_get_pwm_name(g_sensor_init.led_white.pwm_channel);
pwm_dev = (struct rt_device_pwm *)rt_device_find(pPWMDevice);
if (pwm_dev == RT_NULL)
{
FASTAE_ERR("pwm run failed! can't find %s device!\n", pPWMDevice);
}
else
{
rt_pwm_disable(pwm_dev, CAM_PWM_GET_CHANNEL(g_sensor_init.led_white.pwm_channel));
}
}
else
{
const char *pPWMDevice = cam_get_pwm_name(g_sensor_init.led_ir.pwm_channel);
pwm_dev = (struct rt_device_pwm *)rt_device_find(pPWMDevice);
if (pwm_dev == RT_NULL)
{
FASTAE_ERR("pwm run failed! can't find %s device!\n", pPWMDevice);
}
else
{
rt_pwm_disable(pwm_dev, CAM_PWM_GET_CHANNEL(g_sensor_init.led_ir.pwm_channel));
}
}
}
}
}
#endif
continue;
}
if (config->skip_stat_idx < config->skip_stat_num)
{
config->skip_stat_idx++;
continue;
}
fnd_flg = 0;
frm_id = stats_buf->frame_id;
rid = (config->explog_wid) % EXP_VAL_LOG_NUM;
for (i = 0; i < EXP_VAL_LOG_NUM; i++)
{
if ((config->explog[rid].frame_id + exp_dly) == frm_id)
{
fnd_flg = 1;
break;
}
rid = (rid + 1) % EXP_VAL_LOG_NUM;
}
if (fnd_flg)
last_exposure = config->explog[rid].exposure;
calculate_ae(config, stats_buf, &last_exposure, isp_dgain);
}
FastAeRelease();
FASTAE_DBG("stat thread exit\n");
rt_sem_release(config->stat_exitsem);
rt_free(stats_buf);
}
int32_t start_ae(rk_device *isp, rk_device *sensor)
{
rt_thread_t tid = RT_NULL;
struct iq_config *config;
uint32_t i;
config = rt_calloc(1, sizeof(*config));
if (!config)
return 1;
config->isp = isp;
config->sensor = sensor;
for (i = 0; i < EXP_VAL_LOG_NUM; i++)
config->explog[i].frame_id = EXP_INVALID_VAL;
config->exp_sem = rt_sem_create("exp_sem", 0, RT_IPC_FLAG_FIFO);
config->exp_exitsem = rt_sem_create("exp_exitsem", 0, RT_IPC_FLAG_FIFO);
config->stat_exitsem = rt_sem_create("stat_exitsem", 0, RT_IPC_FLAG_FIFO);
config->exp_mutex = rt_mutex_create("exp_mutex", RT_IPC_FLAG_FIFO);
tid = rt_thread_create("exp_thread", exp_thread, config, 4096, RT_THREAD_PRIORITY_MAX / 2, 10);
if (tid)
rt_thread_startup(tid);
config->exp_tid = tid;
tid = rt_thread_create("stat_thread", stat_thread, config, 4096, RT_THREAD_PRIORITY_MAX / 2, 10);
if (tid)
rt_thread_startup(tid);
config->stat_tid = tid;
gConfig = config;
return 0;
}
int32_t stop_ae(struct rk_isp_dev *ispdev)
{
FASTAE_INFO("stop_ae on enter tick:%u\n", rt_tick_get());
struct iq_config *config = gConfig;
rt_base_t level;
if (!config)
return 0;
//ISP PARAMS FOR KERNEL
gShare->md_flag = g_ae_md;
gShare->width = g_sensor_init.cam_w;
gShare->height = g_sensor_init.cam_h;
set_isp_params_for_kernel(gShare, &g_main_calib, g_is_ie_effect, g_iq_bin_mode);
if (gShare->camera_num == 2)
{
map_secondary_ae();
set_isp_params_for_kernel(gShare_next_camera, &g_secondary_calib, g_is_ie_effect, g_iq_bin_mode);
}
config->stat_exit = 1;
rt_sem_release(ispdev->stats_sem);
rt_sem_take(config->stat_exitsem, RT_WAITING_FOREVER);
config->exp_exit = 1;
rt_sem_release(config->exp_sem);
rt_sem_take(config->exp_exitsem, RT_WAITING_FOREVER);
#ifdef RT_USING_RK_AOV
if(g_iq_bin_mode == FULL_IQ_BIN_MODE) {
struct meta_head *metahead_p = (struct meta_head *)(RT_USING_META_DDR_ADRESS);
struct sensor_iq_info *iq = (struct sensor_iq_info *)(metahead_p->load + SENSOR_IQ_BIN_OFFSET);
rk_aiq_rtt_share_info_t *aovhead_p = (rk_aiq_rtt_share_info_t *)(metahead_p->load + WAKEUP_AOV_PARAM_OFFSET);
restoreBinStructMap((uint8_t *)iq->main_sensor_iq_offset, iq->main_sensor_iq_size, aovhead_p->aiq_iq_addr);
if (gShare->camera_num == 2)
restoreBinStructMap((uint8_t *)iq->secondary_sensor_iq_offset, iq->secondary_sensor_iq_size, (aovhead_p + WAKEUP_AOV_PARAM_MAX_SIZE / 2)->aiq_iq_addr);
}
#endif
level = rt_hw_interrupt_disable();
if (config)
{
rt_free(config);
gConfig = NULL;
}
rt_hw_interrupt_enable(level);
return 0;
}
int32_t isae_match()
{
struct iq_config *config = gConfig;
if (config)
{
#ifdef RT_USING_RK_AOV
uint32_t stop_ae = ((config->is_match == 1) ? true : false) && ((config->conv_num == 2) ? true : false);
return stop_ae;
#else
return config->is_match;
#endif
}
else
{
return 0;
}
}
int32_t isae_over_range()
{
struct iq_config *config = gConfig;
if (config)
{
#ifdef RT_USING_RK_AOV
uint32_t stop_ae = ((config->is_over_range == 1) ? true : false) && ((config->conv_num == 2) ? true : false);
return stop_ae;
#else
return config->is_over_range;
#endif
}
else
{
return 0;
}
}
int32_t get_expinfo(uint32_t frm_id, struct rk_camera_exp_val *exp)
{
struct iq_config *config = gConfig;
uint32_t rid, i, fnd_flg;
if (frm_id <= 1)
{
rt_memcpy(exp, &gInitExp.exp, sizeof(*exp));
return 1;
}
if (frm_id <= config->skip_stat_num + 1)
{
rt_memcpy(exp, &gInitExp.exp, sizeof(*exp));
return 1;
}
fnd_flg = 0;
rid = (config->explog_wid) % EXP_VAL_LOG_NUM;
for (i = 0; i < EXP_VAL_LOG_NUM; i++)
{
if ((config->explog[rid].frame_id + config->exp_dly) == frm_id)
{
fnd_flg = 1;
break;
}
rid = (rid + 1) % EXP_VAL_LOG_NUM;
}
if (fnd_flg)
rt_memcpy(exp, &config->explog[rid].exp, sizeof(*exp));
return fnd_flg;
}
uint32_t get_rtt_fps()
{
return g_fastae_init.fps;
}
void fast_ae_set_max_frame(int max_frame)
{
if (max_frame > 0)
{
g_fastae_max_run_frame = max_frame;
}
return ;
}
int fast_ae_get_max_frame(void)
{
return g_fastae_max_run_frame;
}
int32_t parse_meta_params
(
CamCalibDbV2Context_t *parse_main_iq_param,
CamCalibDbV2Context_t *parse_secondary_iq_param,
struct sensor_init_cfg *parse_sensor_init,
struct sensor_init_cfg *parse_secondary_sensor_init,
struct app_param_info *parse_app_param,
struct fastae_init_info *parse_ae_init
)
{
struct meta_head *metahead_p = (struct meta_head *)(RT_USING_META_DDR_ADRESS);
int ret = 0;
#ifndef RT_USING_RK_AOV // 休眠唤醒等不到这个flag直接跳过
int i = 200;
while (--i >= 0)
{
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, (void *)metahead_p, sizeof(struct meta_head));
if ((sirq_status() == RT_TRUE) && (metahead_p->meta_flags == META_READ_DONE_FLAG))
{
metahead_p->meta_flags = 0;
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)metahead_p, sizeof(struct meta_head));
break;
}
HAL_DelayMs(1);
}
RT_ASSERT(i >= 0);
#endif
// 1) app issue params
struct app_param_info *app_param = (struct app_param_info *)(metahead_p->load + APP_PARAM_OFFSET);
*parse_app_param = *app_param;
g_is_bw_night = &app_param->color_mode; //share to kernel & api & app
fast_ae_set_max_frame(app_param->fastae_max_frame);
// 2) AOV params shared with AIQ
rk_aiq_rtt_share_info_t *aovhead_p = (rk_aiq_rtt_share_info_t *)(metahead_p->load + WAKEUP_AOV_PARAM_OFFSET);
g_iq_bin_mode = (rk_aiq_iq_bin_mode_t)aovhead_p->iq_bin_mode;
// 3) iq bin params
if(g_iq_bin_mode == FULL_IQ_BIN_MODE || g_iq_bin_mode == INVALID_IQ_BIN_MODE) {
struct sensor_iq_info *iq = (struct sensor_iq_info *)(metahead_p->load + SENSOR_IQ_BIN_OFFSET);
g_main_camproj = rkaiq_calib_load((void *)(iq->main_sensor_iq_offset), iq->main_sensor_iq_size);
ret = rkaiq_get_default_calib(g_main_camproj, parse_main_iq_param, parse_app_param->cam_hdr);
if (!parse_main_iq_param->calib_scene || ret != 0)
{
FASTAE_ERR("\n------>load main iq bin file failed [%p][%p]\n", parse_main_iq_param->calib_scene,
&g_main_camproj->main_scene[0].sub_scene[0].scene_isp32);
}
else
{
//sync mirror/flip & fps value in IQ
g_main_camproj->sensor_calib.CISFlip = app_param->cam_mirror_flip;
CalibDb_Aec_ParaV2_t *aec_calib = (CalibDb_Aec_ParaV2_t *)(CALIBDBV2_GET_MODULE_PTR((void *)(parse_main_iq_param), ae_calib));
aec_calib->CommCtrl.AecFrameRateMode.FpsValue = app_param->cam_fps;
FASTAE_INFO("\n------>load main iq bin file finished!\n");
}
if (parse_app_param->cam_num == 2)
{
//secondary iq bin params
g_secondary_camproj = rkaiq_calib_load((void *)(iq->secondary_sensor_iq_offset), iq->secondary_sensor_iq_size);
ret = rkaiq_get_default_calib(g_secondary_camproj, parse_secondary_iq_param, parse_app_param->cam2_hdr);
if (!parse_secondary_iq_param->calib_scene || ret != 0)
{
FASTAE_ERR("\n------>load secondary iq bin file failed [%p][%p]\n", parse_secondary_iq_param->calib_scene,
&g_secondary_camproj->main_scene[0].sub_scene[0].scene_isp32);
}
else
{
//sync mirror/flip & fps value in IQ
g_secondary_camproj->sensor_calib.CISFlip = app_param->cam2_mirror_flip;
CalibDb_Aec_ParaV2_t *aec_calib = (CalibDb_Aec_ParaV2_t *)(CALIBDBV2_GET_MODULE_PTR((void *)(parse_secondary_iq_param), ae_calib));
aec_calib->CommCtrl.AecFrameRateMode.FpsValue = app_param->cam2_fps;
FASTAE_INFO("\n------>load secondary iq bin file finished!\n");
}
}
} else if(g_iq_bin_mode == SIM_IQ_BIN_MODE) {
struct sensor_iq_info *iq = (struct sensor_iq_info *)(metahead_p->load + SENSOR_IQ_BIN_OFFSET);
bin2calib((void *)(iq->main_sensor_iq_offset), parse_main_iq_param);
if (parse_app_param->cam_num == 2)
bin2calib((void *)(iq->secondary_sensor_iq_offset), parse_secondary_iq_param);
} else {
FASTAE_ERR("\n------>load main iq bin failed! wrong bin mode=%d\n", g_iq_bin_mode);
}
// 4) sensor_init params
struct sensor_init_cfg *sensor_init = (struct sensor_init_cfg *)(metahead_p->load + SENSOR_INIT_OFFSET);
parse_sensor_init->cam_w = sensor_init->cam_w;
parse_sensor_init->cam_h = sensor_init->cam_h;
parse_sensor_init->als_type = sensor_init->als_type;
parse_sensor_init->als_value = sensor_init->als_value;
parse_sensor_init->ircut_a.gpio_index = sensor_init->ircut_a.gpio_index;
parse_sensor_init->ircut_a.gpio_func = sensor_init->ircut_a.gpio_func;
parse_sensor_init->ircut_b.gpio_index = sensor_init->ircut_b.gpio_index;
parse_sensor_init->ircut_b.gpio_func = sensor_init->ircut_b.gpio_func;
parse_sensor_init->led_ir_enable.gpio_index = sensor_init->led_ir_enable.gpio_index;
parse_sensor_init->led_ir_enable.gpio_func = sensor_init->led_ir_enable.gpio_func;
parse_sensor_init->led_ir.gpio_index = sensor_init->led_ir.gpio_index;
parse_sensor_init->led_ir.gpio_func = sensor_init->led_ir.gpio_func;
parse_sensor_init->led_ir.pwm_channel = sensor_init->led_ir.pwm_channel;
parse_sensor_init->led_ir.pwm_period = sensor_init->led_ir.pwm_period;
parse_sensor_init->led_ir.pwm_pulse = sensor_init->led_ir.pwm_pulse;
parse_sensor_init->led_white_enable.gpio_index = sensor_init->led_white_enable.gpio_index;;
parse_sensor_init->led_white_enable.gpio_func = sensor_init->led_white_enable.gpio_func;
parse_sensor_init->led_white.gpio_index = sensor_init->led_white.gpio_index;
parse_sensor_init->led_white.gpio_func = sensor_init->led_white.gpio_func;
parse_sensor_init->led_white.pwm_channel = sensor_init->led_white.pwm_channel;
parse_sensor_init->led_white.pwm_period = sensor_init->led_white.pwm_period;
parse_sensor_init->led_white.pwm_pulse = sensor_init->led_white.pwm_pulse;
parse_sensor_init->gpio_adc_enable.gpio_index = sensor_init->gpio_adc_enable.gpio_index;
parse_sensor_init->gpio_adc_enable.gpio_func = sensor_init->gpio_adc_enable.gpio_func;
parse_sensor_init->gpio_adc.gpio_index = sensor_init->gpio_adc.gpio_index;
parse_sensor_init->gpio_adc.gpio_func = sensor_init->gpio_adc.gpio_func;
parse_sensor_init->gpio_adc.adc_channel = sensor_init->gpio_adc.adc_channel;
parse_sensor_init->gpio_adc.adc_direction = sensor_init->gpio_adc.adc_direction;
if (parse_app_param->cam_num == 2)
{
// secondary sensor init params
struct sensor_init_cfg *secondary_sensor_init = (struct sensor_init_cfg *)(metahead_p->load + SECONDARY_SENSOR_INIT_OFFSET);
parse_secondary_sensor_init->cam_w = secondary_sensor_init->cam_w;
parse_secondary_sensor_init->cam_h = secondary_sensor_init->cam_h;
parse_secondary_sensor_init->als_type = secondary_sensor_init->als_type;
parse_secondary_sensor_init->als_value = secondary_sensor_init->als_value;
parse_secondary_sensor_init->ircut_a.gpio_index = secondary_sensor_init->ircut_a.gpio_index;
parse_secondary_sensor_init->ircut_a.gpio_func = secondary_sensor_init->ircut_a.gpio_func;
parse_secondary_sensor_init->ircut_b.gpio_index = secondary_sensor_init->ircut_b.gpio_index;
parse_secondary_sensor_init->ircut_b.gpio_func = secondary_sensor_init->ircut_b.gpio_func;
parse_secondary_sensor_init->led_ir_enable.gpio_index = secondary_sensor_init->led_ir_enable.gpio_index;
parse_secondary_sensor_init->led_ir_enable.gpio_func = secondary_sensor_init->led_ir_enable.gpio_func;
parse_secondary_sensor_init->led_ir.gpio_index = secondary_sensor_init->led_ir.gpio_index;
parse_secondary_sensor_init->led_ir.gpio_func = secondary_sensor_init->led_ir.gpio_func;
parse_secondary_sensor_init->led_ir.pwm_channel = secondary_sensor_init->led_ir.pwm_channel;
parse_secondary_sensor_init->led_ir.pwm_period = secondary_sensor_init->led_ir.pwm_period;
parse_secondary_sensor_init->led_ir.pwm_pulse = secondary_sensor_init->led_ir.pwm_pulse;
parse_secondary_sensor_init->led_white_enable.gpio_index = secondary_sensor_init->led_white_enable.gpio_index;;
parse_secondary_sensor_init->led_white_enable.gpio_func = secondary_sensor_init->led_white_enable.gpio_func;
parse_secondary_sensor_init->led_white.gpio_index = secondary_sensor_init->led_white.gpio_index;
parse_secondary_sensor_init->led_white.gpio_func = secondary_sensor_init->led_white.gpio_func;
parse_secondary_sensor_init->led_white.pwm_channel = secondary_sensor_init->led_white.pwm_channel;
parse_secondary_sensor_init->led_white.pwm_period = secondary_sensor_init->led_white.pwm_period;
parse_secondary_sensor_init->led_white.pwm_pulse = secondary_sensor_init->led_white.pwm_pulse;
parse_secondary_sensor_init->gpio_adc_enable.gpio_index = secondary_sensor_init->gpio_adc_enable.gpio_index;
parse_secondary_sensor_init->gpio_adc_enable.gpio_func = secondary_sensor_init->gpio_adc_enable.gpio_func;
parse_secondary_sensor_init->gpio_adc.gpio_index = secondary_sensor_init->gpio_adc.gpio_index;
parse_secondary_sensor_init->gpio_adc.gpio_func = secondary_sensor_init->gpio_adc.gpio_func;
parse_secondary_sensor_init->gpio_adc.adc_channel = secondary_sensor_init->gpio_adc.adc_channel;
parse_secondary_sensor_init->gpio_adc.adc_direction = secondary_sensor_init->gpio_adc.adc_direction;
}
// 5) ae_awb params
struct ae_awb_init_cfg *ae_awb = (struct ae_awb_init_cfg *)(metahead_p->load + AE_TABLE_OFFSET);
parse_ae_init->black_lvl = ae_awb->ae.black_lvl;
parse_ae_init->adc_calib_type = ae_awb->ae.adc_calib_type;
parse_ae_init->adc_range_type = ae_awb->ae.adc_range_type;
if (parse_ae_init->adc_calib_type == 0)
{
parse_ae_init->adc_calib[0] = INT2FIX(ae_awb->ae.adc_calib[0]);
parse_ae_init->adc_calib[1] = INT2FIX(ae_awb->ae.adc_calib[1]);
parse_ae_init->adc_calib[2] = INT2FIX(ae_awb->ae.adc_calib[2]);
parse_ae_init->adc_calib[3] = INT2FIX(ae_awb->ae.adc_calib[3]);
}
else
{
parse_ae_init->adc_table_len = ae_awb->ae.adc_table_len;
for (int i = 0; i < parse_ae_init->adc_table_len; i++)
{
parse_ae_init->adc_table_low[i][0] = INT2FIX(ae_awb->ae.adc_table_low[i][0]);
parse_ae_init->adc_table_low[i][1] = INT2FIX(ae_awb->ae.adc_table_low[i][1]);
}
if (parse_ae_init->adc_range_type == 0)
{
for (int i = 0; i < parse_ae_init->adc_table_len; i++)
{
parse_ae_init->adc_table_high[i][0] = INT2FIX(ae_awb->ae.adc_table_high[i][0]);
parse_ae_init->adc_table_high[i][1] = INT2FIX(ae_awb->ae.adc_table_high[i][1]);
}
}
}
parse_ae_init->exp_calib[0] = INT2FIX(ae_awb->ae.start_exp[0]);
parse_ae_init->exp_calib[1] = INT2FIX(ae_awb->ae.start_exp[1]);
parse_ae_init->exp_calib[2] = INT2FIX(ae_awb->ae.start_exp[2]);
parse_ae_init->ir_config.rggain_base = ae_awb->awb.rg_gain_base;
parse_ae_init->ir_config.bggain_base = ae_awb->awb.bg_gain_base;
parse_ae_init->ir_config.awbgain_rad = ae_awb->awb.awb_gain_rad;
parse_ae_init->ir_config.awbgain_dis = ae_awb->awb.awb_gain_dis;
// TODO: add rtt 2a res
#ifdef RT_USING_RK_AOV
parse_ae_init->conv_day_or_night = ae_awb->rtt_res.day_or_night & 0xff;
parse_ae_init->conv_exp = ae_awb->rtt_res.exp;
parse_ae_init->conv_isp_dgain = ae_awb->rtt_res.isp_dgain;
parse_ae_init->conv_reg_gain = ae_awb->rtt_res.reg_gain;
parse_ae_init->conv_reg_time = ae_awb->rtt_res.reg_time;
parse_ae_init->conv_dcg_mode = ae_awb->rtt_res.dcg_mode;
parse_ae_init->conv_r_gain = ae_awb->rtt_res.awb_gain & 0xffff;
parse_ae_init->conv_b_gain = (ae_awb->rtt_res.awb_gain >> FIXEDPREC) & 0xffff;
parse_ae_init->nr_diff_th = ae_awb->rtt_res.nr_diff_th;
parse_ae_init->ae_diff_th = ae_awb->rtt_res.ae_diff_th;
for (int i = 0; i < AE_GRID_STATS - 1; i++)
{
parse_ae_init->conv_ae_stats[2 * i] = ae_awb->rtt_res.ae_stats[i] & 0xffff;
parse_ae_init->conv_ae_stats[2 * i + 1] = ae_awb->rtt_res.ae_stats[i] >> 16;
}
parse_ae_init->conv_ae_stats[ISP_RAWAEBIG_MEAN_NUM - 1] = ae_awb->rtt_res.ae_stats[AE_GRID_STATS - 1] & 0xffff;
parse_ae_init->last_lodif = ((uint64_t)ae_awb->rtt_res.last_lodif_0 & 0xffffffff) | ((uint64_t)ae_awb->rtt_res.last_lodif_1 << 32);
parse_ae_init->last_hidif = ((uint64_t)ae_awb->rtt_res.last_hidif_0 & 0xffffffff) | ((uint64_t)ae_awb->rtt_res.last_hidif_1 << 32);
FASTAE_DBG("day/night=%d,conv_exp=%d,conv_reg_gain=%d,conv_reg_time=%d,conv_dcg_mode=%d,conv_r_gain=0x%x,conv_b_gain=0x%x,conv_ispG=0x%x\n",
parse_ae_init->conv_day_or_night, parse_ae_init->conv_exp, parse_ae_init->conv_reg_gain, parse_ae_init->conv_reg_time,
parse_ae_init->conv_dcg_mode, parse_ae_init->conv_r_gain, parse_ae_init->conv_b_gain, parse_ae_init->conv_isp_dgain);
#endif
// TODO: day or night threshold
parse_ae_init->ir_config.d2n_envL_th = parse_sensor_init->als_value;
parse_ae_init->ir_config.n2d_envL_th = parse_sensor_init->als_value * 3;
parse_ae_init->als_type = parse_sensor_init->als_type;
parse_ae_init->night_mode = app_param->night_mode;
parse_ae_init->led_value = MIN(app_param->led_value, 100);
return ret;
}
int32_t read_lux_adc
(
struct fastae_init_info *fastae_init,
struct sensor_init_cfg *sensor_init
)
{
static rt_adc_device_t adc_dev;
int32_t ret = 0, count = 0, val_last = 0, val_new = 0, gpio_func = 0;
int direction = sensor_init->gpio_adc.adc_direction;
const char *pADCDevice = CAM_ADC_GET_DEVICE;
adc_dev = (rt_adc_device_t)rt_device_find(pADCDevice);
if (adc_dev == RT_NULL)
{
FASTAE_ERR("ADC run failed! can't find %s device!\n", pADCDevice);
}
val_new = rt_adc_read(adc_dev, sensor_init->gpio_adc.adc_channel);
FASTAE_DBG("read first ADC: val_new %d\n", val_new);
ret = cam_cfg_gpio_func(sensor_init->gpio_adc.gpio_index, sensor_init->gpio_adc.gpio_func);
if (direction == 0)
gpio_func = sensor_init->gpio_adc_enable.gpio_func | FLAG_GPIO_DEFAULT_HIGH;
else
gpio_func = sensor_init->gpio_adc_enable.gpio_func | FLAG_GPIO_DEFAULT_LOW;
ret = cam_cfg_gpio_func(sensor_init->gpio_adc_enable.gpio_index, gpio_func);
FASTAE_DBG("set %s to read dark ADC, tick:%d\n", direction == 0 ? "GPIO_HIGH" : "GPIO_LOW", rt_tick_get());
while (++count)
{
val_last = val_new;
val_new = rt_adc_read(adc_dev, sensor_init->gpio_adc.adc_channel);
FASTAE_DBG("read %d-th ADC: val_new %d\n", count, val_new);
if (FIX_ABS(val_last, val_new) <= 0 || count > 50)
{
fastae_init->low_adc = INT2FIX(val_new);
val_new = 0;
val_last = 0;
count = 0;
break;
}
}
if (direction == 0)
ret = cam_set_gpio_level(sensor_init->gpio_adc_enable.gpio_index, GPIO_LOW);
else
ret = cam_set_gpio_level(sensor_init->gpio_adc_enable.gpio_index, GPIO_HIGH);
FASTAE_DBG("set %s to read light ADC, tick:%d\n", direction == 0 ? "GPIO_LOW" : "GPIO_HIGH", rt_tick_get());
HAL_DelayMs(2);
while (++count)
{
val_last = val_new;
val_new = rt_adc_read(adc_dev, sensor_init->gpio_adc.adc_channel);
FASTAE_DBG("read %d-th ADC: val_new %d\n", count, val_new);
if (FIX_ABS(val_last, val_new) <= 0 || count > 50)
{
fastae_init->high_adc = INT2FIX(val_new);
val_new = 0;
val_last = 0;
count = 0;
break;
}
}
return ret;
}
int32_t read_night_adc
(
struct fastae_init_info *fastae_init,
struct sensor_init_cfg *sensor_init
)
{
static rt_adc_device_t adc_dev;
int32_t ret = 0, count = 0, val_last = 0, val_new = 0;
const char *pADCDevice = CAM_ADC_GET_DEVICE;
adc_dev = (rt_adc_device_t)rt_device_find(pADCDevice);
if (adc_dev == RT_NULL)
{
FASTAE_ERR("ADC run failed! can't find %s device!\n", pADCDevice);
}
// read low adc may cost too much time!
fastae_init->low_adc = -1;
while (++count)
{
val_last = val_new;
val_new = rt_adc_read(adc_dev, sensor_init->gpio_adc.adc_channel);
FASTAE_DBG("read %d-th ADC: val_new %d\n", count, val_new);
if (FIX_ABS(val_last, val_new) <= 0 || count > 50)
{
fastae_init->high_adc = INT2FIX(val_new);
break;
}
}
return ret;
}
int32_t read_digital_lux(struct fastae_init_info *fastae_init)
{
struct rt_device *asl_dev;
int32_t ret = 0;
bool ready;
float lux;
fastae_init->env_lux = 0;
const char *pALSDevice = "als";
asl_dev = (struct rt_device *)rt_device_find(pALSDevice);
if (!asl_dev)
{
FASTAE_ERR("find device:%s failed, assume lux is 100!\n", pALSDevice);
fastae_init->env_lux = FLOAT2LFIX(100);
return ret;
}
FASTAE_DBG("%s start read, tick: %d\n", pALSDevice, rt_tick_get());
do
{
rt_device_control(asl_dev, RK_DEVICE_CTRL_ALS_DATA_READY, &ready);
HAL_DelayUs(500);
}
while (!ready);
FASTAE_DBG("%s over read, tick: %d\n", pALSDevice, rt_tick_get());
if (ready)
{
rt_device_control(asl_dev, RK_DEVICE_CTRL_ALS_GET_VAL, &lux);
fastae_init->env_lux = FLOAT2LFIX(lux);
}
return ret;
}
int32_t set_night_mode
(
struct fastae_init_info *fastae_init,
struct sensor_init_cfg *sensor_init
)
{
int ret = 0;
night_mode_t night_mode = fastae_init->night_mode;
int led_value = fastae_init->led_value;
if (night_mode == NIGHT_WHITE_AUTO || night_mode == NIGHT_WHITE_ON)
{
FASTAE_INFO(">>> white led night mode is working\n");
if (led_value > 0)
{
if (sensor_init->led_white_enable.gpio_index != -1)
{
ret = cam_cfg_gpio_func(sensor_init->led_white_enable.gpio_index, sensor_init->led_white_enable.gpio_func);
}
ret = cam_cfg_gpio_func(sensor_init->led_white.gpio_index, sensor_init->led_white.gpio_func);
if (ret)
{
FASTAE_ERR("error: config white led.\n");
}
struct rt_device_pwm *pwm_dev;
int pwm_pulse = sensor_init->led_white.pwm_period * led_value / 100;
const char *pPWMDevice = cam_get_pwm_name(sensor_init->led_white.pwm_channel);
pwm_dev = (struct rt_device_pwm *)rt_device_find(pPWMDevice);
if (pwm_dev == RT_NULL)
{
FASTAE_ERR("pwm run failed! can't find %s device!\n", pPWMDevice);
}
else
{
rt_pwm_set(pwm_dev,
CAM_PWM_GET_CHANNEL(sensor_init->led_white.pwm_channel),
sensor_init->led_white.pwm_period,
pwm_pulse);
rt_pwm_enable(pwm_dev, CAM_PWM_GET_CHANNEL(sensor_init->led_white.pwm_channel));
}
if (fastae_init->als_type > ALS_TYPE_NONE)
{
HAL_DelayMs(5); //open white led, read adc
if (fastae_init->als_type == ALS_TYPE_ANALOG)
{
read_night_adc(fastae_init, sensor_init);
}
FastAeNightExpCalc(fastae_init);
}
}
}
else if (night_mode == NIGHT_IR_AUTO || night_mode == NIGHT_IR_ON)
{
FASTAE_INFO(">>> ir led night mode is working\n");
// update night calib scene
if (*g_is_bw_night == BW_MODE) {
ret = rkaiq_get_night_calib(g_main_camproj, &g_main_calib, g_app_param.cam_hdr);
if (ret) {
FASTAE_INFO(">>> no need to load night calib scene\n");
} else {
FASTAE_INFO(">>> reload night calib scene\n");
struct fastae_init_info *fastae_night_init = rt_calloc(1, sizeof(struct fastae_init_info));
if (!fastae_night_init) {
FASTAE_ERR("%s alloc failed!\n", __func__);
return 0;
}
fastae_night_init->is_hdr = (g_app_param.cam_hdr > NO_HDR) ? true : false;
parse_ae_params(&g_main_calib, fastae_night_init, g_iq_bin_mode);
FastAeNightInit(fastae_night_init);
rt_free(fastae_night_init);
}
}
if (led_value > 0)
{
if (sensor_init->led_ir_enable.gpio_index != -1)
{
ret = cam_cfg_gpio_func(sensor_init->led_ir_enable.gpio_index, sensor_init->led_ir_enable.gpio_func);
}
ret = cam_cfg_gpio_func(sensor_init->led_ir.gpio_index, sensor_init->led_ir.gpio_func);
if (ret)
{
FASTAE_ERR("error: config ir led.\n");
}
struct rt_device_pwm *pwm_dev;
int pwm_pulse = sensor_init->led_ir.pwm_period * led_value / 100;
const char *pPWMDevice = cam_get_pwm_name(sensor_init->led_ir.pwm_channel);
pwm_dev = (struct rt_device_pwm *)rt_device_find(pPWMDevice);
if (pwm_dev == RT_NULL)
{
FASTAE_ERR("pwm run failed! can't find %s device!\n", pPWMDevice);
}
else
{
rt_pwm_set(pwm_dev,
CAM_PWM_GET_CHANNEL(sensor_init->led_ir.pwm_channel),
sensor_init->led_ir.pwm_period,
pwm_pulse);
rt_pwm_enable(pwm_dev, CAM_PWM_GET_CHANNEL(sensor_init->led_ir.pwm_channel));
}
if (fastae_init->als_type > ALS_TYPE_NONE)
{
HAL_DelayMs(5); //open ir led, open ircut
FastAeNightExpCalc(fastae_init);
}
}
}
return 0;
}
int32_t set_ae_init
(
rk_device *sensor,
struct fastae_init_info *fastae_init,
struct sensor_init_cfg *sensor_init_config
)
{
struct rk_camera_exp_info exp_info = {0};
// 1.0 CONFIG AE PARAMS
rt_memset(&exp_info, 0, sizeof(exp_info));
rt_device_control(sensor, RK_DEVICE_CTRL_CAMERA_GET_EXP_INF, &exp_info);
fastae_init->fps = exp_info.pix_clk / (exp_info.hts * exp_info.vts);
fastae_init->hts = exp_info.hts;
fastae_init->vts = exp_info.vts;
fastae_init->fps_aiq = exp_info.dst_pix_clk / (exp_info.dst_hts * exp_info.dst_vts);
fastae_init->hts_aiq = exp_info.dst_hts;
fastae_init->vts_aiq = exp_info.dst_vts;
//g_param.sensor.dst_vts = exp_info.dst_vts;
FASTAE_INFO(">>> fps/hts/vts: RTT=[%d, %d, %d], MainAIQ=[%d, %d, %d]\n",
fastae_init->fps, fastae_init->hts, fastae_init->vts,
fastae_init->fps_aiq, fastae_init->hts_aiq, fastae_init->vts_aiq);
#ifdef RT_USING_RK_AOV
fastae_init->is_wakeup = true;
#else
fastae_init->is_wakeup = false;
#endif
FastAeInit(fastae_init);
// 2.0 CALC INIT EXPOSURE
FIXED night_thre = sensor_init_config->als_value;
FIXED rk_night_mode = fastae_init->night_mode; //user setting, not current night mode
if (sensor_init_config->als_type == ALS_TYPE_ANALOG || sensor_init_config->als_type == ALS_TYPE_DIGITAL)
{
if (sensor_init_config->als_type == ALS_TYPE_ANALOG)
read_lux_adc(fastae_init, sensor_init_config);
else
read_digital_lux(fastae_init);
FastAeInitExpCalc(fastae_init);
if (((fastae_init->env_lux < night_thre) && (rk_night_mode == NIGHT_IR_AUTO))
|| ((fastae_init->env_lux < night_thre) && (rk_night_mode == NIGHT_WHITE_AUTO))
|| (rk_night_mode == NIGHT_IR_ON) || (rk_night_mode == NIGHT_WHITE_ON))
{
if (rk_night_mode == NIGHT_IR_ON || rk_night_mode == NIGHT_IR_AUTO)
{
g_is_ie_effect = 1;
*g_is_bw_night = BW_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_ON);
}
else
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_OFF);
}
set_night_mode(fastae_init, sensor_init_config);
#ifdef RT_USING_RK_AOV
if (fastae_init->conv_day_or_night == DayORNight_STATUS_NIGHT && fastae_init->conv_exp != 0)
{
// the same night mode, use last conv exposure
fastae_init->start_exp[0] = fastae_init->conv_exp;
fastae_init->start_isp_gain[0] = fastae_init->conv_isp_dgain;
fastae_init->start_reg_time[0] = fastae_init->conv_reg_time;
fastae_init->start_reg_gain[0] = fastae_init->conv_reg_gain;
fastae_init->start_dcg_mode[0] = fastae_init->conv_dcg_mode;
g_use_conv_exp = true;
}
else
{
g_use_conv_exp = false;
}
g_day_or_night = DayORNight_STATUS_NIGHT;
#endif
}
else
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_OFF);
#ifdef RT_USING_RK_AOV
if (fastae_init->conv_day_or_night == DayORNight_STATUS_DAY && fastae_init->conv_exp != 0)
{
// the same day mode, use last conv exposure
fastae_init->start_exp[0] = fastae_init->conv_exp;
fastae_init->start_isp_gain[0] = fastae_init->conv_isp_dgain;
fastae_init->start_reg_time[0] = fastae_init->conv_reg_time;
fastae_init->start_reg_gain[0] = fastae_init->conv_reg_gain;
fastae_init->start_dcg_mode[0] = fastae_init->conv_dcg_mode;
g_use_conv_exp = true;
}
else
{
g_use_conv_exp = false;
}
g_day_or_night = DayORNight_STATUS_DAY;
#endif
}
}
else
{
FastAeInitExpCalc(fastae_init);
if (rk_night_mode == NIGHT_IR_ON || rk_night_mode == NIGHT_WHITE_ON)
{
if (rk_night_mode == NIGHT_IR_ON)
{
g_is_ie_effect = 1;
*g_is_bw_night = BW_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_ON);
}
else
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_OFF);
}
set_night_mode(fastae_init, sensor_init_config); // control led light
g_day_or_night = DayORNight_STATUS_NIGHT;
}
else if (rk_night_mode == NIGHT_OFF)
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_OFF);
g_day_or_night = DayORNight_STATUS_DAY;
}
else
{
// NIGHT_WHITE(IR)_AUTO mode needs to be judged by day_or_night
#ifdef RT_USING_RK_AOV
if (fastae_init->conv_exp != 0)
{
if (fastae_init->conv_day_or_night == DayORNight_STATUS_NIGHT)
{
if (g_fastae_init.night_mode == NIGHT_IR_AUTO)
{
g_is_ie_effect = 1;
*g_is_bw_night = BW_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_ON);
}
else
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_OFF);
}
set_night_mode(fastae_init, sensor_init_config); // control led light
}
else
{
*g_is_bw_night = COLOR_MODE;
ircut_switch(sensor_init_config, IR_STATUS_CUT_OFF);
}
}
#endif
}
#ifdef RT_USING_RK_AOV
if (fastae_init->conv_exp != 0)
{
// for soft light sensor, use last conv exp
fastae_init->start_exp[0] = fastae_init->conv_exp;
fastae_init->start_isp_gain[0] = fastae_init->conv_isp_dgain;
fastae_init->start_reg_time[0] = fastae_init->conv_reg_time;
fastae_init->start_reg_gain[0] = fastae_init->conv_reg_gain;
fastae_init->start_dcg_mode[0] = fastae_init->conv_dcg_mode;
g_use_conv_exp = true;
}
else
{
g_use_conv_exp = false;
}
#endif
}
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)g_is_bw_night, sizeof(*g_is_bw_night));
FASTAE_INFO(">>> als type: %d, als value: 0x%x, night mode: %d\n", sensor_init_config->als_type, night_thre, rk_night_mode);
return 0;
}
int32_t set_firstae(rk_device *isp, rk_device *sensor, struct shared_data *share, rt_sem_t *sem)
{
AE_RESULT ret = 0;
g_is_ie_effect = 0;
gShare = share;
rt_memset(&gShare->cfg, 0, sizeof(struct isp32_isp_params_cfg));
// 1. PARSE META & AE PARAMS
ret = parse_meta_params(&g_main_calib, &g_secondary_calib, &g_sensor_init, &g_secondary_sensor_init, &g_app_param, &g_fastae_init);
g_fastae_init.is_hdr = (g_app_param.cam_hdr > NO_HDR) ? true : false;
parse_ae_params(&g_main_calib, &g_fastae_init, g_iq_bin_mode);
// 2 INIT SENSOR CONFIG
if (g_sensor_init.cam_w && g_sensor_init.cam_h)
{
g_param.sensor.width = g_sensor_init.cam_w;
g_param.sensor.height = g_sensor_init.cam_h;
gShare->hdr_mode = g_app_param.cam_hdr;
struct rk_camera_dst_config cam_config = {0};
cam_config.width = g_sensor_init.cam_w;
cam_config.height = g_sensor_init.cam_h;
cam_config.cam_fps_denominator = g_app_param.cam_fps;
cam_config.cam_fps_numerator = 1;
cam_config.cam_mirror_flip = g_app_param.cam_mirror_flip;
if ((g_app_param.cam_hdr == NO_HDR) ||
(g_app_param.cam_hdr == HDR_X2) ||
(g_app_param.cam_hdr == HDR_X3))
{
cam_config.cam_hdr = g_app_param.cam_hdr;
}
rt_device_control(sensor, RK_DEVICE_CTRL_CID_MATCH_CAM_CONFIG, &cam_config);
}
gShare->camera_num = 1;
if (g_app_param.cam_num == 2)
{
gShare->camera_num = 2;
gShare->camera_index = 0;
gShare_next_camera = share + 1;
gShare_next_camera->camera_num = 2;
gShare_next_camera->camera_index = 1;
rt_memset(&gShare_next_camera->cfg, 0, sizeof(struct isp32_isp_params_cfg));
}
// 3. CALC & SET INIT EXPOSURE
set_ae_init(sensor, &g_fastae_init, &g_sensor_init);
gInitExp.exposure = g_fastae_init.start_exp[0];
gInitExp.exp.reg_time[0] = g_fastae_init.start_reg_time[0];
gInitExp.exp.reg_gain[0] = g_fastae_init.start_reg_gain[0];
gInitExp.exp.dcg_mode[0] = g_fastae_init.start_dcg_mode[0];
rt_device_control(sensor,
RK_DEVICE_CTRL_CAMERA_SET_EXP_VAL,
&gInitExp.exp);
#ifdef RT_USING_RK_AOV
FASTAE_INFO("Final InitExp : initexp=%d.%04d,regtime=%d,reggain=%d\n",
FIX2INT(gInitExp.exposure), FIX2FRA(gInitExp.exposure),
gInitExp.exp.reg_time[0], gInitExp.exp.reg_gain[0]);
#endif
// 4. ISP PARAMS FOR RTT
FIXED black_lvl = g_fastae_init.black_lvl;
struct rkisp_params_buffer isp_params = { 0 };
isp_params.frame_id = 0;
isp_params.module_ens = /*ISP_MODULE_RAWAE0 |*/ ISP_MODULE_RAWAE1 |
ISP_MODULE_RAWAWB | ISP_MODULE_BLS | ISP_MODULE_AWBGAIN;
isp_params.module_en_update = isp_params.module_ens;
isp_params.module_cfg_update = isp_params.module_ens;
isp_params.params.bls.r = black_lvl;
isp_params.params.bls.gr = black_lvl;
isp_params.params.bls.gb = black_lvl;
isp_params.params.bls.b = black_lvl;
struct rk_camera_device *subdev;
subdev = ((struct rk_isp_dev *)isp->user_data)->subdev;
#ifdef RT_USING_RK_AOV
// 1.0 awb gain
if (g_use_conv_exp == true)
{
isp_params.params.awbgain.gb = MAX(256, (256 * g_fastae_init.conv_isp_dgain) >> 16);
isp_params.params.awbgain.gr = MAX(256, (256 * g_fastae_init.conv_isp_dgain) >> 16);
isp_params.params.awbgain.b = g_fastae_init.conv_b_gain;
isp_params.params.awbgain.r = g_fastae_init.conv_r_gain;
}
else
{
int_wbgain(&isp_params.params.awbgain);
isp_params.params.awbgain.gb = (isp_params.params.awbgain.gb * g_fastae_init.start_isp_gain[0]) >> 16;
isp_params.params.awbgain.gr = (isp_params.params.awbgain.gr * g_fastae_init.start_isp_gain[0]) >> 16;
isp_params.params.awbgain.b = (isp_params.params.awbgain.b * g_fastae_init.start_isp_gain[0]) >> 16;
isp_params.params.awbgain.r = (isp_params.params.awbgain.r * g_fastae_init.start_isp_gain[0]) >> 16;
}
// 2.0 nr params
isp_params.module_ens |= ISP32_MODULE_BAY3D;
isp_params.module_en_update |= ISP32_MODULE_BAY3D;
isp_params.module_cfg_update |= ISP32_MODULE_BAY3D;
isp_params.module_ens |= ISP32_MODULE_BAYNR;
isp_params.module_en_update |= ISP32_MODULE_BAYNR;
isp_params.module_cfg_update |= ISP32_MODULE_BAYNR;
set_baynr_params_for_rtt(&isp_params.params.baynr);
set_bay3d_params_for_rtt(&isp_params.params.bay3d, subdev->info.mbus_fmt.width, subdev->info.mbus_fmt.height);
if (g_fastae_init.conv_exp == 0)
isp_params.params.bay3d.is_first = true;
else
isp_params.params.bay3d.is_first = false;
#else
int_wbgain(&isp_params.params.awbgain);
set_bay3d_params_for_rtt(&isp_params.params.bay3d, subdev->info.mbus_fmt.width, subdev->info.mbus_fmt.height); // only set nr cfg, not enable
#endif
isp_params.params.bay3d.buf_off = sizeof(struct shared_data) * gShare->camera_num;
gShare->share_mem_size = isp_params.params.bay3d.buf_off;
gShare->nr_buf_size = isp_params.params.bay3d.iir_size + isp_params.params.bay3d.cur_size + isp_params.params.bay3d.ds_size;
set_params(isp, &isp_params);
#ifdef RT_USING_CAM_STREAM_ON_LATE
rk_semaphore_release(*sem);
FASTAE_INFO("%s %d tick %d\n", __FUNCTION__, __LINE__, rt_tick_get());
#endif
return ret;
}
int secondary_config(struct rk_camera_dst_config *cam_config)
{
if (g_secondary_sensor_init.cam_w <= 0 || g_secondary_sensor_init.cam_h <= 0)
return -RT_EINVAL;
g_param.secondary_sensor.width = g_secondary_sensor_init.cam_w;
g_param.secondary_sensor.height = g_secondary_sensor_init.cam_h;
gShare_next_camera->width = g_secondary_sensor_init.cam_w;
gShare_next_camera->height = g_secondary_sensor_init.cam_h;
gShare_next_camera->hdr_mode = g_app_param.cam2_hdr;
gShare_next_camera->rtt_mode = gShare->rtt_mode;
gShare_next_camera->md_flag = gShare->md_flag;
cam_config->width = g_secondary_sensor_init.cam_w;
cam_config->height = g_secondary_sensor_init.cam_h;
cam_config->cam_fps_denominator = g_app_param.cam2_fps;
cam_config->cam_fps_numerator = 1;
cam_config->cam_mirror_flip = g_app_param.cam2_mirror_flip;
if ((g_app_param.cam2_hdr == NO_HDR) ||
(g_app_param.cam2_hdr == HDR_X2) ||
(g_app_param.cam2_hdr == HDR_X3))
{
cam_config->cam_hdr = g_app_param.cam2_hdr;
}
return RT_EOK;
}
int32_t set_params(rk_device *isp, struct rkisp_params_buffer *buf)
{
return rk_device_control(isp, RK_DEVICE_CTRL_ISP_SET_PARAMS, buf);
}