Files
LuckFox-RV1103-1106/sysdrv/source/mcu/rt-thread/applications/battery-ipc/fast_ae.c
T
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

/**
* 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);
}