mirror of
https://github.com/sipeed/MaixCDK.git
synced 2026-11-09 17:04:38 -06:00
* add gc030a sensor
This commit is contained in:
@@ -20,6 +20,7 @@ append_srcs_dir(middleware_src_dir ${middleware_src_path}/v2/sample/common
|
||||
${middleware_src_path}/v2/component/isp/sensor/sg200x/lontium_lt6911
|
||||
${middleware_src_path}/v2/component/isp/sensor/sg200x/ov_os04a10
|
||||
${middleware_src_path}/v2/component/isp/sensor/sg200x/gcore_gc02m1
|
||||
${middleware_src_path}/v2/component/isp/sensor/sg200x/gcore_gc030a
|
||||
)
|
||||
list(APPEND ADD_SRCS ${middleware_src_dir})
|
||||
set_property(SOURCE ${middleware_src_dir} PROPERTY GENERATED 1)
|
||||
@@ -72,4 +73,5 @@ list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_OV_OV2685)
|
||||
list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_LONTIUM_LT6911)
|
||||
list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_OV_OS04A10)
|
||||
list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_GCORE_GC02M1)
|
||||
list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_GCORE_GC030A)
|
||||
register_component(DYNAMIC)
|
||||
@@ -57,6 +57,7 @@ sensor-$(CONFIG_SENSOR_BRIGATES_BG0808) += brigates_bg0808
|
||||
sensor-$(CONFIG_SENSOR_CVSENS_CV4001) += cvsens_cv4001
|
||||
sensor-$(CONFIG_SENSOR_BYD_BF2253L) += byd_bf2253l
|
||||
sensor-$(CONFIG_SENSOR_GCORE_GC02M1) += gcore_gc02m1
|
||||
sensor-$(CONFIG_SENSOR_GCORE_GC030A) += gcore_gc030a
|
||||
sensor-$(CONFIG_SENSOR_GCORE_GC0312) += gcore_gc0312
|
||||
sensor-$(CONFIG_SENSOR_GCORE_GC0329) += gcore_gc0329
|
||||
sensor-$(CONFIG_SENSOR_GCORE_GC1054) += gcore_gc1054
|
||||
|
||||
@@ -35,6 +35,9 @@ cvsens_cv4001:
|
||||
gcore_gc02m1:
|
||||
$(call MAKE_SENSOR, ${@})
|
||||
|
||||
gcore_gc030a:
|
||||
$(call MAKE_SENSOR, ${@})
|
||||
|
||||
gcore_gc0312:
|
||||
$(call MAKE_SENSOR, ${@})
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
SHELL = /bin/bash
|
||||
ifeq ($(PARAM_FILE), )
|
||||
PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param
|
||||
include $(PARAM_FILE)
|
||||
endif
|
||||
|
||||
SDIR = $(PWD)
|
||||
SRCS = $(wildcard $(SDIR)/*.c)
|
||||
INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
DEPS = $(SRCS:.c=.d)
|
||||
TARGET_A = $(MW_LIB)/libsns_gc030a.a
|
||||
TARGET_SO = $(MW_LIB)/libsns_gc030a.so
|
||||
|
||||
EXTRA_CFLAGS = $(INCS)
|
||||
EXTRA_LDFLAGS =
|
||||
|
||||
.PHONY : clean all
|
||||
all : $(TARGET_A) $(TARGET_SO)
|
||||
|
||||
$(SDIR)/%.o: $(SDIR)/%.c
|
||||
@$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
|
||||
@echo [$(notdir $(CC))] $(notdir $@)
|
||||
|
||||
$(TARGET_A): $(OBJS)
|
||||
@$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
@echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A))
|
||||
|
||||
$(TARGET_SO): $(OBJS)
|
||||
@$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group
|
||||
@echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO))
|
||||
|
||||
clean:
|
||||
@rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO)
|
||||
|
||||
-include $(DEPS)
|
||||
@@ -0,0 +1,740 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#ifdef ARCH_CV182X
|
||||
#include "cvi_type.h"
|
||||
#include "cvi_comm_video.h"
|
||||
#include <linux/cvi_vip_snsr.h>
|
||||
#else
|
||||
#include <linux/cvi_type.h>
|
||||
#include <linux/cvi_comm_video.h>
|
||||
#include <linux/vi_snsr.h>
|
||||
#endif
|
||||
#include "cvi_debug.h"
|
||||
#include "cvi_comm_sns.h"
|
||||
#include "cvi_sns_ctrl.h"
|
||||
#include "cvi_ae_comm.h"
|
||||
#include "cvi_awb_comm.h"
|
||||
#include "cvi_ae.h"
|
||||
#include "cvi_awb.h"
|
||||
#include "cvi_isp.h"
|
||||
|
||||
#include "gc030a_cmos_ex.h"
|
||||
#include "gc030a_cmos_param.h"
|
||||
|
||||
|
||||
#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a))
|
||||
#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a))
|
||||
#define GC030A_ID 0x030a
|
||||
#define GC030A_I2C_ADDR_1 0x21
|
||||
#define GC030A_I2C_ADDR_IS_VALID(addr) ((addr) == GC030A_I2C_ADDR_1)
|
||||
|
||||
/****************************************************************************
|
||||
* global variables *
|
||||
****************************************************************************/
|
||||
|
||||
ISP_SNS_STATE_S *g_pastGc030a[VI_MAX_PIPE_NUM] = {CVI_NULL};
|
||||
|
||||
#define GC030A_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc030a[dev])
|
||||
#define GC030A_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc030a[dev] = pstCtx)
|
||||
#define GC030A_SENSOR_RESET_CTX(dev) (g_pastGc030a[dev] = CVI_NULL)
|
||||
|
||||
ISP_SNS_COMMBUS_U g_aunGc030a_BusInfo[VI_MAX_PIPE_NUM] = {
|
||||
[0] = { .s8I2cDev = 4},
|
||||
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
|
||||
};
|
||||
ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc030a_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL};
|
||||
|
||||
/****************************************************************************
|
||||
* local variables and functions *
|
||||
****************************************************************************/
|
||||
#define GC030A_RES_IS_480P(w, h) ((w) == 640 && (h) == 480)
|
||||
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
|
||||
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
|
||||
};
|
||||
|
||||
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
|
||||
static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0};
|
||||
static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0};
|
||||
static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} };
|
||||
static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0};
|
||||
static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0};
|
||||
CVI_U16 g_au16Gc030a_GainMode[VI_MAX_PIPE_NUM] = {0};
|
||||
|
||||
#define GC030A_FULL_LINES_MAX 0xfff
|
||||
#define GC030A_PAGE_0_ADDR 0xfe
|
||||
#define GC030A_VTS_H_ADDR 0x07
|
||||
#define GC030A_VTS_L_ADDR 0x08
|
||||
#define GC030A_EXP_H_ADDR 0x03
|
||||
#define GC030A_EXP_L_ADDR 0x04
|
||||
#define GC030A_MIRROR_FLIP_ADDR 0x17
|
||||
#define GC030A_AGAIN_ADDR 0xb6
|
||||
|
||||
static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg)
|
||||
{
|
||||
const GC030A_MODE_S *pstMode = CVI_NULL;
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
pstMode = &g_astGc030a_mode[pstSnsState->u8ImgMode];
|
||||
pstIspCfg->frm_num = 1;
|
||||
memcpy(&pstIspCfg->img_size[0], &pstMode->stImg[0], sizeof(ISP_WDR_SIZE_S));
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL;
|
||||
|
||||
CMOS_CHECK_POINTER(pstSnsSyncInfo);
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
pstCfg0 = &pstSnsState->astSyncInfo[0];
|
||||
cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg);
|
||||
memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S));
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode)
|
||||
{
|
||||
CVI_U8 u8SensorImageMode = 0;
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
CMOS_CHECK_POINTER(pstSensorImageMode);
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
u8SensorImageMode = pstSnsState->u8ImgMode;
|
||||
pstSnsState->bSyncInit = CVI_FALSE;
|
||||
|
||||
if (pstSensorImageMode->f32Fps <= 30) {
|
||||
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
|
||||
if (GC030A_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
|
||||
u8SensorImageMode = GC030A_MODE_640X480P30;
|
||||
else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n",
|
||||
pstSensorImageMode->u16Width,
|
||||
pstSensorImageMode->u16Height,
|
||||
pstSensorImageMode->f32Fps,
|
||||
pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n",
|
||||
pstSensorImageMode->u16Width,
|
||||
pstSensorImageMode->u16Height,
|
||||
pstSensorImageMode->f32Fps,
|
||||
pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) {
|
||||
/* Don't need to switch SensorImageMode */
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
pstSnsState->u8ImgMode = u8SensorImageMode;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER_VOID(pstSnsState);
|
||||
|
||||
pstSnsState->bInit = CVI_FALSE;
|
||||
pstSnsState->bSyncInit = CVI_FALSE;
|
||||
pstSnsState->u8ImgMode = GC030A_MODE_640X480P30;
|
||||
pstSnsState->enWDRMode = WDR_MODE_NONE;
|
||||
}
|
||||
|
||||
static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstRxAttr);
|
||||
|
||||
memcpy(pstRxAttr, &gc030a_rx_attr, sizeof(*pstRxAttr));
|
||||
|
||||
pstRxAttr->img_size.width = g_astGc030a_mode[pstSnsState->u8ImgMode].stImg[0].stSnsSize.u32Width;
|
||||
pstRxAttr->img_size.height = g_astGc030a_mode[pstSnsState->u8ImgMode].stImg[0].stSnsSize.u32Height;
|
||||
return CVI_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr)
|
||||
{
|
||||
SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc030a_rx_attr;
|
||||
|
||||
CMOS_CHECK_POINTER(pstRxInitAttr);
|
||||
|
||||
if (pstRxInitAttr->stMclkAttr.bMclkEn)
|
||||
pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk;
|
||||
|
||||
if (pstRxInitAttr->MipiDev >= VI_MAX_DEV_NUM)
|
||||
return CVI_SUCCESS;
|
||||
|
||||
pstRxAttr->devno = pstRxInitAttr->MipiDev;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode)
|
||||
{
|
||||
UNUSED(ViPipe);
|
||||
UNUSED(u8Mode);
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n");
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstAwbSnsDft);
|
||||
UNUSED(ViPipe);
|
||||
memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S));
|
||||
|
||||
pstAwbSnsDft->u16InitGgain = 1024;
|
||||
pstAwbSnsDft->u8AWBRunInterval = 1;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstExpFuncs);
|
||||
|
||||
memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S));
|
||||
|
||||
pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef)
|
||||
{
|
||||
UNUSED(ViPipe);
|
||||
memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S));
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstBlc);
|
||||
UNUSED(ViPipe);
|
||||
memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S));
|
||||
|
||||
memcpy(pstBlc,
|
||||
&g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S));
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstSensorExpFunc);
|
||||
|
||||
memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S));
|
||||
|
||||
pstSensorExpFunc->pfn_cmos_sensor_init = gc030a_init;
|
||||
pstSensorExpFunc->pfn_cmos_sensor_exit = gc030a_exit;
|
||||
pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init;
|
||||
pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode;
|
||||
pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode;
|
||||
pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default;
|
||||
pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default;
|
||||
pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* callback structure *
|
||||
****************************************************************************/
|
||||
static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr)
|
||||
{
|
||||
if (GC030A_I2C_ADDR_IS_VALID(s32I2cAddr))
|
||||
gc030a_i2c_addr = s32I2cAddr;
|
||||
}
|
||||
|
||||
static CVI_S32 gc030a_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
|
||||
{
|
||||
g_aunGc030a_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
|
||||
{
|
||||
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
|
||||
|
||||
if (pastSnsStateCtx == CVI_NULL) {
|
||||
pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S));
|
||||
if (pastSnsStateCtx == CVI_NULL) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S));
|
||||
|
||||
GC030A_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
|
||||
{
|
||||
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
|
||||
SENSOR_FREE(pastSnsStateCtx);
|
||||
GC030A_SENSOR_RESET_CTX(ViPipe);
|
||||
}
|
||||
|
||||
|
||||
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
CMOS_CHECK_POINTER(pstAeSnsDft);
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
|
||||
pstAeSnsDft->u32FlickerFreq = 50 * 256;
|
||||
pstAeSnsDft->u32FullLinesMax = GC030A_FULL_LINES_MAX;
|
||||
pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30);
|
||||
|
||||
pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR;
|
||||
pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1;
|
||||
pstAeSnsDft->stIntTimeAccu.f32Offset = 0;
|
||||
pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE;
|
||||
pstAeSnsDft->stAgainAccu.f32Accuracy = 1;
|
||||
pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE;
|
||||
pstAeSnsDft->stDgainAccu.f32Accuracy = 1;
|
||||
|
||||
pstAeSnsDft->u32ISPDgainShift = 8;
|
||||
pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift;
|
||||
pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift;
|
||||
|
||||
if (g_au32LinesPer500ms[ViPipe] == 0)
|
||||
pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2;
|
||||
else
|
||||
pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe];
|
||||
switch (pstSnsState->enWDRMode) {
|
||||
default:
|
||||
case WDR_MODE_NONE: /*linear mode*/
|
||||
pstAeSnsDft->f32Fps = g_astGc030a_mode[GC030A_MODE_640X480P30].f32MaxFps;
|
||||
pstAeSnsDft->f32MinFps = g_astGc030a_mode[GC030A_MODE_640X480P30].f32MinFps;
|
||||
pstAeSnsDft->au8HistThresh[0] = 0xd;
|
||||
pstAeSnsDft->au8HistThresh[1] = 0x28;
|
||||
pstAeSnsDft->au8HistThresh[2] = 0x60;
|
||||
pstAeSnsDft->au8HistThresh[3] = 0x80;
|
||||
|
||||
pstAeSnsDft->u32MaxAgain = 60880;
|
||||
pstAeSnsDft->u32MinAgain = 1024;
|
||||
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
|
||||
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
|
||||
|
||||
pstAeSnsDft->u32MaxDgain = 1024;
|
||||
pstAeSnsDft->u32MinDgain = 1024;
|
||||
pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain;
|
||||
pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;
|
||||
|
||||
pstAeSnsDft->u8AeCompensation = 40;
|
||||
pstAeSnsDft->u32InitAESpeed = 64;
|
||||
pstAeSnsDft->u32InitAETolerance = 5;
|
||||
pstAeSnsDft->u32AEResponseFrame = 4;
|
||||
pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;
|
||||
pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ?
|
||||
g_au32InitExposure[ViPipe] : g_astGc030a_mode[GC030A_MODE_640X480P30].stExp[0].u16Def;
|
||||
|
||||
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8;
|
||||
pstAeSnsDft->u32MinIntTime = g_astGc030a_mode[GC030A_MODE_640X480P30].stExp[0].u16Min;
|
||||
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
|
||||
pstAeSnsDft->u32MinIntTimeTarget = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
CVI_U32 u32VMAX;
|
||||
CVI_FLOAT f32MaxFps = 0;
|
||||
CVI_FLOAT f32MinFps = 0;
|
||||
CVI_U32 u32Vts = 0;
|
||||
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
|
||||
|
||||
CMOS_CHECK_POINTER(pstAeSnsDft);
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
u32Vts = g_astGc030a_mode[pstSnsState->u8ImgMode].u32VtsDef;
|
||||
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
|
||||
f32MaxFps = g_astGc030a_mode[pstSnsState->u8ImgMode].f32MaxFps;
|
||||
f32MinFps = g_astGc030a_mode[pstSnsState->u8ImgMode].f32MinFps;
|
||||
|
||||
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
|
||||
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
u32VMAX = (u32VMAX > GC030A_FULL_LINES_MAX) ? GC030A_FULL_LINES_MAX : u32VMAX;
|
||||
|
||||
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8);
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF);
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
pstSnsState->u32FLStd = u32VMAX;
|
||||
|
||||
pstAeSnsDft->f32Fps = f32Fps;
|
||||
pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2;
|
||||
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
|
||||
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8;
|
||||
pstSnsState->au32FL[0] = pstSnsState->u32FLStd;
|
||||
pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0];
|
||||
pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps));
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
CMOS_CHECK_POINTER(u32IntTime);
|
||||
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
|
||||
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F);
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF);
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static CVI_U32 regValTable[] = {
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
};
|
||||
|
||||
static CVI_U32 gain_table[] = {
|
||||
16 * 64,
|
||||
16 * 96,
|
||||
16 * 127,
|
||||
16 * 157,
|
||||
16 * 197,
|
||||
16 * 226,
|
||||
16 * 259,
|
||||
16 * 287,
|
||||
16 * 318,
|
||||
16 * 356,
|
||||
16 * 391,
|
||||
16 * 419,
|
||||
16 * 450,
|
||||
16 * 480,
|
||||
16 * 513,
|
||||
16 * 646,
|
||||
};
|
||||
|
||||
static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb)
|
||||
{
|
||||
int i;
|
||||
|
||||
UNUSED(ViPipe);
|
||||
CMOS_CHECK_POINTER(pu32AgainLin);
|
||||
CMOS_CHECK_POINTER(pu32AgainDb);
|
||||
int total = ARRAY_SIZE(gain_table);
|
||||
|
||||
if (*pu32AgainLin >= gain_table[total - 1]) {
|
||||
*pu32AgainDb = total - 1;
|
||||
*pu32AgainLin = gain_table[total - 1];
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 0; i < total; i++) {
|
||||
if (*pu32AgainLin < gain_table[i]) {
|
||||
*pu32AgainDb = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pu32AgainLin = gain_table[i - 1];
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pu32DgainLin);
|
||||
CMOS_CHECK_POINTER(pu32DgainDb);
|
||||
UNUSED(ViPipe);
|
||||
|
||||
*pu32DgainLin = 1024;
|
||||
*pu32DgainDb = 0;
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
|
||||
CVI_U32 u32Again;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
CMOS_CHECK_POINTER(pu32Again);
|
||||
CMOS_CHECK_POINTER(pu32Dgain);
|
||||
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
|
||||
/* only surpport linear mode */
|
||||
u32Again = pu32Again[0];
|
||||
|
||||
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = regValTable[u32Again];
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
|
||||
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
|
||||
{
|
||||
UNUSED(ViPipe);
|
||||
UNUSED(u16ManRatioEnable);
|
||||
UNUSED(au32Ratio);
|
||||
UNUSED(au32IntTimeMax);
|
||||
UNUSED(au32IntTimeMin);
|
||||
UNUSED(pu32LFMaxIntTime);
|
||||
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n");
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Only used in LINE_WDR mode */
|
||||
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
|
||||
|
||||
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
|
||||
gu32MaxTimeGetCnt[ViPipe] = 0;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstExpFuncs);
|
||||
|
||||
memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S));
|
||||
|
||||
pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default;
|
||||
pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set;
|
||||
// pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set;
|
||||
pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update;
|
||||
pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update;
|
||||
pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table;
|
||||
pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table;
|
||||
pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max;
|
||||
pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib)
|
||||
{
|
||||
CVI_S32 s32Ret;
|
||||
ISP_SENSOR_REGISTER_S stIspRegister;
|
||||
AE_SENSOR_REGISTER_S stAeRegister;
|
||||
AWB_SENSOR_REGISTER_S stAwbRegister;
|
||||
ISP_SNS_ATTR_INFO_S stSnsAttrInfo;
|
||||
|
||||
(void) pstAeLib;
|
||||
(void) pstAwbLib;
|
||||
|
||||
s32Ret = sensor_ctx_init(ViPipe);
|
||||
|
||||
if (s32Ret != CVI_SUCCESS)
|
||||
return CVI_FAILURE;
|
||||
|
||||
stSnsAttrInfo.eSensorId = GC030A_ID;
|
||||
|
||||
s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp);
|
||||
s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister);
|
||||
|
||||
if (s32Ret != CVI_SUCCESS) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp);
|
||||
s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister);
|
||||
if (s32Ret != CVI_SUCCESS) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp);
|
||||
s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister);
|
||||
|
||||
if (s32Ret != CVI_SUCCESS) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
|
||||
CVI_U8 value;
|
||||
|
||||
GC030A_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER_VOID(pstSnsState);
|
||||
|
||||
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
|
||||
|
||||
/* Apply the setting on the fly */
|
||||
if (pstSnsState->bInit == CVI_TRUE && g_aeGc030a_MirrorFip[ViPipe] != eSnsMirrorFlip) {
|
||||
switch (eSnsMirrorFlip) {
|
||||
case ISP_SNS_NORMAL:
|
||||
value = 0;
|
||||
break;
|
||||
case ISP_SNS_MIRROR:
|
||||
value = 0x01;
|
||||
break;
|
||||
case ISP_SNS_FLIP:
|
||||
value = 0x02;
|
||||
break;
|
||||
case ISP_SNS_MIRROR_FLIP:
|
||||
value = 0x03;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u32Data = value;
|
||||
|
||||
g_aeGc030a_MirrorFip[ViPipe] = eSnsMirrorFlip;
|
||||
}
|
||||
}
|
||||
|
||||
static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib)
|
||||
{
|
||||
CVI_S32 s32Ret;
|
||||
|
||||
(void) pstAeLib;
|
||||
(void) pstAwbLib;
|
||||
|
||||
s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC030A_ID);
|
||||
if (s32Ret != CVI_SUCCESS) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC030A_ID);
|
||||
if (s32Ret != CVI_SUCCESS) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC030A_ID);
|
||||
if (s32Ret != CVI_SUCCESS) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
sensor_ctx_exit(ViPipe);
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr)
|
||||
{
|
||||
CMOS_CHECK_POINTER(pstInitAttr);
|
||||
|
||||
g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure;
|
||||
g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms;
|
||||
g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain;
|
||||
g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain;
|
||||
g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain;
|
||||
g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain;
|
||||
g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain;
|
||||
g_au16Gc030a_GainMode[ViPipe] = pstInitAttr->enGainMode;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static CVI_S32 sensor_probe(VI_PIPE ViPipe)
|
||||
{
|
||||
return gc030a_probe(ViPipe);
|
||||
}
|
||||
|
||||
ISP_SNS_OBJ_S stSnsGc030a_Obj = {
|
||||
.pfnRegisterCallback = sensor_register_callback,
|
||||
.pfnUnRegisterCallback = sensor_unregister_callback,
|
||||
.pfnStandby = CVI_NULL,
|
||||
.pfnRestart = CVI_NULL,
|
||||
.pfnWriteReg = gc030a_write_register,
|
||||
.pfnReadReg = gc030a_read_register,
|
||||
.pfnSetBusInfo = gc030a_set_bus_info,
|
||||
.pfnSetInit = sensor_set_init,
|
||||
.pfnMirrorFlip = sensor_mirror_flip,
|
||||
.pfnPatchRxAttr = sensor_patch_rx_attr,
|
||||
.pfnPatchI2cAddr = sensor_patch_i2c_addr,
|
||||
.pfnGetRxAttr = sensor_rx_attr,
|
||||
.pfnExpSensorCb = cmos_init_sensor_exp_function,
|
||||
.pfnExpAeCb = cmos_init_ae_exp_function,
|
||||
.pfnSnsProbe = sensor_probe,
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef __GC030A_CMOS_EX_H_
|
||||
#define __GC030A_CMOS_EX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_CV182X
|
||||
#include <linux/cvi_vip_cif.h>
|
||||
#include <linux/cvi_vip_snsr.h>
|
||||
#include "cvi_type.h"
|
||||
#else
|
||||
#include <linux/cif_uapi.h>
|
||||
#include <linux/vi_snsr.h>
|
||||
#include <linux/cvi_type.h>
|
||||
#endif
|
||||
#include "cvi_sns_ctrl.h"
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)(x))
|
||||
#endif
|
||||
|
||||
enum gc030a_linear_regs_e {
|
||||
LINEAR_PAGE_0,
|
||||
LINEAR_EXP_H,
|
||||
LINEAR_EXP_L,
|
||||
LINEAR_AGAIN,
|
||||
LINEAR_VTS_H,
|
||||
LINEAR_VTS_L,
|
||||
LINEAR_MIRROR_FLIP,
|
||||
|
||||
LINEAR_REGS_NUM
|
||||
};
|
||||
|
||||
typedef enum _GC030A_MODE_E {
|
||||
GC030A_MODE_640X480P30 = 0,
|
||||
GC030A_MODE_NUM
|
||||
} GC030A_MODE_E;
|
||||
|
||||
typedef struct _GC030A_MODE_S {
|
||||
ISP_WDR_SIZE_S stImg[2];
|
||||
CVI_FLOAT f32MaxFps;
|
||||
CVI_FLOAT f32MinFps;
|
||||
CVI_U32 u32HtsDef;
|
||||
CVI_U32 u32VtsDef;
|
||||
SNS_ATTR_S stExp[2];
|
||||
SNS_ATTR_LARGE_S stAgain[2];
|
||||
SNS_ATTR_LARGE_S stDgain[2];
|
||||
char name[64];
|
||||
} GC030A_MODE_S;
|
||||
|
||||
/****************************************************************************
|
||||
* external variables and functions *
|
||||
****************************************************************************/
|
||||
|
||||
extern ISP_SNS_STATE_S *g_pastGc030a[VI_MAX_PIPE_NUM];
|
||||
extern ISP_SNS_COMMBUS_U g_aunGc030a_BusInfo[];
|
||||
extern CVI_U8 gc030a_i2c_addr;
|
||||
extern const CVI_U32 gc030a_addr_byte;
|
||||
extern const CVI_U32 gc030a_data_byte;
|
||||
extern void gc030a_init(VI_PIPE ViPipe);
|
||||
extern void gc030a_exit(VI_PIPE ViPipe);
|
||||
extern void gc030a_standby(VI_PIPE ViPipe);
|
||||
extern void gc030a_restart(VI_PIPE ViPipe);
|
||||
extern int gc030a_write_register(VI_PIPE ViPipe, int addr, int data);
|
||||
extern int gc030a_read_register(VI_PIPE ViPipe, int addr);
|
||||
extern void gc030a_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip);
|
||||
extern int gc030a_probe(VI_PIPE ViPipe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
|
||||
#endif /* __GC030A_CMOS_EX_H_ */
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef __GC030A_CMOS_PARAM_H_
|
||||
#define __GC030A_CMOS_PARAM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_CV182X
|
||||
#include <linux/cvi_vip_cif.h>
|
||||
#include <linux/cvi_vip_snsr.h>
|
||||
#include "cvi_type.h"
|
||||
#else
|
||||
#include <linux/cif_uapi.h>
|
||||
#include <linux/vi_snsr.h>
|
||||
#include <linux/cvi_type.h>
|
||||
#endif
|
||||
#include "cvi_sns_ctrl.h"
|
||||
#include "gc030a_cmos_ex.h"
|
||||
|
||||
static const GC030A_MODE_S g_astGc030a_mode[GC030A_MODE_NUM] = {
|
||||
[GC030A_MODE_640X480P30] = {
|
||||
.name = "640X480P30",
|
||||
.stImg[0] = {
|
||||
.stSnsSize = {
|
||||
.u32Width = 640,
|
||||
.u32Height = 480,
|
||||
},
|
||||
.stWndRect = {
|
||||
.s32X = 0,
|
||||
.s32Y = 0,
|
||||
.u32Width = 640,
|
||||
.u32Height = 480,
|
||||
},
|
||||
.stMaxSize = {
|
||||
.u32Width = 640,
|
||||
.u32Height = 480,
|
||||
},
|
||||
},
|
||||
.f32MaxFps = 30,
|
||||
.f32MinFps = 0.92, /* 506 * 30 / 0x3FFF */
|
||||
.u32HtsDef = 1579,
|
||||
.u32VtsDef = 506,
|
||||
.stExp[0] = {
|
||||
.u16Min = 1,
|
||||
.u16Max = 1268 - 8,
|
||||
.u16Def = 100,
|
||||
.u16Step = 1,
|
||||
},
|
||||
.stAgain[0] = {
|
||||
.u32Min = 1024,
|
||||
.u32Max = 16 * 646,
|
||||
.u32Def = 1024,
|
||||
.u32Step = 1,
|
||||
},
|
||||
.stDgain[0] = {
|
||||
.u32Min = 1024,
|
||||
.u32Max = 1024,
|
||||
.u32Def = 1024,
|
||||
.u32Step = 1,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
|
||||
.bUpdate = CVI_TRUE,
|
||||
.blcAttr = {
|
||||
.Enable = 1,
|
||||
.enOpType = OP_TYPE_AUTO,
|
||||
.stManual = {256, 256, 256, 256, 0, 0, 0, 0
|
||||
#ifdef ARCH_CV182X
|
||||
, 1092, 1092, 1092, 1092
|
||||
#endif
|
||||
},
|
||||
.stAuto = {
|
||||
{256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 },
|
||||
{256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 },
|
||||
{256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 },
|
||||
{256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 },
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
#ifdef ARCH_CV182X
|
||||
{1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092,
|
||||
1092, 1092},
|
||||
{1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092,
|
||||
1092, 1092},
|
||||
{1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092,
|
||||
1092, 1092},
|
||||
{1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092,
|
||||
1092, 1092},
|
||||
#endif
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
struct combo_dev_attr_s gc030a_rx_attr = {
|
||||
.input_mode = INPUT_MODE_MIPI,
|
||||
.mac_clk = RX_MAC_CLK_200M,
|
||||
.mipi_attr = {
|
||||
.raw_data_type = RAW_DATA_10BIT,
|
||||
.lane_id = {0, 1, -1, -1, -1},
|
||||
.pn_swap = {1, 1, 0, 0, 0},
|
||||
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
|
||||
},
|
||||
.mclk = {
|
||||
.cam = 0,
|
||||
.freq = CAMPLL_FREQ_24M,
|
||||
},
|
||||
.devno = 0,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
|
||||
#endif /* __GC030A_CMOS_PARAM_H_ */
|
||||
@@ -0,0 +1,337 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#ifdef ARCH_CV182X
|
||||
#include <linux/cvi_vip_snsr.h>
|
||||
#include "cvi_comm_video.h"
|
||||
#else
|
||||
#include <linux/vi_snsr.h>
|
||||
#include <linux/cvi_comm_video.h>
|
||||
#endif
|
||||
#include "cvi_sns_ctrl.h"
|
||||
#include "gc030a_cmos_ex.h"
|
||||
|
||||
static void gc030a_linear_480p30_init(VI_PIPE ViPipe);
|
||||
|
||||
#define IMAGE_NO_MIRROR
|
||||
//#define IMAGE_H_MIRROR
|
||||
//#define IMAGE_V_MIRROR
|
||||
//#define IMAGE_HV_MIRROR
|
||||
|
||||
#ifdef IMAGE_NO_MIRROR
|
||||
#define MIRROR 0x54
|
||||
#define STARTY 0x01
|
||||
#define STARTX 0x01
|
||||
#endif
|
||||
|
||||
#ifdef IMAGE_H_MIRROR
|
||||
#define MIRROR 0x55
|
||||
#define STARTY 0x01
|
||||
#define STARTX 0x00
|
||||
#endif
|
||||
|
||||
#ifdef IMAGE_V_MIRROR
|
||||
#define MIRROR 0x56
|
||||
#define STARTY 0x02
|
||||
#define STARTX 0x01
|
||||
#endif
|
||||
|
||||
#ifdef IMAGE_HV_MIRROR
|
||||
#define MIRROR 0x57
|
||||
#define STARTY 0x02
|
||||
#define STARTX 0x00
|
||||
#endif
|
||||
|
||||
CVI_U8 gc030a_i2c_addr = 0x21;
|
||||
const CVI_U32 gc030a_addr_byte = 1;
|
||||
const CVI_U32 gc030a_data_byte = 1;
|
||||
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
|
||||
|
||||
int gc030a_i2c_init(VI_PIPE ViPipe)
|
||||
{
|
||||
char acDevFile[16] = {0};
|
||||
CVI_U8 u8DevNum;
|
||||
|
||||
if (g_fd[ViPipe] >= 0)
|
||||
return CVI_SUCCESS;
|
||||
int ret;
|
||||
|
||||
u8DevNum = g_aunGc030a_BusInfo[ViPipe].s8I2cDev;
|
||||
snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum);
|
||||
|
||||
g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600);
|
||||
|
||||
if (g_fd[ViPipe] < 0) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc030a_i2c_addr);
|
||||
if (ret < 0) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
|
||||
close(g_fd[ViPipe]);
|
||||
g_fd[ViPipe] = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
int gc030a_i2c_exit(VI_PIPE ViPipe)
|
||||
{
|
||||
if (g_fd[ViPipe] >= 0) {
|
||||
close(g_fd[ViPipe]);
|
||||
g_fd[ViPipe] = -1;
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
int gc030a_read_register(VI_PIPE ViPipe, int addr)
|
||||
{
|
||||
int ret, data;
|
||||
CVI_U8 buf[8];
|
||||
CVI_U8 idx = 0;
|
||||
|
||||
if (g_fd[ViPipe] < 0)
|
||||
return CVI_FAILURE;
|
||||
|
||||
if (gc030a_addr_byte == 2)
|
||||
buf[idx++] = (addr >> 8) & 0xff;
|
||||
|
||||
// add address byte 0
|
||||
buf[idx++] = addr & 0xff;
|
||||
|
||||
ret = write(g_fd[ViPipe], buf, gc030a_addr_byte);
|
||||
if (ret < 0) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
buf[1] = 0;
|
||||
ret = read(g_fd[ViPipe], buf, gc030a_data_byte);
|
||||
if (ret < 0) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// pack read back data
|
||||
data = 0;
|
||||
if (gc030a_data_byte == 2) {
|
||||
data = buf[0] << 8;
|
||||
data += buf[1];
|
||||
} else {
|
||||
data = buf[0];
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
int gc030a_write_register(VI_PIPE ViPipe, int addr, int data)
|
||||
{
|
||||
CVI_U8 idx = 0;
|
||||
int ret;
|
||||
CVI_U8 buf[8];
|
||||
|
||||
if (g_fd[ViPipe] < 0)
|
||||
return CVI_SUCCESS;
|
||||
|
||||
if (gc030a_addr_byte == 1) {
|
||||
buf[idx] = addr & 0xff;
|
||||
idx++;
|
||||
}
|
||||
if (gc030a_data_byte == 1) {
|
||||
buf[idx] = data & 0xff;
|
||||
idx++;
|
||||
}
|
||||
|
||||
ret = write(g_fd[ViPipe], buf, gc030a_addr_byte + gc030a_data_byte);
|
||||
if (ret < 0) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
// syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data);
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static void delay_ms(int ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
#define GC030A_CHIP_ID 0x030a
|
||||
#define GC030A_CHIP_ID_ADDR_H 0xf0
|
||||
#define GC030A_CHIP_ID_ADDR_L 0xf1
|
||||
|
||||
int gc030a_probe(VI_PIPE ViPipe)
|
||||
{
|
||||
int nVal;
|
||||
int nVal2;
|
||||
|
||||
usleep(50);
|
||||
if (gc030a_i2c_init(ViPipe) != CVI_SUCCESS)
|
||||
return CVI_FAILURE;
|
||||
|
||||
nVal = gc030a_read_register(ViPipe, GC030A_CHIP_ID_ADDR_H);
|
||||
nVal2 = gc030a_read_register(ViPipe, GC030A_CHIP_ID_ADDR_L);
|
||||
if (nVal < 0 || nVal2 < 0) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
|
||||
return nVal;
|
||||
}
|
||||
|
||||
if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC030A_CHIP_ID) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
printf("%d\n", ViPipe);
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
void gc030a_init(VI_PIPE ViPipe)
|
||||
{
|
||||
gc030a_i2c_init(ViPipe);
|
||||
|
||||
gc030a_linear_480p30_init(ViPipe);
|
||||
|
||||
g_pastGc030a[ViPipe]->bInit = CVI_TRUE;
|
||||
}
|
||||
|
||||
void gc030a_exit(VI_PIPE ViPipe)
|
||||
{
|
||||
gc030a_i2c_exit(ViPipe);
|
||||
}
|
||||
|
||||
static void gc030a_linear_480p30_init(VI_PIPE ViPipe)
|
||||
{
|
||||
/*SYS*/
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x80);
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x80);
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x80);
|
||||
gc030a_write_register(ViPipe, 0xf7, 0x01);
|
||||
gc030a_write_register(ViPipe, 0xf8, 0x05);
|
||||
gc030a_write_register(ViPipe, 0xf9, 0x0f);
|
||||
gc030a_write_register(ViPipe, 0xfa, 0x00);
|
||||
gc030a_write_register(ViPipe, 0xfc, 0x0f);
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x00);
|
||||
|
||||
/*ANALOG & CISCTL*/
|
||||
gc030a_write_register(ViPipe, 0x03, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x04, 0xc8);
|
||||
gc030a_write_register(ViPipe, 0x05, 0x03);
|
||||
gc030a_write_register(ViPipe, 0x06, 0x7b);
|
||||
gc030a_write_register(ViPipe, 0x07, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x08, 0x06);
|
||||
gc030a_write_register(ViPipe, 0x0a, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x0c, 0x08);
|
||||
gc030a_write_register(ViPipe, 0x0d, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x0e, 0xe8);
|
||||
gc030a_write_register(ViPipe, 0x0f, 0x02);
|
||||
gc030a_write_register(ViPipe, 0x10, 0x88);
|
||||
gc030a_write_register(ViPipe, 0x17, MIRROR);//Don't Change Here!!!
|
||||
gc030a_write_register(ViPipe, 0x18, 0x12);
|
||||
gc030a_write_register(ViPipe, 0x19, 0x07);
|
||||
gc030a_write_register(ViPipe, 0x1a, 0x1b);
|
||||
gc030a_write_register(ViPipe, 0x1d, 0x40);
|
||||
gc030a_write_register(ViPipe, 0x1e, 0x50);
|
||||
gc030a_write_register(ViPipe, 0x1f, 0x80);
|
||||
gc030a_write_register(ViPipe, 0x23, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x24, 0xc8);
|
||||
gc030a_write_register(ViPipe, 0x27, 0xaf);
|
||||
gc030a_write_register(ViPipe, 0x28, 0x24);
|
||||
gc030a_write_register(ViPipe, 0x29, 0x1a);
|
||||
gc030a_write_register(ViPipe, 0x2f, 0x14);
|
||||
gc030a_write_register(ViPipe, 0x30, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x31, 0x04);
|
||||
gc030a_write_register(ViPipe, 0x32, 0x08);
|
||||
gc030a_write_register(ViPipe, 0x33, 0x0c);
|
||||
gc030a_write_register(ViPipe, 0x34, 0x0d);
|
||||
gc030a_write_register(ViPipe, 0x35, 0x0e);
|
||||
gc030a_write_register(ViPipe, 0x36, 0x0f);
|
||||
gc030a_write_register(ViPipe, 0x72, 0x98);
|
||||
gc030a_write_register(ViPipe, 0x73, 0x9a);
|
||||
gc030a_write_register(ViPipe, 0x74, 0x47);
|
||||
gc030a_write_register(ViPipe, 0x76, 0x82);
|
||||
gc030a_write_register(ViPipe, 0x7a, 0xcb);
|
||||
gc030a_write_register(ViPipe, 0xc2, 0x0c);
|
||||
gc030a_write_register(ViPipe, 0xce, 0x03);
|
||||
gc030a_write_register(ViPipe, 0xcf, 0x48);
|
||||
gc030a_write_register(ViPipe, 0xd0, 0x10);
|
||||
gc030a_write_register(ViPipe, 0xdc, 0x75);
|
||||
gc030a_write_register(ViPipe, 0xeb, 0x78);
|
||||
|
||||
/*ISP*/
|
||||
gc030a_write_register(ViPipe, 0x90, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x92, STARTY);//Don't Change Here!!!
|
||||
gc030a_write_register(ViPipe, 0x94, STARTX);//Don't Change Here!!!
|
||||
gc030a_write_register(ViPipe, 0x95, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x96, 0xe0);
|
||||
gc030a_write_register(ViPipe, 0x97, 0x02);
|
||||
gc030a_write_register(ViPipe, 0x98, 0x80);
|
||||
|
||||
/*Gain*/
|
||||
gc030a_write_register(ViPipe, 0xb0, 0x46);
|
||||
gc030a_write_register(ViPipe, 0xb1, 0x01);
|
||||
gc030a_write_register(ViPipe, 0xb2, 0x00);
|
||||
gc030a_write_register(ViPipe, 0xb3, 0x40);
|
||||
gc030a_write_register(ViPipe, 0xb4, 0x40);
|
||||
gc030a_write_register(ViPipe, 0xb5, 0x40);
|
||||
gc030a_write_register(ViPipe, 0xb6, 0x00);
|
||||
|
||||
/*BLK*/
|
||||
gc030a_write_register(ViPipe, 0x40, 0x26);
|
||||
gc030a_write_register(ViPipe, 0x4e, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x4f, 0x3c);
|
||||
|
||||
/*Dark Sun*/
|
||||
gc030a_write_register(ViPipe, 0xe0, 0x9f);
|
||||
gc030a_write_register(ViPipe, 0xe1, 0x90);
|
||||
gc030a_write_register(ViPipe, 0xe4, 0x0f);
|
||||
gc030a_write_register(ViPipe, 0xe5, 0xff);
|
||||
|
||||
/*MIPI*/
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x03);
|
||||
gc030a_write_register(ViPipe, 0x10, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x01, 0x03);
|
||||
gc030a_write_register(ViPipe, 0x02, 0x33);
|
||||
gc030a_write_register(ViPipe, 0x03, 0x96);
|
||||
gc030a_write_register(ViPipe, 0x04, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x05, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x06, 0x80);
|
||||
gc030a_write_register(ViPipe, 0x11, 0x2b);
|
||||
gc030a_write_register(ViPipe, 0x12, 0x20);
|
||||
gc030a_write_register(ViPipe, 0x13, 0x03);
|
||||
gc030a_write_register(ViPipe, 0x15, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x21, 0x10);
|
||||
gc030a_write_register(ViPipe, 0x22, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x23, 0x30);
|
||||
gc030a_write_register(ViPipe, 0x24, 0x02);
|
||||
gc030a_write_register(ViPipe, 0x25, 0x12);
|
||||
gc030a_write_register(ViPipe, 0x26, 0x02);
|
||||
gc030a_write_register(ViPipe, 0x29, 0x01);
|
||||
gc030a_write_register(ViPipe, 0x2a, 0x0a);
|
||||
gc030a_write_register(ViPipe, 0x2b, 0x08);
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x00);
|
||||
gc030a_write_register(ViPipe, 0xf9, 0x0e);
|
||||
gc030a_write_register(ViPipe, 0xfc, 0x0e);
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x00);
|
||||
gc030a_write_register(ViPipe, 0x25, 0xa2);
|
||||
gc030a_write_register(ViPipe, 0x3f, 0x1a);
|
||||
delay_ms(100);
|
||||
gc030a_write_register(ViPipe, 0x25, 0xe2);
|
||||
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x03);
|
||||
gc030a_write_register(ViPipe, 0x10, 0x90);
|
||||
gc030a_write_register(ViPipe, 0xfe, 0x00);
|
||||
|
||||
printf("ViPipe:%d,===GC030A 480P 30fps RAW Init OK!===\n", ViPipe);
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ extern ISP_SNS_OBJ_S stSnsBG0808_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsBF2253L_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsCV4001_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsGc02m1_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsGc030a_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsGc0312_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsGc0329_Obj;
|
||||
extern ISP_SNS_OBJ_S stSnsGc1054_Obj;
|
||||
|
||||
@@ -17,6 +17,10 @@ ifeq ($(CONFIG_SENSOR_GCORE_GC02M1), y)
|
||||
KBUILD_DEFINES += -DSENSOR_GCORE_GC02M1
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSOR_GCORE_GC030A), y)
|
||||
KBUILD_DEFINES += -DSENSOR_GCORE_GC030A
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSOR_GCORE_GC0312), y)
|
||||
KBUILD_DEFINES += -DSENSOR_GCORE_GC0312
|
||||
endif
|
||||
|
||||
@@ -182,6 +182,7 @@ typedef enum _SAMPLE_SNS_TYPE_E {
|
||||
BYD_BF2253L_MIPI_1200P_30FPS_10BIT,
|
||||
CVSENS_CV4001_MIPI_4M_1440P_25FPS_12BIT,
|
||||
GCORE_GC02M1_MIPI_2M_30FPS_10BIT,
|
||||
GCORE_GC030A_MIPI_480P_30FPS_10BIT,
|
||||
GCORE_GC0312_MIPI_480P_20FPS_8BIT,
|
||||
GCORE_GC0329_MIPI_480P_10FPS_8BIT,
|
||||
GCORE_GC1054_MIPI_1M_30FPS_10BIT,
|
||||
|
||||
@@ -88,6 +88,7 @@ static const char *snsr_type_name[SAMPLE_SNS_TYPE_BUTT] = {
|
||||
"BYD_BF2253L_MIPI_1200P_30FPS_10BIT",
|
||||
"CVSENS_CV4001_MIPI_4M_1440P_25FPS_12BIT",
|
||||
"GCORE_GC02M1_MIPI_2M_30FPS_10BIT",
|
||||
"GCORE_GC030A_MIPI_480P_30FPS_10BIT",
|
||||
"GCORE_GC0312_MIPI_480P_20FPS_8BIT",
|
||||
"GCORE_GC0329_MIPI_480P_10FPS_8BIT",
|
||||
"GCORE_GC1054_MIPI_1M_30FPS_10BIT",
|
||||
@@ -510,6 +511,7 @@ CVI_S32 SAMPLE_COMM_SNS_GetSize(SAMPLE_SNS_TYPE_E enMode, PIC_SIZE_E *penSize)
|
||||
case SMS_SC035HGS_1L_MIPI_480P_120FPS_10BIT:
|
||||
case GCORE_GC0312_MIPI_480P_20FPS_8BIT:
|
||||
case GCORE_GC0329_MIPI_480P_10FPS_8BIT:
|
||||
case GCORE_GC030A_MIPI_480P_30FPS_10BIT:
|
||||
*penSize = PIC_640x480;
|
||||
break;
|
||||
case PICO640_THERMAL_479P:
|
||||
@@ -910,6 +912,7 @@ CVI_S32 SAMPLE_COMM_SNS_GetDevAttr(SAMPLE_SNS_TYPE_E enSnsType, VI_DEV_ATTR_S *p
|
||||
pstViDevAttr->enBayerFormat = BAYER_FORMAT_BG;
|
||||
break;
|
||||
case GCORE_GC4653_MIPI_720P_60FPS_10BIT:
|
||||
case GCORE_GC030A_MIPI_480P_30FPS_10BIT:
|
||||
pstViDevAttr->enBayerFormat = BAYER_FORMAT_GR;
|
||||
break;
|
||||
case GCORE_OV2685_MIPI_1600x1200_30FPS_10BIT:
|
||||
@@ -1043,6 +1046,7 @@ CVI_S32 SAMPLE_COMM_SNS_GetIspAttrBySns(SAMPLE_SNS_TYPE_E enSnsType, ISP_PUB_ATT
|
||||
case GCORE_GC1084_SLAVE_MIPI_1M_30FPS_10BIT:
|
||||
case GCORE_GC2083_MIPI_2M_30FPS_10BIT:
|
||||
case BYD_BF2253L_MIPI_1200P_30FPS_10BIT:
|
||||
case GCORE_GC030A_MIPI_480P_30FPS_10BIT:
|
||||
pstPubAttr->f32FrameRate = 30;
|
||||
break;
|
||||
case GCORE_GC2145_MIPI_2M_12FPS_8BIT:
|
||||
@@ -1151,6 +1155,10 @@ CVI_S32 SAMPLE_COMM_SNS_GetIspAttrBySns(SAMPLE_SNS_TYPE_E enSnsType, ISP_PUB_ATT
|
||||
pstPubAttr->enBayer = BAYER_BGRGI;
|
||||
break;
|
||||
#endif
|
||||
case GCORE_GC030A_MIPI_480P_30FPS_10BIT:
|
||||
pstPubAttr->enBayer = BAYER_GRBG;
|
||||
pstPubAttr->f32FrameRate = 30;
|
||||
break;
|
||||
case GCORE_GC4653_MIPI_720P_60FPS_10BIT:
|
||||
pstPubAttr->enBayer = BAYER_GRBG;
|
||||
pstPubAttr->f32FrameRate = 60;
|
||||
@@ -1195,6 +1203,10 @@ CVI_VOID *SAMPLE_COMM_SNS_GetSnsObj(SAMPLE_SNS_TYPE_E enSnsType)
|
||||
case GCORE_GC02M1_MIPI_2M_30FPS_10BIT:
|
||||
return &stSnsGc02m1_Obj;
|
||||
#endif
|
||||
#if defined(SENSOR_GCORE_GC030A)
|
||||
case GCORE_GC030A_MIPI_480P_30FPS_10BIT:
|
||||
return &stSnsGc030a_Obj;
|
||||
#endif
|
||||
#if defined(SENSOR_GCORE_GC0312)
|
||||
case GCORE_GC0312_MIPI_480P_20FPS_8BIT:
|
||||
return &stSnsGc0312_Obj;
|
||||
|
||||
@@ -309,6 +309,9 @@ _retry:
|
||||
for (size_t i = 0; i < addr_list.size(); i++) {
|
||||
// log::info("i2c4 addr: 0x%02x", addr_list[i]);
|
||||
switch (addr_list[i]) {
|
||||
case 0x21:
|
||||
snprintf(name, sizeof(name), "gcore_gc030a");
|
||||
return {true, name};
|
||||
case 0x29:
|
||||
// log::info("find gcore_gc4653, addr %#x", addr_list[i]);
|
||||
snprintf(name, sizeof(name), "gcore_gc4653");
|
||||
@@ -387,6 +390,8 @@ _retry:
|
||||
std::vector<int> addr_list = i2c_obj.scan();
|
||||
for (size_t i = 0; i < addr_list.size(); i++) {
|
||||
switch (addr_list[i]) {
|
||||
case 0x21: // gcore_gc030a
|
||||
return {640, 480};
|
||||
case 0x29: // gcore_gc4653
|
||||
return {2560, 1440};
|
||||
case 0x30: // sms_sc035gs
|
||||
@@ -588,6 +593,16 @@ _retry:
|
||||
vi_format = PIXEL_FORMAT_NV21;
|
||||
vi_vpss_format = PIXEL_FORMAT_NV21;
|
||||
err::check_bool_raise(!CVI_BIN_SetBinName(WDR_MODE_NONE, "/mnt/cfg/param/cvi_sdr_bin.gc02m1"), "set config path failed!");
|
||||
} else if (!strcmp(sensor_name, "gcore_gc030a")) {
|
||||
sensor_cfg.sns_type = GCORE_GC030A_MIPI_480P_30FPS_10BIT;
|
||||
sensor_cfg.lane_id = {0, 1, -1, -1, -1};
|
||||
sensor_cfg.pn_swap = {1, 1, 0, 0, 0};
|
||||
sensor_cfg.mclk_en = 1;
|
||||
sensor_cfg.i2c_addr = 0x21;
|
||||
sensor_cfg.exptime_max = 363636;
|
||||
sensor_cfg.exptime_min = 33333;
|
||||
vi_format = PIXEL_FORMAT_NV21;
|
||||
vi_vpss_format = PIXEL_FORMAT_NV21;
|
||||
} else { // default is gcore_gc4653
|
||||
if (width <= 1280 && height <= 720 && fps > 30) {
|
||||
sensor_cfg.sns_type = GCORE_GC4653_MIPI_720P_60FPS_10BIT;
|
||||
@@ -662,6 +677,16 @@ _retry:
|
||||
vi_format = PIXEL_FORMAT_NV21;
|
||||
vi_vpss_format = PIXEL_FORMAT_NV21;
|
||||
err::check_bool_raise(!CVI_BIN_SetBinName(WDR_MODE_NONE, "/mnt/cfg/param/cvi_sdr_bin.gc02m1"), "set config path failed!");
|
||||
} else if (!strcmp(sensor_name, "gcore_gc030a")) {
|
||||
sensor_cfg.sns_type = GCORE_GC030A_MIPI_480P_30FPS_10BIT;
|
||||
sensor_cfg.lane_id = {4, 3, -1, -1, -1};
|
||||
sensor_cfg.pn_swap = {0, 0, 0, 0, 0};
|
||||
sensor_cfg.mclk_en = 1;
|
||||
sensor_cfg.i2c_addr = 0x21;
|
||||
sensor_cfg.exptime_max = 363636;
|
||||
sensor_cfg.exptime_min = 33333;
|
||||
vi_format = PIXEL_FORMAT_NV21;
|
||||
vi_vpss_format = PIXEL_FORMAT_NV21;
|
||||
} else { // default is gcore_gc4653
|
||||
if (width <= 1280 && height <= 720 && fps > 30) {
|
||||
sensor_cfg.sns_type = GCORE_GC4653_MIPI_720P_60FPS_10BIT;
|
||||
|
||||
Reference in New Issue
Block a user