GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
SDK_DIR := $(shell cd $(CURDIR)/../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
objects := isp
objects += svp
objects += ext
objects_clean := $(addsuffix _clean, $(objects))
objects_dumptools := dump_tools
object_dumptools_clean := $(addsuffix _clean, $(objects_dumptools))
.PHONY: all clean $(objects) $(objects_clean) $(objects_dumptools) $(object_dumptools_clean)
all: $(objects) $(objects_dumptools)
clean: $(objects_clean) $(object_dumptools_clean)
$(objects_dumptools):$(objects)
$(AT)$(MAKE) -C $@
$(object_dumptools_clean):
$(AT)$(MAKE) -C $(patsubst %_clean, %, $@) clean
$(objects):
$(AT)$(MAKE) -C $@
$(objects_clean):
$(AT)$(MAKE) -C $(patsubst %_clean, %, $@) clean
+52
View File
@@ -0,0 +1,52 @@
ifeq ($(CFG_XMEDIA_EXPORT_FLAG),)
SDK_DIR := $(shell cd $(CURDIR)/../../../.. && /bin/pwd)
endif
include $(SDK_DIR)/build/base.mk
SYS_LIBS := -lpthread -lm -lc -lrt -ldl -lstdc++
GMP_LIBS += -lxmedia_vpss \
-lxmedia_region \
-lxmedia_vi \
-lxmedia_vgs \
-lxmedia_common \
-lxmedia_tde \
-lxmedia_isp \
-lxmedia_ae \
-lxmedia_venc \
-lxmedia_vo \
-lxmedia_awb \
-lxmedia_svp \
-lxmedia_cl \
-lxmedia_npu \
-lxmedia_flatcc
TOOL_LIBS += -L$(XMEDIA_STATIC_LIB_DIR)
TOOL_LIBS += -Wl,-Bstatic,--start-group $(GMP_LIBS) -Wl,--end-group,-Bdynamic $(SYS_LIBS)
CFLAGS := $(SDK_USR_CFLAGS) $(TOOL_LIBS)
CFLAGS += -I$(SDK_DIR)/source/gmp/include
SRCS := $(wildcard ./*.c)
OBJS := $(patsubst %.c, %.o, $(SRCS))
TARGET := $(OBJS:%.o=%)
.PHONY: all clean
.PHONY : clean all $(SNS)
all: $(TARGET)
$(TARGET):%:%.o
$(AT)$(CC) -o $@ $^ $(CFLAGS)
$(AT)rm $^
%.o : %.c
$(AT)$(CC) -c -o $@ $< $(CFLAGS)
clean:
$(AT)rm -f $(TARGET)
$(AT)rm -f $(OBJS)
Binary file not shown.
+504
View File
@@ -0,0 +1,504 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "xmedia_vi.h"
#include "xmedia_mmz.h"
#include "xmedia_video_common.h"
#define MAX_FRAME_CNT 100
#define MAX_FRAME_WIDTH 3840
#define MAX_WAIT_TIME 1000 // 获取帧最长等待时间,单位ms
#define RAW_DUMP_DEPTH 2
#define FILE_NAME_LEN 256
#define r_printf(fmt, ...) \
do { \
printf("\e[31m\e[1m [%s]-%d: " fmt "\e[0m", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
xmedia_void vi_bayer_dump_usage(xmedia_void)
{
printf("\n"
"***************************************************************\n"
"Usage: ./vi_bayer_dump [pipe] [frame_cnt] [ratio_show]\n"
"pipe: \n"
" 0 ~ 7: Vi pipe 0 ~ 7, default is 0\n"
"frame_cnt: \n"
" The count of frame to be dump, default is 1\n"
"ratio_show: \n"
" Whether the file name of raw show ratio info, default is 0\n"
"e.g: ./vi_bayer_dump 0 1 1\n"
"***************************************************************\n"
"\n");
exit(1);
}
xmedia_s32 get_dump_pipe(xmedia_s32 pipe, xmedia_vi_dev_bind_pipe_attr *dev_bind_pipe)
{
xmedia_s32 ret;
xmedia_s32 dev;
xmedia_s32 i, j;
xmedia_bool is_get_dev = XMEDIA_FALSE;
xmedia_vi_grp_config grp_config;
xmedia_bool is_wdr_pipe = XMEDIA_FALSE;
xmedia_vi_dev_bind_pipe_attr dev_bind_pipe_tmp;
for (i = 0; i < VI_MAX_DEV_NUM; i++) {
ret = xmedia_vi_get_pipe_by_dev(i, &dev_bind_pipe_tmp);
if (ret == XMEDIA_SUCCESS) {
for (j = 0; j < dev_bind_pipe_tmp.pipe_num; j++) {
if (pipe == dev_bind_pipe_tmp.pipe_id[j]) {
dev = i;
is_get_dev = XMEDIA_TRUE;
break;
}
}
}
}
if (is_get_dev == XMEDIA_FALSE) {
r_printf("pipe %d get bind dev failed\n", pipe);
return XMEDIA_FAILURE;
}
memset(dev_bind_pipe, 0, sizeof(xmedia_vi_dev_bind_pipe_attr));
ret = xmedia_vi_get_pipe_by_dev(dev, dev_bind_pipe);
if (ret != XMEDIA_SUCCESS) {
r_printf("xmedia_vi_get_pipe_by_dev failed with 0x%x\n", ret);
return XMEDIA_FAILURE;
}
for (i = 0; i < VI_MAX_GRP_NUM; i++) {
ret = xmedia_vi_get_grp_config(i, &grp_config);
if (ret == XMEDIA_SUCCESS) {
if (grp_config.grp_type == XMEDIA_VI_GRP_TYPE_WDR) {
for (j = 0; j < VI_MAX_WDR_NUM; j++) {
if (grp_config.wdr_grp_config.pipe_id[j] == pipe) {
is_wdr_pipe = XMEDIA_TRUE;
break;
}
}
}
}
}
if (is_wdr_pipe == XMEDIA_FALSE) {
dev_bind_pipe->pipe_num = 1;
dev_bind_pipe->pipe_id[0] = pipe;
}
return XMEDIA_SUCCESS;
}
xmedia_char *compress_mode_to_string(xmedia_video_compress_mode compress_mode)
{
if (compress_mode == XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
return "cmp_none";
} else if (compress_mode == XMEDIA_VIDEO_COMPRESS_MODE_LINE) {
return "cmp_line";
} else if (compress_mode == XMEDIA_VIDEO_COMPRESS_MODE_SEG) {
return "cmp_seg";
} else {
return "cmp_xxx";
}
}
xmedia_u32 data_width_to_num(xmedia_video_data_width data_width)
{
if (data_width == XMEDIA_VIDEO_DATA_WIDTH_8) {
return 8;
} else if (data_width == XMEDIA_VIDEO_DATA_WIDTH_10) {
return 10;
} else if (data_width == XMEDIA_VIDEO_DATA_WIDTH_12) {
return 12;
} else if (data_width == XMEDIA_VIDEO_DATA_WIDTH_14) {
return 14;
} else if (data_width == XMEDIA_VIDEO_DATA_WIDTH_16) {
return 16;
} else {
return 0;
}
}
xmedia_s32 save_uncompress_raw_to_file(xmedia_video_frame *frame, FILE *fd)
{
xmedia_s32 i;
xmedia_u32 row;
xmedia_u32 stride;
xmedia_u64 phy_addr, size;
xmedia_u8 *data = XMEDIA_NULL;
xmedia_u8 *data_tmp = XMEDIA_NULL;
xmedia_u8 *usr_page_addr = XMEDIA_NULL;
xmedia_u16 *buf_tmp = XMEDIA_NULL;
xmedia_u32 tmp;
xmedia_u64 value;
xmedia_u32 out_cnt;
stride = frame->stride.y_stride;
size = stride * frame->height;
phy_addr = frame->addr.y_phy_addr;
usr_page_addr = xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
if (usr_page_addr == XMEDIA_NULL) {
r_printf("mmz map phy 0x%llx size %llu failed\n", phy_addr, size);
return XMEDIA_FAILURE;
}
if (frame->bit_width != XMEDIA_VIDEO_DATA_WIDTH_8 && frame->bit_width != XMEDIA_VIDEO_DATA_WIDTH_16) {
buf_tmp = (xmedia_u16 *)malloc(frame->width * 2); // 文件非紧凑排布,10,12,14bits不超两倍
if (buf_tmp == XMEDIA_NULL) {
r_printf("malloc failed\n");
xmedia_mmz_unmap(usr_page_addr);
return XMEDIA_FAILURE;
}
}
data = usr_page_addr;
printf("saving Y............\n");
for (row = 0; row < frame->height; row++) {
out_cnt = 0;
if (frame->bit_width == XMEDIA_VIDEO_DATA_WIDTH_8) {
fwrite(data, frame->width, 1, fd);
} else if (frame->bit_width == XMEDIA_VIDEO_DATA_WIDTH_16) {
fwrite(data, frame->width, 2, fd);
} else if (frame->bit_width == XMEDIA_VIDEO_DATA_WIDTH_10) {
// 4 pixels consist of 5 bytes
tmp = frame->width / 4;
for (i = 0; i < tmp; i++) {
// byte4 byte3 byte2 byte1 byte0
data_tmp = data + 5 * i;
value = data_tmp[0] + ((xmedia_u32)data_tmp[1] << 8) + ((xmedia_u32)data_tmp[2] << 16) +
((xmedia_u32)data_tmp[3] << 24) + ((xmedia_u64)data_tmp[4] << 32);
buf_tmp[out_cnt++] = value & 0x3ff;
buf_tmp[out_cnt++] = (value >> 10) & 0x3ff;
buf_tmp[out_cnt++] = (value >> 20) & 0x3ff;
buf_tmp[out_cnt++] = (value >> 30) & 0x3ff;
}
fwrite(buf_tmp, frame->width, 2, fd);
} else if (frame->bit_width == XMEDIA_VIDEO_DATA_WIDTH_12) {
// 2 pixels consist of 3 bytes
tmp = frame->width / 2;
for (i = 0; i < tmp; i++) {
// byte2 byte1 byte0
data_tmp = data + 3 * i;
value = data_tmp[0] + ((xmedia_u32)data_tmp[1] << 8) + ((xmedia_u32)data_tmp[2] << 16);
buf_tmp[out_cnt++] = value & 0xfff;
buf_tmp[out_cnt++] = (value >> 12) & 0xfff;
}
fwrite(buf_tmp, frame->width, 2, fd);
} else if (frame->bit_width == XMEDIA_VIDEO_DATA_WIDTH_14) {
// 4 pixels consist of 7 bytes
tmp = frame->width / 4;
for (i = 0; i < tmp; i++) {
// byte6 byte5 byte4 byte3 byte2 byte1 byte0
data_tmp = data + 7 * i;
value = data_tmp[0] + ((xmedia_u32)data_tmp[1] << 8) + ((xmedia_u32)data_tmp[2] << 16) +
((xmedia_u32)data_tmp[3] << 24) + ((xmedia_u64)data_tmp[4] << 32) +
((xmedia_u64)data_tmp[5] << 40) + ((xmedia_u64)data_tmp[6] << 48);
buf_tmp[out_cnt++] = value & 0x3fff;
buf_tmp[out_cnt++] = (value >> 14) & 0x3fff;
buf_tmp[out_cnt++] = (value >> 28) & 0x3fff;
buf_tmp[out_cnt++] = (value >> 42) & 0x3fff;
}
fwrite(buf_tmp, frame->width, 2, fd);
}
data += frame->stride.y_stride;
}
if (frame->bit_width != XMEDIA_VIDEO_DATA_WIDTH_8 && frame->bit_width != XMEDIA_VIDEO_DATA_WIDTH_16) {
free(buf_tmp);
}
xmedia_mmz_unmap(usr_page_addr);
return XMEDIA_SUCCESS;
}
xmedia_s32 save_compress_raw_to_file(xmedia_video_frame *frame, FILE *fd)
{
// todo
return XMEDIA_SUCCESS;
}
xmedia_s32 save_raw_to_file(xmedia_video_frame *frame, FILE *fd)
{
if (frame->compress_mode == XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
return save_uncompress_raw_to_file(frame, fd);
} else {
return save_compress_raw_to_file(frame, fd);
}
}
xmedia_s32 dump_linear_bayer(xmedia_s32 pipe, xmedia_u32 cnt, xmedia_u32 ratio_show)
{
xmedia_s32 i, j;
xmedia_s32 ret;
FILE *fd = NULL;
xmedia_char file_name[FILE_NAME_LEN] = { 0 };
xmedia_video_frame_info *frame_info = XMEDIA_NULL;
frame_info = malloc(sizeof(xmedia_video_frame_info) * cnt);
if (frame_info == XMEDIA_NULL) {
r_printf("malloc failed\n");
return XMEDIA_FAILURE;
}
for (i = 0; i < cnt; i++) {
ret = xmedia_vi_acquire_pipe_frame(pipe, &frame_info[i], MAX_WAIT_TIME);
if (ret != XMEDIA_SUCCESS) {
r_printf("linear: get pipe %d frame failed with 0x%x", pipe, ret);
r_printf("only get %d frames\n", i);
break;
}
printf("linear: get pipe %d frame %d ok\n", pipe, i);
}
if (i == 0) {
free(frame_info);
return XMEDIA_FAILURE;
}
// make file name
if (ratio_show == 0) {
snprintf(file_name, FILE_NAME_LEN, "./vi_pipe_%d_%ux%u_%d_%dbits_%s_%d.raw", pipe, frame_info[0].frame.width,
frame_info[0].frame.height, cnt, data_width_to_num(frame_info[0].frame.bit_width),
compress_mode_to_string(frame_info[0].frame.compress_mode), ratio_show);
} else {
// todo
snprintf(file_name, FILE_NAME_LEN, "./vi_pipe_%d_%ux%u_%d_%dbits_%s_%d.raw", pipe, frame_info[0].frame.width,
frame_info[0].frame.height, cnt, data_width_to_num(frame_info[0].frame.bit_width),
compress_mode_to_string(frame_info[0].frame.compress_mode), ratio_show);
}
fd = fopen(file_name, "wb");
if (fd == NULL) {
r_printf("open file faied\n");
goto failed;
}
// todo,压缩文件,先保存压缩param
for (j = 0; j < i; j++) {
printf("frame %d save start\n", j);
save_raw_to_file(&frame_info[j].frame, fd);
printf("frame %d save completed\n", j);
xmedia_vi_release_pipe_frame(pipe, &frame_info[j]);
}
fclose(fd);
free(frame_info);
return XMEDIA_SUCCESS;
failed:
for (j = 0; j < i; j++) {
xmedia_vi_release_pipe_frame(pipe, &frame_info[j]);
}
free(frame_info);
return XMEDIA_FAILURE;
}
xmedia_s32 dump_wdr_bayer(xmedia_vi_dev_bind_pipe_attr *bind_attr, xmedia_u32 cnt, xmedia_u32 ratio_show)
{
xmedia_s32 i, j, k;
xmedia_s32 ret;
FILE *fd = NULL;
xmedia_u32 frame_cnt = 0;
xmedia_char file_name[FILE_NAME_LEN] = { 0 };
xmedia_video_frame_info *frame_info[VI_MAX_WDR_FRAME_NUM] = { XMEDIA_NULL };
for (i = 0; i < bind_attr->pipe_num; i++) {
frame_info[i] = malloc(sizeof(xmedia_video_frame_info) * cnt);
if (frame_info[i] == XMEDIA_NULL) {
r_printf("pipe %d malloc frame info failed\n", bind_attr->pipe_id[i]);
for (j = 0; j < i; j++) {
free(frame_info[j]);
}
return XMEDIA_FAILURE;
}
}
for (i = 0; i < cnt; i++) {
for (j = 0; j < bind_attr->pipe_num; j++) {
ret = xmedia_vi_acquire_pipe_frame(bind_attr->pipe_id[j], &frame_info[j][i], MAX_WAIT_TIME);
if (ret != XMEDIA_SUCCESS) {
r_printf("wdr: get pipe %d frame failed with 0x%x", bind_attr->pipe_id[j], ret);
r_printf("only get %d frames\n", i);
frame_cnt = i;
for (k = 0; k < bind_attr->pipe_num; k++) {
xmedia_vi_release_pipe_frame(bind_attr->pipe_id[k], &frame_info[k][i]);
goto save_frame;
}
} else {
printf("wdr: get pipe %d frame %d ok\n", bind_attr->pipe_id[j], i);
}
}
}
frame_cnt = i;
// make file name
if (ratio_show == 0) {
snprintf(file_name, FILE_NAME_LEN, "./vi_pipe_%d_%ux%u_%d_%dbits_%s_%d_wdr.raw", bind_attr->pipe_id[0],
frame_info[0][0].frame.width, frame_info[0][0].frame.height, cnt * bind_attr->pipe_num,
data_width_to_num(frame_info[0][0].frame.bit_width),
compress_mode_to_string(frame_info[0][0].frame.compress_mode), ratio_show);
} else {
// todo
snprintf(file_name, FILE_NAME_LEN, "./vi_pipe_%d_%ux%u_%d_%dbits_%s_%d_wdr.raw", bind_attr->pipe_id[0],
frame_info[0][0].frame.width, frame_info[0][0].frame.height, cnt * bind_attr->pipe_num,
data_width_to_num(frame_info[0][0].frame.bit_width),
compress_mode_to_string(frame_info[0][0].frame.compress_mode), ratio_show);
}
fd = fopen(file_name, "wb");
if (fd == NULL) {
r_printf("open file faied\n");
goto end;
}
save_frame:
if (frame_cnt == 0) {
for (i = 0; i < bind_attr->pipe_num; i++) {
free(frame_info[i]);
}
return XMEDIA_FAILURE;
}
for (i = 0; i < frame_cnt; i++) {
for (j = 0; j < bind_attr->pipe_num; j++) {
printf("pipe %d frame %d save start\n", bind_attr->pipe_id[j], i);
save_raw_to_file(&frame_info[j][i].frame, fd);
printf("pipe %d frame %d save completed\n", bind_attr->pipe_id[j], i);
}
}
end:
if (fd != XMEDIA_NULL) {
fclose(fd);
}
for (i = 0; i < frame_cnt; i++) {
for (j = 0; j < bind_attr->pipe_num; j++) {
xmedia_vi_release_pipe_frame(bind_attr->pipe_id[j], &frame_info[j][i]);
}
}
for (i = 0; i < bind_attr->pipe_num; i++) {
free(frame_info[i]);
}
return XMEDIA_SUCCESS;
}
xmedia_s32 main(xmedia_s32 argc, xmedia_char *argv[])
{
xmedia_s32 i;
xmedia_s32 ret;
xmedia_s32 pipe = 0;
xmedia_u32 frame_cnt = 1;
xmedia_u32 ratio_show = 0;
xmedia_vi_dev_bind_pipe_attr dev_bind_pipe;
xmedia_vi_frame_dump_attr dump_attr;
xmedia_vi_frame_dump_attr dump_attr_tmp;
printf("\nNOTIC: this tool only can be used for TESTING !!!\n");
printf("\n To see more usage, please enter: ./vi_bayer_dump -h\n\n");
if (argc > 1) {
if (strncmp(argv[1], "-h", 2) == 0) {
vi_bayer_dump_usage();
exit(XMEDIA_SUCCESS);
} else {
pipe = atoi(argv[1]); // pipe
}
}
if (argc > 2) {
frame_cnt = atoi(argv[2]); // the frame number
if (frame_cnt < 1 || frame_cnt > MAX_FRAME_CNT) {
r_printf("invalid frame cnt %u, range [1, %d]\n", frame_cnt, MAX_FRAME_CNT);
exit(XMEDIA_FAILURE);
}
}
if (argc > 3) {
if (atoi(argv[3]) > 0) {
ratio_show = 1;
} else {
ratio_show = 0;
}
}
ret = xmedia_vi_init();
if (ret != XMEDIA_SUCCESS) {
r_printf("vi init failed !\n");
return ret;
}
ret = get_dump_pipe(pipe, &dev_bind_pipe);
if (ret != XMEDIA_SUCCESS) {
xmedia_vi_exit();
r_printf("get_dump_pipe failed !\n");
return ret;
}
for (i = 0; i < dev_bind_pipe.pipe_num; i++) {
ret = xmedia_vi_get_pipe_frame_dump_attr(dev_bind_pipe.pipe_id[i], &dump_attr_tmp);
if (ret != XMEDIA_SUCCESS) {
xmedia_vi_exit();
r_printf("get pipe %d dump attr failed with 0x%x\n", dev_bind_pipe.pipe_id[i], ret);
return ret;
}
dump_attr.enable = XMEDIA_TRUE;
dump_attr.depth = RAW_DUMP_DEPTH;
ret = xmedia_vi_set_pipe_frame_dump_attr(dev_bind_pipe.pipe_id[i], &dump_attr);
if (ret != XMEDIA_SUCCESS) {
r_printf("set pipe %d dump attr failed with 0x%x\n", dev_bind_pipe.pipe_id[i], ret);
xmedia_vi_exit();
return ret;
}
}
if (dev_bind_pipe.pipe_num == 1) {
dump_linear_bayer(pipe, frame_cnt, ratio_show);
} else {
dump_wdr_bayer(&dev_bind_pipe, frame_cnt, ratio_show);
}
for (i = 0; i < dev_bind_pipe.pipe_num; i++) {
ret = xmedia_vi_set_pipe_frame_dump_attr(dev_bind_pipe.pipe_id[i], &dump_attr_tmp);
if (ret != XMEDIA_SUCCESS) {
r_printf("set pipe %d dump attr failed with 0x%x\n", dev_bind_pipe.pipe_id[i], ret);
xmedia_vi_exit();
return ret;
}
}
xmedia_vi_exit();
return XMEDIA_SUCCESS;
}
Binary file not shown.
+446
View File
@@ -0,0 +1,446 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "xmedia_vi.h"
#include "xmedia_mmz.h"
#include "xmedia_vb.h"
#include "xmedia_vgs.h"
#include "xmedia_video_common.h"
#define MAX_FRAME_CNT 100
#define MAX_FRAME_WIDTH 3840
#define MAX_WAIT_TIME 1000 // 获取帧最长等待时间,单位ms
#define YUV_DUMP_DEPTH 2
#define FILE_NAME_LEN 256
#define PIXEL_NAME_LEN 10
#define VIDEO_FRAME_LEN 20
#define r_printf(fmt, ...) \
do { \
printf("\e[31m\e[1m [%s]-%d: " fmt "\e[0m", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
xmedia_void vi_chn_dump_usage(xmedia_void)
{
printf("\n"
"***************************************************************\n"
"Usage: ./vi_chn_dump [pipe] [chn] [frame_cnt]\n"
"pipe: \n"
" 0 ~ 7: Vi pipe 0 ~ 7\n"
"chn: \n"
" 0: Vi chn\n"
"frame_cnt: \n"
" The count of frame to be dump\n"
"e.g: ./vi_chn_dump 0 0 1\n"
"***************************************************************\n"
"\n");
exit(1);
}
xmedia_s32 make_yuv_file_name(xmedia_s32 pipe, xmedia_s32 chn, xmedia_u32 cnt, xmedia_char *file_name)
{
xmedia_s32 ret;
xmedia_char pixel_format[PIXEL_NAME_LEN];
xmedia_char video_format[VIDEO_FRAME_LEN];
xmedia_video_frame_info frame_info;
ret = xmedia_vi_acquire_chn_frame(pipe, chn, &frame_info, MAX_WAIT_TIME);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d get chn frame failed with 0x%x\n", pipe, chn, ret);
return ret;
}
switch (frame_info.frame.pixel_fmt) {
case XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420:
case XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420:
snprintf(pixel_format, PIXEL_NAME_LEN, "p420");
break;
case XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422:
case XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422:
snprintf(pixel_format, PIXEL_NAME_LEN, "p422");
break;
case XMEDIA_VIDEO_PIXEL_FMT_YUV_400:
snprintf(pixel_format, PIXEL_NAME_LEN, "p400");
break;
default:
snprintf(pixel_format, PIXEL_NAME_LEN, "--");
break;
}
switch (frame_info.frame.video_fmt) {
case XMEDIA_VIDEO_FMT_LINEAR:
snprintf(video_format, VIDEO_FRAME_LEN, "linear");
break;
case XMEDIA_VIDEO_FMT_TILE_32x4:
snprintf(video_format, VIDEO_FRAME_LEN, "tile_32x4");
break;
case XMEDIA_VIDEO_FMT_TILE_64x4:
snprintf(video_format, VIDEO_FRAME_LEN, "tile_64x4");
break;
default:
snprintf(video_format, VIDEO_FRAME_LEN, "--");
break;
}
snprintf(file_name, FILE_NAME_LEN, "./vi_pipe%d_chn%d_%ux%u_%s_%s_%u.yuv", pipe, chn, frame_info.frame.width,
frame_info.frame.height, pixel_format, video_format, cnt);
ret = xmedia_vi_release_chn_frame(pipe, chn, &frame_info);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d release chn frame failed with 0x%x\n", pipe, chn, ret);
return ret;
}
return XMEDIA_SUCCESS;
}
xmedia_s32 save_yuv_8bit_to_file(xmedia_video_frame *frame, FILE *fd)
{
xmedia_u32 width, height, size;
xmedia_u32 c_height;
xmedia_u64 phy_addr;
xmedia_char *usr_page_addr = XMEDIA_NULL;
xmedia_char *y_virt = XMEDIA_NULL;
xmedia_char *c_virt = XMEDIA_NULL;
xmedia_char *mem_offset = XMEDIA_NULL;
xmedia_char buf_tmp[MAX_FRAME_WIDTH];
if (frame->pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420 ||
frame->pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) {
size = frame->stride.y_stride * frame->height * 3 / 2;
c_height = frame->height / 2;
} else if (frame->pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422 ||
frame->pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) {
size = frame->stride.y_stride * frame->height * 2;
c_height = frame->height;
} else if (frame->pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
size = frame->width * frame->height;
c_height = 0;
} else {
r_printf("unknown pixel format %d\n", frame->pixel_fmt);
return XMEDIA_FAILURE;
}
phy_addr = frame->addr.y_phy_addr;
usr_page_addr = xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
if (usr_page_addr == XMEDIA_NULL) {
r_printf("mmz map phy 0x%llx size %u failed\n", phy_addr, size);
return XMEDIA_FAILURE;
}
y_virt = usr_page_addr;
c_virt = y_virt + frame->stride.y_stride * frame->height;
printf("saving......Y......\n");
for (height = 0; height < frame->height; height++) {
mem_offset = y_virt + frame->stride.y_stride * height;
fwrite(mem_offset, frame->width, 1, fd);
}
if (frame->pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
printf("saving......U......\n");
for (height = 0; height < c_height; height++) {
mem_offset = c_virt + frame->stride.c_stride * height;
mem_offset += 1;
for (width = 0; width < frame->width / 2; width++) {
buf_tmp[width] = *mem_offset;
mem_offset += 2;
}
fwrite(buf_tmp, frame->width / 2, 1, fd);
}
printf("saving......V......\n");
for (height = 0; height < c_height; height++) {
mem_offset = c_virt + frame->stride.c_stride * height;
for (width = 0; width < frame->width / 2; width++) {
buf_tmp[width] = *mem_offset;
mem_offset += 2;
}
fwrite(buf_tmp, frame->width / 2, 1, fd);
}
}
printf("done %llu\n", frame->pts);
xmedia_mmz_unmap(usr_page_addr);
return XMEDIA_SUCCESS;
}
xmedia_s32 submit_vgs_to_transform(xmedia_s32 pipe, xmedia_s32 chn, xmedia_video_frame_info *in_frame, FILE *fd)
{
xmedia_s32 ret;
xmedia_vb_base_info base_info;
xmedia_vb_cal_cfg cal_cfg;
xmedia_vb_pool_config pool_config = {0};
xmedia_u32 pool_id;
xmedia_handle vb_handle;
xmedia_u64 phy_addr;
xmedia_s32 handle;
xmedia_vgs_frame_info task_info;
xmedia_video_rotation rot = XMEDIA_VIDEO_ROTATION_0;
xmedia_video_frame_info out_frame;
xmedia_vb_config vb_config = {0};
base_info.align = 0;
base_info.bit_width = in_frame->frame.bit_width;
base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
base_info.width = in_frame->frame.width;
base_info.height = in_frame->frame.height;
base_info.pixel_fmt = in_frame->frame.pixel_fmt;
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d get buffer config failed with 0x%x\n", pipe, chn, ret);
return ret;
}
vb_config.max_pool_cnt = 1;
vb_config.common_pool[0].block_size = cal_cfg.vb_size;
vb_config.common_pool[0].block_cnt = 1;
ret = xmedia_vb_init(&vb_config);
if (ret != XMEDIA_SUCCESS) {
r_printf("vb init failed\n");
return ret;
}
pool_config.block_size = cal_cfg.vb_size;
pool_config.block_cnt = 1;
pool_config.map_mode = XMEDIA_VB_MAP_MODE_NONE;
pool_id = xmedia_vb_create_pool(&pool_config);
if (pool_id == VB_INVALID_POOLID) {
r_printf("pipe %d chn %d create pool failed\n", pipe, chn);
xmedia_vb_exit();
return XMEDIA_FAILURE;
}
vb_handle = xmedia_vb_get_block(pool_id, cal_cfg.vb_size, XMEDIA_NULL);
if (vb_handle == VB_INVALID_HANDLE) {
r_printf("pipe %d chn %d get block failed\n", pipe, chn);
xmedia_vb_exit();
return XMEDIA_FAILURE;
}
phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
memset(&out_frame, 0, sizeof(xmedia_video_frame_info));
out_frame.pool_id = pool_id;
out_frame.mod_id = MOD_ID_VI;
out_frame.frame.addr.y_phy_addr = phy_addr;
out_frame.frame.addr.c_phy_addr = phy_addr + cal_cfg.main_y_size;
out_frame.frame.width = in_frame->frame.width;
out_frame.frame.height = in_frame->frame.height;
out_frame.frame.stride.y_stride = cal_cfg.main_stride;
out_frame.frame.stride.c_stride = cal_cfg.main_stride;
out_frame.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
out_frame.frame.pixel_fmt = in_frame->frame.pixel_fmt;
out_frame.frame.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
out_frame.frame.dynamic_range = in_frame->frame.dynamic_range;
out_frame.frame.pts = in_frame->frame.pts;
out_frame.frame.index = in_frame->frame.index;
ret = xmedia_vgs_init();
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d init failed\n", pipe, chn);
xmedia_vb_release_block(vb_handle);
xmedia_vb_destroy_pool(pool_id);
xmedia_vb_exit();
return ret;
}
ret = xmedia_vgs_create_job(&handle);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d create vgs job failed\n", pipe, chn);
xmedia_vgs_exit();
xmedia_vb_release_block(vb_handle);
xmedia_vb_destroy_pool(pool_id);
xmedia_vb_exit();
return ret;
}
memcpy(&task_info.img_in, in_frame, sizeof(xmedia_video_frame_info));
memcpy(&task_info.img_out, &out_frame, sizeof(xmedia_video_frame_info));
ret = xmedia_vgs_add_task_rotation(handle, &task_info, rot);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d add vgs task failed\n", pipe, chn);
xmedia_vgs_cancel_job(handle);
xmedia_vgs_exit();
xmedia_vb_release_block(vb_handle);
xmedia_vb_destroy_pool(pool_id);
xmedia_vb_exit();
return ret;
}
ret = xmedia_vgs_submit_job(handle);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d submit vgs job failed\n", pipe, chn);
xmedia_vgs_cancel_job(handle);
xmedia_vgs_exit();
xmedia_vb_release_block(vb_handle);
xmedia_vb_destroy_pool(pool_id);
xmedia_vb_exit();
return ret;
}
ret = xmedia_vgs_wait_job(handle, 2000);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d wait vgs job failed\n", pipe, chn);
xmedia_vgs_exit();
xmedia_vb_release_block(vb_handle);
xmedia_vb_destroy_pool(pool_id);
xmedia_vb_exit();
return ret;
}
save_yuv_8bit_to_file(&task_info.img_out.frame, fd);
xmedia_vgs_exit();
xmedia_vb_release_block(vb_handle);
xmedia_vb_destroy_pool(pool_id);
xmedia_vb_exit();
return XMEDIA_SUCCESS;
}
xmedia_void dump_yuv(xmedia_s32 pipe, xmedia_s32 chn, xmedia_u32 cnt)
{
xmedia_s32 ret;
FILE *fd = XMEDIA_NULL;
xmedia_char file_name[FILE_NAME_LEN];
xmedia_video_frame_info frame_info;
ret = make_yuv_file_name(pipe, chn, cnt, file_name);
if (ret != XMEDIA_SUCCESS) {
return;
}
fd = fopen(file_name, "wb");
if (fd == XMEDIA_NULL) {
r_printf("opne file failed\n");
return;
}
while (cnt--) {
ret = xmedia_vi_acquire_chn_frame(pipe, chn, &frame_info, MAX_WAIT_TIME);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d get chn frame %u failed with 0x%x\n", pipe, chn, cnt, ret);
continue;
}
if (frame_info.frame.compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE ||
frame_info.frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
submit_vgs_to_transform(pipe, chn, &frame_info, fd);
} else {
save_yuv_8bit_to_file(&frame_info.frame, fd);
}
ret = xmedia_vi_release_chn_frame(pipe, chn, &frame_info);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d release chn frame %u failed with 0x%x\n", pipe, chn, cnt, ret);
}
}
fclose(fd);
}
xmedia_s32 main(xmedia_s32 argc, xmedia_char *argv[])
{
xmedia_s32 ret;
xmedia_s32 pipe;
xmedia_s32 chn;
xmedia_u32 frame_cnt = 0;
xmedia_u32 origin_depth;
xmedia_u32 depth;
printf("\nNOTIC: this tool only can be used for TESTING !!!\n");
printf("\n To see more usage, please enter: ./vi_chn_dump -h\n\n");
if (argc > 1) {
if (strncmp(argv[1], "-h", 2) == 0) {
vi_chn_dump_usage();
exit(XMEDIA_SUCCESS);
}
}
if (argc < 4) {
vi_chn_dump_usage();
exit(XMEDIA_SUCCESS);
}
pipe = atoi(argv[1]);
if (pipe < 0 || pipe >= VI_MAX_PIPE_NUM) {
r_printf("pipe %d is illegal!\n", pipe);
return XMEDIA_FAILURE;
}
chn = atoi(argv[2]);
if (chn < 0 || chn >= VI_MAX_CHN_NUM) {
r_printf("chn %d is illegal!\n", chn);
return XMEDIA_FAILURE;
}
frame_cnt = atoi(argv[3]);
if (frame_cnt < 0 || frame_cnt > MAX_FRAME_CNT) {
r_printf("frame cnt %d is illegal!\n", frame_cnt);
return XMEDIA_FAILURE;
}
ret = xmedia_vi_init();
if (ret != XMEDIA_SUCCESS) {
r_printf("vi init failed\n");
return ret;
}
ret = xmedia_vi_get_chn_depth(pipe, chn, &origin_depth);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d get chn depth failed with 0x%x", pipe, chn, ret);
xmedia_vi_exit();
return ret;
}
depth = YUV_DUMP_DEPTH;
ret = xmedia_vi_set_chn_depth(pipe, chn, depth);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d set chn depth failed with 0x%x", pipe, chn, ret);
xmedia_vi_exit();
return ret;
}
dump_yuv(pipe, chn, frame_cnt);
depth = origin_depth;
ret = xmedia_vi_set_chn_depth(pipe, chn, depth);
if (ret != XMEDIA_SUCCESS) {
r_printf("pipe %d chn %d set chn depth failed with 0x%x", pipe, chn, ret);
xmedia_vi_exit();
return ret;
}
xmedia_vi_exit();
return XMEDIA_SUCCESS;
}
Binary file not shown.
+289
View File
@@ -0,0 +1,289 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "xmedia_sys.h"
#include "xmedia_mmz.h"
#include "xmedia_vb.h"
#include "xmedia_vo.h"
#define VALUE_BETWEEN(x,min,max) (((x) >= (min)) && ((x) <= (max)))
static volatile sig_atomic_t g_vo_signal_flag = 0;
static xmedia_vo_layer g_vo_layer_id = 0;
static xmedia_vo_chn g_vo_chn_id = 0;
static xmedia_video_frame_info g_vo_frame_info;
static FILE* g_vo_fd = XMEDIA_NULL;
static void vo_dump_8bit_yuv(xmedia_video_frame *video_frame, FILE *fd)
{
unsigned int w, h;
char* virt_addr_y;
char* virt_addr_c;
char* mem_content;
unsigned char tmp_buff[8192];
xmedia_u64 phy_addr;
xmedia_u32 c_height;
xmedia_u32 size;
xmedia_char* page_addr[2];
xmedia_bool uv_invert;
xmedia_video_pixel_format pixel_fmt = video_frame->pixel_fmt;
uv_invert = (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) ? XMEDIA_TRUE : XMEDIA_FALSE;
if (video_frame->compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
video_frame->stride.y_stride = video_frame->width;
video_frame->stride.c_stride = video_frame->width;
}
if ((pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) ||
(pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420)) {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
} else if (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
size = video_frame->stride.y_stride * video_frame->height;
c_height = video_frame->height;
} else {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
}
phy_addr = video_frame->addr.y_phy_addr;
page_addr[0] = (xmedia_char*)xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
if (XMEDIA_NULL == page_addr[0]) {
return;
}
virt_addr_y = page_addr[0];
virt_addr_c = virt_addr_y + (video_frame->stride.y_stride) * (video_frame->height);
fprintf(stderr, "saving......Y......");
fflush(stderr);
for (h = 0; h < video_frame->height; h++) {
mem_content = virt_addr_y + h * video_frame->stride.y_stride;
fwrite(mem_content, video_frame->width, 1, fd);
}
if (pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
fflush(fd);
fprintf(stderr, "U......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (!uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
fflush(fd);
fprintf(stderr, "V......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
}
fflush(fd);
fprintf(stderr, "done!\n");
fflush(stderr);
xmedia_mmz_unmap(page_addr[0]);
page_addr[0] = XMEDIA_NULL;
}
void vo_chn_dump_handle_signal(xmedia_s32 signal)
{
if (g_vo_signal_flag != 0) {
return;
}
if (signal == SIGINT || signal == SIGTERM) {
g_vo_signal_flag = 1;
}
return;
}
xmedia_void vo_misc_dump(xmedia_vo_layer layer_id, xmedia_vo_chn chn_id, xmedia_u32 frame_cnt)
{
xmedia_s32 ret;
xmedia_char yuv_name[128];
xmedia_char pixel_format[10];
xmedia_char sys_chmod[140];
xmedia_s32 millisec = -1;
xmedia_vo_chn_attr chn_attr;
xmedia_s32 i = 0;
ret = xmedia_vo_init();
if (ret != XMEDIA_SUCCESS) {
printf("vo init failed!\n");
return;
}
ret = xmedia_vo_get_chn_attr(layer_id, chn_id, &chn_attr);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get ochn attr failed!\n", layer_id, chn_id);
goto OUT;
}
memset(&g_vo_frame_info, 0, sizeof(xmedia_video_frame_info));
g_vo_frame_info.pool_id = VB_INVALID_POOLID;
for(i = 0;i < frame_cnt;i++) {
if (xmedia_vo_acquire_chn_frame(layer_id, chn_id, &g_vo_frame_info, millisec) != XMEDIA_SUCCESS) {
printf("layer(%d) chn(%d) get frame error for 10 times, now exit!\n", layer_id, chn_id);
goto OUT;
}
if(g_vo_fd == XMEDIA_NULL) {
switch (g_vo_frame_info.frame.pixel_fmt) {
case XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420:
case XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420:
snprintf(pixel_format, 10, "P420");
break;
case XMEDIA_VIDEO_PIXEL_FMT_YUV_400:
snprintf(pixel_format, 10, "YUV400");
break;
default:
snprintf(pixel_format, 10, "P420");
break;
}
snprintf(yuv_name, 128, "./layer%d_chn%d_%dx%d_%s_%d.yuv", layer_id, chn_id,
g_vo_frame_info.frame.width, g_vo_frame_info.frame.height, pixel_format, frame_cnt);
printf("layer(%d) chn(%d) dump frame to file: \"%s\"\n", layer_id, chn_id, yuv_name);
fflush(stdout);
g_vo_fd = fopen(yuv_name, "wb");
if (g_vo_fd == XMEDIA_NULL) {
printf("open file failed:%s!\n", strerror(errno));
goto OUT;
}
}
vo_dump_8bit_yuv(&g_vo_frame_info.frame, g_vo_fd);
ret = xmedia_vo_release_chn_frame(layer_id, chn_id, &g_vo_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("layer(%d) chn(%d) release frame failed!\n", layer_id, chn_id);
goto OUT;
}
memset(&g_vo_frame_info, 0, sizeof(xmedia_video_frame_info));
g_vo_frame_info.pool_id = VB_INVALID_POOLID;
}
sprintf(sys_chmod, "chmod 666 %s", yuv_name);
system(sys_chmod);
OUT:
if(g_vo_fd != XMEDIA_NULL) {
fclose(g_vo_fd);
g_vo_fd = XMEDIA_NULL;
}
if(g_vo_frame_info.pool_id != VB_INVALID_POOLID) {
ret = xmedia_vo_release_chn_frame(layer_id, chn_id, &g_vo_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("layer(%d) chn(%d) release frame failed!\n", layer_id, chn_id);
}
}
xmedia_vo_exit();
return;
}
static void usage(void)
{
printf(
"\n"
"*************************************************\n"
"Usage: ./vo_chn_dump [dev_id] [chn_id] [frame_cnt]\n"
"1)dev_id: \n"
" vo dev id\n"
"2)chn_id: \n"
" vo chn id\n"
"3)frame_cnt: \n"
" the count of frame to be dumped\n"
"*)Example:\n"
" e.g : ./vo_chn_dump 0 0 1\n"
" e.g : ./vo_chn_dump 1 0 2\n"
"*************************************************\n"
"\n");
}
xmedia_s32 main(int argc, char* argv[])
{
xmedia_u32 frame_cnt;
printf("\nNOTICE: This tool only can be used for TESTING !!!\n");
printf("\tTo see more usage, please enter: ./vo_chn_dump -h\n\n");
if (argc > 1) {
if (!strncmp(argv[1], "-h", 2)) {
usage();
exit(XMEDIA_SUCCESS);
}
}
if (argc < 4) {
usage();
exit(XMEDIA_SUCCESS);
}
g_vo_layer_id = atoi(argv[1]);
if (!VALUE_BETWEEN(g_vo_layer_id, 0, XMEDIA_VO_DEV_MAX - 1)) {
printf("vo dev id must be [0,%d]!\n\n", XMEDIA_VO_DEV_MAX - 1);
return -1;
}
g_vo_chn_id = atoi(argv[2]);
if (!VALUE_BETWEEN(g_vo_chn_id, 0, VO_MAX_CHN_NUM - 1)) {
printf("vo chn id must be [0,%d]!\n\n", VO_MAX_CHN_NUM - 1);
return -1;
}
frame_cnt = atoi(argv[3]);
if (frame_cnt < 1) {
printf("frame_cnt can't be small than 1!\n\n");
return -1;
}
g_vo_signal_flag = 0;
g_vo_fd = XMEDIA_NULL;
g_vo_frame_info.pool_id = VB_INVALID_POOLID;
signal(SIGINT, vo_chn_dump_handle_signal);
signal(SIGTERM, vo_chn_dump_handle_signal);
vo_misc_dump(g_vo_layer_id, g_vo_chn_id, frame_cnt);
return XMEDIA_SUCCESS;
}
Binary file not shown.
+280
View File
@@ -0,0 +1,280 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "xmedia_sys.h"
#include "xmedia_mmz.h"
#include "xmedia_vb.h"
#include "xmedia_vo.h"
#define VALUE_BETWEEN(x,min,max) (((x) >= (min)) && ((x) <= (max)))
static volatile sig_atomic_t g_vo_signal_flag = 0;
static xmedia_vo_layer g_vo_layer_id = 0;
static xmedia_video_frame_info g_vo_frame_info;
static FILE* g_vo_fd = XMEDIA_NULL;
static void vo_dump_8bit_yuv(xmedia_video_frame *video_frame, FILE *fd)
{
unsigned int w, h;
char* virt_addr_y;
char* virt_addr_c;
char* mem_content;
unsigned char tmp_buff[8192];
xmedia_u64 phy_addr;
xmedia_u32 c_height;
xmedia_u32 size;
xmedia_char* page_addr[2];
xmedia_bool uv_invert;
xmedia_video_pixel_format pixel_fmt = video_frame->pixel_fmt;
uv_invert = (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) ? XMEDIA_TRUE : XMEDIA_FALSE;
if (video_frame->compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
video_frame->stride.y_stride = video_frame->width;
video_frame->stride.c_stride = video_frame->width;
}
if ((pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) ||
(pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420)) {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
} else if (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
size = video_frame->stride.y_stride * video_frame->height;
c_height = video_frame->height;
} else {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
}
phy_addr = video_frame->addr.y_phy_addr;
page_addr[0] = (xmedia_char*)xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
if (XMEDIA_NULL == page_addr[0]) {
return;
}
virt_addr_y = page_addr[0];
virt_addr_c = virt_addr_y + (video_frame->stride.y_stride) * (video_frame->height);
fprintf(stderr, "saving......Y......");
fflush(stderr);
for (h = 0; h < video_frame->height; h++) {
mem_content = virt_addr_y + h * video_frame->stride.y_stride;
fwrite(mem_content, video_frame->width, 1, fd);
}
if (pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
fflush(fd);
fprintf(stderr, "U......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (!uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
fflush(fd);
fprintf(stderr, "V......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
}
fflush(fd);
fprintf(stderr, "done!\n");
fflush(stderr);
xmedia_mmz_unmap(page_addr[0]);
page_addr[0] = XMEDIA_NULL;
}
void vo_chn_dump_handle_signal(xmedia_s32 signal)
{
if (g_vo_signal_flag != 0) {
return;
}
if (signal == SIGINT || signal == SIGTERM) {
g_vo_signal_flag = 1;
}
return;
}
xmedia_void vo_misc_dump(xmedia_vo_layer layer_id, xmedia_u32 frame_cnt)
{
xmedia_s32 ret;
xmedia_char yuv_name[128];
xmedia_char pixel_format[10];
xmedia_char sys_chmod[140];
xmedia_s32 millisec = -1;
xmedia_s32 i = 0;
xmedia_vo_layer_config layer_config;
ret = xmedia_vo_init();
if (ret != XMEDIA_SUCCESS) {
printf("vo init failed!\n");
return;
}
ret = xmedia_vo_get_layer_config(layer_id, &layer_config);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) get ochn attr failed!\n", layer_id);
goto OUT;
}
memset(&g_vo_frame_info, 0, sizeof(xmedia_video_frame_info));
g_vo_frame_info.pool_id = VB_INVALID_POOLID;
for(i = 0;i < frame_cnt;i++) {
if (xmedia_vo_acquire_layer_frame(layer_id, &g_vo_frame_info, millisec) != XMEDIA_SUCCESS) {
printf("layer(%d) get frame error for 10 times, now exit!\n", layer_id);
goto OUT;
}
if(g_vo_fd == XMEDIA_NULL) {
switch (g_vo_frame_info.frame.pixel_fmt) {
case XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420:
case XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420:
snprintf(pixel_format, 10, "P420");
break;
case XMEDIA_VIDEO_PIXEL_FMT_YUV_400:
snprintf(pixel_format, 10, "YUV400");
break;
default:
snprintf(pixel_format, 10, "P420");
break;
}
snprintf(yuv_name, 128, "./layer%d_%dx%d_%s_%d.yuv", layer_id,
g_vo_frame_info.frame.width, g_vo_frame_info.frame.height, pixel_format, frame_cnt);
printf("layer(%d) dump frame to file: \"%s\"\n", layer_id, yuv_name);
fflush(stdout);
g_vo_fd = fopen(yuv_name, "wb");
if (g_vo_fd == XMEDIA_NULL) {
printf("open file failed:%s!\n", strerror(errno));
goto OUT;
}
}
vo_dump_8bit_yuv(&g_vo_frame_info.frame, g_vo_fd);
ret = xmedia_vo_release_layer_frame(layer_id, &g_vo_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("layer(%d) release frame failed!\n", layer_id);
goto OUT;
}
memset(&g_vo_frame_info, 0, sizeof(xmedia_video_frame_info));
g_vo_frame_info.pool_id = VB_INVALID_POOLID;
}
sprintf(sys_chmod, "chmod 666 %s", yuv_name);
system(sys_chmod);
OUT:
if(g_vo_fd != XMEDIA_NULL) {
fclose(g_vo_fd);
g_vo_fd = XMEDIA_NULL;
}
if(g_vo_frame_info.pool_id != VB_INVALID_POOLID) {
ret = xmedia_vo_release_layer_frame(layer_id, &g_vo_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("layer(%d) release frame failed!\n", layer_id);
}
}
xmedia_vo_exit();
return;
}
static void usage(void)
{
printf(
"\n"
"*************************************************\n"
"Usage: ./vo_chn_dump [dev_id] [frame_cnt]\n"
"1)dev_id: \n"
" vo dev id\n"
"2)frame_cnt: \n"
" the count of frame to be dumped\n"
"*)Example:\n"
" e.g : ./vo_chn_dump 0 1\n"
" e.g : ./vo_chn_dump 1 20\n"
"*************************************************\n"
"\n");
}
xmedia_s32 main(int argc, char* argv[])
{
xmedia_u32 frame_cnt;
printf("\nNOTICE: This tool only can be used for TESTING !!!\n");
printf("\tTo see more usage, please enter: ./vo_chn_dump -h\n\n");
if (argc > 1) {
if (!strncmp(argv[1], "-h", 2)) {
usage();
exit(XMEDIA_SUCCESS);
}
}
if (argc < 3) {
usage();
exit(XMEDIA_SUCCESS);
}
g_vo_layer_id = atoi(argv[1]);
if (!VALUE_BETWEEN(g_vo_layer_id, 0, XMEDIA_VO_DEV_MAX - 1)) {
printf("vo dev id must be [0,%d]!\n\n", XMEDIA_VO_DEV_MAX - 1);
return -1;
}
frame_cnt = atoi(argv[2]);
if (frame_cnt < 1) {
printf("frame_cnt can't be small than 1!\n\n");
return -1;
}
g_vo_signal_flag = 0;
g_vo_fd = XMEDIA_NULL;
g_vo_frame_info.pool_id = VB_INVALID_POOLID;
signal(SIGINT, vo_chn_dump_handle_signal);
signal(SIGTERM, vo_chn_dump_handle_signal);
vo_misc_dump(g_vo_layer_id, frame_cnt);
return XMEDIA_SUCCESS;
}
Binary file not shown.
+569
View File
@@ -0,0 +1,569 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "xmedia_sys.h"
#include "xmedia_mmz.h"
#include "xmedia_vb.h"
#include "xmedia_vpss.h"
#include "xmedia_vgs.h"
#define VALUE_BETWEEN(x,min,max) (((x) >= (min)) && ((x) <= (max)))
#define VPSS_MAX_FRAME_CNT 50
static volatile sig_atomic_t g_vpss_signal_flag = 0;
static xmedia_u32 g_vpss_continuous_dump = 0;
static xmedia_s32 g_vpss_pipe_id = 0;
static xmedia_s32 g_vpss_ichn_id = 0;
static xmedia_video_frame_info g_vpss_frame_info;
static xmedia_video_frame_info g_vpss_multi_frame_info[VPSS_MAX_FRAME_CNT];
static FILE* g_vpss_fd = XMEDIA_NULL;
static void vpss_ichn_dump_8bit_yuv(xmedia_video_frame *video_frame, FILE *fd)
{
unsigned int w, h;
char* virt_addr_y;
char* virt_addr_c;
char* mem_content;
unsigned char tmp_buff[8192];
xmedia_u64 phy_addr;
xmedia_u32 c_height;
xmedia_u32 size;
xmedia_char* page_addr[2];
xmedia_bool uv_invert;
xmedia_video_pixel_format pixel_fmt = video_frame->pixel_fmt;
uv_invert = (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) ? XMEDIA_TRUE : XMEDIA_FALSE;
if (video_frame->compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
video_frame->stride.y_stride = video_frame->width;
video_frame->stride.c_stride = video_frame->width;
}
if ((pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) ||
(pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420)) {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
} else if (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
size = video_frame->stride.y_stride * video_frame->height;
c_height = video_frame->height;
} else {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
}
phy_addr = video_frame->addr.y_phy_addr;
page_addr[0] = (xmedia_char*)xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
if (XMEDIA_NULL == page_addr[0]) {
return;
}
virt_addr_y = page_addr[0];
virt_addr_c = virt_addr_y + (video_frame->stride.y_stride) * (video_frame->height);
fprintf(stderr, "saving......Y......");
fflush(stderr);
for (h = 0; h < video_frame->height; h++) {
mem_content = virt_addr_y + h * video_frame->stride.y_stride;
fwrite(mem_content, video_frame->width, 1, fd);
}
if (pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
fflush(fd);
fprintf(stderr, "U......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (!uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
fflush(fd);
fprintf(stderr, "V......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
}
fflush(fd);
fprintf(stderr, "done!\n");
fflush(stderr);
xmedia_mmz_unmap(page_addr[0]);
page_addr[0] = XMEDIA_NULL;
}
static xmedia_s32 vpss_ichn_restore(xmedia_s32 pipe_id, xmedia_s32 ichn_id)
{
xmedia_s32 ret = XMEDIA_FAILURE;
xmedia_u32 i;
if (g_vpss_continuous_dump == 0) {
if (g_vpss_frame_info.pool_id != VB_INVALID_POOLID) {
ret = xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) release frame failed!\n", pipe_id, ichn_id);
}
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
}
} else {
for (i = 0; i < VPSS_MAX_FRAME_CNT; i++) {
if (g_vpss_multi_frame_info[i].pool_id != VB_INVALID_POOLID) {
ret = xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_multi_frame_info[i]);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) release frame failed!\n", pipe_id, ichn_id);
}
g_vpss_multi_frame_info[i].pool_id = VB_INVALID_POOLID;
}
}
}
if (g_vpss_fd != XMEDIA_NULL) {
fclose(g_vpss_fd);
g_vpss_fd = XMEDIA_NULL;
}
ret = xmedia_vpss_exit();
if (ret != XMEDIA_SUCCESS) {
printf("vpss exit failed!\n");
}
return XMEDIA_SUCCESS;
}
void vpss_ichn_dump_handle_signal(xmedia_s32 signal)
{
if (g_vpss_signal_flag != 0) {
exit(-1);
}
if (signal == SIGINT || signal == SIGTERM) {
g_vpss_signal_flag++;
vpss_ichn_restore(g_vpss_pipe_id, g_vpss_ichn_id);
g_vpss_signal_flag--;
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
}
exit(-1);
}
static xmedia_s32 vpss_ichn_dump_transform_format(xmedia_video_frame_info *frame_in,
xmedia_video_frame_info *frame_out)
{
xmedia_s32 ret;
xmedia_vgs_frame_info task_info;
xmedia_s32 job_handle;
ret = xmedia_vgs_init();
if (ret != XMEDIA_SUCCESS) {
printf("vgs init failed\n");
return ret;
}
ret = xmedia_vgs_create_job(&job_handle);
if (ret != XMEDIA_SUCCESS) {
printf("create vgs job failed\n");
xmedia_vgs_exit();
goto EXIT1;
}
memcpy(&task_info.img_in, frame_in, sizeof(xmedia_video_frame_info));
memcpy(&task_info.img_out, frame_out, sizeof(xmedia_video_frame_info));
ret = xmedia_vgs_add_task_rotation(job_handle, &task_info, XMEDIA_VIDEO_ROTATION_0);
if (ret != XMEDIA_SUCCESS) {
printf("add vgs task failed\n");
goto EXIT2;
}
ret = xmedia_vgs_submit_job(job_handle);
if (ret != XMEDIA_SUCCESS) {
printf("submit vgs job failed\n");
goto EXIT2;
}
ret = xmedia_vgs_wait_job(job_handle, 2000);
if (ret != XMEDIA_SUCCESS) {
printf("wait vgs job failed\n");
goto EXIT1;
}
xmedia_vgs_exit();
return XMEDIA_SUCCESS;
EXIT2:
xmedia_vgs_cancel_job(job_handle);
EXIT1:
xmedia_vgs_exit();
return XMEDIA_FAILURE;
}
static xmedia_void vpss_ichn_uncontinuous_dump(xmedia_s32 pipe_id, xmedia_s32 ichn_id,
xmedia_u32 frame_cnt, xmedia_char *yuv_name)
{
xmedia_s32 ret;
xmedia_u32 cnt = frame_cnt;
xmedia_s32 millisec = -1;
xmedia_handle vb_handle = VB_INVALID_HANDLE;
xmedia_vb_base_info base_info;
xmedia_vb_cal_cfg cal_cfg;
xmedia_video_frame_info frame_out = {0};
while (cnt--) {
if (xmedia_vpss_acquire_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info, millisec) != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) get frame failed!\n", pipe_id, ichn_id);
usleep(1000);
continue;
}
printf("pipe(%d) ichn(%d) save frame %d!\n", pipe_id, ichn_id, cnt);
if (g_vpss_frame_info.frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
base_info.align = 0;
base_info.bit_width = g_vpss_frame_info.frame.bit_width;
base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
base_info.width = g_vpss_frame_info.frame.width;
base_info.height = g_vpss_frame_info.frame.height;
base_info.pixel_fmt = g_vpss_frame_info.frame.pixel_fmt;
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info);
return;
}
vb_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, XMEDIA_NULL);
if (vb_handle == VB_INVALID_HANDLE) {
printf("get block failed\n");
xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info);
return;
}
memcpy(&frame_out, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
frame_out.pool_id = xmedia_vb_handle_to_pool_id(vb_handle);
frame_out.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
frame_out.frame.addr.y_head_phy_addr = frame_out.frame.addr.y_phy_addr;
frame_out.frame.addr.c_phy_addr = frame_out.frame.addr.y_phy_addr + cal_cfg.main_y_size;
frame_out.frame.stride.y_stride = cal_cfg.main_stride;
frame_out.frame.stride.c_stride = cal_cfg.main_stride;
frame_out.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
frame_out.frame.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = vpss_ichn_dump_transform_format(&g_vpss_frame_info, &frame_out);
if (ret != XMEDIA_SUCCESS) {
printf("pipe %d ichn %d vpss_ichn_dump_transform_format failed\n", pipe_id, ichn_id);
xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info);
return;
}
} else {
memcpy(&frame_out, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
}
vpss_ichn_dump_8bit_yuv(&frame_out.frame, g_vpss_fd);
if (g_vpss_frame_info.frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
xmedia_vb_release_block(vb_handle);
}
ret = xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) release frame failed!\n", pipe_id, ichn_id);
return;
}
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
}
return;
}
static xmedia_void vpss_ichn_continuous_dump(xmedia_s32 pipe_id, xmedia_s32 ichn_id,
xmedia_u32 frame_cnt, xmedia_char *yuv_name)
{
xmedia_s32 ret;
xmedia_u32 cnt = frame_cnt;
xmedia_s32 millisec = -1;
xmedia_u32 get_frame_cnt = 0;
xmedia_handle vb_handle = VB_INVALID_HANDLE;
xmedia_vb_base_info base_info;
xmedia_vb_cal_cfg cal_cfg;
xmedia_video_frame_info frame_out = {0};
while (cnt--) {
if (xmedia_vpss_acquire_ichn_frame(pipe_id, ichn_id, &g_vpss_multi_frame_info[get_frame_cnt], millisec) !=
XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) get frame failed!\n", pipe_id, ichn_id);
usleep(1000);
continue;
}
get_frame_cnt++;
if (get_frame_cnt >= VPSS_MAX_FRAME_CNT) {
printf("pipe(%d) ichn(%d) get frame cnt err!\n", pipe_id, ichn_id);
return;
}
}
cnt = 0;
while (cnt < get_frame_cnt) {
printf("pipe(%d) ichn(%d) save frame %d!\n", pipe_id, ichn_id, (get_frame_cnt - cnt - 1));
if (g_vpss_multi_frame_info[cnt].frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
base_info.align = 0;
base_info.bit_width = g_vpss_multi_frame_info[cnt].frame.bit_width;
base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
base_info.width = g_vpss_multi_frame_info[cnt].frame.width;
base_info.height = g_vpss_multi_frame_info[cnt].frame.height;
base_info.pixel_fmt = g_vpss_multi_frame_info[cnt].frame.pixel_fmt;
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_multi_frame_info[cnt]);
return;
}
vb_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, XMEDIA_NULL);
if (vb_handle == VB_INVALID_HANDLE) {
printf("get block failed\n");
xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_multi_frame_info[cnt]);
return;
}
memcpy(&frame_out, &g_vpss_multi_frame_info[cnt], sizeof(xmedia_video_frame_info));
frame_out.pool_id = xmedia_vb_handle_to_pool_id(vb_handle);
frame_out.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
frame_out.frame.addr.y_head_phy_addr = frame_out.frame.addr.y_phy_addr;
frame_out.frame.addr.c_phy_addr = frame_out.frame.addr.y_phy_addr + cal_cfg.main_y_size;
frame_out.frame.stride.y_stride = cal_cfg.main_stride;
frame_out.frame.stride.c_stride = cal_cfg.main_stride;
frame_out.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
frame_out.frame.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = vpss_ichn_dump_transform_format(&g_vpss_multi_frame_info[cnt], &frame_out);
if (ret != XMEDIA_SUCCESS) {
printf("pipe %d ichn %d vpss_ichn_dump_transform_format failed\n", pipe_id, ichn_id);
xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_multi_frame_info[cnt]);
return;
}
} else {
memcpy(&frame_out, &g_vpss_multi_frame_info[cnt], sizeof(xmedia_video_frame_info));
}
vpss_ichn_dump_8bit_yuv(&frame_out.frame, g_vpss_fd);
if (g_vpss_multi_frame_info[cnt].frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
xmedia_vb_release_block(vb_handle);
}
ret = xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_multi_frame_info[cnt]);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) release frame failed!\n", pipe_id, ichn_id);
return;
}
g_vpss_multi_frame_info[cnt].pool_id = VB_INVALID_POOLID;
cnt++;
}
return;
}
xmedia_void vpss_ichn_misc_dump(xmedia_s32 pipe_id, xmedia_s32 ichn_id, xmedia_u32 frame_cnt)
{
xmedia_s32 ret;
xmedia_char yuv_name[128];
xmedia_char pixel_format[10];
xmedia_char sys_chmod[140];
xmedia_u32 cnt = frame_cnt;
xmedia_s32 millisec = -1;
ret = xmedia_vpss_init();
if (ret != XMEDIA_SUCCESS) {
printf("vpss init failed!\n");
return;
}
memset(&g_vpss_frame_info, 0, sizeof(xmedia_video_frame_info));
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
if (xmedia_vpss_acquire_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info, millisec) != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) get frame error, now exit!\n", pipe_id, ichn_id);
goto EXIT;
}
switch (g_vpss_frame_info.frame.pixel_fmt) {
case XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420:
case XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420:
snprintf(pixel_format, 10, "P420");
break;
case XMEDIA_VIDEO_PIXEL_FMT_YUV_400:
snprintf(pixel_format, 10, "YUV400");
break;
default:
snprintf(pixel_format, 10, "P420");
break;
}
snprintf(yuv_name, 128, "./pipe%d_ichn%d_%dx%d_%s_%d.yuv", pipe_id, ichn_id,
g_vpss_frame_info.frame.width, g_vpss_frame_info.frame.height, pixel_format, cnt);
printf("pipe(%d) ichn(%d) dump frame to file: \"%s\"\n", pipe_id, ichn_id, yuv_name);
fflush(stdout);
ret = xmedia_vpss_release_ichn_frame(pipe_id, ichn_id, &g_vpss_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ichn(%d) release frame failed!\n", pipe_id, ichn_id);
goto EXIT;
}
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
g_vpss_fd = fopen(yuv_name, "wb");
if (g_vpss_fd == XMEDIA_NULL) {
printf("open file failed:%s!\n", strerror(errno));
goto EXIT;
}
if (g_vpss_continuous_dump == 0) {
vpss_ichn_uncontinuous_dump(pipe_id, ichn_id, frame_cnt, yuv_name);
} else {
vpss_ichn_continuous_dump(pipe_id, ichn_id, frame_cnt, yuv_name);
}
sprintf(sys_chmod, "chmod 666 %s", yuv_name);
system(sys_chmod);
EXIT:
vpss_ichn_restore(pipe_id, ichn_id);
return;
}
static void usage(void)
{
printf(
"\n"
"*************************************************\n"
"Usage: ./vpss_ichn_dump [pipe_id] [ichn_id] [frame_cnt] [mode]\n"
"1)pipe_id: \n"
" vpss pipe id\n"
"2)ichn_id: \n"
" vpss ichn id\n"
"3)frame_cnt: \n"
" the count of frame to be dumped\n"
"*)Example:\n"
" e.g : ./vpss_ichn_dump 0 0 1\n"
"*************************************************\n"
"\n");
}
xmedia_s32 main(int argc, char* argv[])
{
xmedia_u32 frame_cnt;
xmedia_u32 i;
printf("\nNOTICE: This tool only can be used for TESTING !!!\n");
printf("\tTo see more usage, please enter: ./vpss_ichn_dump -h\n\n");
if (argc > 1) {
if (!strncmp(argv[1], "-h", 2)) {
usage();
exit(XMEDIA_SUCCESS);
}
}
if (argc < 4) {
usage();
exit(XMEDIA_SUCCESS);
}
g_vpss_pipe_id = atoi(argv[1]);
if (!VALUE_BETWEEN(g_vpss_pipe_id, 0, VPSS_MAX_PIPE_NUM - 1)) {
printf("vpss pipe id must be [0,%d]!\n\n", VPSS_MAX_PIPE_NUM - 1);
return -1;
}
g_vpss_ichn_id = atoi(argv[2]);
if (!VALUE_BETWEEN(g_vpss_ichn_id, 0, VPSS_MAX_ICHN_NUM - 1)) {
printf("vpss ichn id must be [0,%d]!\n\n", VPSS_MAX_ICHN_NUM - 1);
return -1;
}
frame_cnt = atoi(argv[3]);
if (frame_cnt < 1) {
printf("frame_cnt can't be small than 1!\n\n");
return -1;
}
if (!VALUE_BETWEEN(g_vpss_continuous_dump, 0, 1)) {
printf("vpss dump mode must be [0,1]!\n\n");
return -1;
}
if ((g_vpss_continuous_dump == 1) && (frame_cnt > VPSS_MAX_FRAME_CNT)) {
printf("frame_cnt must be [1,%d] in continuous mode!\n\n", VPSS_MAX_FRAME_CNT);
return -1;
}
g_vpss_signal_flag = 0;
g_vpss_fd = XMEDIA_NULL;
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
for (i = 0; i < VPSS_MAX_FRAME_CNT; i++) {
g_vpss_multi_frame_info[i].pool_id = VB_INVALID_POOLID;
}
signal(SIGINT, vpss_ichn_dump_handle_signal);
signal(SIGTERM, vpss_ichn_dump_handle_signal);
vpss_ichn_misc_dump(g_vpss_pipe_id, g_vpss_ichn_id, frame_cnt);
return XMEDIA_SUCCESS;
}
Binary file not shown.
+776
View File
@@ -0,0 +1,776 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "xmedia_sys.h"
#include "xmedia_mmz.h"
#include "xmedia_vb.h"
#include "xmedia_vpss.h"
#include "xmedia_vgs.h"
#define VALUE_BETWEEN(x,min,max) (((x) >= (min)) && ((x) <= (max)))
#define VPSS_MAX_FRAME_CNT 50
static xmedia_u32 g_vpss_depth_flag = 0;
static volatile sig_atomic_t g_vpss_signal_flag = 0;
static xmedia_u32 g_vpss_continuous_dump = 0;
static xmedia_s32 g_vpss_pipe_id = 0;
static xmedia_s32 g_vpss_ochn_id = 0;
static xmedia_u32 g_vpss_ori_depth = 0;
static xmedia_video_frame_info g_vpss_frame_info;
static xmedia_video_frame_info g_vpss_multi_frame_info[VPSS_MAX_FRAME_CNT];
static FILE* g_vpss_fd = XMEDIA_NULL;
static void vpss_ochn_dump_8bit_yuv(xmedia_video_frame *video_frame, FILE *fd)
{
unsigned int w, h;
char* virt_addr_y;
char* virt_addr_c;
char* mem_content;
unsigned char tmp_buff[8192];
xmedia_u64 phy_addr;
xmedia_u32 c_height;
xmedia_u32 size;
xmedia_char* page_addr[2];
xmedia_bool uv_invert;
xmedia_video_pixel_format pixel_fmt = video_frame->pixel_fmt;
uv_invert = (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) ? XMEDIA_TRUE : XMEDIA_FALSE;
if (video_frame->compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
video_frame->stride.y_stride = video_frame->width;
video_frame->stride.c_stride = video_frame->width;
}
if ((pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) ||
(pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420)) {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
} else if (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
size = video_frame->stride.y_stride * video_frame->height;
c_height = video_frame->height;
} else {
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
c_height = video_frame->height / 2;
}
phy_addr = video_frame->addr.y_phy_addr;
page_addr[0] = (xmedia_char*)xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
if (XMEDIA_NULL == page_addr[0]) {
return;
}
virt_addr_y = page_addr[0];
virt_addr_c = virt_addr_y + (video_frame->stride.y_stride) * (video_frame->height);
fprintf(stderr, "saving......Y......");
fflush(stderr);
for (h = 0; h < video_frame->height; h++) {
mem_content = virt_addr_y + h * video_frame->stride.y_stride;
fwrite(mem_content, video_frame->width, 1, fd);
}
if (pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
fflush(fd);
fprintf(stderr, "U......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (!uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
fflush(fd);
fprintf(stderr, "V......");
fflush(stderr);
for (h = 0; h < c_height; h++) {
mem_content = virt_addr_c + h * video_frame->stride.c_stride;
if (uv_invert) {
mem_content += 1;
}
for (w = 0; w < video_frame->width / 2; w++) {
tmp_buff[w] = *mem_content;
mem_content += 2;
}
fwrite(tmp_buff, video_frame->width / 2, 1, fd);
}
}
fflush(fd);
fprintf(stderr, "done!\n");
fflush(stderr);
xmedia_mmz_unmap(page_addr[0]);
page_addr[0] = XMEDIA_NULL;
}
static xmedia_s32 vpss_ochn_restore(xmedia_s32 pipe_id, xmedia_s32 ochn_id)
{
xmedia_s32 ret = XMEDIA_FAILURE;
xmedia_u32 i;
if (g_vpss_continuous_dump == 0) {
if (g_vpss_frame_info.pool_id != VB_INVALID_POOLID) {
ret = xmedia_vpss_release_ochn_frame(pipe_id, ochn_id, &g_vpss_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) release frame failed!\n", pipe_id, ochn_id);
}
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
}
} else {
for (i = 0; i < VPSS_MAX_FRAME_CNT; i++) {
if (g_vpss_multi_frame_info[i].pool_id != VB_INVALID_POOLID) {
ret = xmedia_vpss_release_ochn_frame(pipe_id, ochn_id, &g_vpss_multi_frame_info[i]);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) release frame failed!\n", pipe_id, ochn_id);
}
g_vpss_multi_frame_info[i].pool_id = VB_INVALID_POOLID;
}
}
}
if (g_vpss_fd != XMEDIA_NULL) {
fclose(g_vpss_fd);
g_vpss_fd = XMEDIA_NULL;
}
if (g_vpss_depth_flag != 0) {
if (ochn_id < VPSS_MAX_PHY_OCHN_NUM) {
xmedia_vpss_ochn_attr ochn_attr = {0};
ret = xmedia_vpss_get_ochn_attr(pipe_id, ochn_id, &ochn_attr) ;
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get ochn attr failed!\n", pipe_id, ochn_id);
}
ochn_attr.depth = g_vpss_ori_depth;
ret = xmedia_vpss_set_ochn_attr(pipe_id, ochn_id, &ochn_attr) ;
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) set ochn attr failed!\n", pipe_id, ochn_id);
}
} else {
xmedia_vpss_ext_ochn_attr ext_ochn_attr = {0};
ret = xmedia_vpss_get_ext_ochn_attr(pipe_id, ochn_id, &ext_ochn_attr) ;
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get ext ochn attr failed!\n", pipe_id, ochn_id);
}
ext_ochn_attr.depth = g_vpss_ori_depth;
ret = xmedia_vpss_set_ext_ochn_attr(pipe_id, ochn_id, &ext_ochn_attr) ;
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) set ext ochn attr failed!\n", pipe_id, ochn_id);
}
}
g_vpss_depth_flag = 0;
}
ret = xmedia_vpss_exit();
if (ret != XMEDIA_SUCCESS) {
printf("vpss exit failed!\n");
}
return XMEDIA_SUCCESS;
}
void vpss_ochn_dump_handle_signal(xmedia_s32 signal)
{
if (g_vpss_signal_flag != 0) {
exit(-1);
}
if (signal == SIGINT || signal == SIGTERM) {
g_vpss_signal_flag++;
vpss_ochn_restore(g_vpss_pipe_id, g_vpss_ochn_id);
g_vpss_signal_flag--;
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
}
exit(-1);
}
static xmedia_s32 vpss_ochn_dump_transform_format(xmedia_video_frame_info *frame_in,
xmedia_video_frame_info *tmp_frame, xmedia_video_frame_info *frame_out)
{
xmedia_s32 ret;
xmedia_vgs_frame_info task_info;
xmedia_s32 job_handle;
ret = xmedia_vgs_init();
if (ret != XMEDIA_SUCCESS) {
printf("vgs init failed\n");
return ret;
}
ret = xmedia_vgs_create_job(&job_handle);
if (ret != XMEDIA_SUCCESS) {
printf("create vgs job failed\n");
xmedia_vgs_exit();
goto EXIT1;
}
memcpy(&task_info.img_in, tmp_frame, sizeof(xmedia_video_frame_info));
memcpy(&task_info.img_out, frame_out, sizeof(xmedia_video_frame_info));
ret = xmedia_vgs_add_task_rotation(job_handle, &task_info, XMEDIA_VIDEO_ROTATION_0);
if (ret != XMEDIA_SUCCESS) {
printf("add vgs task failed\n");
goto EXIT2;
}
ret = xmedia_vgs_submit_job(job_handle);
if (ret != XMEDIA_SUCCESS) {
printf("submit vgs job failed\n");
goto EXIT2;
}
ret = xmedia_vgs_wait_job(job_handle, 2000);
if (ret != XMEDIA_SUCCESS) {
printf("wait vgs job failed\n");
goto EXIT1;
}
xmedia_vgs_exit();
return XMEDIA_SUCCESS;
EXIT2:
xmedia_vgs_cancel_job(job_handle);
EXIT1:
xmedia_vgs_exit();
return XMEDIA_FAILURE;
}
static xmedia_void vpss_ochn_uncontinuous_dump(xmedia_s32 pipe_id, xmedia_s32 ochn_id,
xmedia_u32 frame_cnt, xmedia_char *yuv_name)
{
xmedia_s32 ret;
xmedia_u32 cnt = frame_cnt;
xmedia_s32 millisec = -1;
xmedia_handle vb_handle = VB_INVALID_HANDLE;
xmedia_handle tmp_handle = VB_INVALID_HANDLE;
xmedia_vb_base_info base_info;
xmedia_vb_cal_cfg cal_cfg;
xmedia_video_frame_info tmp_frame = {0};
xmedia_video_frame_info frame_out = {0};
xmedia_vb_config vb_config = {0};
xmedia_u32 pool_num = 0;
xmedia_s32 vb_pool_init = 0;
while (cnt--) {
if (xmedia_vpss_acquire_ochn_frame(pipe_id, ochn_id, &g_vpss_frame_info, millisec) != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get frame failed!\n", pipe_id, ochn_id);
usleep(1000);
continue;
}
printf("pipe(%d) ochn(%d) video_fmt(%d) save frame %d!\n", pipe_id, ochn_id,
g_vpss_frame_info.frame.video_fmt, cnt);
if (g_vpss_frame_info.frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
base_info.align = 0;
base_info.bit_width = g_vpss_frame_info.frame.bit_width;
base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
base_info.width = g_vpss_frame_info.frame.width;
base_info.height = g_vpss_frame_info.frame.height;
base_info.pixel_fmt = g_vpss_frame_info.frame.pixel_fmt;
if(vb_pool_init == 0) {
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
goto RELEASE;
}
vb_config.common_pool[pool_num].block_size = cal_cfg.vb_size;
vb_config.common_pool[pool_num].block_cnt = 1;
vb_config.common_pool[pool_num].map_mode = XMEDIA_VB_MAP_MODE_NONE;
pool_num++;
vb_config.max_pool_cnt = pool_num;
ret = xmedia_vb_init(&vb_config);
if (ret != XMEDIA_SUCCESS) {
printf("vb init failed\n");
goto RELEASE;
}
vb_pool_init = 1;
}
memcpy(&tmp_frame, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
goto FREEVB;
}
vb_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, XMEDIA_NULL);
if (vb_handle == VB_INVALID_HANDLE) {
printf("get block failed\n");
goto FREEVB;
}
memcpy(&frame_out, &tmp_frame, sizeof(xmedia_video_frame_info));
frame_out.pool_id = xmedia_vb_handle_to_pool_id(vb_handle);
frame_out.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
frame_out.frame.addr.y_head_phy_addr = frame_out.frame.addr.y_phy_addr;
frame_out.frame.addr.c_phy_addr = frame_out.frame.addr.y_phy_addr + cal_cfg.main_y_size;
frame_out.frame.stride.y_stride = cal_cfg.main_stride;
frame_out.frame.stride.c_stride = cal_cfg.main_stride;
frame_out.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
frame_out.frame.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = vpss_ochn_dump_transform_format(&g_vpss_frame_info, &tmp_frame, &frame_out);
if (ret != XMEDIA_SUCCESS) {
printf("pipe %d ochn %d vpss_ochn_dump_transform_format failed\n", pipe_id, ochn_id);
goto FREEVB;
}
} else {
memcpy(&frame_out, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
}
vpss_ochn_dump_8bit_yuv(&frame_out.frame, g_vpss_fd);
FREEVB:
if (tmp_handle != VB_INVALID_HANDLE) {
xmedia_vb_release_block(tmp_handle);
tmp_handle = VB_INVALID_HANDLE;
}
if (vb_handle != VB_INVALID_HANDLE) {
xmedia_vb_release_block(vb_handle);
vb_handle = VB_INVALID_HANDLE;
}
RELEASE:
ret = xmedia_vpss_release_ochn_frame(pipe_id, ochn_id, &g_vpss_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) release frame failed!\n", pipe_id, ochn_id);
break;
}
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
}
if(vb_pool_init == 1) {
ret = xmedia_vb_exit();
if (ret != XMEDIA_SUCCESS) {
printf("vb exit fail!\n");
return;
}
}
return;
}
static xmedia_void vpss_ochn_continuous_dump(xmedia_s32 pipe_id, xmedia_s32 ochn_id,
xmedia_u32 frame_cnt, xmedia_char *yuv_name)
{
xmedia_s32 ret;
xmedia_u32 cnt = frame_cnt;
xmedia_s32 millisec = -1;
xmedia_u32 get_frame_cnt = 0;
xmedia_handle vb_handle = VB_INVALID_HANDLE;
xmedia_handle tmp_handle = VB_INVALID_HANDLE;
xmedia_vb_base_info base_info;
xmedia_vb_cal_cfg cal_cfg;
xmedia_video_frame_info tmp_frame = {0};
xmedia_video_frame_info frame_out = {0};
xmedia_vb_config vb_config = {0};
xmedia_u32 pool_num = 0;
xmedia_s32 vb_pool_init = 0;
while (cnt--) {
if (xmedia_vpss_acquire_ochn_frame(pipe_id, ochn_id, &g_vpss_multi_frame_info[get_frame_cnt], millisec) !=
XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get frame failed!\n", pipe_id, ochn_id);
usleep(1000);
continue;
}
get_frame_cnt++;
if (get_frame_cnt >= VPSS_MAX_FRAME_CNT) {
printf("pipe(%d) ochn(%d) get frame cnt err!\n", pipe_id, ochn_id);
return;
}
}
cnt = 0;
while (cnt < get_frame_cnt) {
printf("pipe(%d) ochn(%d) save frame %d!\n", pipe_id, ochn_id, (get_frame_cnt - cnt - 1));
if (g_vpss_multi_frame_info[cnt].frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
base_info.align = 0;
base_info.bit_width = g_vpss_multi_frame_info[cnt].frame.bit_width;
base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
base_info.width = g_vpss_multi_frame_info[cnt].frame.width;
base_info.height = g_vpss_multi_frame_info[cnt].frame.height;
base_info.pixel_fmt = g_vpss_multi_frame_info[cnt].frame.pixel_fmt;
if(vb_pool_init == 0) {
if (g_vpss_frame_info.frame.video_fmt == XMEDIA_VIDEO_FMT_TILE_16x4) {
base_info.video_fmt = XMEDIA_VIDEO_FMT_TILE_64x4;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
goto RELEASE;
}
vb_config.common_pool[pool_num].block_size = cal_cfg.vb_size;
vb_config.common_pool[pool_num].block_cnt = 1;
vb_config.common_pool[pool_num].map_mode = XMEDIA_VB_MAP_MODE_NONE;
pool_num++;
}
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
goto RELEASE;
}
vb_config.common_pool[pool_num].block_size = cal_cfg.vb_size;
vb_config.common_pool[pool_num].block_cnt = 1;
vb_config.common_pool[pool_num].map_mode = XMEDIA_VB_MAP_MODE_NONE;
pool_num++;
vb_config.max_pool_cnt = pool_num;
ret = xmedia_vb_init(&vb_config);
if (ret != XMEDIA_SUCCESS) {
printf("vb init failed\n");
goto RELEASE;
}
vb_pool_init = 1;
}
if (g_vpss_multi_frame_info[cnt].frame.video_fmt == XMEDIA_VIDEO_FMT_TILE_16x4) {
base_info.video_fmt = XMEDIA_VIDEO_FMT_TILE_64x4;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
goto RELEASE;
}
tmp_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, XMEDIA_NULL);
if (tmp_handle == VB_INVALID_HANDLE) {
printf("get block failed\n");
goto RELEASE;
}
memcpy(&tmp_frame, &g_vpss_multi_frame_info[cnt], sizeof(xmedia_video_frame_info));
tmp_frame.pool_id = xmedia_vb_handle_to_pool_id(tmp_handle);
tmp_frame.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(tmp_handle);
tmp_frame.frame.addr.y_head_phy_addr = tmp_frame.frame.addr.y_phy_addr;
tmp_frame.frame.addr.c_phy_addr = tmp_frame.frame.addr.y_phy_addr + cal_cfg.main_y_size;
tmp_frame.frame.stride.y_stride = cal_cfg.main_stride;
tmp_frame.frame.stride.c_stride = cal_cfg.main_stride;
tmp_frame.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
tmp_frame.frame.video_fmt = XMEDIA_VIDEO_FMT_TILE_64x4;
} else {
memcpy(&tmp_frame, &g_vpss_multi_frame_info[cnt], sizeof(xmedia_video_frame_info));
}
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
if (ret != XMEDIA_SUCCESS) {
printf("get buffer config failed with 0x%x\n", ret);
goto FREEVB;
}
vb_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, XMEDIA_NULL);
if (vb_handle == VB_INVALID_HANDLE) {
printf("get block failed\n");
goto FREEVB;
}
memcpy(&frame_out, &tmp_frame, sizeof(xmedia_video_frame_info));
frame_out.pool_id = xmedia_vb_handle_to_pool_id(vb_handle);
frame_out.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
frame_out.frame.addr.y_head_phy_addr = frame_out.frame.addr.y_phy_addr;
frame_out.frame.addr.c_phy_addr = frame_out.frame.addr.y_phy_addr + cal_cfg.main_y_size;
frame_out.frame.stride.y_stride = cal_cfg.main_stride;
frame_out.frame.stride.c_stride = cal_cfg.main_stride;
frame_out.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
frame_out.frame.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
ret = vpss_ochn_dump_transform_format(&g_vpss_multi_frame_info[cnt], &tmp_frame, &frame_out);
if (ret != XMEDIA_SUCCESS) {
printf("pipe %d ochn %d vpss_ochn_dump_transform_format failed\n", pipe_id, ochn_id);
goto FREEVB;
}
} else {
memcpy(&frame_out, &g_vpss_multi_frame_info[cnt], sizeof(xmedia_video_frame_info));
}
vpss_ochn_dump_8bit_yuv(&frame_out.frame, g_vpss_fd);
FREEVB:
if (tmp_handle != VB_INVALID_HANDLE) {
xmedia_vb_release_block(tmp_handle);
tmp_handle = VB_INVALID_HANDLE;
}
if (vb_handle != VB_INVALID_HANDLE) {
xmedia_vb_release_block(vb_handle);
vb_handle = VB_INVALID_HANDLE;
}
RELEASE:
ret = xmedia_vpss_release_ochn_frame(pipe_id, ochn_id, &g_vpss_multi_frame_info[cnt]);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) release frame failed!\n", pipe_id, ochn_id);
cnt++;
continue;
}
g_vpss_multi_frame_info[cnt].pool_id = VB_INVALID_POOLID;
cnt++;
}
if(vb_pool_init == 1) {
ret = xmedia_vb_exit();
if (ret != XMEDIA_SUCCESS) {
printf("vb exit fail!\n");
return;
}
}
return;
}
xmedia_void vpss_ochn_misc_dump(xmedia_s32 pipe_id, xmedia_s32 ochn_id, xmedia_u32 frame_cnt)
{
xmedia_s32 ret;
xmedia_char yuv_name[128];
xmedia_char pixel_format[10];
xmedia_char sys_chmod[140];
xmedia_u32 cnt = frame_cnt;
xmedia_u32 depth = 1;
xmedia_s32 millisec = -1;
ret = xmedia_vpss_init();
if (ret != XMEDIA_SUCCESS) {
printf("vpss init failed!\n");
return;
}
if (ochn_id < VPSS_MAX_PHY_OCHN_NUM) {
xmedia_vpss_ochn_attr ochn_attr = {0};
ret = xmedia_vpss_get_ochn_attr(pipe_id, ochn_id, &ochn_attr);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get ochn attr failed!\n", pipe_id, ochn_id);
return;
}
g_vpss_ori_depth = ochn_attr.depth;
ochn_attr.depth = depth;
ret = xmedia_vpss_set_ochn_attr(pipe_id, ochn_id, &ochn_attr);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) set ochn attr failed!\n", pipe_id, ochn_id);
vpss_ochn_restore(pipe_id, ochn_id);
return;
}
} else {
xmedia_vpss_ext_ochn_attr ext_ochn_attr = {0};
ret = xmedia_vpss_get_ext_ochn_attr(pipe_id, ochn_id, &ext_ochn_attr);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get ext ochn attr failed!\n", pipe_id, ochn_id);
return;
}
g_vpss_ori_depth = ext_ochn_attr.depth;
ext_ochn_attr.depth = depth;
ret = xmedia_vpss_set_ext_ochn_attr(pipe_id, ochn_id, &ext_ochn_attr);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) set ext ochn attr failed!\n", pipe_id, ochn_id);
vpss_ochn_restore(pipe_id, ochn_id);
return;
}
}
g_vpss_depth_flag = 1;
memset(&g_vpss_frame_info, 0, sizeof(xmedia_video_frame_info));
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
if (xmedia_vpss_acquire_ochn_frame(pipe_id, ochn_id, &g_vpss_frame_info, millisec) != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) get frame error, now exit!\n", pipe_id, ochn_id);
goto EXIT;
}
switch (g_vpss_frame_info.frame.pixel_fmt) {
case XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420:
case XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420:
snprintf(pixel_format, 10, "P420");
break;
case XMEDIA_VIDEO_PIXEL_FMT_YUV_400:
snprintf(pixel_format, 10, "YUV400");
break;
default:
snprintf(pixel_format, 10, "P420");
break;
}
snprintf(yuv_name, 128, "./pipe%d_ochn%d_%dx%d_%s_%d.yuv", pipe_id, ochn_id,
g_vpss_frame_info.frame.width, g_vpss_frame_info.frame.height, pixel_format, cnt);
printf("pipe(%d) ochn(%d) dump frame to file: \"%s\"\n", pipe_id, ochn_id, yuv_name);
fflush(stdout);
ret = xmedia_vpss_release_ochn_frame(pipe_id, ochn_id, &g_vpss_frame_info);
if (ret != XMEDIA_SUCCESS) {
printf("pipe(%d) ochn(%d) release frame failed!\n", pipe_id, ochn_id);
goto EXIT;
}
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
g_vpss_fd = fopen(yuv_name, "wb");
if (g_vpss_fd == XMEDIA_NULL) {
printf("open file failed:%s!\n", strerror(errno));
goto EXIT;
}
if (g_vpss_continuous_dump == 0) {
vpss_ochn_uncontinuous_dump(pipe_id, ochn_id, frame_cnt, yuv_name);
} else {
vpss_ochn_continuous_dump(pipe_id, ochn_id, frame_cnt, yuv_name);
}
sprintf(sys_chmod, "chmod 666 %s", yuv_name);
system(sys_chmod);
EXIT:
vpss_ochn_restore(pipe_id, ochn_id);
return;
}
static void usage(void)
{
printf(
"\n"
"*************************************************\n"
"Usage: ./vpss_ochn_dump [pipe_id] [ochn_id] [frame_cnt] [mode]\n"
"1)pipe_id: \n"
" vpss pipe id\n"
"2)ochn_id: \n"
" vpss ochn id\n"
"3)frame_cnt: \n"
" the count of frame to be dumped\n"
"4)mode: \n"
" 0: uncontinuous dump\n"
" 1: continuous dump\n"
"*)Example:\n"
" e.g : ./vpss_ochn_dump 0 0 1 0\n"
" e.g : ./vpss_ochn_dump 1 0 2 1\n"
"*************************************************\n"
"\n");
}
xmedia_s32 main(int argc, char* argv[])
{
xmedia_u32 frame_cnt;
xmedia_u32 i;
printf("\nNOTICE: This tool only can be used for TESTING !!!\n");
printf("\tTo see more usage, please enter: ./vpss_ochn_dump -h\n\n");
if (argc > 1) {
if (!strncmp(argv[1], "-h", 2)) {
usage();
exit(XMEDIA_SUCCESS);
}
}
if (argc < 5) {
usage();
exit(XMEDIA_SUCCESS);
}
g_vpss_pipe_id = atoi(argv[1]);
if (!VALUE_BETWEEN(g_vpss_pipe_id, 0, VPSS_MAX_PIPE_NUM - 1)) {
printf("vpss pipe id must be [0,%d]!\n\n", VPSS_MAX_PIPE_NUM - 1);
return -1;
}
g_vpss_ochn_id = atoi(argv[2]);
if (!VALUE_BETWEEN(g_vpss_ochn_id, 0, VPSS_MAX_OCHN_NUM - 1)) {
printf("vpss ochn id must be [0,%d]!\n\n", VPSS_MAX_OCHN_NUM - 1);
return -1;
}
frame_cnt = atoi(argv[3]);
if (frame_cnt < 1) {
printf("frame_cnt can't be small than 1!\n\n");
return -1;
}
g_vpss_continuous_dump = atoi(argv[4]);
if (!VALUE_BETWEEN(g_vpss_continuous_dump, 0, 1)) {
printf("vpss dump mode must be [0,1]!\n\n");
return -1;
}
if ((g_vpss_continuous_dump == 1) && (frame_cnt > VPSS_MAX_FRAME_CNT)) {
printf("frame_cnt must be [1,%d] in continuous mode!\n\n", VPSS_MAX_FRAME_CNT);
return -1;
}
g_vpss_depth_flag = 0;
g_vpss_signal_flag = 0;
g_vpss_ori_depth = 0;
g_vpss_fd = XMEDIA_NULL;
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
for (i = 0; i < VPSS_MAX_FRAME_CNT; i++) {
g_vpss_multi_frame_info[i].pool_id = VB_INVALID_POOLID;
}
signal(SIGINT, vpss_ochn_dump_handle_signal);
signal(SIGTERM, vpss_ochn_dump_handle_signal);
vpss_ochn_misc_dump(g_vpss_pipe_id, g_vpss_ochn_id, frame_cnt);
return XMEDIA_SUCCESS;
}
+15
View File
@@ -0,0 +1,15 @@
SDK_DIR ?= $(shell cd $(CURDIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
.PHONY: all clean
all: msensor
clean: msensor_clean
.PHONY: msensor msensor_clean
msensor:
$(AT)$(MAKE) -C msensor
msensor_clean:
$(AT)$(MAKE) -C msensor clean
+19
View File
@@ -0,0 +1,19 @@
SDK_DIR ?= $(shell cd $(CURDIR)/../../../../.. && /bin/pwd)
$(warning SDK_DIR=$(SDK_DIR))
include $(SDK_DIR)/build/base.mk
LIB_NAME := libxmedia_msensor
SRCS := xmedia_msensor.c
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/drv/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/drv/ext/msensor/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/drv/ext/msensor/msensor_mng/include
$(info SDK_USR_CFLAGS=$(SDK_USR_CFLAGS))
$(info SRCS=$(SRCS))
$(info SDK_DIR=$(SDK_DIR))
include $(SDK_DIR)/build/sdk_lib_rules.mk
+298
View File
@@ -0,0 +1,298 @@
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "xmedia_debug.h"
#include "xmedia_msensor.h"
#include "msensor_chip_ioctl.h"
#include "msensor_mng_ioctl.h"
#define MSENSOR_CHIP_NAME "/dev/msensor_chip"
#define MSENSOR_MNG_NAME "/dev/msensor_mng"
static xmedia_bool g_msensor_tgid_init = XMEDIA_FALSE;
static xmedia_s32 g_msensor_chip_fd[XMEDIA_MSENSOR_MAX_DEV_NUM] = { [0 ...(XMEDIA_MSENSOR_MAX_DEV_NUM - 1)] = -1 };
static xmedia_s32 g_msensor_mng_fd[XMEDIA_MSENSOR_MAX_DEV_NUM] = { [0 ...(XMEDIA_MSENSOR_MAX_DEV_NUM - 1)] = -1 };
static pthread_mutex_t g_msensor_mutex = PTHREAD_MUTEX_INITIALIZER;
#define MSENSOR_MUTEX_LOCK() \
do { \
(void)pthread_mutex_lock(&g_msensor_mutex); \
} while (0)
#define MSENSOR_MUTEX_UNLOCK() \
do { \
(void)pthread_mutex_unlock(&g_msensor_mutex); \
} while (0)
#define MSENSOR_TRACE(level, fmt, ...) \
do { \
printf("[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define MSENSOR_CHECK_INIT_RETURN() \
do { \
MSENSOR_MUTEX_LOCK(); \
if (g_msensor_tgid_init != XMEDIA_TRUE) { \
printf("msensor not init!\n"); \
MSENSOR_MUTEX_UNLOCK(); \
return XMEDIA_ERRCODE_NOT_INIT; \
} \
MSENSOR_MUTEX_UNLOCK(); \
} while (0)
static xmedia_s32 msensor_check_dev(xmedia_s32 dev)
{
if ((dev >= XMEDIA_MSENSOR_MAX_DEV_NUM) || (dev < 0)) {
MSENSOR_TRACE(MODULE_DBG_ERR, "dev id(%d) is invalid\r\n", dev);
return XMEDIA_ERRCODE_INVALID_PIPE_ID;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 msensor_check_null_ptr(xmedia_void *ptr)
{
if (ptr == XMEDIA_NULL) {
MSENSOR_TRACE(MODULE_DBG_ERR, "null pointer\n");
return XMEDIA_ERRCODE_NULL_PTR;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 msensor_check_chip_open(xmedia_s32 dev)
{
MSENSOR_MUTEX_LOCK();
if (g_msensor_chip_fd[dev] < 0) {
xmedia_s32 arg = dev;
g_msensor_chip_fd[dev] = open(MSENSOR_CHIP_NAME, O_RDONLY);
if (g_msensor_chip_fd[dev] < 0) {
MSENSOR_MUTEX_UNLOCK();
MSENSOR_TRACE(MODULE_DBG_ERR, "open msensor dev %d err, ret %d\n", dev, g_msensor_chip_fd[dev]);
return XMEDIA_ERRCODE_NOT_READY;
}
if (ioctl(g_msensor_chip_fd[dev], MSENSOR_CMD_CHIP_BIND_FLAG2FD, &arg)) {
close(g_msensor_chip_fd[dev]);
g_msensor_chip_fd[dev] = -1;
MSENSOR_MUTEX_UNLOCK();
MSENSOR_TRACE(MODULE_DBG_ERR, "msensor dev %d, ret %d\n", dev, g_msensor_chip_fd[dev]);
return XMEDIA_ERRCODE_NOT_READY;
}
}
MSENSOR_MUTEX_UNLOCK();
return XMEDIA_SUCCESS;
}
static xmedia_s32 msensor_check_mng_open(xmedia_s32 dev)
{
MSENSOR_MUTEX_LOCK();
if (g_msensor_mng_fd[dev] < 0) {
xmedia_s32 arg = dev;
g_msensor_mng_fd[dev] = open(MSENSOR_MNG_NAME, O_RDONLY);
if (g_msensor_mng_fd[dev] < 0) {
MSENSOR_MUTEX_UNLOCK();
MSENSOR_TRACE(MODULE_DBG_ERR, "open msensor dev %d err, ret %d\n", dev, g_msensor_mng_fd[dev]);
return XMEDIA_ERRCODE_NOT_READY;
}
if (ioctl(g_msensor_mng_fd[dev], MSENSOR_CMD_MNG_BIND_FLAG2FD, &arg)) {
close(g_msensor_mng_fd[dev]);
g_msensor_mng_fd[dev] = -1;
MSENSOR_MUTEX_UNLOCK();
MSENSOR_TRACE(MODULE_DBG_ERR, "msensor dev %d, ret %d\n", dev, g_msensor_mng_fd[dev]);
return XMEDIA_ERRCODE_NOT_READY;
}
}
MSENSOR_MUTEX_UNLOCK();
return XMEDIA_SUCCESS;
}
#define MSENSOR_CHECK_NULL_PTR_RETURN(ptr) \
do { \
xmedia_s32 ret = msensor_check_null_ptr((xmedia_void *)(ptr)); \
if (ret != XMEDIA_SUCCESS) { \
return ret; \
} \
} while (0)
#define MSENSOR_CHECK_DEV_ID_RETURN(dev) \
do { \
xmedia_s32 ret = msensor_check_dev(dev); \
if (ret != XMEDIA_SUCCESS) { \
return ret; \
} \
} while (0)
#define MSENSOR_CHECK_CHIP_OPEN_RETURN(dev) \
do { \
xmedia_s32 ret = msensor_check_chip_open(dev); \
if (ret != XMEDIA_SUCCESS) { \
return ret; \
} \
} while (0)
#define MSENSOR_CHECK_MNG_OPEN_RETURN(dev) \
do { \
xmedia_s32 ret = msensor_check_mng_open(dev); \
if (ret != XMEDIA_SUCCESS) { \
return ret; \
} \
} while (0)
xmedia_s32 xmedia_msensor_init(xmedia_void)
{
MSENSOR_MUTEX_LOCK();
if (g_msensor_tgid_init == XMEDIA_TRUE) {
MSENSOR_MUTEX_UNLOCK();
return XMEDIA_SUCCESS;
}
g_msensor_tgid_init = XMEDIA_TRUE;
MSENSOR_MUTEX_UNLOCK();
return XMEDIA_SUCCESS;
}
xmedia_void xmedia_msensor_exit(xmedia_void)
{
xmedia_s32 i;
MSENSOR_MUTEX_LOCK();
if (g_msensor_tgid_init == XMEDIA_FALSE) {
MSENSOR_MUTEX_UNLOCK();
return ;
}
for (i = 0; i < XMEDIA_MSENSOR_MAX_DEV_NUM; i++) {
if (g_msensor_mng_fd[i] >= 0) {
close(g_msensor_mng_fd[i]);
g_msensor_mng_fd[i] = -1;
}
}
for (i = 0; i < XMEDIA_MSENSOR_MAX_DEV_NUM; i++) {
if (g_msensor_chip_fd[i] >= 0) {
close(g_msensor_chip_fd[i]);
g_msensor_chip_fd[i] = -1;
}
}
g_msensor_tgid_init = XMEDIA_FALSE;
MSENSOR_MUTEX_UNLOCK();
return;
}
xmedia_s32 xmedia_msensor_create_dev(xmedia_s32 dev, const xmedia_msensor_param *param)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_NULL_PTR_RETURN(param);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
return ioctl(g_msensor_chip_fd[dev], MSENSOR_CMD_CREATE, param);
}
xmedia_s32 xmedia_msensor_destroy_dev(xmedia_s32 dev)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
return ioctl(g_msensor_chip_fd[dev], MSENSOR_CMD_DESTROY);
}
xmedia_s32 xmedia_msensor_get_param(xmedia_s32 dev, xmedia_msensor_param *param)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_NULL_PTR_RETURN(param);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
return ioctl(g_msensor_chip_fd[dev], MSENSOR_CMD_GET_PARAM, param);
}
xmedia_s32 xmedia_msensor_start_dev(xmedia_s32 dev)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
return ioctl(g_msensor_chip_fd[dev], MSENSOR_CMD_START);
}
xmedia_s32 xmedia_msensor_stop_dev(xmedia_s32 dev)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
return ioctl(g_msensor_chip_fd[dev], MSENSOR_CMD_STOP);
}
xmedia_s32 xmedia_msensor_add_user(xmedia_s32 dev, xmedia_s32 *user_id)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
MSENSOR_CHECK_MNG_OPEN_RETURN(dev);
return ioctl(g_msensor_mng_fd[dev], MSENSOR_CMD_ADD_USER, user_id);
}
xmedia_s32 xmedia_msensor_delete_user(xmedia_s32 dev, xmedia_s32 user_id)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
MSENSOR_CHECK_MNG_OPEN_RETURN(dev);
return ioctl(g_msensor_mng_fd[dev], MSENSOR_CMD_DELETE_USER, &user_id);
}
xmedia_s32 xmedia_msensor_get_data(xmedia_s32 dev, xmedia_msensor_data_info *data)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_NULL_PTR_RETURN(data);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
MSENSOR_CHECK_MNG_OPEN_RETURN(dev);
return ioctl(g_msensor_mng_fd[dev], MSENSOR_CMD_GET_DATA, data);
}
xmedia_s32 xmedia_msensor_send_data(xmedia_s32 dev, const xmedia_msensor_data_info *data)
{
MSENSOR_CHECK_DEV_ID_RETURN(dev);
MSENSOR_CHECK_NULL_PTR_RETURN(data);
MSENSOR_CHECK_INIT_RETURN();
MSENSOR_CHECK_CHIP_OPEN_RETURN(dev);
MSENSOR_CHECK_MNG_OPEN_RETURN(dev);
return ioctl(g_msensor_mng_fd[dev], MSENSOR_CMD_SEND_DATA, data);
}
+15
View File
@@ -0,0 +1,15 @@
.PHONY: all clean sensor sensor_clean libs libs_clean
all: sensor libs
clean: sensor_clean libs_clean
sensor:
$(AT)$(MAKE) -C sensor
sensor_clean:
$(AT)$(MAKE) -C sensor clean
libs:
$(AT)$(MAKE) -C libs
libs_clean:
$(AT)$(MAKE) -C libs clean
+15
View File
@@ -0,0 +1,15 @@
#ifndef _I2C_DEV_H_
#define _I2C_DEV_H_
#include "xmedia_type.h"
#include "xmedia_errcode.h"
xmedia_s32 i2c_open(xmedia_u8 i2c_dev);
xmedia_s32 i2c_close(xmedia_s32 fd);
xmedia_s32 i2c_set_slave_addr(xmedia_s32 fd, xmedia_u16 slave_addr);
xmedia_s32 i2c_read(xmedia_s32 fd, xmedia_u16 slave_addr, xmedia_u32 read_addr,
xmedia_u8 addr_width, xmedia_u8 *buff, xmedia_u32 length);
xmedia_s32 i2c_write(xmedia_s32 fd, xmedia_u16 slave_addr, xmedia_u8 *buff, xmedia_u32 length);
#endif
+30
View File
@@ -0,0 +1,30 @@
SDK_DIR ?= $(shell cd ../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include config.mk
.PHONY: all clean
all: linux riscv
clean: linux_clean riscv_clean
.PHONY: linux linux_clean
linux:
ifeq ($(LINUX_LIB), TRUE)
make -f Makefile.linux.mk
endif
linux_clean:
ifeq ($(LINUX_LIB), TRUE)
make -f Makefile.linux.mk clean
endif
.PHONY: riscv riscv_clean
riscv:
ifeq ($(RISCV_LIB), TRUE)
make -f Makefile.riscv.mk
endif
riscv_clean:
ifeq ($(RISCV_LIB), TRUE)
make -f Makefile.riscv.mk clean
endif
+38
View File
@@ -0,0 +1,38 @@
SDK_DIR ?= $(shell cd ../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include config.mk
.PHONY: all clean
all: ae awb af
clean: ae_clean awb_clean af_clean
.PHONY: ae ae_clean
ae:
ifneq ($(AE_LIB), )
$(AT)$(MAKE) -C $(AE_LIB)
endif
ae_clean:
ifneq ($(AE_LIB), )
$(AT)$(MAKE) -C $(AE_LIB) clean
endif
.PHONY: awb awb_clean
awb:
ifneq ($(AWB_LIB), )
$(AT)$(MAKE) -C $(AWB_LIB)
endif
awb_clean:
ifneq ($(AWB_LIB), )
$(AT)$(MAKE) -C $(AWB_LIB) clean
endif
.PHONY: af af_clean
af:
ifneq ($(AF_LIB), )
$(AT)$(MAKE) -C $(AF_LIB)
endif
af_clean:
ifneq ($(AF_LIB), )
$(AT)$(MAKE) -C $(AF_LIB) clean
endif
+54
View File
@@ -0,0 +1,54 @@
SDK_DIR ?= $(shell cd ../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include config.mk
MAKEFILE_PATH := $(MCU_MEDIA_DIR)/Makefile
BAK_MAKEFILE_PATH := $(MCU_MEDIA_DIR)/_Makefile.bak
AE_LN_PATH := $(MCU_MEDIA_DIR)/ae
AWB_LN_PATH := $(MCU_MEDIA_DIR)/awb
AF_LN_PATH := $(MCU_MEDIA_DIR)/af
AT := @
define func_generate_makefile
$(AT)test -f $(BAK_MAKEFILE_PATH) || (test -f $(MAKEFILE_PATH) && mv $(MAKEFILE_PATH) $(BAK_MAKEFILE_PATH))
$(AT)touch $(MAKEFILE_PATH)
$(if $(AE_LIB), echo SRCS-y += ae/ > $(MAKEFILE_PATH), )
$(if $(AWB_LIB), echo SRCS-y += awb/ >> $(MAKEFILE_PATH), )
$(if $(AF_LIB), echo SRCS-y += af/ >> $(MAKEFILE_PATH), )
endef
define func_generate_ln_soft
$(if $(AE_LIB), $(AT)test -d $(AE_LN_PATH) || ln -s $(ISP_ALG_DIR)/$(AE_LIB) $(AE_LN_PATH), )
$(if $(AWB_LIB), $(AT)test -d $(AWB_LN_PATH) || ln -s $(ISP_ALG_DIR)/$(AWB_LIB) $(AWB_LN_PATH), )
$(if $(AF_LIB), $(AT)test -d $(AF_LN_PATH) || ln -s $(ISP_ALG_DIR)/$(AF_LIB) $(AF_LN_PATH), )
endef
define func_rm_ln
-rm $(AE_LN_PATH)
-rm $(AWB_LN_PATH)
-rm $(AF_LN_PATH)
endef
define func_restore_makefile
$(AT)test -f $(BAK_MAKEFILE_PATH) && mv $(BAK_MAKEFILE_PATH) $(MAKEFILE_PATH)
endef
define func_cp_lib_to_isp
$(if $(AE_LIB), $(AT)cp $(OUT_DIR)/media/ae/libae.a $(ISP_LIBS_DIR), )
$(if $(AWB_LIB), $(AT)cp $(OUT_DIR)/media/awb/libawb.a $(ISP_LIBS_DIR), )
$(if $(AF_LIB), $(AT)cp $(OUT_DIR)/media/af/libaf.a $(ISP_LIBS_DIR), )
endef
.PHONY: all clean
all:
$(call func_generate_makefile)
$(call func_generate_ln_soft)
$(if $(MCU_DEFCONFIG), $(AT)make -C $(MCU_RISCV_DIR) $(MCU_DEFCONFIG) || echo make failed;, )
$(AT)make -C $(MCU_RISCV_DIR) $(MCU_TARGET) || echo make failed;
$(call func_cp_lib_to_isp)
$(call func_rm_ln)
$(call func_restore_makefile)
clean:;
+2
View File
@@ -0,0 +1,2 @@
ascii_to_lower = $(shell echo $(1) | tr '[:upper:]' '[:lower:]')
CHIPARCH := $(call ascii_to_lower,$(CHIPARCH))
+19
View File
@@ -0,0 +1,19 @@
include common.mk
AE_LIB := sample_ae_v1
AWB_LIB := sample_awb_v1
LINUX_LIB := TRUE
RISCV_LIB := TRUE
MCU_DIR := $(shell cd ../../../../../mcu && pwd)
ISP_ALG_DIR := $(shell pwd)
OUT_DIR := $(MCU_DIR)/riscv/out
ISP_DIR := $(shell cd ../../isp && pwd)
ISP_LIBS_DIR := $(shell cd $(ISP_DIR)/libs/riscv && pwd)
MCU_MEDIA_DIR := $(MCU_DIR)/media
MCU_RISCV_DIR := $(MCU_DIR)/riscv
MCU_DEFCONFIG := xmorca_defconfig
MCU_TARGET := media/libmedia.a
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv.mk
else
include Makefile.linux.mk
endif
@@ -0,0 +1,23 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_ae
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT -DCONFIG_LOG_TRACE_SUPPORT=1
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,16 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd ../../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
default:
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.log.mk
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk
$(AT)$(MAKE) -C $(ISP_DIR)/libs
clean:
$(AT)$(MAKE) -C $(ISP_DIR)/libs clean
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
@@ -0,0 +1,23 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_ae
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,3 @@
SRCS-y += sample_ae_adp.c
@@ -0,0 +1,365 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "xmedia_type.h"
#include "xmedia_ae.h"
#include "sample_ae_adp.h"
#define ISP_AE_MAX_WDR_EXP_RATIO (XMEDIA_ISP_WDR_MAX_EXP_RATIO * 64)
/****************************************************************************
* GLOBAL VARIABLES *
****************************************************************************/
ae_context *g_ae_ctx[XMEDIA_ISP_PIPE_MAX_NUM] = { XMEDIA_NULL };
static const xmedia_ae_exposure_attr default_exposure_attr = {
.bypass = XMEDIA_FALSE,
.op_type = XMEDIA_VIDEO_OPERATION_MODE_AUTO,
.ae_run_interval = 1,
.hist_stat_adjust = XMEDIA_FALSE,
.ae_route_ex_valid = XMEDIA_FALSE,
.prior_frame = XMEDIA_LONG_FRAME,
.ae_gain_sep_cfg = XMEDIA_FALSE,
.manual_attr = { XMEDIA_VIDEO_OPERATION_MODE_MANUAL, XMEDIA_VIDEO_OPERATION_MODE_MANUAL,
XMEDIA_VIDEO_OPERATION_MODE_MANUAL, XMEDIA_VIDEO_OPERATION_MODE_MANUAL, 10000, 1024, 1024, 1024 },
.auto_attr = { { 1000000, 30 },
{ 131072, 1024 },
{ 131072, 1024 },
{ 262144, 1024 },
{ 33554432, 1024 },
102400, 192, 8,
128, 2,
1, 1, 5,
{ 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800, 409600,
819200, 1638400, 3276800 },
{ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
{ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 },
XMEDIA_ISP_AE_STRATEGY_EXP_HIGHLIGHT_PRIOR,
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
XMEDIA_AE_MODE_FIX_FRAME_RATE, { XMEDIA_FALSE, 50, XMEDIA_AE_ANTIFLICKER_NORMAL_MODE },
{ XMEDIA_FALSE, 0 },
{ 0, 0 },
XMEDIA_FALSE, 1024000,
XMEDIA_ISP_WDR_MODE_NORMAL, XMEDIA_FALSE,
100 }
};
/****************************************************************************
* INTERNAL FUNCTION DECLARATION *
****************************************************************************/
static xmedia_void ae_init_ctx(ae_context *ae_ctx, const xmedia_isp_ae_param *ae_param)
{
memcpy(&(ae_ctx->ae_param), ae_param, sizeof(xmedia_isp_ae_param));
}
static xmedia_s32 ae_update_default_param(xmedia_u32 pipe, ae_context *ae_ctx)
{
xmedia_u32 dev_id;
xmedia_s32 ret;
dev_id = ae_ctx->sns_register.dev_id;
ret = ae_ctx->sns_register.func.pfn_sensor_get_ae_default(dev_id, &(ae_ctx->sns_dft));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
ret = ae_ctx->sns_register.func.pfn_sensor_set_fps(dev_id, ae_ctx->ae_param.fps, &(ae_ctx->sns_dft));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
return XMEDIA_SUCCESS;
}
static xmedia_void ae_ext_regs_init(alg_ae_vreg *ae_vreg)
{
// set ext registers as a default value
memcpy(&(ae_vreg->exposure_attr), &default_exposure_attr, sizeof(xmedia_ae_exposure_attr));
return;
}
static xmedia_void ae_read_ext_regs(ae_context *ae_ctx, const alg_ae_vreg *ae_vreg)
{
// read the extregs to the user setting
memcpy(&(ae_ctx->ae_exposure_attr), &(ae_vreg->exposure_attr), sizeof(xmedia_ae_exposure_attr));
return;
}
static xmedia_void ae_calculate_luma_avg(ae_context *ae_ctx)
{
ae_ctx->ae_inner_status.luma_wgt_final = 256 * 56;
}
static xmedia_void ae_calc_exp_target(ae_context *ae_ctx)
{
ae_ctx->ae_inner_status.exp_value_target = 100000;
}
static xmedia_s32 ae_assign_exp_target(ae_context *ae_ctx)
{
ae_param_assign param_assign = { 0 };
param_assign.inttime[0] = 1000;
param_assign.again = 1024;
param_assign.isp_dgain = 1024;
param_assign.dgain = 1024;
memcpy(&(ae_ctx->param_assign), &param_assign, sizeof(ae_param_assign));
return XMEDIA_SUCCESS;
}
static xmedia_void ae_update_param_by_driver(ae_context *ae_ctx)
{
ae_ctx->ae_inner_status.luma_target = ae_ctx->sns_dft.ae_compensation << 8;
return;
}
static xmedia_s32 ae_expo_param_config(ae_context *ae_ctx, ae_param_assign *param_assign)
{
xmedia_s32 ret;
xmedia_u32 inttime_line;
xmedia_u32 dev_id = ae_ctx->sns_register.dev_id;
inttime_line = (xmedia_u64)ae_ctx->sns_dft.lines_per_500ms * param_assign->inttime[0] / 500000;
ret = ae_ctx->sns_register.func.pfn_sensor_update_inttime(dev_id, inttime_line);
AE_CHECK_RET_RETURN(ret);
// ret = ae_ctx->sns_register.func.pfn_sensor_update_gains(dev_id, param_assign->again, param_assign->dgain);
ret =
ae_ctx->sns_register.func.pfn_sensor_update_gains(dev_id, ae_ctx->sns_dft.min_again, ae_ctx->sns_dft.min_dgain);
AE_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_void ae_print_debug_info(ae_context *ae_ctx)
{
AE_TRACE(MODULE_DBG_DEBUG,
"frameCnt:%5llu, lumaCal:%5u, gloAvg:%5u/%5u/%5u, isConverge:%2u,"
" aeParam:%5u/%5u/%5u/%5u/",
ae_ctx->ae_info.frame_cnt, ae_ctx->ae_inner_status.luma_wgt_final,
ae_ctx->ae_info.fe_ae_stat_global_avg->global_avg[0][1],
ae_ctx->ae_info.fe_ae_stat_global_avg->global_avg[1][1],
ae_ctx->ae_info.be_ae_stat_global_avg->global_avg[1], ae_ctx->ae_inner_status.is_ae_converge,
ae_ctx->param_assign.inttime[0], ae_ctx->param_assign.again, ae_ctx->param_assign.dgain,
ae_ctx->param_assign.isp_dgain);
}
static xmedia_void ae_record_calc_result(ae_context *ae_ctx, xmedia_isp_ae_result *pstAeResult,
ae_param_assign *param_assign)
{
// fill the result after calculate
pstAeResult->iso = 100;
pstAeResult->int_time[0] = ae_ctx->param_assign.inttime[0];
pstAeResult->again = ae_ctx->param_assign.again;
pstAeResult->dgain = ae_ctx->param_assign.dgain;
pstAeResult->isp_dgain = ae_ctx->param_assign.isp_dgain >> 2;
}
static xmedia_void ae_update_ext_regs(ae_context *ae_ctx, alg_ae_vreg *ae_vreg)
{
// read the inner param to vreg
ae_vreg->exp_info.exp_time = ae_ctx->param_assign.inttime[0];
ae_vreg->exp_info.again = ae_ctx->param_assign.again;
ae_vreg->exp_info.dgain = ae_ctx->param_assign.dgain;
ae_vreg->exp_info.isp_dgain = ae_ctx->param_assign.isp_dgain;
}
/****************************************************************************
* AE FUNCTION *
* ---- Assistant Function Area *
****************************************************************************/
static xmedia_s32 ae_init(xmedia_u32 channel, const xmedia_isp_ae_param *ae_param)
{
xmedia_u32 pipe;
ae_context *ae_ctx = XMEDIA_NULL;
xmedia_s32 ret;
alg_ae_vreg *ae_vreg = XMEDIA_NULL;
AE_CHECK_CHANNEL_ID_RETURN(channel);
AE_CHECK_POINTER_RETURN(ae_param);
ae_ctx = AE_GET_CTX(channel);
pipe = ae_ctx->isp_bind_dev;
/*
需要为vreg分配内存,且要支持多进程,把分配出来的buffer地址分配给该变量
用户自己分配vreg内存时,不支持使用pqtools导入导出pqbin
*/
ae_ctx->ae_vreg = (alg_ae_vreg *)malloc(sizeof(alg_ae_vreg));
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_ctx->ae_vreg);
ae_vreg = ae_ctx->ae_vreg;
// 初始化vrge
ae_ext_regs_init(ae_vreg);
// 从vreg读取到ae_ctx
ae_read_ext_regs(ae_ctx, ae_vreg);
// 将相关ae参数赋给ae_ctx
ae_init_ctx(ae_ctx, ae_param);
// only manual ae mode supported if sensor not registered
if (ae_ctx->is_sns_register == XMEDIA_FALSE) {
AE_TRACE(MODULE_DBG_ERR, "Channel[%u] no sensor registered, only support manual ae mode!\n", channel);
return XMEDIA_SUCCESS;
}
// 从sensor驱动中得到AE相关参数
ret = ae_update_default_param(pipe, ae_ctx);
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
// 将sensor驱动中AE相关参数更新到ae_ctx里
ae_update_param_by_driver(ae_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 ae_run(xmedia_u32 channel, const xmedia_isp_ae_info *ae_info, xmedia_isp_ae_result *ae_result)
{
ae_context *ae_ctx = XMEDIA_NULL;
xmedia_s32 ret = 0;
alg_ae_vreg *ae_vreg = XMEDIA_NULL;
#ifdef __linux__
xmedia_u32 pipe = 0;
#endif
ae_ctx = AE_GET_CTX(channel);
#ifdef __linux__
pipe = ae_ctx->isp_bind_dev;
#endif
// verg 作用 1:存储API参数 2:支持多进程访问
ae_vreg = ae_ctx->ae_vreg;
if (ae_vreg->exposure_attr.bypass == XMEDIA_TRUE) {
ae_ctx->ae_exposure_attr.bypass = ae_vreg->exposure_attr.bypass;
memcpy(ae_result, &(ae_ctx->ae_result), sizeof(xmedia_isp_ae_result));
return XMEDIA_SUCCESS;
}
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_vreg);
ae_ctx->frame_cnt = ae_info->frame_cnt;
if (ae_info->frame_cnt % ae_ctx->ae_exposure_attr.ae_run_interval != 0) {
memcpy(ae_result, &(ae_ctx->ae_result), sizeof(xmedia_isp_ae_result));
return XMEDIA_SUCCESS;
}
// 得到统计信息
memcpy(&ae_ctx->ae_info, ae_info, sizeof(xmedia_isp_ae_info));
// 从vreg中读取api参数到ae_ctx
ae_read_ext_regs(ae_ctx, ae_vreg);
// 通过统计信息计算平均亮度
ae_calculate_luma_avg(ae_ctx);
// 得到目标曝光量
ae_calc_exp_target(ae_ctx);
// 通过ae_route表得到曝光时间,agian,dgian,isp_dgain
ret = ae_assign_exp_target(ae_ctx);
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
// 调用sensor接口将相关参数配置
ret = ae_expo_param_config(ae_ctx, &(ae_ctx->param_assign));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
// 将相关参数记录下来,给其它模块使用
ae_record_calc_result(ae_ctx, ae_result, &(ae_ctx->param_assign));
// 将相关参数保存到api,以便用户查看
ae_update_ext_regs(ae_ctx, ae_vreg);
ae_print_debug_info(ae_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 ae_ctrl(xmedia_u32 channel, xmedia_u32 u32Cmd, xmedia_void *pValue)
{
ae_context *ae_ctx = XMEDIA_NULL;
xmedia_u32 dev_id;
xmedia_s32 ret;
xmedia_float fps;
#ifdef __linux__
xmedia_u32 pipe = 0;
#endif
alg_ae_vreg *ae_vreg = XMEDIA_NULL;
AE_CHECK_CHANNEL_ID_RETURN(channel);
ae_ctx = AE_GET_CTX(channel);
#ifdef __linux__
pipe = ae_ctx->isp_bind_dev;
#endif
ae_vreg = ae_ctx->ae_vreg;
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_vreg);
switch (u32Cmd) {
case XMEDIA_ISP_AAA_CMD_WDR_MODE_SET:
// do something ...
break;
case XMEDIA_ISP_AAA_CMD_AE_INIT_INFO_GET:
break;
case XMEDIA_ISP_AAA_CMD_AE_FPS_BASE_SET:
AE_CHECK_PIPE_POINTER_RETURN(pipe, pValue);
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_ctx->sns_register.func.pfn_sensor_set_fps);
fps = *(xmedia_float *)pValue;
dev_id = ae_ctx->sns_register.dev_id;
ret = ae_ctx->sns_register.func.pfn_sensor_set_fps(dev_id, fps, &(ae_ctx->sns_dft));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
break;
case XMEDIA_ISP_AAA_CMD_AE_BLC_SET:
break;
default:
break;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 ae_exit(xmedia_u32 channel)
{
// 退出时需要释放vreg的内存
ae_context *ae_ctx = XMEDIA_NULL;
ae_ctx = g_ae_ctx[channel];
free(ae_ctx->ae_vreg);
return XMEDIA_SUCCESS;
}
/****************************************************************************
* EXTERN FUNCTION DECLARATION *
****************************************************************************/
xmedia_s32 xmedia_ae_register(xmedia_u32 pipe)
{
xmedia_isp_ae_register_info ae_register;
xmedia_s32 ret = XMEDIA_SUCCESS;
ae_context *ae_ctx = XMEDIA_NULL;
AE_CHECK_PIPE_RETURN(pipe);
if (g_ae_ctx[pipe] != XMEDIA_NULL) {
AE_TRACE(MODULE_DBG_ERR, "pipe %u already registered, ae register failed!\n", pipe);
return XMEDIA_ERRCODE_EXIST;
}
g_ae_ctx[pipe] = (ae_context *)malloc(sizeof(ae_context));
if (g_ae_ctx[pipe] == XMEDIA_NULL) {
AE_TRACE(MODULE_DBG_ERR, "pipe %u malloc failed, no memory!\n", pipe);
return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY;
}
memset(g_ae_ctx[pipe], 0, sizeof(ae_context));
ae_ctx = g_ae_ctx[pipe];
ae_ctx->isp_bind_dev = pipe;
strcpy(ae_register.alg_name, AE_LIB_NAME);
ae_register.alg_id = pipe;
ae_register.pfn_ae_init = ae_init;
ae_register.pfn_ae_run = ae_run;
ae_register.pfn_ae_ctrl = ae_ctrl;
ae_register.pfn_ae_exit = ae_exit;
ret = xmedia_isp_register_ae_lib(pipe, &ae_register, &(ae_ctx->sns_register));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
if (ae_ctx->sns_register.func.pfn_sensor_get_ae_default != XMEDIA_NULL) {
ae_ctx->is_sns_register = XMEDIA_TRUE;
} else {
ae_ctx->is_sns_register = XMEDIA_FALSE;
}
return ret;
}
xmedia_s32 xmedia_ae_unregister(xmedia_u32 pipe)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 channel;
xmedia_char lib_name[XMEDIA_ISP_ALG_NAME_MAX_SIZE] = AE_LIB_NAME;
AE_CHECK_PIPE_RETURN(pipe);
channel = pipe;
AE_FREE(g_ae_ctx[channel]);
ret = xmedia_isp_unregister_ae_lib(pipe, lib_name, channel);
if (ret != XMEDIA_SUCCESS) {
AE_TRACE(MODULE_DBG_ERR, "ae unregister failed!\n");
}
return ret;
}
@@ -0,0 +1,218 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#ifndef __AE_ADP_H__
#define __AE_ADP_H__
#include <string.h>
#include "xmedia_ae.h"
#include "xmedia_isp.h"
#include "xmedia_errcode.h"
#include "xmedia_debug.h"
#include "sample_ae_vreg_config.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
#define AE_LIB_NAME "ae"
#define AE_STAT_MAX_NUM 10
typedef struct {
xmedia_u32 luma_target;
xmedia_u32 luma_wgt_final;
xmedia_u64 exp_value_target;
xmedia_bool converge_dir;
xmedia_bool is_ae_converge;
} ae_status_inner;
typedef struct {
xmedia_u32 inttime[XMEDIA_ISP_WDR_CHN_MAX_NUM];
xmedia_u32 again;
xmedia_u32 dgain;
xmedia_u32 isp_dgain;
} ae_param_assign;
typedef struct {
// communicate with isp
xmedia_isp_ae_param ae_param;
xmedia_ae_exposure_attr ae_exposure_attr;
xmedia_u32 frame_cnt;
xmedia_isp_ae_info ae_info;
xmedia_isp_smart_info smart_info;
xmedia_isp_ae_result ae_result;
xmedia_u32 isp_bind_dev;
// communicate with sensor, defined by user.
xmedia_bool is_sns_register;
xmedia_isp_ae_sensor_default sns_dft;
xmedia_sensor_register_ae_info sns_register;
// global variables of ae algorithm
ae_status_inner ae_inner_status;
ae_param_assign param_assign;
alg_ae_vreg *ae_vreg;
} ae_context;
extern ae_context *g_ae_ctx[XMEDIA_ISP_PIPE_MAX_NUM];
#define IS_LINEAR_MODE(mode) ((mode) == XMEDIA_VIDEO_WDR_MODE_NONE)
#define IS_WDR_MODE(mode) (((mode) > XMEDIA_VIDEO_WDR_MODE_BUILT_IN) && ((mode) < XMEDIA_VIDEO_WDR_MODE_MAX))
#define IS_BUILT_IN_WDR_MODE(mode) ((mode) == XMEDIA_VIDEO_WDR_MODE_BUILT_IN)
#define IS_2TO1_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_FRAME) || ((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE))
#define IS_3TO1_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_FRAME) || ((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE))
#define IS_4TO1_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_FRAME) || ((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE))
#define IS_LINE_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE) || ((mode) == XMEDIA_VIDEO_WDR_MODE_3TO1_LINE) || \
((mode) == XMEDIA_VIDEO_WDR_MODE_4TO1_LINE))
/* we assumed that the different lib instance have different id,
* use the id 0 & 1.
*/
#define AE_GET_CTX(channel) (g_ae_ctx[channel])
#define AE_PRINT(fmt, ...) XMEDIA_PRINT("[AE][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define AE_TRACE(level, fmt, ...) \
do { \
MODULE_TRACE(level, MOD_ID_AE, "[AE][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define AE_CHECK_CHANNEL_ID_RETURN(channel) \
do { \
if (((channel) < 0) || ((channel) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AE_TRACE(MODULE_DBG_ERR, "Illegal channel id %d is out of range [0, %u).\n", (channel), \
XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AE_CHECK_POINTER_RETURN(ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "%s is null pointer!\n", #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_POINTER_RETURN(pipe, ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] %s is null pointer!\n", pipe, #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_INPUT_POINTER_RETURN(ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "Input param %s is null pointer!\n", #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_INPUT_POINTER_RETURN(pipe, ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] Input param %s is null pointer!\n", pipe, #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_BUFFER_RETURN(buffer) \
do { \
if (buffer == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "%s is null pointer!\n", #buffer); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_BUFFER_RETURN(pipe, buffer) \
do { \
if (buffer == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] %s is null pointer!\n", pipe, #buffer); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_RETURN(pipe) \
do { \
if (((pipe) < 0) || ((pipe) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AE_TRACE(MODULE_DBG_ERR, "Invalid pipe %d is out of range [0, %u).\n", pipe, XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_PIPE_ID; \
} \
} while (0)
#define AE_CHECK_RET_RETURN(ret) \
do { \
if ((ret) != XMEDIA_SUCCESS) { \
AE_TRACE(MODULE_DBG_ERR, "error code = 0x%X.\n", ret); \
return (ret); \
} \
} while (0)
#define AE_CHECK_PIPE_RET_RETURN(pipe, ret) \
do { \
if ((ret) != XMEDIA_SUCCESS) { \
AE_TRACE(MODULE_DBG_ERR, "isp%u error code = 0x%X.\n", pipe, ret); \
return (ret); \
} \
} while (0)
#define AE_CHECK_INPUT_PARAM_RANGE_RETURN(param, min, max) \
do { \
if (((param) < min) || ((param) > max)) { \
AE_TRACE(MODULE_DBG_ERR, "Input param %s is out of range [%u, %u].\n", #param, min, max); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AE_CHECK_PIPE_INPUT_PARAM_RANGE_RETURN(pipe, param, min, max) \
do { \
if (((param) < min) || ((param) > max)) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] Input param %s is out of range [%u, %u].\n", pipe, #param, min, max); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AE_FREE(ptr) \
do { \
if (ptr != XMEDIA_NULL) { \
free(ptr); \
ptr = XMEDIA_NULL; \
} \
} while (0)
#ifndef DIV_0_TO_1
#define DIV_0_TO_1(a) (((a) == 0) ? 1 : (a))
#endif
#ifndef DIV_0_TO_1_FLOAT
#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a))
#endif
#ifndef MAX
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
#endif
#ifndef MIN
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
#endif
#ifndef CLIP
#define CLIP(x, a, b) (MIN(MAX(x, a), b))
#endif
#ifndef ABS
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#endif
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
#endif
@@ -0,0 +1,92 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <string.h>
#include <stdio.h>
#include "sample_ae_adp.h"
#include "sample_ae_vreg_config.h"
#include "xmedia_ae.h"
#include "xmedia_isp.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
xmedia_s32 xmedia_ae_set_exposure_attr(xmedia_u32 pipe, const xmedia_ae_exposure_attr *exposure_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_exposure_attr(xmedia_u32 pipe, xmedia_ae_exposure_attr *exposure_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_wdr_exposure_attr(xmedia_u32 pipe, const xmedia_ae_wdr_exposure_attr *wdr_exp_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_wdr_exposure_attr(xmedia_u32 pipe, xmedia_ae_wdr_exposure_attr *wdr_exp_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_route_attr(xmedia_u32 pipe, const xmedia_isp_ae_route *ae_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_route_attr(xmedia_u32 pipe, xmedia_isp_ae_route *ae_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_route_sf_attr(xmedia_u32 pipe, const xmedia_isp_ae_route *ae_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_route_sf_attr(xmedia_u32 pipe, xmedia_isp_ae_route *ae_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_query_exposure_info(xmedia_u32 pipe, xmedia_ae_exp_info *exp_info)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_ext_route_attr(xmedia_u32 pipe, const xmedia_isp_ae_ext_route *ae_ext_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_ext_route_attr(xmedia_u32 pipe, xmedia_isp_ae_ext_route *ae_ext_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_ext_route_sf_attr(xmedia_u32 pipe, const xmedia_isp_ae_ext_route *ae_ext_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_ext_route_sf_attr(xmedia_u32 pipe, xmedia_isp_ae_ext_route *ae_ext_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_smart_exposure_attr(xmedia_u32 pipe, const xmedia_ae_smart_exposure_attr *smart_exp_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_smart_exposure_attr(xmedia_u32 pipe, xmedia_ae_smart_exposure_attr *smart_exp_attr)
{
return XMEDIA_SUCCESS;
}
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
@@ -0,0 +1,31 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#ifndef __AE_VREG_CONFIG_H__
#define __AE_VREG_CONFIG_H__
#include "xmedia_ae.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
#define AE_VREG_VERSION 0x1001
typedef struct {
xmedia_ae_exposure_attr exposure_attr;
xmedia_ae_wdr_exposure_attr wdr_exp_attr;
xmedia_isp_ae_route ae_route_attr;
xmedia_isp_ae_route ae_route_sf_attr;
xmedia_ae_exp_info exp_info;
xmedia_isp_ae_ext_route ae_ext_route_attr;
xmedia_isp_ae_ext_route ae_ext_route_sf_attr;
xmedia_ae_smart_exposure_attr smart_exp_attr;
xmedia_isp_debug_info ae_debug_info;
} alg_ae_vreg;
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
#endif
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv.mk
else
include Makefile.linux.mk
endif
@@ -0,0 +1,22 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_awb
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/isp/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT -DCONFIG_LOG_TRACE_SUPPORT=1
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,16 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
default:
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.log.mk
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk
$(AT)$(MAKE) -C $(ISP_DIR)/libs
clean:
$(AT)$(MAKE) -C $(ISP_DIR)/libs clean
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
@@ -0,0 +1,22 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_awb
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/isp/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,3 @@
SRCS-y += sample_awb_adp.c
@@ -0,0 +1,363 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "math.h"
#include "sample_awb_adp.h"
#include "xmedia_isp.h"
#include "xmedia_awb.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
/****************************************************************************
* MACRO DEFINITION *
****************************************************************************/
#define AWB_MAX2(x, y) ((x) > (y) ? (x) : (y))
#define AWB_MIN2(x, y) ((x) < (y) ? (x) : (y))
#define AWB_DIV_0_TO_1(a) ((a) == 0 ? 1 : (a))
#define AWB_ABS(x) ((x) >= 0 ? (x) : (-(x)))
#define AWB_CLIP3(x, a, b) ((x < a) ? a : ((x > b) ? b : x))
#define AWB_DIVISION(x) ((AWB_ABS(x - 0) < 1) ? 1 : (x))
#define UNIT_GAIN 256
#define AWB_UNIT_RATIO 128
#define AWB_RUN_FRM 2
/****************************************************************************
* EXTERN VARIABLES *
****************************************************************************/
#define AWB_FIRMWARE_VREG_VERSION 0x1001
#define ISP_AWB_VREG_SIZE (sizeof(alg_awb_vreg))
/****************************************************************************
* GLOBAL VARIABLES *
****************************************************************************/
awb_context *g_awb_context[XMEDIA_ISP_PIPE_MAX_NUM] = { 0 };
#define AWB_GET_CTX(handle) (g_awb_context[handle])
static xmedia_void awb_init_vreg_wb_attr(alg_awb_vreg *awb_vreg)
{
awb_vreg->awb_attr.bypass = XMEDIA_FALSE;
awb_vreg->awb_attr.awb_runinterval = 1;
}
static xmedia_void awb_isp_regs_init(awb_context *awb_ctx)
{
xmedia_s32 i;
xmedia_isp_awb_raw_stat_attr *raw_stat_attr = XMEDIA_NULL;
raw_stat_attr = &awb_ctx->awb_result.raw_stat_attr;
raw_stat_attr->metering_white_level_awb = 0xFFF;
raw_stat_attr->metering_black_level_awb = 0x08;
raw_stat_attr->metering_crref_max_awb = 0x130;
raw_stat_attr->metering_crref_min_awb = 0x40;
raw_stat_attr->metering_cbref_max_awb = 0x120;
raw_stat_attr->metering_cbref_min_awb = 0x40;
raw_stat_attr->change = XMEDIA_TRUE;
awb_ctx->awb_result.ct = 5000;
awb_ctx->awb_result.saturation = 128;
for (i = 0; i < 4; i++) {
awb_ctx->awb_result.white_balance_gain[i] = 256;
}
}
static xmedia_s32 awb_init_sensor_default_param(awb_context *awb_ctx )
{
xmedia_isp_awb_sensor_default sensor_default_param = { 0 };
xmedia_s32 ret;
xmedia_u32 dev_id;
dev_id = awb_ctx->st_sns_register.dev_id;
if (awb_ctx->st_sns_register.func.pfn_sensor_get_awb_default != XMEDIA_NULL) {
ret = awb_ctx->st_sns_register.func.pfn_sensor_get_awb_default(dev_id, &sensor_default_param);
AWB_CHECK_RET_RETURN(ret);
} else {
return XMEDIA_SUCCESS;
}
memcpy(&awb_ctx->sns_dft, &sensor_default_param, sizeof(xmedia_isp_awb_sensor_default));
return XMEDIA_SUCCESS;
}
static xmedia_void awb_run_update_params(awb_context *awb_ctx, xmedia_isp_awb_result *awb_result)
{
memcpy(awb_result, &awb_ctx->awb_result, sizeof(xmedia_isp_awb_result));
}
static xmedia_void color_sector(awb_context *awb_ctx, xmedia_s16 (*ccm_out)[XMEDIA_ISP_CCM_MATRIX_SIZE]){
return;
}
static xmedia_void ccm_calculate(awb_context *awb_ctx)
{
awb_ctx->awb_result.color_matrix[0] = 256;
awb_ctx->awb_result.color_matrix[1] = 0;
awb_ctx->awb_result.color_matrix[2] = 0;
awb_ctx->awb_result.color_matrix[3] = 0;
awb_ctx->awb_result.color_matrix[4] = 256;
awb_ctx->awb_result.color_matrix[5] = 0;
awb_ctx->awb_result.color_matrix[6] = 0;
awb_ctx->awb_result.color_matrix[7] = 0;
awb_ctx->awb_result.color_matrix[8] = 256;
if (awb_ctx->cs_attr.sector_en) {
//实现 color_sector功能
color_sector(awb_ctx, awb_ctx->awb_result.sector_matrix);
} else {
memcpy(&awb_ctx->awb_result.sector_matrix[0], &awb_ctx->awb_result.color_matrix,
sizeof(xmedia_u16) * XMEDIA_ISP_CCM_MATRIX_SIZE);
}
awb_ctx->awb_result.ccm_hue_en = awb_ctx->cs_attr.sector_en;
}
static xmedia_s32 awb_auto(xmedia_u32 channel, const xmedia_isp_awb_info *awb_info, xmedia_isp_awb_result *awb_result,
awb_context *awb_ctx)
{
awb_ctx->awb_result.white_balance_gain[0] = 512;
awb_ctx->awb_result.white_balance_gain[1] = 256;
awb_ctx->awb_result.white_balance_gain[2] = 256;
awb_ctx->awb_result.white_balance_gain[3] = 512;
awb_ctx->awb_result.ct = 6500;
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_manual(xmedia_u32 channel, awb_context *awb_ctx)
{
awb_ctx->awb_result.white_balance_gain[0] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.rgain;
awb_ctx->awb_result.white_balance_gain[1] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.grgain;
awb_ctx->awb_result.white_balance_gain[2] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.gbgain;
awb_ctx->awb_result.white_balance_gain[3] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.bgain;
return XMEDIA_SUCCESS;
}
static xmedia_void awb_read_extregs(awb_context *awb_ctx , const alg_awb_vreg *awb_vreg)
{
memcpy(&awb_ctx->awb_attr, &awb_vreg->awb_attr, sizeof(xmedia_awb_attr));
}
static xmedia_void awb_update_extregs(awb_context *awb_ctx , alg_awb_vreg *awb_vreg)
{
memcpy(&awb_vreg->wb_info, &awb_ctx->wb_info, sizeof(xmedia_awb_info));
}
static xmedia_void awb_write_sensor_param_to_regs(awb_context *awb_ctx, alg_awb_vreg *awb_vreg)
{
memcpy(&awb_vreg->awb_attr, &awb_ctx->awb_attr, sizeof(xmedia_awb_attr));
}
static xmedia_void awb_print_debug_info(awb_context *awb_ctx)
{
AWB_TRACE(MODULE_DBG_DEBUG,
"frameCnt:%5u, wbgain:%5u,%5u,%5u,%5u ccm:%5d, %5d, %5d, %5d, %5d, %5d, %5d, %5d, %5d,sat:%d\n",
awb_ctx->frame_cnt, awb_ctx->awb_result.white_balance_gain[0], awb_ctx->awb_result.white_balance_gain[1],
awb_ctx->awb_result.white_balance_gain[2], awb_ctx->awb_result.white_balance_gain[3],
awb_ctx->awb_result.color_matrix[0], awb_ctx->awb_result.color_matrix[1],
awb_ctx->awb_result.color_matrix[2], awb_ctx->awb_result.color_matrix[3],
awb_ctx->awb_result.color_matrix[4], awb_ctx->awb_result.color_matrix[5],
awb_ctx->awb_result.color_matrix[6], awb_ctx->awb_result.color_matrix[7],
awb_ctx->awb_result.color_matrix[8], awb_ctx->awb_result.saturation);
}
static xmedia_s32 awb_init(xmedia_u32 channel, const xmedia_isp_awb_param *awb_param)
{
xmedia_s32 ret;
alg_awb_vreg *awb_vreg = XMEDIA_NULL;
awb_context *awb_ctx = XMEDIA_NULL;
AWB_CHECK_POINTER_RETURN(awb_param);
AWB_CHECK_PIPE_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
/*
需要为vreg分配内存,且要支持多进程,把分配出来的buffer地址分配给该变量
用户自己分配vreg内存时,不支持使用pqtools导入导出pqbin
verg 作用 1:存储API参数 2:支持多进程访问
*/
awb_ctx->awb_vreg = (alg_awb_vreg*) malloc(sizeof(alg_awb_vreg));
memcpy(&awb_ctx->awb_param, awb_param, sizeof(xmedia_isp_awb_param));
awb_vreg = awb_ctx->awb_vreg;
AWB_CHECK_POINTER_RETURN(awb_vreg);
//初始化verg参数
awb_init_vreg_wb_attr(awb_vreg);
//初始化isp_相关参数
awb_isp_regs_init(awb_ctx);
//将verg参数赋值给awb_ctx
awb_read_extregs(awb_ctx, awb_vreg);
//awb_ctx获得sensor设置的awb默认参数
ret = awb_init_sensor_default_param(awb_ctx);
AWB_CHECK_RET_RETURN(ret);
//将sensor相关参数更新到awb_verg
awb_write_sensor_param_to_regs(awb_ctx, awb_vreg);
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_run(xmedia_u32 channel, const xmedia_isp_awb_info *awb_info, xmedia_isp_awb_result *awb_result)
{
xmedia_s8 ret = 0;
awb_context *awb_ctx = XMEDIA_NULL;
alg_awb_vreg *awb_vreg = XMEDIA_NULL;
AWB_CHECK_CHANNEL_ID_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
AWB_CHECK_POINTER_RETURN(awb_info);
AWB_CHECK_POINTER_RETURN(awb_result);
awb_ctx->frame_cnt = awb_info->frame_cnt;
// verg 作用 1:存储API参数 2:支持多进程访问
awb_vreg = awb_ctx->awb_vreg;
AWB_CHECK_POINTER_RETURN(awb_vreg);
if (awb_vreg->awb_attr.bypass == XMEDIA_TRUE) {
return XMEDIA_SUCCESS;
}
//将verg参数赋值给awb_ctx
awb_read_extregs(awb_ctx, awb_vreg);
if (awb_info->frame_cnt % awb_ctx->awb_attr.awb_runinterval != 0) {
memcpy(awb_result, &awb_ctx->awb_result, sizeof(xmedia_isp_awb_result));
return XMEDIA_SUCCESS;
}
if (awb_ctx->awb_attr.op_type == XMEDIA_VIDEO_OPERATION_MODE_AUTO) {
//根据awb的统计信息计算awb 结果
ret = awb_auto(channel, awb_info, awb_result, awb_ctx);
AWB_CHECK_RET_RETURN(ret);
} else {
//设置手动awb结果
ret = awb_manual(channel, awb_ctx);
AWB_CHECK_RET_RETURN(ret);
}
//计算CCM矩阵
ccm_calculate(awb_ctx);
//将AWB结果记录下来,以便其它模块使用
awb_run_update_params(awb_ctx, awb_result);
//相关参数保存到api,以便用户查看
awb_update_extregs(awb_ctx, awb_vreg);
awb_print_debug_info(awb_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_ctrl(xmedia_u32 channel, xmedia_u32 cmd, xmedia_void *value)
{
awb_context *awb_ctx = XMEDIA_NULL;
xmedia_isp_awb_result *awb_result = XMEDIA_NULL;
AWB_CHECK_CHANNEL_ID_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
switch (cmd) {
/* system ctrl */
case XMEDIA_ISP_AAA_CMD_WDR_MODE_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_ISO_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_INTTIME_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_BLC_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_GAIN_GET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_RESULT_GET:
AWB_CHECK_POINTER_RETURN(value);
awb_result = (xmedia_isp_awb_result *)value;
memcpy(awb_result, &(awb_ctx->awb_result), sizeof(xmedia_isp_awb_result));
break;
case XMEDIA_ISP_AAA_CMD_PROC_WRITE:
break;
default:
break;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_exit(xmedia_u32 channel)
{
awb_context *awb_ctx = XMEDIA_NULL;
AWB_CHECK_CHANNEL_ID_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
free(awb_ctx->awb_vreg);
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_register(xmedia_u32 pipe)
{
xmedia_isp_awb_register_info awb_register;
xmedia_s32 ret = XMEDIA_SUCCESS;
awb_context *awb_ctx = XMEDIA_NULL;
AWB_CHECK_PIPE_RETURN(pipe);
if (g_awb_context[pipe] != XMEDIA_NULL) {
AWB_TRACE(MODULE_DBG_ERR, "pipe %u already registered, awb register failed!\n", pipe);
return XMEDIA_ERRCODE_EXIST;
}
g_awb_context[pipe] = (awb_context *)malloc(sizeof(awb_context));
AWB_CHECK_POINTER_RETURN(g_awb_context[pipe]);
memset(g_awb_context[pipe], 0, sizeof(awb_context));
awb_ctx = g_awb_context[pipe];
awb_ctx->isp_bind_dev = pipe;
strcpy(awb_register.alg_name, AWB_LIB_NAME);
awb_register.alg_id = pipe;
awb_register.pfn_awb_init = awb_init;
awb_register.pfn_awb_run = awb_run;
awb_register.pfn_awb_ctrl = awb_ctrl;
awb_register.pfn_awb_exit = awb_exit;
ret = xmedia_isp_register_awb_lib(pipe, &awb_register, &(awb_ctx->st_sns_register));
if (ret != XMEDIA_SUCCESS) {
AWB_TRACE(MODULE_DBG_ERR, "awb register failed!\n");
}
return ret;
}
xmedia_s32 xmedia_awb_unregister(xmedia_u32 pipe)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 channel;
xmedia_char name[XMEDIA_ISP_ALG_NAME_MAX_SIZE] = AWB_LIB_NAME;
AWB_CHECK_PIPE_RETURN(pipe);
channel = pipe; // mapping table remain to be added; 20230213
AWB_FREE(g_awb_context[channel]);
ret = xmedia_isp_unregister_awb_lib(pipe, name, channel);
if (ret != XMEDIA_SUCCESS) {
AWB_TRACE(MODULE_DBG_ERR, "awb unregister failed!\n");
}
return ret;
}
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
@@ -0,0 +1,183 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#ifndef __AWB_ADP_H__
#define __AWB_ADP_H__
#include <string.h>
#include "xmedia_awb.h"
#include "xmedia_isp.h"
#include "xmedia_errcode.h"
#include "xmedia_debug.h"
#define AWB_LIB_NAME "awb"
#define AWB_RG_BG_NUM 7
#define AWB_SUPER_COLOR_NUM 3
#define AWB_EQUIVAL_EXPTIME_NUM 8
#define AWB_MULTI_WT_NUM 128
#define AWB_MONO_HIST_NUM 128
#define AWB_HIST_BIN_NUM 256
#define AWB_MONO_WT_NUM 17
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
typedef struct {
xmedia_awb_attr awb_attr;
xmedia_awb_scene_adj_attr awb_scene_adj_attr;
xmedia_awb_ccm_attr ccm_attr;
xmedia_awb_saturation_attr sat_attr;
xmedia_awb_color_tone_attr ct_attr;
xmedia_awb_info wb_info;
xmedia_isp_debug_info awb_debug_info;
xmedia_color_sector_attr cs_attr;
} alg_awb_vreg;
typedef struct {
// communicate with isp
xmedia_isp_awb_param awb_param;
xmedia_u32 frame_cnt;
xmedia_isp_awb_result awb_result;
xmedia_u32 isp_bind_dev;
// communicate with sensor, defined by user.
xmedia_bool sns_register;
xmedia_isp_awb_sensor_default sns_dft;
xmedia_sensor_register_awb_info st_sns_register;
//////////////////////////////////////////////////////
// usr var
xmedia_awb_attr awb_attr;
xmedia_awb_scene_adj_attr awb_scene_adj_attr;
xmedia_awb_ccm_attr ccm_attr;
xmedia_awb_saturation_attr sat_attr;
xmedia_awb_color_tone_attr ct_attr;
xmedia_color_sector_attr cs_attr;
// update info
xmedia_awb_info wb_info;
// intrinsic param;
xmedia_s16 awb_frames_cnt;
xmedia_u8 frm_num;
alg_awb_vreg *awb_vreg;
} awb_context;
#define AWB_PRINT(fmt, ...) XMEDIA_PRINT("[AWB][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define AWB_TRACE(level, fmt, ...) \
do { \
MODULE_TRACE(level, MOD_ID_AWB, "[AWB][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, \
##__VA_ARGS__); \
} while (0)
#define AWB_CHECK_PIPE_RETURN(pipe) \
do { \
if (((pipe) < 0) || ((pipe) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AWB_TRACE(MODULE_DBG_ERR, "Invalid pipe. Input pipe %u is out of range [0, %u).\n", pipe, \
XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_PIPE_ID; \
} \
} while (0)
#define AWB_CHECK_PTR_RETURN(ptr) \
do { \
if ((ptr) == XMEDIA_NULL) { \
AWB_TRACE(MODULE_DBG_ERR, "Invalid parameter, %s is null pointer.\n", #ptr); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AWB_CHECK_WHITE_POINT(ret) \
do { \
if ((ret) < 0) { \
/* AWB_TRACE(MODULE_DBG_ERR, "AWB not in white area!\n"); */ \
} \
} while (0)
#define AWB_CHECK_RET_RETURN(ret) \
do { \
if ((ret) != XMEDIA_SUCCESS) { \
AWB_TRACE(MODULE_DBG_ERR, "AWB error code 0x%X!\n", ret); \
return (ret); \
} \
} while (0)
#define AWB_CHECK_POINTER_RETURN(ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AWB_TRACE(MODULE_DBG_ERR, "%s is null pointer!\n", #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AWB_CHECK_CHANNEL_ID_RETURN(channel) \
do { \
if (((channel) < 0) || ((channel) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AWB_TRACE(MODULE_DBG_ERR, "Illegal channel id %d is out of range [0, %u)!\n", (channel), \
XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_CHN_ID; \
} \
} while (0)
#define AWB_FREE(ptr) \
do { \
if (ptr != XMEDIA_NULL) { \
free(ptr); \
ptr = XMEDIA_NULL; \
} \
} while (0)
#define AWB_CHECK_INPUT_PARAM_RANGE_RETURN(param, min, max) \
do { \
if (((param) < min) || ((param) > max)) { \
AWB_TRACE(MODULE_DBG_ERR, "Input param %s is out of range [%u, %u].\n", #param, min, max); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AWB_CHECK_INPUT_PARAM_ASCEND_ORDER_RETURN(param1, param2) \
do { \
if (param1 > param2) { \
AWB_TRACE(MODULE_DBG_ERR, "Input param need to be %s <= %s.\n", #param1, #param2); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AWB_CHECK_ARRAY_PARAM_RANGE_RETURN(var, min, max, array_len) \
do { \
xmedia_u32 i__; \
for (i__ = 0; i__ < array_len; i__++) { \
if ((var[i__]) < (min) || (var[i__]) > (max)) { \
AWB_TRACE(MODULE_DBG_ERR, "invalid param %s[%u] !\n", #var, i__); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} \
} while (0)
#define AWB_CHECK_2D_ARRAY_PARAM_RANGE_RETURN(var, min, max, array_len1, array_len2) \
do { \
xmedia_u32 i__, j__; \
for (i__ = 0; i__ < array_len1; i__++) { \
for (j__ = 0; j__ < array_len2; j__++) { \
if ((var[i__][j__]) < (min) || (var[i__][j__]) > (max)) { \
AWB_TRACE(MODULE_DBG_ERR, "invalid param %s[%u][%u] !\n", #var, i__, j__); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} \
} \
} while (0)
/* we assumed that the different lib instance have different id,
* use the id 0 & 1.
*/
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
#endif
@@ -0,0 +1,113 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <string.h>
#include <stdio.h>
#include "sample_awb_adp.h"
#include "xmedia_awb.h"
#include "xmedia_isp.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
xmedia_s32 xmedia_awb_set_attr(xmedia_u32 pipe, const xmedia_awb_attr *awb_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_attr(xmedia_u32 pipe, xmedia_awb_attr *awb_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_scene_adj_attr(xmedia_u32 pipe, const xmedia_awb_scene_adj_attr *awb_scene_adj_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_scene_adj_attr(xmedia_u32 pipe, xmedia_awb_scene_adj_attr *awb_scene_adj_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_ccm_attr(xmedia_u32 pipe, const xmedia_awb_ccm_attr *ccm_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_ccm_attr(xmedia_u32 pipe, xmedia_awb_ccm_attr *ccm_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_color_sector_attr(xmedia_u32 pipe, const xmedia_color_sector_attr * color_sector_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_color_sector_attr(xmedia_u32 pipe, xmedia_color_sector_attr * color_sector_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_saturation_attr(xmedia_u32 pipe, const xmedia_awb_saturation_attr *sat_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_saturation_attr(xmedia_u32 pipe, xmedia_awb_saturation_attr *sat_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_query_info(xmedia_u32 pipe, xmedia_awb_info *wb_info)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_color_tone_attr(xmedia_u32 pipe, const xmedia_awb_color_tone_attr *ct_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_color_tone_attr(xmedia_u32 pipe, xmedia_awb_color_tone_attr *ct_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_cal_gain_by_temp(xmedia_u32 pipe, const xmedia_awb_attr *awb_attr, xmedia_u16 color_temp,
xmedia_s16 shift, xmedia_u16 *awb_gain)
{
return XMEDIA_SUCCESS;
}
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv.mk
else
include Makefile.linux.mk
endif
+26
View File
@@ -0,0 +1,26 @@
ISP_DIR := $(shell cd .. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
ifeq ($(CONFIG_XMEDIA_SDK_LOG_MODE), log)
LIB_DIR := $(shell cd $(ISP_DIR)/libs/linux/log && /bin/pwd)
else
LIB_DIR := $(shell cd $(ISP_DIR)/libs/linux/nolog && /bin/pwd)
endif
STATIC_LIB := $(wildcard $(LIB_DIR)/*.a)
SHARE_LIB := $(wildcard $(LIB_DIR)/*.so)
.NOTPARALLEL:
.PHONY: all clean
all:
$(AT)test -d $(SDK_STATIC_LIB_DIR) || mkdir -p $(SDK_STATIC_LIB_DIR)
$(AT)test -d $(SDK_SHARE_LIB_DIR) || mkdir -p $(SDK_SHARE_LIB_DIR)
$(AT)cp $(STATIC_LIB) $(SDK_STATIC_LIB_DIR)
$(AT)cp $(SHARE_LIB) $(SDK_SHARE_LIB_DIR)
clean:
$(AT)rm -f $(STATIC_LIB:$(LIB_DIR)/%=$(SDK_STATIC_LIB_DIR)/%)
$(AT)rm -f $(SHARE_LIB:$(LIB_DIR)/%=$(SDK_SHARE_LIB_DIR)/%)
View File
+8
View File
@@ -0,0 +1,8 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+79
View File
@@ -0,0 +1,79 @@
ISP_DIR := $(shell cd .. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
OBJ :=
OBJ += omnivision_os02k10
OBJ += omnivision_ox03f10
OBJ += omnivision_os04a10
OBJ += omnivision_os04c10
OBJ += omnivision_os04d10
OBJ += omnivision_os04j10
OBJ += omnivision_os05a10
OBJ += omnivision_ox05b1s
OBJ += omnivision_os08a20
OBJ += omnivision_os08b10
OBJ += omnivision_ov4689
OBJ += smartsens_sc200ai
OBJ += smartsens_sc450ai
OBJ += smartsens_sc500ai
OBJ += smartsens_sc530ai
OBJ += smartsens_sc485sl
OBJ += smartsens_sc850sl
OBJ += smartsens_sc3338
OBJ += smartsens_sc4336
OBJ += smartsens_sc4336p
OBJ += smartsens_sc5336
OBJ += smartsens_sc8238
OBJ += smartsens_sc235hai
OBJ += smartsens_sc835hai
OBJ += smartsens_sc231hai
OBJ += smartsens_sc431hai
OBJ += smartsens_sc435hai
OBJ += smartsens_sc465sl
OBJ += smartsens_sc2337p
OBJ += smartsens_sc533hai
OBJ += smartsens_sc285sl
OBJ += imagedesign_mis40h1
OBJ += imagedesign_mis20s1
OBJ += galaxycore_gc2053
OBJ += galaxycore_gc20c3
OBJ += galaxycore_gc20b3
OBJ += galaxycore_gc2083
OBJ += galaxycore_gc4663
OBJ += galaxycore_gc8613
OBJ += galaxycore_gc5603
OBJ += galaxycore_gc4653
OBJ += galaxycore_gc4683
OBJ += galaxycore_gc6603
OBJ += byd_bf3a03
OBJ += silicon_jxf37p
OBJ += sony_imx307
OBJ += sony_imx415
OBJ += sony_imx678
OBJ += sony_imx179
OBJ += cvsens_cv8001
OBJ += cvsens_cv4003
OBJ += cvsens_cv2005
OBJ_CLEAN := $(addsuffix _clean, $(OBJ))
.PHONY: all clean $(OBJ) $(OBJ_CLEAN)
all: $(OBJ)
clean: $(OBJ_CLEAN)
$(OBJ):
$(AT)$(MAKE) -C $@
$(OBJ_CLEAN):
$(AT)$(MAKE) -C $(patsubst %_clean, %, $@) clean
+3
View File
@@ -0,0 +1,3 @@
SRCS-y += smartsens_sc485sl/
#SRCS-y += smartsens_sc235hai/
+5
View File
@@ -0,0 +1,5 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+20
View File
@@ -0,0 +1,20 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_bf3a03
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/../include
SDK_USR_CFLAGS += -I.
AT := @
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
+4
View File
@@ -0,0 +1,4 @@
SRCS-y += bf3a03.c
SRCS-y += bf3a03_ctrl.c
+951
View File
@@ -0,0 +1,951 @@
#include <stdlib.h>
#include <string.h>
#include "bf3a03.h"
#include "bf3a03_ctrl.h"
#include "bf3a03_ex.h"
#include "xmedia_isp.h"
#define BF3A03_NAME "BF3A03"
#define BF3A03_SPECS_MAX_NUM 1
#ifdef __linux__
#define BF3A03_ISP_DEFAULT_SUPPORT
#endif
#define BF3A03_HMAX_640X480_LINEAR 0x500 // 未找到vmax对应的寄存器
#define BF3A03_640X480_BIT_RATE_LINEAR 432
#define BF3A03_REG_ADDR_STANDBY 0x09
#define BF3A03_RES_IS_640X480(w, h) ((w) == 640 && (h) == 480)
#define BF3A03_ERR_MODE_PRINT(sns_attr) \
do { \
SENSOR_TRACE(MODULE_DBG_ERR, "Not support! Width:%d, Height:%d, WDRMode:%d\n", sns_attr->width, \
sns_attr->height, sns_attr->wdr_mode); \
} while (0)
sensor_context *g_bf3a03_ctx[XMEDIA_SENSOR_DEV_MAX_NUM] = { XMEDIA_NULL };
#define BF3A03_SET_CTX(dev, sns_ctx) g_bf3a03_ctx[dev] = sns_ctx
#define BF3A03_GET_CTX(dev, sns_ctx) sns_ctx = g_bf3a03_ctx[dev]
static xmedia_u32 g_bf3a03_exposure[XMEDIA_SENSOR_DEV_MAX_NUM] = { 0 };
static xmedia_u16 g_bf3a03_sample_r_gain[XMEDIA_SENSOR_DEV_MAX_NUM] = { 0 };
static xmedia_u16 g_bf3a03_sample_b_gain[XMEDIA_SENSOR_DEV_MAX_NUM] = { 0 };
static xmedia_u16 g_bf3a03_wb_gain[XMEDIA_SENSOR_DEV_MAX_NUM][SENSOR_AWB_CHN_GIAN_MAX_NUM] = { { 0 } };
static xmedia_s32 g_bf3a03_dev_map[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ... XMEDIA_SENSOR_DEV_MAX_NUM - 1] = SENSOR_DEV_INVALID };
static const xmedia_sensor_property g_bf3a03_property[BF3A03_SPECS_MAX_NUM] = {
{
// width, height, wdr_mode
640, 480, XMEDIA_VIDEO_WDR_MODE_NONE,
// wdr_format, max_fps, input_clock
XMEDIA_VIDEO_WDR_FMT_NONE, 30, XMEDIA_SENSOR_CLOCK_FREQ_24MHZ,
// output_intf, pixel_format, bit_width
XMEDIA_INTF_TYPE_DC, XMEDIA_VIDEO_PIXEL_FMT_YUYV_PACKAGE_422, XMEDIA_VIDEO_DATA_WIDTH_8,
// bayer_format - mirror&flip /mirror /flip /normal
{ XMEDIA_VIDEO_BAYER_FMT_BGGR, XMEDIA_VIDEO_BAYER_FMT_BGGR,
XMEDIA_VIDEO_BAYER_FMT_BGGR, XMEDIA_VIDEO_BAYER_FMT_BGGR },
// vcid, bit_rate
{ 0 }, BF3A03_640X480_BIT_RATE_LINEAR,
},
};
static const xmedia_sensor_capability g_bf3a03_capability = {
.max_width = 640,
.max_height = 480,
.max_fps = 30,
.output_intf = XMEDIA_INTF_TYPE_DC,
.init_mclk = XMEDIA_SENSOR_CLOCK_FREQ_24MHZ,
.wdr_mode = XMEDIA_VIDEO_WDR_MODE_NONE,
.wdr_format = XMEDIA_VIDEO_WDR_FMT_NONE,
.bit_width = XMEDIA_VIDEO_DATA_WIDTH_8,
.reset_time = 200, // TODO: 待后续确认复位所需时间
.slave_mode_supported = XMEDIA_FALSE,
.mipi_lanes_supported = XMEDIA_FALSE,
.standby_info = {
.standby_supported = XMEDIA_FALSE,
.addr_byte_num = BF3A03_ADDR_BYTE,
.data_byte_num = BF3A03_DATA_BYTE,
.standby_reg_num = 1,
.standby_reg_addr = { BF3A03_REG_ADDR_STANDBY },
.standby_reg_data = { 0xD5 },
.resume_reg_num = 1,
.resume_reg_addr = { BF3A03_REG_ADDR_STANDBY },
.resume_reg_data = { 0x55 },
},
};
static xmedia_s32 bf3a03_ctx_init(xmedia_u32 dev)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
BF3A03_GET_CTX(dev, bf3a03_ctx);
if (bf3a03_ctx != XMEDIA_NULL) {
SENSOR_TRACE(MODULE_DBG_ERR, " sensor-[%d] ctx already malloc!\n", dev);
return XMEDIA_ERRCODE_EXIST;
}
bf3a03_ctx = (sensor_context *)malloc(sizeof(sensor_context));
if (bf3a03_ctx == XMEDIA_NULL) {
SENSOR_TRACE(MODULE_DBG_ERR, " sensor-[%d] ctx malloc memory failed!\n", dev);
return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY;
}
memset(bf3a03_ctx, 0, sizeof(sensor_context));
bf3a03_ctx->i2c_addr = BF3A03_I2C_ADDR;
bf3a03_ctx->lanes = XMEDIA_SENSOR_MIPI_LANES_2L;
bf3a03_ctx->work_mode = XMEDIA_SENSOR_WORK_MODE_NORMAL;
bf3a03_ctx->bus_info.i2c_dev = SENSOR_I2C_INVALID;
bf3a03_ctx->size.width = 640;
bf3a03_ctx->size.height = 480;
bf3a03_ctx->fps = g_bf3a03_property[0].max_fps;
bf3a03_ctx->wdr_mode = XMEDIA_VIDEO_WDR_MODE_NONE;
bf3a03_ctx->img_mode = BF3A03_DVP_640X480_LINEAR_MODE;
bf3a03_ctx->fl_std = BF3A03_VMAX_640X480_LINEAR << BF3A03_EXP_SHIFT;
bf3a03_ctx->fl[SENSOR_CUR_FRAME] = BF3A03_VMAX_640X480_LINEAR << BF3A03_EXP_SHIFT;
bf3a03_ctx->fl[SENSOR_PRE_FRAME] = BF3A03_VMAX_640X480_LINEAR << BF3A03_EXP_SHIFT;
BF3A03_SET_CTX(dev, bf3a03_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_void bf3a03_ctx_exit(xmedia_u32 dev)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_FREE(bf3a03_ctx);
BF3A03_SET_CTX(dev, XMEDIA_NULL);
}
static xmedia_s32 bf3a03_get_property(xmedia_u32 dev, xmedia_sensor_property *property)
{
xmedia_u8 i;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(property);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
for (i = 0; i < BF3A03_SPECS_MAX_NUM; i++) {
if (g_bf3a03_property[i].width == bf3a03_ctx->size.width &&
g_bf3a03_property[i].height == bf3a03_ctx->size.height &&
g_bf3a03_property[i].wdr_mode == bf3a03_ctx->wdr_mode) {
memcpy(property, &g_bf3a03_property[i], sizeof(xmedia_sensor_property));
return XMEDIA_SUCCESS;
}
}
SENSOR_TRACE(MODULE_DBG_ERR, "Not support! Width: %d, Height: %d, Wdr_mode: %d !\n", bf3a03_ctx->size.width,
bf3a03_ctx->size.height, bf3a03_ctx->wdr_mode);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_set_work_mode(xmedia_u32 dev, xmedia_sensor_work_mode work_mode)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
if (work_mode != XMEDIA_SENSOR_WORK_MODE_NORMAL) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor work mode param invalid!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
bf3a03_ctx->work_mode = work_mode;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_set_mipi_lanes(xmedia_u32 dev, xmedia_sensor_mipi_lanes mipi_lanes)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_set_bus_info(xmedia_u32 dev, const xmedia_sensor_commbus *sns_bus_info)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(sns_bus_info);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
if (sns_bus_info->type == XMEDIA_SENSOR_BUS_TYPE_I2C) {
bf3a03_ctx->bus_info.i2c_dev = sns_bus_info->i2c_dev;
} else if (sns_bus_info->type == XMEDIA_SENSOR_BUS_TYPE_SPI) {
bf3a03_ctx->bus_info.spi_info.spi_dev = sns_bus_info->spi_info.spi_dev;
bf3a03_ctx->bus_info.spi_info.spi_cs = sns_bus_info->spi_info.spi_cs;
} else {
SENSOR_TRACE(MODULE_DBG_ERR,
"Not support [%d], the value of bus type is {%d-i2c, %d-spi}, please check input type!\n",
sns_bus_info->type, XMEDIA_SENSOR_BUS_TYPE_I2C, XMEDIA_SENSOR_BUS_TYPE_SPI);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return XMEDIA_SUCCESS;
}
// one i2c dev shared by multiple sensors
static xmedia_s32 bf3a03_set_dev_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
bf3a03_ctx->i2c_addr = slave_addr;
ret = bf3a03_set_slave_addr(dev, slave_addr);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_dev_addr(xmedia_u32 dev, xmedia_u32 *slave_addr)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(slave_addr);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
*slave_addr = bf3a03_ctx->i2c_addr;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_init(xmedia_u32 dev, xmedia_sensor_init_mode init_mode)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
bf3a03_ctx->init_mode = init_mode;
ret = bf3a03_i2c_init(dev, bf3a03_ctx->bus_info.i2c_dev, bf3a03_ctx->i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
bf3a03_ctx->init = XMEDIA_TRUE;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
ret = bf3a03_i2c_exit(dev);
SENSOR_CHECK_RET_RETURN(ret);
bf3a03_ctx->init = XMEDIA_FALSE;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_mirror(xmedia_u32 dev, xmedia_bool mirror_en)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
bf3a03_ctx->mirror_en = mirror_en;
ret = bf3a03_set_mirror_flip(dev, mirror_en, bf3a03_ctx->flip_en);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_flip(xmedia_u32 dev, xmedia_bool flip_en)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
bf3a03_ctx->flip_en = flip_en;
ret = bf3a03_set_mirror_flip(dev, bf3a03_ctx->mirror_en, flip_en);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_set_image_mode(sensor_context *bf3a03_ctx, xmedia_u8 *image_mode,
const xmedia_sensor_attr *sns_attr)
{
SENSOR_CHECK_PTR_RETURN(image_mode);
if (bf3a03_ctx->wdr_mode == XMEDIA_VIDEO_WDR_MODE_NONE) {
if (BF3A03_RES_IS_640X480(sns_attr->width, sns_attr->height)) {
*image_mode = BF3A03_DVP_640X480_LINEAR_MODE;
if (bf3a03_ctx->work_mode == XMEDIA_SENSOR_WORK_MODE_NORMAL) {
bf3a03_ctx->fl_std = BF3A03_VMAX_640X480_LINEAR << BF3A03_EXP_SHIFT;
} else {
SENSOR_TRACE(MODULE_DBG_ERR, "Not support work mode: %d\n", bf3a03_ctx->work_mode);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
} else {
BF3A03_ERR_MODE_PRINT(sns_attr);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
} else {
BF3A03_ERR_MODE_PRINT(sns_attr);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
bf3a03_ctx->size.width = sns_attr->width;
bf3a03_ctx->size.height = sns_attr->height;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_set_wdr_mode(xmedia_u32 dev, xmedia_u8 wdr_mode)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
switch (wdr_mode) {
case XMEDIA_VIDEO_WDR_MODE_NONE:
bf3a03_ctx->wdr_mode = XMEDIA_VIDEO_WDR_MODE_NONE;
SENSOR_PRINT("linear mode\n");
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "NOT support this mode!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
memset(bf3a03_ctx->wdr_int_time, 0, sizeof(bf3a03_ctx->wdr_int_time));
return XMEDIA_SUCCESS;
}
static xmedia_void bf3a03_init_common_reg_info(sensor_context *bf3a03_ctx)
{
return;
}
static xmedia_s32 bf3a03_init_reg_info(xmedia_u32 dev)
{
xmedia_u32 i;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].com_bus.i2c_dev = bf3a03_ctx->bus_info.i2c_dev;
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].cfg_to_valid_delay_max = 2; // maximum delay valid frames
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].reg_num = BF3A03_REG_MAX_NUM;
for (i = 0; i < bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].reg_num; i++) {
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].update = XMEDIA_TRUE;
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].dev_addr = bf3a03_ctx->i2c_addr;
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].addr_byte_num = BF3A03_ADDR_BYTE;
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].data_byte_num = BF3A03_DATA_BYTE;
}
// init general register - The registers should init both in linear
bf3a03_init_common_reg_info(bf3a03_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_set_attr(xmedia_u32 dev, const xmedia_sensor_attr *sns_attr)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(sns_attr);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
// Set wdr mode
ret = bf3a03_set_wdr_mode(dev, sns_attr->wdr_mode);
SENSOR_CHECK_RET_RETURN(ret);
// Set image mode
ret = bf3a03_set_image_mode(bf3a03_ctx, &bf3a03_ctx->img_mode, sns_attr);
SENSOR_CHECK_RET_RETURN(ret);
bf3a03_ctx->fl[SENSOR_CUR_FRAME] = bf3a03_ctx->fl_std;
bf3a03_ctx->fl[SENSOR_PRE_FRAME] = bf3a03_ctx->fl[SENSOR_CUR_FRAME];
ret = bf3a03_init_reg_info(dev);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_isp_default(xmedia_u32 dev, xmedia_sensor_isp_default *isp_default)
{
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(isp_default);
memset(isp_default, 0, sizeof(xmedia_sensor_isp_default));
#ifdef BF3A03_ISP_DEFAULT_SUPPORT
// TO-DO: alg add param
isp_default->ainr = XMEDIA_NULL;
isp_default->anti_false_color = XMEDIA_NULL;
isp_default->blc = XMEDIA_NULL;
isp_default->bnr = XMEDIA_NULL;
isp_default->ca = XMEDIA_NULL;
isp_default->clut_attr = XMEDIA_NULL;
isp_default->crosstalk = XMEDIA_NULL;
isp_default->csc = XMEDIA_NULL;
isp_default->dehaze = XMEDIA_NULL;
isp_default->demosaic = XMEDIA_NULL;
isp_default->dpc_dynamic = XMEDIA_NULL;
isp_default->dpc_static = XMEDIA_NULL;
isp_default->drc = XMEDIA_NULL;
isp_default->expander = XMEDIA_NULL;
isp_default->fpn = XMEDIA_NULL;
isp_default->gamma = XMEDIA_NULL;
isp_default->gcac = XMEDIA_NULL;
isp_default->hlc = XMEDIA_NULL;
isp_default->lcac = XMEDIA_NULL;
isp_default->lce = XMEDIA_NULL;
isp_default->mlsc_attr = XMEDIA_NULL;
isp_default->mlsc_lut = XMEDIA_NULL;
isp_default->radial_crop = XMEDIA_NULL;
isp_default->rgbir = XMEDIA_NULL;
isp_default->rlsc_attr = XMEDIA_NULL;
isp_default->rlsc_lut = XMEDIA_NULL;
isp_default->sharpen = XMEDIA_NULL;
isp_default->stnr = XMEDIA_NULL;
isp_default->wdr = XMEDIA_NULL;
return XMEDIA_SUCCESS;
#else
SENSOR_TRACE(MODULE_DBG_WARN, "Not support isp getting default param from bf3a03!\n ");
return XMEDIA_ERRCODE_NOT_SUPPORT;
#endif
}
static xmedia_s32 bf3a03_get_isp_black_level(xmedia_u32 dev, xmedia_sensor_black_level *black_level)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(black_level);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
// Don't need to update black level when iso change
black_level->update = XMEDIA_FALSE;
if (bf3a03_ctx->wdr_mode == XMEDIA_VIDEO_WDR_MODE_NONE) {
black_level->black_level[XMEDIA_SENSOR_BAYER_CHN_R] = 64;
black_level->black_level[XMEDIA_SENSOR_BAYER_CHN_GR] = 64;
black_level->black_level[XMEDIA_SENSOR_BAYER_CHN_GB] = 64;
black_level->black_level[XMEDIA_SENSOR_BAYER_CHN_B] = 64;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_bayer_pattern(xmedia_u32 dev, xmedia_video_bayer_format *bayer_pattern)
{
xmedia_u8 i;
xmedia_sensor_mirror_flip_type type;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(bayer_pattern);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
if (bf3a03_ctx->mirror_en && bf3a03_ctx->flip_en) {
type = XMEDIA_SENSOR_MIRROR_FLIP_TYPE_MIRROR_FLIP;
} else if (bf3a03_ctx->mirror_en && (!bf3a03_ctx->flip_en)) {
type = XMEDIA_SENSOR_MIRROR_FLIP_TYPE_MIRROR;
} else if ((!bf3a03_ctx->mirror_en) && bf3a03_ctx->flip_en) {
type = XMEDIA_SENSOR_MIRROR_FLIP_TYPE_FLIP;
} else {
type = XMEDIA_SENSOR_MIRROR_FLIP_TYPE_NORMAL;
}
for (i = 0; i < BF3A03_SPECS_MAX_NUM; i++) {
if (g_bf3a03_property[i].width == bf3a03_ctx->size.width &&
g_bf3a03_property[i].height == bf3a03_ctx->size.height &&
g_bf3a03_property[i].wdr_mode == bf3a03_ctx->wdr_mode) {
*bayer_pattern = g_bf3a03_property[i].bayer_format[type];
break;
}
}
if (i >= BF3A03_SPECS_MAX_NUM) {
*bayer_pattern = XMEDIA_VIDEO_BAYER_MAX;
SENSOR_TRACE(MODULE_DBG_ERR, "ERR! Get bayer pattern failed!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_capability(xmedia_sensor_capability *capability)
{
SENSOR_CHECK_PTR_RETURN(capability);
memcpy(capability, &g_bf3a03_capability, sizeof(xmedia_sensor_capability));
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_trig_attr(xmedia_sensor_trig_attr *trig_attr)
{
SENSOR_CHECK_PTR_RETURN(trig_attr);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_set_ae_wdr_attr(xmedia_u32 dev, xmedia_isp_ae_wdr_mode ae_wdr_mode)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
if (ae_wdr_mode >= XMEDIA_ISP_AE_WDR_MODE_MAX) {
SENSOR_TRACE(MODULE_DBG_ERR, "Not supported AE wdr mode!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
bf3a03_ctx->ae_wdr_mode = ae_wdr_mode;
return XMEDIA_SUCCESS;
}
// 用户期望第一帧生效的参数,且AE/AWB头几帧计算的基础
static xmedia_s32 bf3a03_set_init_param(xmedia_u32 dev, const xmedia_sensor_init_param *init_param)
{
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(init_param);
g_bf3a03_exposure[dev] = init_param->exposure;
g_bf3a03_sample_r_gain[dev] = init_param->sample_rgain;
g_bf3a03_sample_b_gain[dev] = init_param->sample_bgain;
g_bf3a03_wb_gain[dev][SENSOR_AWB_CHN_GIAN_R] = init_param->wb_rgain;
g_bf3a03_wb_gain[dev][SENSOR_AWB_CHN_GIAN_G] = init_param->wb_ggain;
g_bf3a03_wb_gain[dev][SENSOR_AWB_CHN_GIAN_B] = init_param->wb_bgain;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_ae_default(xmedia_u32 dev, xmedia_isp_ae_sensor_default *ae_sns_dft)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_update_inttime(xmedia_u32 dev, xmedia_u32 int_time)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_calc_again(xmedia_u32 dev, xmedia_u32 *again_lin, xmedia_u32 *again_db)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_calc_dgain(xmedia_u32 dev, xmedia_u32 *dgain_lin, xmedia_u32 *dgain_db)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_update_gains(xmedia_u32 dev, xmedia_u32 again, xmedia_u32 dgain)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
// AWB
static xmedia_s32 bf3a03_get_awb_default(xmedia_u32 dev, xmedia_isp_awb_sensor_default *awb_sns_dft)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_get_max_fps(xmedia_u8 img_mode, xmedia_float *max_fps)
{
switch (img_mode) {
case BF3A03_DVP_640X480_LINEAR_MODE:
*max_fps = 30.0;
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support img mode: %d\n", img_mode);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_standby(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
SENSOR_CHECK_DEV_RETURN(dev);
ret = bf3a03_write_reg(dev, BF3A03_REG_ADDR_STANDBY, 0xD5);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_resume(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
SENSOR_CHECK_DEV_RETURN(dev);
ret = bf3a03_write_reg(dev, BF3A03_REG_ADDR_STANDBY, 0x55);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_config_init_param(xmedia_u32 dev)
{
xmedia_u32 i;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 reg_data_sum = 0;
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
// exceptional process for AE unregister
for (i = 0; i < bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].reg_num; i++) {
reg_data_sum += bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].data;
}
if (reg_data_sum == 0) {
return XMEDIA_SUCCESS;
}
for (i = 0; i < bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].reg_num; i++) {
ret |= bf3a03_write_reg(dev, bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].reg_addr,
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].data);
}
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] config init param failed!\n", dev);
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_start(xmedia_u32 dev)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
if (bf3a03_ctx->init_mode == XMEDIA_SENSOR_INIT_MODE_NORMAL) {
ret = bf3a03_init_image(dev, bf3a03_ctx->img_mode, bf3a03_ctx->work_mode);
SENSOR_CHECK_RET_RETURN(ret);
}
ret = bf3a03_config_init_param(dev);
SENSOR_CHECK_RET_RETURN(ret);
ret = bf3a03_set_mirror_flip(dev, bf3a03_ctx->mirror_en, bf3a03_ctx->flip_en);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_stop(xmedia_u32 dev)
{
xmedia_s32 ret;
SENSOR_CHECK_DEV_RETURN(dev);
ret = bf3a03_standby(dev);
SENSOR_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_search_dev(xmedia_u32 pipe, xmedia_u32 *dev)
{
xmedia_u32 index;
SENSOR_CHECK_PTR_RETURN(dev);
for (index = 0; index < XMEDIA_SENSOR_DEV_MAX_NUM; index++) {
if (g_bf3a03_dev_map[index] == SENSOR_DEV_INVALID) {
g_bf3a03_dev_map[index] = pipe;
*dev = index;
return XMEDIA_SUCCESS;
}
}
SENSOR_TRACE(MODULE_DBG_ERR, "all sensor dev are registered!\n");
return XMEDIA_ERRCODE_BINDED;
}
static xmedia_s32 bf3a03_match_dev(xmedia_u32 pipe, xmedia_u32 *dev)
{
xmedia_u32 index;
SENSOR_CHECK_PTR_RETURN(dev);
for (index = 0; index < XMEDIA_SENSOR_DEV_MAX_NUM; index++) {
if (g_bf3a03_dev_map[index] == pipe) {
*dev = index;
return XMEDIA_SUCCESS;
}
}
SENSOR_TRACE(MODULE_DBG_ERR, "There is no sensor dev to match pipe[%d]!\n", pipe);
return XMEDIA_ERRCODE_NOT_BIND;
}
static xmedia_s32 bf3a03_get_min_fps(xmedia_u8 img_mode, xmedia_float *min_fps)
{
switch (img_mode) {
case BF3A03_DVP_640X480_LINEAR_MODE:
*min_fps = 1.5;
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support img mode: %d\n", img_mode);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_reg_info(xmedia_u32 dev, xmedia_sensor_regs_info *sns_regs_info)
{
xmedia_s32 i;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(sns_regs_info);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
for (i = 0; i < bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].reg_num; i++) {
if (bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].data ==
bf3a03_ctx->regs_info[SENSOR_PRE_FRAME].i2c_data[i].data) {
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].update = XMEDIA_FALSE;
} else {
bf3a03_ctx->regs_info[SENSOR_CUR_FRAME].i2c_data[i].update = XMEDIA_TRUE;
}
}
memcpy(sns_regs_info, &bf3a03_ctx->regs_info[SENSOR_CUR_FRAME], sizeof(xmedia_sensor_regs_info));
memcpy(&bf3a03_ctx->regs_info[SENSOR_PRE_FRAME], &bf3a03_ctx->regs_info[SENSOR_CUR_FRAME],
sizeof(xmedia_sensor_regs_info));
bf3a03_ctx->fl[SENSOR_PRE_FRAME] = bf3a03_ctx->fl[SENSOR_CUR_FRAME];
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_set_fps(xmedia_u32 dev, xmedia_float fps, xmedia_isp_ae_sensor_default *ae_sns_dft)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
// line wdr模式下,根据AE期望曝光比,返回不同模式下长短帧的最大/最小曝光时间
static xmedia_s32 bf3a03_get_max_inttime(xmedia_u32 dev, xmedia_sensor_ae_inttime_attr *inttime_attr)
{
return XMEDIA_SUCCESS;
}
/*
* 线性:full_lines, AE期望的曝光时间, VMAX = full_lines + EXP_OFFSET_LINEAR
* 2TO1 WDR: full_lines, AE期望的长帧+短帧的曝光时间, VMAX = full_lines + EXP_OFFSET_WDR
* 注意:2to1 wdr模式下,曝光比和ae wdr mode 由AE传入,调用本接口前,AE需先调用bf3a03_get_wdr_max_inttime
*/
static xmedia_s32 bf3a03_set_slow_framerate(xmedia_u32 dev, xmedia_u32 full_lines,
xmedia_isp_ae_sensor_default *ae_sns_dft)
{
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
static xmedia_s32 bf3a03_get_hmax_vmax(xmedia_u32 dev, xmedia_u32 *hmax, xmedia_u32 *vmax)
{
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(hmax);
SENSOR_CHECK_PTR_RETURN(vmax);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
*vmax = bf3a03_ctx->fl[SENSOR_CUR_FRAME] >> BF3A03_EXP_SHIFT;
switch (bf3a03_ctx->img_mode) {
case BF3A03_DVP_640X480_LINEAR_MODE:
if (bf3a03_ctx->work_mode == XMEDIA_SENSOR_WORK_MODE_NORMAL) {
*hmax = BF3A03_HMAX_640X480_LINEAR; // TODO: 待确认寄存器值是否就是真正的hmax
} else {
SENSOR_TRACE(MODULE_DBG_ERR, "Not support work mode: %d\n", bf3a03_ctx->work_mode);
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_get_fps(xmedia_u32 dev, xmedia_float *fps, xmedia_float *min_fps, xmedia_float *max_fps)
{
xmedia_s32 ret;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_DEV_RETURN(dev);
SENSOR_CHECK_PTR_RETURN(fps);
SENSOR_CHECK_PTR_RETURN(min_fps);
SENSOR_CHECK_PTR_RETURN(max_fps);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
ret = bf3a03_get_min_fps(bf3a03_ctx->img_mode, min_fps);
SENSOR_CHECK_RET_RETURN(ret);
ret = bf3a03_get_max_fps(bf3a03_ctx->img_mode, max_fps);
SENSOR_CHECK_RET_RETURN(ret);
*fps = bf3a03_ctx->fps;
return XMEDIA_SUCCESS;
}
static xmedia_s32 bf3a03_init_register_func(xmedia_sensor_register_info *info)
{
SENSOR_CHECK_PTR_RETURN(info);
memcpy(info->sensor_name, BF3A03_NAME, sizeof(BF3A03_NAME));
// Called by user
info->isp_func.pfn_sensor_get_property = bf3a03_get_property;
info->isp_func.pfn_sensor_set_work_mode = bf3a03_set_work_mode;
info->isp_func.pfn_sensor_set_mipi_lanes = bf3a03_set_mipi_lanes;
info->isp_func.pfn_sensor_mirror = bf3a03_mirror;
info->isp_func.pfn_sensor_flip = bf3a03_flip;
info->isp_func.pfn_sensor_set_bus_info = bf3a03_set_bus_info;
info->isp_func.pfn_sensor_set_dev_addr = bf3a03_set_dev_addr;
info->isp_func.pfn_sensor_set_init_param = bf3a03_set_init_param;
info->isp_func.pfn_sensor_start = bf3a03_start;
info->isp_func.pfn_sensor_stop = bf3a03_stop;
info->isp_func.pfn_sensor_standby = bf3a03_standby;
info->isp_func.pfn_sensor_resume = bf3a03_resume;
info->isp_func.pfn_sensor_write_reg = bf3a03_write_reg;
info->isp_func.pfn_sensor_read_reg = bf3a03_read_reg;
info->isp_func.pfn_sensor_init = bf3a03_init;
info->isp_func.pfn_sensor_exit = bf3a03_exit;
info->isp_func.pfn_sensor_set_attr = bf3a03_set_attr;
// called by ISP
info->isp_func.pfn_sensor_get_isp_default = bf3a03_get_isp_default;
info->isp_func.pfn_sensor_get_isp_black_level = bf3a03_get_isp_black_level;
info->isp_func.pfn_sensor_get_reg_info = bf3a03_get_reg_info;
info->isp_func.pfn_sensor_get_bayer_pattern = bf3a03_get_bayer_pattern;
info->isp_func.pfn_sensor_get_capability = bf3a03_get_capability;
info->isp_func.pfn_sensor_get_dev_addr = bf3a03_get_dev_addr;
info->isp_func.pfn_sensor_get_trig_attr = bf3a03_get_trig_attr;
info->isp_func.pfn_sensor_get_hmax_vmax = bf3a03_get_hmax_vmax;
info->isp_func.pfn_sensor_get_fps = bf3a03_get_fps;
// AE
info->ae_func.pfn_sensor_get_ae_default = bf3a03_get_ae_default;
info->ae_func.pfn_sensor_set_fps = bf3a03_set_fps;
info->ae_func.pfn_sensor_set_slow_framerate = bf3a03_set_slow_framerate;
info->ae_func.pfn_sensor_get_max_inttime = bf3a03_get_max_inttime;
info->ae_func.pfn_sensor_update_inttime = bf3a03_update_inttime;
info->ae_func.pfn_sensor_calc_again = bf3a03_calc_again;
info->ae_func.pfn_sensor_calc_dgain = bf3a03_calc_dgain;
info->ae_func.pfn_sensor_update_gains = bf3a03_update_gains;
info->ae_func.pfn_sensor_set_ae_wdr_attr = bf3a03_set_ae_wdr_attr;
// AWB
info->awb_func.pfn_sensor_get_awb_default = bf3a03_get_awb_default;
return XMEDIA_SUCCESS;
}
xmedia_s32 bf3a03_register(xmedia_u32 pipe)
{
xmedia_s32 ret;
xmedia_u32 dev;
xmedia_sensor_register_info info;
SENSOR_CHECK_PIPE_RETURN(pipe);
ret = bf3a03_search_dev(pipe, &dev);
SENSOR_CHECK_RET_RETURN(ret);
ret = bf3a03_ctx_init(dev);
SENSOR_CHECK_RET_RETURN(ret);
memset(&info, 0, sizeof(xmedia_sensor_register_info));
info.dev_id = dev;
ret = bf3a03_init_register_func(&info);
SENSOR_CHECK_RET_RETURN(ret);
ret = xmedia_isp_register_sensor(pipe, &info);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "BF3A03 register failed! error code = %d.\n", ret);
return ret;
}
return XMEDIA_SUCCESS;
}
xmedia_s32 bf3a03_unregister(xmedia_u32 pipe)
{
xmedia_s32 ret;
xmedia_u32 dev;
sensor_context *bf3a03_ctx = XMEDIA_NULL;
SENSOR_CHECK_PIPE_RETURN(pipe);
ret = bf3a03_match_dev(pipe, &dev);
SENSOR_CHECK_RET_RETURN(ret);
BF3A03_GET_CTX(dev, bf3a03_ctx);
SENSOR_CHECK_PTR_RETURN(bf3a03_ctx);
if (bf3a03_ctx->init == XMEDIA_TRUE) {
SENSOR_PRINT("Operation not allowed, please EXIT at first!\n");
return XMEDIA_ERRCODE_NOT_PERMITTED;
}
ret = xmedia_isp_unregister_sensor(pipe, dev);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "BF3A03 unregister function failed!\n");
return ret;
}
bf3a03_ctx_exit(dev);
g_bf3a03_dev_map[dev] = SENSOR_DEV_INVALID;
return XMEDIA_SUCCESS;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef __BF3A03_H__
#define __BF3A03_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BF3A03_FULL_LINES_MAX 0xFFFF // 未找到vmax对应的寄存器
#define BF3A03_VMAX_640X480_LINEAR 0x465 // 未找到vmax对应的寄存器
#define BF3A03_EXP_OFFSET_LINEAR 0 // TODO: 待确认
#define BF3A03_EXP_SHIFT 0
typedef enum {
BF3A03_REG_MAX_NUM
} bf3a03_reg_info;
#ifdef __cplusplus
}
#endif
#endif // __BF3A03_H__
+317
View File
@@ -0,0 +1,317 @@
#include <stdio.h>
#include <string.h>
#include "i2c_dev.h"
#include "bf3a03.h"
#include "bf3a03_ctrl.h"
static xmedia_s32 g_bf3a03_i2c_addr[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
static xmedia_s32 g_bf3a03_i2c_fd[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
#define BF3A03_REG_ADDR_MIRROR_FLIP 0x12
xmedia_void bf3a03_delay_ms(xmedia_s32 ms)
{
sleep_us(ms * 1000);
}
static xmedia_s32 bf3a03_dvp_linear_640x480_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
bf3a03_write_reg(dev, 0x12, 0x80);
ret |= bf3a03_write_reg(dev, 0x09, 0x55);
ret |= bf3a03_write_reg(dev, 0x15, 0x02);
ret |= bf3a03_write_reg(dev, 0x1e, 0x40);
ret |= bf3a03_write_reg(dev, 0x06, 0x78);
ret |= bf3a03_write_reg(dev, 0x21, 0x00);
ret |= bf3a03_write_reg(dev, 0x3e, 0x37);
ret |= bf3a03_write_reg(dev, 0x29, 0x2b);
ret |= bf3a03_write_reg(dev, 0x27, 0x98);
ret |= bf3a03_write_reg(dev, 0x16, 0x25);
ret |= bf3a03_write_reg(dev, 0x20, 0x00);
ret |= bf3a03_write_reg(dev, 0xd2, 0x18);
ret |= bf3a03_write_reg(dev, 0x11, 0x10);
ret |= bf3a03_write_reg(dev, 0x2f, 0x4e);
ret |= bf3a03_write_reg(dev, 0x1b, 0x09);
ret |= bf3a03_write_reg(dev, 0x3a, 0x00);
ret |= bf3a03_write_reg(dev, 0x4a, 0x98);
ret |= bf3a03_write_reg(dev, 0x12, 0x00);
ret |= bf3a03_write_reg(dev, 0x13, 0x08);
ret |= bf3a03_write_reg(dev, 0x01, 0x14);
ret |= bf3a03_write_reg(dev, 0x02, 0x20);
ret |= bf3a03_write_reg(dev, 0x8c, 0x02);
ret |= bf3a03_write_reg(dev, 0x8d, 0x4c);
ret |= bf3a03_write_reg(dev, 0x87, 0x16);
ret |= bf3a03_write_reg(dev, 0x13, 0x07);
ret |= bf3a03_write_reg(dev, 0x70, 0x0f);
ret |= bf3a03_write_reg(dev, 0x3b, 0x00);
ret |= bf3a03_write_reg(dev, 0x71, 0x0c);
ret |= bf3a03_write_reg(dev, 0x73, 0x27);
ret |= bf3a03_write_reg(dev, 0x75, 0x88);
ret |= bf3a03_write_reg(dev, 0x76, 0xd8);
ret |= bf3a03_write_reg(dev, 0x77, 0x0a);
ret |= bf3a03_write_reg(dev, 0x78, 0xff);
ret |= bf3a03_write_reg(dev, 0x79, 0x14);
ret |= bf3a03_write_reg(dev, 0x7a, 0x23);
ret |= bf3a03_write_reg(dev, 0x9e, 0x04);
ret |= bf3a03_write_reg(dev, 0x7d, 0x2a);
ret |= bf3a03_write_reg(dev, 0x39, 0xa0);
ret |= bf3a03_write_reg(dev, 0x3f, 0xa0);
ret |= bf3a03_write_reg(dev, 0x40, 0x19);
ret |= bf3a03_write_reg(dev, 0x41, 0x1e);
ret |= bf3a03_write_reg(dev, 0x42, 0x1f);
ret |= bf3a03_write_reg(dev, 0x43, 0x20);
ret |= bf3a03_write_reg(dev, 0x44, 0x1d);
ret |= bf3a03_write_reg(dev, 0x45, 0x19);
ret |= bf3a03_write_reg(dev, 0x46, 0x17);
ret |= bf3a03_write_reg(dev, 0x47, 0x17);
ret |= bf3a03_write_reg(dev, 0x48, 0x14);
ret |= bf3a03_write_reg(dev, 0x49, 0x12);
ret |= bf3a03_write_reg(dev, 0x4b, 0x0f);
ret |= bf3a03_write_reg(dev, 0x4c, 0x0c);
ret |= bf3a03_write_reg(dev, 0x4e, 0x08);
ret |= bf3a03_write_reg(dev, 0x4f, 0x06);
ret |= bf3a03_write_reg(dev, 0x50, 0x03);
ret |= bf3a03_write_reg(dev, 0x24, 0x50);
ret |= bf3a03_write_reg(dev, 0x97, 0x40);
ret |= bf3a03_write_reg(dev, 0x25, 0x88);
ret |= bf3a03_write_reg(dev, 0x81, 0x00);
ret |= bf3a03_write_reg(dev, 0x82, 0x18);
ret |= bf3a03_write_reg(dev, 0x83, 0x30);
ret |= bf3a03_write_reg(dev, 0x84, 0x20);
ret |= bf3a03_write_reg(dev, 0x85, 0x38);
ret |= bf3a03_write_reg(dev, 0x86, 0xa0);
ret |= bf3a03_write_reg(dev, 0x94, 0x82);
ret |= bf3a03_write_reg(dev, 0x80, 0x92);
ret |= bf3a03_write_reg(dev, 0x98, 0x8a);
ret |= bf3a03_write_reg(dev, 0x89, 0x7d);
ret |= bf3a03_write_reg(dev, 0x8e, 0x2c);
ret |= bf3a03_write_reg(dev, 0x8f, 0x82);
ret |= bf3a03_write_reg(dev, 0x2b, 0x20);
ret |= bf3a03_write_reg(dev, 0x8a, 0x49);
ret |= bf3a03_write_reg(dev, 0x8b, 0x3d);
ret |= bf3a03_write_reg(dev, 0x92, 0x6D);
ret |= bf3a03_write_reg(dev, 0x5a, 0xec);
ret |= bf3a03_write_reg(dev, 0x51, 0x90);
ret |= bf3a03_write_reg(dev, 0x52, 0x10);
ret |= bf3a03_write_reg(dev, 0x53, 0x8d);
ret |= bf3a03_write_reg(dev, 0x54, 0x88);
ret |= bf3a03_write_reg(dev, 0x57, 0x82);
ret |= bf3a03_write_reg(dev, 0x58, 0x8d);
ret |= bf3a03_write_reg(dev, 0x5a, 0x7c);
ret |= bf3a03_write_reg(dev, 0x51, 0x80);
ret |= bf3a03_write_reg(dev, 0x52, 0x04);
ret |= bf3a03_write_reg(dev, 0x53, 0x8d);
ret |= bf3a03_write_reg(dev, 0x54, 0x88);
ret |= bf3a03_write_reg(dev, 0x57, 0x82);
ret |= bf3a03_write_reg(dev, 0x58, 0x8d);
ret |= bf3a03_write_reg(dev, 0x5a, 0x6c);
ret |= bf3a03_write_reg(dev, 0x51, 0x8a);
ret |= bf3a03_write_reg(dev, 0x52, 0x04);
ret |= bf3a03_write_reg(dev, 0x53, 0x8a);
ret |= bf3a03_write_reg(dev, 0x54, 0x85);
ret |= bf3a03_write_reg(dev, 0x57, 0x04);
ret |= bf3a03_write_reg(dev, 0x58, 0x8a);
ret |= bf3a03_write_reg(dev, 0xb0, 0xa0);
ret |= bf3a03_write_reg(dev, 0xb1, 0x26);
ret |= bf3a03_write_reg(dev, 0xb2, 0x1c);
ret |= bf3a03_write_reg(dev, 0xb4, 0xfd);
ret |= bf3a03_write_reg(dev, 0xb0, 0x30);
ret |= bf3a03_write_reg(dev, 0xb1, 0xd8);
ret |= bf3a03_write_reg(dev, 0xb2, 0xb0);
ret |= bf3a03_write_reg(dev, 0xb4, 0xf1);
ret |= bf3a03_write_reg(dev, 0x3c, 0x40);
ret |= bf3a03_write_reg(dev, 0x56, 0x48);
ret |= bf3a03_write_reg(dev, 0x4d, 0x40);
ret |= bf3a03_write_reg(dev, 0x59, 0x40);
ret |= bf3a03_write_reg(dev, 0x35, 0x46);
ret |= bf3a03_write_reg(dev, 0x65, 0x38);
ret |= bf3a03_write_reg(dev, 0x66, 0x42);
ret |= bf3a03_write_reg(dev, 0x6a, 0xd1);
ret |= bf3a03_write_reg(dev, 0x23, 0x11);
ret |= bf3a03_write_reg(dev, 0xa2, 0x0b);
ret |= bf3a03_write_reg(dev, 0xa3, 0x26);
ret |= bf3a03_write_reg(dev, 0xa4, 0x04);
ret |= bf3a03_write_reg(dev, 0xa5, 0x26);
ret |= bf3a03_write_reg(dev, 0xa7, 0x15);
ret |= bf3a03_write_reg(dev, 0xa8, 0x0e);
ret |= bf3a03_write_reg(dev, 0xa9, 0x20);
ret |= bf3a03_write_reg(dev, 0xaa, 0x20);
ret |= bf3a03_write_reg(dev, 0xab, 0x16);
ret |= bf3a03_write_reg(dev, 0xac, 0x30);
ret |= bf3a03_write_reg(dev, 0xad, 0xf0);
ret |= bf3a03_write_reg(dev, 0xae, 0x57);
ret |= bf3a03_write_reg(dev, 0xc5, 0x66);
ret |= bf3a03_write_reg(dev, 0xc7, 0x38);
ret |= bf3a03_write_reg(dev, 0xc8, 0x0d);
ret |= bf3a03_write_reg(dev, 0xc9, 0x16);
ret |= bf3a03_write_reg(dev, 0xd3, 0x09);
ret |= bf3a03_write_reg(dev, 0xd4, 0x15);
ret |= bf3a03_write_reg(dev, 0xd0, 0x00);
ret |= bf3a03_write_reg(dev, 0xd1, 0x00);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "bf3a03_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("=============================================================================================\n");
SENSOR_PRINT("============ bf3a03_normal_dvp_24Minput_yuv422_linear_640x480_30fps init success! ===========\n");
SENSOR_PRINT("=============================================================================================\n");
return XMEDIA_SUCCESS;
}
}
xmedia_s32 bf3a03_init_image(xmedia_u32 dev, xmedia_u8 image_mode, xmedia_sensor_work_mode work_mode)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
switch (image_mode) {
case BF3A03_DVP_640X480_LINEAR_MODE:
ret = bf3a03_dvp_linear_640x480_init(dev);
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return ret;
}
SENSOR_PRIORITY_FUNC xmedia_s32 bf3a03_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
if (g_bf3a03_i2c_fd[dev] < 0) {
SENSOR_PRINT("Sensor dev [%d], i2c not open. please init i2c at first.\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_set_slave_addr(g_bf3a03_i2c_fd[dev], slave_addr);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
i2c_close(g_bf3a03_i2c_fd[dev]);
g_bf3a03_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_FAILURE;
}
g_bf3a03_i2c_addr[dev] = slave_addr;
SENSOR_PRINT("Sensor dev [%d] set slave addr 0x%x success.\n", dev, slave_addr);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 bf3a03_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr)
{
xmedia_s32 ret;
if (g_bf3a03_i2c_fd[dev] >= 0) {
SENSOR_PRINT("====== Sensor dev [%d], i2c already init !=======\n", dev);
return XMEDIA_SUCCESS;
}
if (i2c_dev == SENSOR_I2C_INVALID) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor i2c dev invalid! Please set i2c dev at first!\n");
return XMEDIA_ERRCODE_NOT_CONFIG;
}
g_bf3a03_i2c_fd[dev] = i2c_open(i2c_dev);
if (g_bf3a03_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "Open /dev/i2c_drv-%u error!\n", i2c_dev);
return XMEDIA_ERRCODE_OPEN_FAILED;
}
ret = bf3a03_set_slave_addr(dev, i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
SENSOR_PRINT("====== i2c[%d] init success!=======\n", i2c_dev);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 bf3a03_i2c_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
ret = i2c_close(g_bf3a03_i2c_fd[dev]);
if(ret < 0 ) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] close i2c failed!\n", dev);
return ret;
}
g_bf3a03_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 bf3a03_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data)
{
xmedia_s32 ret;
xmedia_u8 buf[BF3A03_DATA_BYTE];
if (g_bf3a03_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_read(g_bf3a03_i2c_fd[dev], g_bf3a03_i2c_addr[dev], addr, BF3A03_ADDR_BYTE, buf, BF3A03_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] read i2c addr [0x%X] failed!\n", dev, addr);
return ret;
}
*data = buf[0]; //BF3A03_DATA_BYTE == 1
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 bf3a03_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data)
{
xmedia_u32 idx = 0;
xmedia_s32 ret;
xmedia_u8 buf[8];
if (g_bf3a03_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
buf[idx] = addr & 0xff;
idx++;
buf[idx] = data & 0xff;
ret = i2c_write(g_bf3a03_i2c_fd[dev], g_bf3a03_i2c_addr[dev], buf, BF3A03_ADDR_BYTE + BF3A03_DATA_BYTE);
if (ret != (BF3A03_ADDR_BYTE + BF3A03_DATA_BYTE)) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_WRITE error!ret=%d.\n", ret);
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
xmedia_s32 bf3a03_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en)
{
xmedia_s32 ret;
xmedia_u32 mirror_flip_type;
bf3a03_read_reg(dev, BF3A03_REG_ADDR_MIRROR_FLIP, &mirror_flip_type);
if (mirror_en) {
mirror_flip_type |= 0x20;
} else {
mirror_flip_type &= 0xdf;
}
if (flip_en) {
mirror_flip_type |= 0x10;
} else {
mirror_flip_type &= 0xef;
}
ret = bf3a03_write_reg(dev, BF3A03_REG_ADDR_MIRROR_FLIP, mirror_flip_type);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "bf3a03_write_reg failed\n");
}
return XMEDIA_SUCCESS;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef __BF3A03_CTRL_H__
#define __BF3A03_CTRL_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BF3A03_I2C_ADDR 0xDC
#define BF3A03_ADDR_BYTE 1
#define BF3A03_DATA_BYTE 1
// bf3a03 specs list
#define BF3A03_DVP_640X480_LINEAR_MODE 1
xmedia_s32 bf3a03_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr);
xmedia_s32 bf3a03_i2c_exit(xmedia_u32 dev);
xmedia_s32 bf3a03_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data);
xmedia_s32 bf3a03_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data);
xmedia_s32 bf3a03_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en);
xmedia_s32 bf3a03_init_image(xmedia_u32 dev, xmedia_u8 img_mode, xmedia_sensor_work_mode work_mode);
xmedia_s32 bf3a03_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr);
#ifdef __cplusplus
}
#endif
#endif //__BF3A03_CTRL_H__
+53
View File
@@ -0,0 +1,53 @@
#ifndef __BF3A03_EX_H__
#define __BF3A03_EX_H__
#ifdef __cplusplus
extern "C" {
#endif
// Piris attr
static const xmedia_isp_piris_attr g_bf3a03_piris_attr = {
0,
1,
94,
62,
// Step-F number mapping table. Must be from small to large. F1.0 is 1024 and F32.0 is 1
{30, 35, 40, 45, 50, 56, 61, 67, 73, 79, 85, 92, 98, 105, 112, 120, 127, 135, 143, 150, 158,
166, 174, 183, 191, 200, 208, 217, 225, 234, 243, 252, 261, 270, 279, 289, 298, 307, 316, 325, 335, 344,
353, 362, 372, 381, 390, 399, 408, 417, 426, 435, 444, 453, 462, 470, 478, 486, 493, 500, 506, 512},
XMEDIA_ISP_IRIS_F_NO_1_4,
XMEDIA_ISP_IRIS_F_NO_5_6
};
static const xmedia_isp_awb_ccm g_bf3a03_awb_ccm = {
3,
{
{
6300,
{699,33237,26,32804,344,32820,32792,33114,626},
},
{
3850,
{622,33009,32893,32805,442,32917,32787,33015,522},
},
{
2750,
{556,32913,32923,32888,554,32946,32770,33052,542},
},
},
};
static const xmedia_isp_awb_agc_table g_bf3a03_awb_agc_table = {
// bvalid
1,
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
// saturation
{ 125, 120, 115, 115, 115, 115, 115, 105, 96, 86, 86, 76, 56, 56, 56, 56}
};
#ifdef __cplusplus
}
#endif
#endif
+5
View File
@@ -0,0 +1,5 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+20
View File
@@ -0,0 +1,20 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_cv2005
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/../include
SDK_USR_CFLAGS += -I.
AT := @
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
+6
View File
@@ -0,0 +1,6 @@
SRCS-y += cv2005.c
SRCS-y += cv2005_ctrl.c
SRCS-y += cv2005_master.c
SRCS-y += cv2005_slave.c
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
#ifndef __CV2005_H__
#define __CV2005_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
// sensor fps mode
#define CV2005_FULL_LINES_MAX 0xFFFFF
#define CV2005_VMAX_1920X1080_LINEAR 0x49C
#define CV2005_EXP_OFFSET_LINEAR 6
#define CV2005_REG_ADDR_EXP_H 0x304A
#define CV2005_REG_ADDR_EXP_M 0x3049
#define CV2005_REG_ADDR_EXP_L 0x3048
#define CV2005_REG_ADDR_AGAIN 0x3118
#define CV2005_REG_ADDR_DGAIN_H 0x311D
#define CV2005_REG_ADDR_DGAIN_L 0x311C
#define CV2005_REG_ADDR_VMAX_H 0x301E
#define CV2005_REG_ADDR_VMAX_M 0x301D
#define CV2005_REG_ADDR_VMAX_L 0x301C
typedef enum {
CV2005_REG_EXP_H = 0,
CV2005_REG_EXP_M,
CV2005_REG_EXP_L,
CV2005_REG_AGAIN,
CV2005_REG_DGAIN_H,
CV2005_REG_DGAIN_L,
CV2005_REG_VMAX_H,
CV2005_REG_VMAX_M,
CV2005_REG_VMAX_L,
CV2005_REG_MAX_NUM
} cv2005_reg_info;
#ifdef __cplusplus
}
#endif
#endif // __CV2005_H__
+216
View File
@@ -0,0 +1,216 @@
#include <stdio.h>
#include <string.h>
#include "i2c_dev.h"
#include "cv2005.h"
#include "cv2005_ctrl.h"
static xmedia_s32 g_cv2005_i2c_addr[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
static xmedia_s32 g_cv2005_i2c_fd[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
#define CV2005_REG_ADDR_MIRROR_FLIP 0x3028
#define CV2005_REG_ADDR_X_START 0x3038
#define CV2005_REG_ADDR_Y_START 0x3034
#define CV2005_REG_VALUE_X_START 4
#define CV2005_REG_VALUE_Y_START 4
static xmedia_s32 cv2005_2lane_linear_1920x1080_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= cv2005_write_reg(dev, 0x301C, 0x9C);
ret |= cv2005_write_reg(dev, 0x301D, 0x04);
ret |= cv2005_write_reg(dev, 0x301E, 0x00);
ret |= cv2005_write_reg(dev, 0x3020, 0x4E);
ret |= cv2005_write_reg(dev, 0x3021, 0x04);
ret |= cv2005_write_reg(dev, 0x3808, 0x41);
ret |= cv2005_write_reg(dev, 0x3031, 0x00);
ret |= cv2005_write_reg(dev, 0x3204, 0x40);
ret |= cv2005_write_reg(dev, 0x359d, 0x00);
ret |= cv2005_write_reg(dev, 0x389D, 0x0A);
ret |= cv2005_write_reg(dev, 0x389C, 0x6A);
ret |= cv2005_write_reg(dev, 0x38A0, 0x2B);
ret |= cv2005_write_reg(dev, 0x3878, 0x01);
ret |= cv2005_write_reg(dev, 0x3879, 0x15);
ret |= cv2005_write_reg(dev, 0x356F, 0x0f);
ret |= cv2005_write_reg(dev, 0x3109, 0x01);
ret |= cv2005_write_reg(dev, 0x3420, 0x2f);
ret |= cv2005_write_reg(dev, 0x3422, 0x87);
ret |= cv2005_write_reg(dev, 0x3424, 0x3f);
ret |= cv2005_write_reg(dev, 0x3426, 0x57);
ret |= cv2005_write_reg(dev, 0x3428, 0x2f);
ret |= cv2005_write_reg(dev, 0x3000, 0x00); // Streaming
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv2005_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("=============================================================================================\n");
SENSOR_PRINT("======== cv2005_normal_mipi_24Minput_2lane_10bit_linear_1920x1080_30fps init success ========\n");
SENSOR_PRINT("=============================================================================================\n");
return XMEDIA_SUCCESS;
}
}
xmedia_s32 cv2005_init_image(xmedia_u32 dev, xmedia_u8 image_mode, xmedia_sensor_work_mode work_mode)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
switch (image_mode) {
case CV2005_2LANE_1920X1080_LINEAR_MODE:
ret = cv2005_2lane_linear_1920x1080_init(dev);
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return ret;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv2005_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
if (g_cv2005_i2c_fd[dev] < 0) {
SENSOR_PRINT("Sensor dev [%d], i2c not open. please init i2c at first.\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_set_slave_addr(g_cv2005_i2c_fd[dev], slave_addr);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
i2c_close(g_cv2005_i2c_fd[dev]);
g_cv2005_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_FAILURE;
}
g_cv2005_i2c_addr[dev] = slave_addr;
SENSOR_PRINT("Sensor dev [%d] set slave addr 0x%x success.\n", dev, slave_addr);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv2005_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr)
{
xmedia_s32 ret;
if (g_cv2005_i2c_fd[dev] >= 0) {
SENSOR_PRINT("====== Sensor dev [%d], i2c already init !=======\n", dev);
return XMEDIA_SUCCESS;
}
if (i2c_dev == SENSOR_I2C_INVALID) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor i2c dev invalid! Please set i2c dev at first!\n");
return XMEDIA_ERRCODE_NOT_CONFIG;
}
g_cv2005_i2c_fd[dev] = i2c_open(i2c_dev);
if (g_cv2005_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "Open /dev/i2c_drv-%u error!\n", i2c_dev);
return XMEDIA_ERRCODE_OPEN_FAILED;
}
ret = cv2005_set_slave_addr(dev, i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
SENSOR_PRINT("====== i2c[%d] init success!=======\n", i2c_dev);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv2005_i2c_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
ret = i2c_close(g_cv2005_i2c_fd[dev]);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] close i2c failed!\n", dev);
return ret;
}
g_cv2005_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv2005_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data)
{
xmedia_s32 ret;
xmedia_u8 buf[CV2005_DATA_BYTE];
if (g_cv2005_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_read(g_cv2005_i2c_fd[dev], g_cv2005_i2c_addr[dev], addr, CV2005_ADDR_BYTE, buf, CV2005_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] read i2c addr [0x%X] failed!\n", dev, addr);
return ret;
}
*data = buf[0]; // CV2005_DATA_BYTE == 1
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv2005_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data)
{
xmedia_u32 idx = 0;
xmedia_s32 ret;
xmedia_u8 buf[8];
if (g_cv2005_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
buf[idx] = data & 0xff;
ret = i2c_write(g_cv2005_i2c_fd[dev], g_cv2005_i2c_addr[dev], buf, CV2005_ADDR_BYTE + CV2005_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_WRITE error!\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
xmedia_s32 cv2005_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en)
{
xmedia_s32 ret;
xmedia_u32 mirror_flip_type;
xmedia_u32 x, y;
cv2005_read_reg(dev, CV2005_REG_ADDR_MIRROR_FLIP, &mirror_flip_type);
if (mirror_en) {
mirror_flip_type |= 0x01;
x = CV2005_REG_VALUE_X_START + 1;
} else {
mirror_flip_type &= 0xfe;
x = CV2005_REG_VALUE_X_START;
}
if (flip_en) {
mirror_flip_type |= 0x02;
y = CV2005_REG_VALUE_Y_START + 1;
} else {
mirror_flip_type &= 0xfd;
y = CV2005_REG_VALUE_Y_START;
}
cv2005_write_reg(dev, CV2005_REG_ADDR_X_START, x);
cv2005_write_reg(dev, CV2005_REG_ADDR_Y_START, y);
ret = cv2005_write_reg(dev, CV2005_REG_ADDR_MIRROR_FLIP, mirror_flip_type);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv2005_write_reg failed\n");
}
return XMEDIA_SUCCESS;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef __CV2005_CTRL_H__
#define __CV2005_CTRL_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CV2005_I2C_ADDR 0x6a
#define CV2005_ADDR_BYTE 2
#define CV2005_DATA_BYTE 1
// cv2005 specs list
#define CV2005_2LANE_1920X1080_LINEAR_MODE 1
xmedia_s32 cv2005_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr);
xmedia_s32 cv2005_i2c_exit(xmedia_u32 dev);
xmedia_s32 cv2005_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data);
xmedia_s32 cv2005_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data);
xmedia_s32 cv2005_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en);
xmedia_s32 cv2005_init_image(xmedia_u32 dev, xmedia_u8 img_mode, xmedia_sensor_work_mode work_mode);
xmedia_s32 cv2005_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr);
#ifdef __cplusplus
}
#endif
#endif //__CV2005_CTRL_H__
+102
View File
@@ -0,0 +1,102 @@
#ifndef __CV2005_EX_H__
#define __CV2005_EX_H__
#ifdef __cplusplus
extern "C" {
#endif
// Piris attr
static const xmedia_isp_piris_attr g_cv2005_piris_attr = {
0,
1,
94,
62,
// Step-F number mapping table. Must be from small to large. F1.0 is 1024 and F32.0 is 1
{30, 35, 40, 45, 50, 56, 61, 67, 73, 79, 85, 92, 98, 105, 112, 120, 127, 135, 143, 150, 158,
166, 174, 183, 191, 200, 208, 217, 225, 234, 243, 252, 261, 270, 279, 289, 298, 307, 316, 325, 335, 344,
353, 362, 372, 381, 390, 399, 408, 417, 426, 435, 444, 453, 462, 470, 478, 486, 493, 500, 506, 512},
XMEDIA_ISP_IRIS_F_NO_1_4,
XMEDIA_ISP_IRIS_F_NO_5_6
};
static const xmedia_isp_awb_ccm g_cv2005_awb_ccm = {
4,
{
{
6150,
{
0x018C, 0x805D, 0x802F,
0x803E, 0x0184, 0x8046,
0x8001, 0x80C5, 0x01C6
},
},
{
4850,
{
0x01FA, 0x80E0, 0x801A,
0x8063, 0x0177, 0x8014,
0x8013, 0x811F, 0x0232
},
},
{
3650,
{
0x01CB, 0x8030, 0x809B,
0x806B, 0x01BD, 0x8052,
0x800C, 0x80ED, 0x01F9
},
},
{
2650,
{
0x01B9, 0x80A5, 0x8014,
0x8090, 0x01A7, 0x8017,
0x801D, 0x8159, 0x0276
},
},
},
};
static const xmedia_isp_awb_agc_table g_cv2005_awb_agc_table = {
/* bvalid */
1,
/* saturation */
/* 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 */
{0x80, 0x78, 0x73, 0x6E, 0x69, 0x5F, 0x58, 0x50, 0x48, 0x40, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38}
};
static const xmedia_isp_blc_attr g_cv2005_blc_attr = {
.op_type = 0,
.manual_attr = {
.black_level = {512,512,512,512},
},
.auto_attr = {
.iso_num = 10,
.iso_level = {100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800, 409600, 819200, 1638400, 3276800},
.black_level = {
{ 256,256,256,256, },//0
{ 256,256,256,256, },//1
{ 256,256,256,256, },//2
{ 256,256,256,256, },//3
{ 256,256,256,256, },//4
{ 256,256,256,256, },//5
{ 256,256,256,256, },//6
{ 256,256,256,256, },//7
{ 256,256,256,256, },//8
{ 256,256,256,256, },//9
},
},
};
#ifdef __cplusplus
}
#endif
#endif // __CV2005_EX_H__
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+20
View File
@@ -0,0 +1,20 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_cv4003
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/../include
SDK_USR_CFLAGS += -I.
AT := @
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
+4
View File
@@ -0,0 +1,4 @@
SRCS-y += cv4003.c
SRCS-y += cv4003_ctrl.c
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
#ifndef __CV4003_H__
#define __CV4003_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CV4003_VMAX_4M_LINEAR 0x15e0 // 10bit
#define CV4003_VMAX_1M_LINEAR 0x708 // 10bit
#define CV4003_EXP_OFFSET_LINEAR 8
// CV4003 Register Address
#define CV4003_REG_ADDR_EXP_H 0x304a
#define CV4003_REG_ADDR_EXP_M 0x3049
#define CV4003_REG_ADDR_EXP_L 0x3048
#define CV4003_REG_ADDR_AGAIN 0x3118
#define CV4003_REG_ADDR_DGAIN_H 0x311D
#define CV4003_REG_ADDR_DGAIN_L 0x311C
#define CV4003_REG_ADDR_VMAX_H 0x301E
#define CV4003_REG_ADDR_VMAX_M 0x301D
#define CV4003_REG_ADDR_VMAX_L 0x301C
typedef enum {
CV4003_REG_EXP_L = 0,
CV4003_REG_EXP_M,
CV4003_REG_EXP_H,
CV4003_REG_AGAIN,
CV4003_REG_DGAIN_L,
CV4003_REG_DGAIN_H,
CV4003_REG_VMAX_L,
CV4003_REG_VMAX_M,
CV4003_REG_VMAX_H,
CV4003_REG_MAX_NUM,
} cv4003_reg_index;
#ifdef __cplusplus
}
#endif
#endif // __CV4003_H__
+729
View File
@@ -0,0 +1,729 @@
#include <stdio.h>
#include <string.h>
#include "i2c_dev.h"
#include "cv4003.h"
#include "cv4003_ctrl.h"
#define CV4003_REG_ADDR_MIRROR_FLIP 0x3028
SENSOR_PRIORITY_DATA static xmedia_s32 g_cv4003_i2c_fd[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
SENSOR_PRIORITY_DATA static xmedia_s32 g_cv4003_i2c_addr[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
#ifdef USE_PREROLL_INFO
static xmedia_u32 g_sns_info_expo; //exposure time, unit : ns
static xmedia_u32 g_sns_info_gain; //real_gain * 1024
static xmedia_u32 g_sns_info_luma;
// static unsigned int sns_info_ev; //gain * expo_line.
xmedia_u32 exp_time_clac(xmedia_u32 dev)
{
xmedia_u32 exp_time = 0x08;
// ns 转化成以行为单位的曝光时间 5292ns:一行的曝光时间; 5592:vmax
if (g_sns_info_expo > 5292) {
g_sns_info_expo = g_sns_info_expo / 5292;
exp_time = (g_sns_info_expo > 5592) ? 0 : (5592 - g_sns_info_expo);
exp_time = (exp_time > (5592 - 2)) ? (5592 - 2) : exp_time;
exp_time = exp_time / 2 * 2;
exp_time = (exp_time < 8)? 8: exp_time;
}
return exp_time;
}
xmedia_void gain_clac(xmedia_u32 dev, xmedia_s32 *again, xmedia_s32 *dgain)
{
xmedia_s32 again_reg, again_real, dgain_want, dgain_reg;
if (g_sns_info_gain <= 32768) { // 32 * 1024
again_reg = (262144 - 268435456 / g_sns_info_gain) / 1024; // 等价于除以1024
again_real = 262144 / (256 - again_reg);
dgain_want = g_sns_info_gain * 1024 / again_real;
dgain_reg = dgain_want * 64 / 1024;
} else {
again_reg = 0xf8;
again_real = 32768;
dgain_want = g_sns_info_gain * 1024 / again_real;
dgain_reg = dgain_want / 16;
}
if (dgain_reg < 64) {
dgain_reg = 64;
}
*again = again_reg;
*dgain = dgain_reg;
SENSOR_PRINT("again %x, dgain %x \n", *again, *dgain);
return;
}
//name :cv4003_get_internal_ae_info
//desc: get exposure time & Gain infomation of final frame.
// 在预录即将结束之前,获取到最后一张图的曝光时间和增益信息.
//timing: 1. 在预录即将结束前调用.
static xmedia_s32 cv4003_get_internal_ae_info(xmedia_u32 dev)
{
xmedia_s32 ret = 0;
xmedia_uchar mode = 0;
xmedia_s32 intl_expo = 0;
xmedia_s32 intl_dgain = 0;
xmedia_s32 intl_again = 0;
xmedia_s32 dgain_reg = 0;
xmedia_s32 again_reg = 0;
xmedia_s32 intl_luma = 0;
xmedia_s64 gain_tmp = 0;
xmedia_u32 tmp[3];
xmedia_s32 one_line_ns_fullmode = 5952; //ns. //10**9/1.0/30/0x15e0
xmedia_s32 one_line_ns_preroll_720P = 6360; //ns. //10**9/1.0/5/0x2bc0
xmedia_s32 fullmode_max_exposure_lines = 0x15e0; //lines.
// 获取模式值
// mode = cv4003_read_reg(dev, 0x347B);
// 获取曝光值
ret |= cv4003_read_reg(dev, 0x3040, &tmp[0]);
ret |= cv4003_read_reg(dev, 0x3041, &tmp[1]);
ret |= cv4003_read_reg(dev, 0x3042, &tmp[2]);
intl_expo = (tmp[2] << 16) | (tmp[1] << 8) | tmp[0];
// 检查读取过程中是否有错误发生
// if (mode == -1 || tmp[0] == -1 || tmp[1] == -1 || tmp[2] == -1)
// goto error;
// 获取增益值
ret |= cv4003_read_reg(dev, 0x3340, &tmp[0]); // DGain_L
ret |= cv4003_read_reg(dev, 0x3341, &tmp[1]); // DGain_H
ret |= cv4003_read_reg(dev, 0x3342, &tmp[2]); // AGain
dgain_reg = (tmp[1] << 8) | tmp[0];
again_reg = tmp[2];
// 检查读取过程中是否有错误发生
if (tmp[0] == -1 || tmp[1] == -1 || tmp[2] == -1)
goto error;
// Get luma value
ret |= cv4003_read_reg(dev, 0x32C2, &tmp[0]);
intl_luma = tmp[0];
if(ret) {
goto error;
}
SENSOR_PRINT("###AE-INFO##[Get]##> expo:0x%x, gain(a,d):0x%x,0x%x luma:0x%x ,mode:0x%x. \n",
intl_expo, intl_again, intl_dgain, intl_luma, mode);
SENSOR_PRINT("again_reg:0x%x. dgain_reg:0x%x.intl_luma:0x%x.\n", again_reg, dgain_reg, intl_luma);
g_sns_info_expo = 0;
g_sns_info_gain = 0;
g_sns_info_luma = 0;
if (again_reg == 0x00) {
if( intl_expo * one_line_ns_preroll_720P >
fullmode_max_exposure_lines*one_line_ns_fullmode - one_line_ns_fullmode * 10)
{
g_sns_info_expo = fullmode_max_exposure_lines * one_line_ns_fullmode - one_line_ns_fullmode * 10 ;
g_sns_info_gain = intl_expo * one_line_ns_preroll_720P * 16 /
fullmode_max_exposure_lines * 1024 / one_line_ns_fullmode / 16; // 16 & /16 is for prection
SENSOR_PRINT("###shaokc0..720P.g_sns_info_gain = %d\n", g_sns_info_gain);
} else {
g_sns_info_expo = intl_expo * one_line_ns_preroll_720P;
g_sns_info_gain = 1024;
}
} else {
g_sns_info_expo = fullmode_max_exposure_lines * one_line_ns_fullmode - one_line_ns_fullmode * 10;
intl_again = 256 * 1024 / (256 - again_reg);
intl_dgain = dgain_reg * 1024 / 0x40;
gain_tmp = intl_again * intl_dgain;
//gain_tmp = gain_tmp * intl_expo * one_line_ns_preroll_720P
// / fullmode_max_exposure_lines / one_line_ns_fullmode; //shaokc. may has risk. pay attention!!!!
gain_tmp = gain_tmp / fullmode_max_exposure_lines * one_line_ns_preroll_720P
/ one_line_ns_fullmode * intl_expo ; //shaokc. may has risk. pay attention!!!!
gain_tmp /= 1024;
//g_sns_info_gain = (int64_t)gain_tmp; //---------------------暂时不强制转化
g_sns_info_gain = gain_tmp;
SENSOR_PRINT("###shaokc2...720P g_sns_info_gain = %d\n", g_sns_info_gain);
}
if (g_sns_info_gain > 256 * 1024) {
g_sns_info_gain = 256 * 1024;
}
SENSOR_PRINT("###AE-INFO##[PPP]##> g_sns_info_expo:%d, gain:%d,a:%d,d:%d,tmp:%lld\n",
g_sns_info_expo, g_sns_info_gain,intl_again,intl_dgain,gain_tmp);
return ret;
error:
g_sns_info_expo = -1;
g_sns_info_gain = -1;
g_sns_info_luma = -1;
return ret;
}
static xmedia_s32 g_psram_final_addr = 0;
//name :cv4003_get_preroll_psram_final_addr
//desc : read psram final address.
// 在预录即将结束之前,获取到最后一张raw图对应的PSRAM地址指针(g_psram_final_addr)
//timing: 1. call cv4003_get_internal_ae_info 获取到最新的AE信息,
// 这个信息可以供后续主控做fastAE使用,或者直接出大图的时候使用.
// 2. call stream off.(0x3000,0x01). 确保当前数据被完整写入.
// (如果遇到数据正在写入中,则一直查询状态寄存器,确保数据被写入.)
// 3. 读取相关寄存器,换算 g_psram_final_addr
xmedia_s32 cv4003_get_preroll_psram_final_addr(xmedia_u32 dev)
{
xmedia_s32 ret = 0;
xmedia_u8 psram_final_addr_okflag = 0;
xmedia_u32 val_sensor_sys_standby = 0;
xmedia_u32 val_dc;
xmedia_u32 val_dd;
xmedia_u32 val_de;
xmedia_u32 val_df;
xmedia_u32 wait_ms;
//要停流之前,先读取曝光信息.
// Full Mode Get AE info
ret = cv4003_get_internal_ae_info(dev);
SENSOR_PRINT("sizes[1]===> cv4003 Full Mode Get Internal AE Info(%d)\n", ret);
if(ret < XMEDIA_SUCCESS) {
return ret;
}
//如果遇到正在写入,等待20ms可以确保数据被写完整到PSRAM当中.
ret |= cv4003_write_reg(dev, 0x3000, 0x01);
//usleep(20000);
cv4003_read_reg(dev, 0x30D8, &val_sensor_sys_standby);
//查询当前是否处于预录正在写入中,如果正在写入,等待写入完成.最大等待30ms,查询不到也退出逻辑,避免异常卡死.
wait_ms = 0;
while(val_sensor_sys_standby == 0x02 && wait_ms <= 30) //1是standby0是非standby
{
usleep(1*1000);
ret |= cv4003_read_reg(dev, 0x30D8, &val_sensor_sys_standby);
SENSOR_PRINT(" wait sensor sys standby...\n");
wait_ms++;
}
if (wait_ms > 30) {
SENSOR_PRINT(" wait sensor sys standby timeout!\n");
}
//获取到PSRAM的final address. 这个是预录的最后一帧的最后一个byte的地址.
ret |= cv4003_read_reg(dev, 0x32dc, &val_dc);
ret |= cv4003_read_reg(dev, 0x32dd, &val_dd);
ret |= cv4003_read_reg(dev, 0x32de, &val_de);
ret |= cv4003_read_reg(dev, 0x32df, &val_df);
SENSOR_PRINT("psram final addr: 0x%02X%02X%02X%02X\n", val_df, val_de, val_dd,val_dc);
wait_ms = 0;
g_psram_final_addr = (val_df << 24) | (val_de << 16) | (val_dd << 8) | val_dc;
while (wait_ms <= 15)
{
if((g_psram_final_addr + 1) % (1280 * 720) == 0)
{
psram_final_addr_okflag = 1;
break;
} else {
psram_final_addr_okflag = 0;
usleep(1*1000);
//获取到PSRAM的final address. 这个是预录的最后一帧的最后一个byte的地址.
ret |= cv4003_read_reg(dev, 0x32dc, &val_dc);
ret |= cv4003_read_reg(dev, 0x32dd, &val_dd);
ret |= cv4003_read_reg(dev, 0x32de, &val_de);
ret |= cv4003_read_reg(dev, 0x32df, &val_df);
SENSOR_PRINT("psram final addr: 0x%02X%02X%02X%02X\n", val_df, val_de, val_dd, val_dc);
g_psram_final_addr = (val_df << 24) | (val_de << 16) | (val_dd << 8) | val_dc;
wait_ms++;
}
}
if(ret < XMEDIA_SUCCESS) {
return ret;
}
if (psram_final_addr_okflag == 0) {
SENSOR_PRINT("shaokc Warning!!!!!! psram final addr is not ok, g_psram_final_addr: 0x%08x\n", g_psram_final_addr);
}
return XMEDIA_SUCCESS;
}
//name :cv4003_set_psram_read_region
//desc: set psram read region.
// 设置回读的起始和结束地址.确保出图顺序是对的(
//从最久远的一张开始回读,一直到最新的一张,出完之后,就sensor 自动停止出流.)
//timing: 1. set psram readback seq (cv4003_preroll_720p_readback_psram2cis2mipi_init);
// 2. call cv4003_set_psram_read_region
// 3. stream on.
SENSOR_PRIORITY_FUNC static xmedia_s32 cv4003_set_psram_read_region(xmedia_u32 dev, xmedia_u32 final_addr)
{
//final_addr OPI mode address is 4 byte.
xmedia_s32 ret = 0;
xmedia_u32 sta = final_addr + 1;
xmedia_u32 end = final_addr;
if (final_addr == 0x3F47fff) { //when final addr is full.(eg: 1280*720*72fps @8bit )
sta = 0x0;
end = 0x3F47fff;
}
// Set Read Region Start
ret |= cv4003_write_reg(dev, 0x32E8, (xmedia_u8)(sta));
ret |= cv4003_write_reg(dev, 0x32E9, (xmedia_u8)(sta >> 8));
ret |= cv4003_write_reg(dev, 0x32EA, (xmedia_u8)(sta >> 16));
ret |= cv4003_write_reg(dev, 0x32EB, (xmedia_u8)(sta >> 24));
// Set Read Region End
ret |= cv4003_write_reg(dev, 0x32EC, (xmedia_u8)(end));
ret |= cv4003_write_reg(dev, 0x32ED, (xmedia_u8)(end >> 8));
ret |= cv4003_write_reg(dev, 0x32EE, (xmedia_u8)(end >> 16));
ret |= cv4003_write_reg(dev, 0x32EF, (xmedia_u8)(end >> 24));
return ret;
}
xmedia_s32 cv4003_preroll_720p_write_cis2psram_init(xmedia_u32 dev)
{
xmedia_u32 ret = XMEDIA_SUCCESS;
ret |= cv4003_write_reg(dev, 0x3010, 0x01);
ret |= cv4003_write_reg(dev, 0x3011, 0x01);
ret |= cv4003_write_reg(dev, 0x3017, 0x32);
ret |= cv4003_write_reg(dev, 0x301C, 0x2A); // [19:0] FRAME_LENGTH //3fps
ret |= cv4003_write_reg(dev, 0x301D, 0xE5);
ret |= cv4003_write_reg(dev, 0x301E, 0x00);
ret |= cv4003_write_reg(dev, 0x3020, 0x2C); // [15:0] LINE_LENGTH = 012C(dec:300)
ret |= cv4003_write_reg(dev, 0x3021, 0x01);
ret |= cv4003_write_reg(dev, 0x3068, 0x61);
ret |= cv4003_write_reg(dev, 0x302C, 0x01);
ret |= cv4003_write_reg(dev, 0x30D0, 0x01);
ret |= cv4003_write_reg(dev, 0x30D1, 0x6E);
ret |= cv4003_write_reg(dev, 0x30D2, 0x6E);
ret |= cv4003_write_reg(dev, 0x30D3, 0x50);
ret |= cv4003_write_reg(dev, 0x30D4, 0x02);
ret |= cv4003_write_reg(dev, 0x30D5, 0x08);
ret |= cv4003_write_reg(dev, 0x3139, 0x01);
ret |= cv4003_write_reg(dev, 0x3151, 0x01);
ret |= cv4003_write_reg(dev, 0x3206, 0x01);
ret |= cv4003_write_reg(dev, 0x3218, 0x01);
ret |= cv4003_write_reg(dev, 0x32D2, 0x04); // [10:0] PS_WR_ADDR_OFST = 004(dec:4)
ret |= cv4003_write_reg(dev, 0x32D3, 0x00);
ret |= cv4003_write_reg(dev, 0x330C, 0x90);
ret |= cv4003_write_reg(dev, 0x330D, 0x00);
ret |= cv4003_write_reg(dev, 0x330E, 0x80);
ret |= cv4003_write_reg(dev, 0x330F, 0x04);
ret |= cv4003_write_reg(dev, 0x3310, 0x49);
ret |= cv4003_write_reg(dev, 0x3311, 0x00);
ret |= cv4003_write_reg(dev, 0x3312, 0x46);
ret |= cv4003_write_reg(dev, 0x3313, 0x02);
ret |= cv4003_write_reg(dev, 0x335C, 0x03);
ret |= cv4003_write_reg(dev, 0x335D, 0x03);
ret |= cv4003_write_reg(dev, 0x337C, 0x08); // [10:0] BLK_STAX = 008(dec:08)
ret |= cv4003_write_reg(dev, 0x337D, 0x00);
ret |= cv4003_write_reg(dev, 0x337E, 0x16); // [5:0] UNIT_SIZEX = 16(dec:22)
ret |= cv4003_write_reg(dev, 0x3380, 0x08); // [11:0] BLK_STAY = 008(dec:8)
ret |= cv4003_write_reg(dev, 0x3381, 0x00);
ret |= cv4003_write_reg(dev, 0x3382, 0x58); // [7:0] UNIT_SIZEY = 58(dec:88)
ret |= cv4003_write_reg(dev, 0x3524, 0x05);
ret |= cv4003_write_reg(dev, 0x351F, 0x19);
ret |= cv4003_write_reg(dev, 0x3527, 0x05);
ret |= cv4003_write_reg(dev, 0x3522, 0x08);
ret |= cv4003_write_reg(dev, 0x3523, 0x08);
ret |= cv4003_write_reg(dev, 0x3525, 0x10);
ret |= cv4003_write_reg(dev, 0x3526, 0x1B);
ret |= cv4003_write_reg(dev, 0x350D, 0x7F);
ret |= cv4003_write_reg(dev, 0x362E, 0xAA);
ret |= cv4003_write_reg(dev, 0x36B6, 0xAA);
ret |= cv4003_write_reg(dev, 0x366E, 0x01);
ret |= cv4003_write_reg(dev, 0x3703, 0x03);
ret |= cv4003_write_reg(dev, 0x3808, 0xB0); // [7:0] PLL_MUL_NUM_POST = 8C(dec:140)
ret |= cv4003_write_reg(dev, 0x380A, 0x01); // [3:0] PLL_DIV_NUM_POST = 1(dec:1)
ret |= cv4003_write_reg(dev, 0x3814, 0x02);
ret |= cv4003_write_reg(dev, 0x3815, 0x00);
ret |= cv4003_write_reg(dev, 0x3827, 0x00);
ret |= cv4003_write_reg(dev, 0x394A, 0x06);
ret |= cv4003_write_reg(dev, 0x394B, 0x00);
ret |= cv4003_write_reg(dev, 0x3953, 0x10);
ret |= cv4003_write_reg(dev, 0x3953, 0x30);
ret |= cv4003_write_reg(dev, 0x32D8, 0x0B); // [27:0] PS_WR_ADDR_MAX 128Mbit容量最多存放Raw10数据14帧
ret |= cv4003_write_reg(dev, 0x32D9, 0x0F);
ret |= cv4003_write_reg(dev, 0x32DA, 0xF7);
ret |= cv4003_write_reg(dev, 0x32DB, 0x00);
ret |= cv4003_write_reg(dev, 0x3034, 0x04);
ret |= cv4003_write_reg(dev, 0x3035, 0x00);
ret |= cv4003_write_reg(dev, 0x3036, 0xD0);
ret |= cv4003_write_reg(dev, 0x3037, 0x02);
ret |= cv4003_write_reg(dev, 0x3038, 0x50);
ret |= cv4003_write_reg(dev, 0x3039, 0x00);
ret |= cv4003_write_reg(dev, 0x303A, 0x00);
ret |= cv4003_write_reg(dev, 0x303B, 0x05);
ret |= cv4003_write_reg(dev, 0x3308, 0xB0);//AE_TARGET
ret |= cv4003_write_reg(dev, 0x3309, 0x00);
ret |= cv4003_write_reg(dev, 0x3204, 0x40);
ret |= cv4003_write_reg(dev, 0x3673, 0x00);
ret |= cv4003_write_reg(dev, 0x385A, 0x03);
ret |= cv4003_write_reg(dev, 0x38AD, 0x11);
ret |= cv4003_write_reg(dev, 0x3638, 0x02);
ret |= cv4003_write_reg(dev, 0x3639, 0x00);
ret |= cv4003_write_reg(dev, 0x3628, 0x64);
ret |= cv4003_write_reg(dev, 0x3629, 0x00);
ret |= cv4003_write_reg(dev, 0x369C, 0x64);
ret |= cv4003_write_reg(dev, 0x369D, 0x00);
ret |= cv4003_write_reg(dev, 0x360C, 0x01);
ret |= cv4003_write_reg(dev, 0x360E, 0x01);
ret |= cv4003_write_reg(dev, 0x3000, 0x00);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv4003_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("=============PREROLL CVSENS CV4003_720P_3FPS_10BIT_LINEAR_Init_OK! ==============\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
}
#endif
SENSOR_PRIORITY_FUNC static xmedia_s32 cv4003_2lane_linear_2560x1440_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
//reset
ret |= cv4003_write_reg(dev, 0x3004,0x01);
ret |= cv4003_write_reg(dev, 0x3004,0x00);
// ret |= cv4003_write_reg(dev, 0x3012,0xF0);
ret |= cv4003_write_reg(dev, 0x300D,0x01);
ret |= cv4003_write_reg(dev, 0x300E,0x00);
ret |= cv4003_write_reg(dev, 0x3204,0x40);
ret |= cv4003_write_reg(dev, 0x3478,0x00);
ret |= cv4003_write_reg(dev, 0x385A,0x03);
ret |= cv4003_write_reg(dev, 0x310C,0x64);
ret |= cv4003_write_reg(dev, 0x3048,0x08);
ret |= cv4003_write_reg(dev, 0x3134,0x01);
ret |= cv4003_write_reg(dev, 0x326c,0xdc);
ret |= cv4003_write_reg(dev, 0x326e,0x24);
ret |= cv4003_write_reg(dev, 0x3154,0x11);
ret |= cv4003_write_reg(dev, 0x31BC,0x40);
ret |= cv4003_write_reg(dev, 0x31D5,0x03);
ret |= cv4003_write_reg(dev, 0x31D6,0x04);
ret |= cv4003_write_reg(dev, 0x3164,0x09);
ret |= cv4003_write_reg(dev, 0x351F,0x32);
ret |= cv4003_write_reg(dev, 0x3527,0x05);
ret |= cv4003_write_reg(dev, 0x38AD,0x10);
ret |= cv4003_write_reg(dev, 0x3638,0x02);
ret |= cv4003_write_reg(dev, 0x3639,0x00);
ret |= cv4003_write_reg(dev, 0x301c,0xe0);
ret |= cv4003_write_reg(dev, 0x301d,0x15);
ret |= cv4003_write_reg(dev, 0x3020,0x89);
ret |= cv4003_write_reg(dev, 0x3021,0x01);
ret |= cv4003_write_reg(dev, 0x3048,0x0A);
////CVSENS Sensor Window setting.
//full_width = 2888
//full_height = 1628
//active_width = 2560
//active_height = 1440
#ifdef USE_PREROLL_INFO
xmedia_u32 exp_time = 0x08;
xmedia_s32 again = 0x00;
xmedia_s32 dgain = 0x40;
exp_time = exp_time_clac(dev);
gain_clac(dev, &again, &dgain);
// 配置根据小图换成出大图的曝光时间 again dgain
ret |= cv4003_write_reg(dev, 0x3048, exp_time & 0xFF);
ret |= cv4003_write_reg(dev, 0x3049, (exp_time & 0x00FF00) >> 8);
ret |= cv4003_write_reg(dev, 0x3118, again & 0xff); //Again
ret |= cv4003_write_reg(dev, 0x311c, dgain & 0xff); //Dgain Low
ret |= cv4003_write_reg(dev, 0x311d, (dgain & 0xff00) >> 8); //Dgain High
#endif
ret |= cv4003_write_reg(dev, 0x3014,0x04); //WCROP_MODE
ret |= cv4003_write_reg(dev, 0x303C,0x56); //Y_WCROP_STA_L
ret |= cv4003_write_reg(dev, 0x303D,0x00); //Y_WCROP_STA_H
ret |= cv4003_write_reg(dev, 0x303E,0xb0); //Y_WCROP_HEIGHT_L
ret |= cv4003_write_reg(dev, 0x303F,0x05); //Y_WCROP_HEIGHT_H
ret |= cv4003_write_reg(dev, 0x3030,0x01); //DCROP_MODE
ret |= cv4003_write_reg(dev, 0x3038,0xa4); //X_CROP_STA_L
ret |= cv4003_write_reg(dev, 0x3039,0x00); //X_CROP_STA_H
ret |= cv4003_write_reg(dev, 0x303A,0x00); //X_CROP_WIDTH_L
ret |= cv4003_write_reg(dev, 0x303B,0x0a); //X_CROP_WIDTH_H
ret |= cv4003_write_reg(dev, 0x3034,0x08); //Y_DCROP_STA_L
ret |= cv4003_write_reg(dev, 0x3035,0x00); //Y_DCROP_STA_H
ret |= cv4003_write_reg(dev, 0x3036,0xa0); //Y_DCROP_HEIGHT_L
ret |= cv4003_write_reg(dev, 0x3037,0x05); //Y_DCROP_HEIGHT_H
//split gain Enable.
ret |= cv4003_write_reg(dev, 0x3109,0x01); //Use Again * Dgain.
ret |= cv4003_write_reg(dev, 0x3000,0x00); //Streaming
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv4003_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("=== CV4003_24MInput_MIPI_2lane_10bit_2560x1440_30fps init success!===============\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
}
SENSOR_PRIORITY_FUNC static xmedia_s32 cv4003_preroll_720p_readback_psram2cis2mipi_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= cv4003_write_reg(dev, 0x3010, 0x01);
ret |= cv4003_write_reg(dev, 0x3011, 0x01);
ret |= cv4003_write_reg(dev, 0x3017, 0x32);
ret |= cv4003_write_reg(dev, 0x301C, 0x08); // [19:0] FRAME_LENGTH = 00708(dec:1800)
ret |= cv4003_write_reg(dev, 0x301D, 0x07);
ret |= cv4003_write_reg(dev, 0x301E, 0x00);
ret |= cv4003_write_reg(dev, 0x3020, 0xF3); // [15:0] LINE_LENGTH = 00F3(dec:243)
ret |= cv4003_write_reg(dev, 0x3021, 0x00);
ret |= cv4003_write_reg(dev, 0x302C, 0x01);
ret |= cv4003_write_reg(dev, 0x3034, 0x04);
ret |= cv4003_write_reg(dev, 0x3035, 0x00);
ret |= cv4003_write_reg(dev, 0x3036, 0xD0);
ret |= cv4003_write_reg(dev, 0x3037, 0x02);
ret |= cv4003_write_reg(dev, 0x3038, 0x50);
ret |= cv4003_write_reg(dev, 0x3039, 0x00);
ret |= cv4003_write_reg(dev, 0x303A, 0x00);
ret |= cv4003_write_reg(dev, 0x303B, 0x05);
ret |= cv4003_write_reg(dev, 0x305C, 0x01);
ret |= cv4003_write_reg(dev, 0x3218, 0x01);
ret |= cv4003_write_reg(dev, 0x32D2, 0x04); // [10:0] PS_WR_ADDR_OFST = 004(dec:4)
ret |= cv4003_write_reg(dev, 0x32D3, 0x00);
ret |= cv4003_write_reg(dev, 0x32E5, 0x03);
ret |= cv4003_write_reg(dev, 0x32F0, 0xD0);
ret |= cv4003_write_reg(dev, 0x32F1, 0x02);
ret |= cv4003_write_reg(dev, 0x32F2, 0x00);
ret |= cv4003_write_reg(dev, 0x32F3, 0x05);
ret |= cv4003_write_reg(dev, 0x3418, 0x77);
ret |= cv4003_write_reg(dev, 0x3419, 0x00);
ret |= cv4003_write_reg(dev, 0x341A, 0x37);
ret |= cv4003_write_reg(dev, 0x341B, 0x00);
ret |= cv4003_write_reg(dev, 0x341C, 0x37);
ret |= cv4003_write_reg(dev, 0x341D, 0x00);
ret |= cv4003_write_reg(dev, 0x341E, 0xE7);
ret |= cv4003_write_reg(dev, 0x341F, 0x00);
ret |= cv4003_write_reg(dev, 0x3420, 0x37);
ret |= cv4003_write_reg(dev, 0x3421, 0x00);
ret |= cv4003_write_reg(dev, 0x3422, 0x9F);
ret |= cv4003_write_reg(dev, 0x3423, 0x00);
ret |= cv4003_write_reg(dev, 0x3424, 0x37);
ret |= cv4003_write_reg(dev, 0x3425, 0x00);
ret |= cv4003_write_reg(dev, 0x3426, 0x57);
ret |= cv4003_write_reg(dev, 0x3427, 0x00);
ret |= cv4003_write_reg(dev, 0x3428, 0x2F);
ret |= cv4003_write_reg(dev, 0x3429, 0x00);
ret |= cv4003_write_reg(dev, 0x3808, 0x8c); // [7:0] PLL_MUL_NUM_POST = 8C(dec:140)
ret |= cv4003_write_reg(dev, 0x380A, 0x01); // [3:0] PLL_DIV_NUM_POST = 1(dec:1)
ret |= cv4003_write_reg(dev, 0x3814, 0x02);
ret |= cv4003_write_reg(dev, 0x3815, 0x00);
ret |= cv4003_write_reg(dev, 0x3827, 0x00);
ret |= cv4003_write_reg(dev, 0x3829, 0x00);
ret |= cv4003_write_reg(dev, 0x394A, 0x06);
ret |= cv4003_write_reg(dev, 0x394B, 0x00);
ret |= cv4003_write_reg(dev, 0x3953, 0x10);
ret |= cv4003_write_reg(dev, 0x3953, 0x30);
ret |= cv4003_write_reg(dev, 0x32D8, 0x0B); // [27:0] PS_WR_ADDR_MAX //128Mbit容量,Max存14frame
ret |= cv4003_write_reg(dev, 0x32D9, 0x0F);
ret |= cv4003_write_reg(dev, 0x32DA, 0xF7);
ret |= cv4003_write_reg(dev, 0x32DB, 0x00);
ret |= cv4003_write_reg(dev, 0x32E8, 0x00); // [27:0] PS_RD_ADDR_STA
ret |= cv4003_write_reg(dev, 0x32E9, 0x00);
ret |= cv4003_write_reg(dev, 0x32EA, 0x00);
ret |= cv4003_write_reg(dev, 0x32EB, 0x00);
ret |= cv4003_write_reg(dev, 0x32EC, 0x0B); // [27:0] PS_RD_ADDR_END
ret |= cv4003_write_reg(dev, 0x32ED, 0x0F);
ret |= cv4003_write_reg(dev, 0x32EE, 0xF8);
ret |= cv4003_write_reg(dev, 0x32EF, 0x00);
ret |= cv4003_write_reg(dev, 0x3204, 0x40);
#ifdef USE_PREROLL_INFO
ret |= cv4003_set_psram_read_region(dev, g_psram_final_addr);
#endif
ret |= cv4003_write_reg(dev, 0x3000,0x00); //Streaming
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv4003_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("==============================================================\n");
SENSOR_PRINT("===READ BACK CVSENS CV4003_720P_120FPS_10BIT_LINEAR_Init_OK!==\n");
SENSOR_PRINT("==============================================================\n");
return XMEDIA_SUCCESS;
}
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_init_image(xmedia_u32 dev, xmedia_u8 image_mode)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
switch(image_mode) {
case CV4003_4M_LINEAR_MODE:
#ifdef USE_PREROLL_INFO
ret = cv4003_get_preroll_psram_final_addr(dev);
#endif
ret = cv4003_2lane_linear_2560x1440_init(dev);
break;
case CV4003_1M_LINEAR_MODE:
ret = cv4003_preroll_720p_readback_psram2cis2mipi_init(dev);
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return ret;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
if (g_cv4003_i2c_fd[dev] < 0) {
SENSOR_PRINT("Sensor dev [%d], i2c not open. please init i2c at first.\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_set_slave_addr(g_cv4003_i2c_fd[dev], slave_addr);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
i2c_close(g_cv4003_i2c_fd[dev]);
g_cv4003_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_FAILURE;
}
g_cv4003_i2c_addr[dev] = slave_addr;
SENSOR_PRINT("Sensor dev [%d] set slave addr 0x%x success.\n", dev, slave_addr);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr)
{
xmedia_s32 ret;
if (g_cv4003_i2c_fd[dev] >= 0) {
SENSOR_PRINT("====== Sensor dev [%d], i2c already init !=======\n", dev);
return XMEDIA_SUCCESS;
}
if (i2c_dev == SENSOR_I2C_INVALID) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor i2c dev invalid! Please set i2c dev at first!\n");
return XMEDIA_ERRCODE_NOT_CONFIG;
}
g_cv4003_i2c_fd[dev] = i2c_open(i2c_dev);
if (g_cv4003_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "Open /dev/i2c_drv-%u error!\n", i2c_dev);
return XMEDIA_ERRCODE_OPEN_FAILED;
}
ret = cv4003_set_slave_addr(dev, i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
SENSOR_PRINT("====== i2c[%d] init success!=======\n", i2c_dev);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_i2c_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
ret = i2c_close(g_cv4003_i2c_fd[dev]);
if(ret < 0 ) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] close i2c failed!\n", dev);
return ret;
}
g_cv4003_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data)
{
xmedia_s32 ret;
xmedia_u8 buf[CV4003_DATA_BYTE];
if (g_cv4003_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_read(g_cv4003_i2c_fd[dev], g_cv4003_i2c_addr[dev], addr, CV4003_ADDR_BYTE, buf, CV4003_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] read i2c addr [0x%X] failed!\n", dev, addr);
return ret;
}
*data = buf[0]; //CV4003_DATA_BYTE == 1
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data)
{
xmedia_u32 idx = 0;
xmedia_s32 ret;
xmedia_u8 buf[8];
if (g_cv4003_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
buf[idx] = data & 0xff;
ret = i2c_write(g_cv4003_i2c_fd[dev], g_cv4003_i2c_addr[dev], buf, CV4003_ADDR_BYTE + CV4003_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_WRITE error!\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv4003_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 mirror_flip_type;
cv4003_read_reg(dev, CV4003_REG_ADDR_MIRROR_FLIP, &mirror_flip_type);
if (mirror_en){
mirror_flip_type |= 0x01;
} else {
mirror_flip_type &= 0xFE;
}
if (flip_en){
mirror_flip_type |= 0x02;
} else {
mirror_flip_type &= 0xFD;
}
ret = cv4003_write_reg(dev, CV4003_REG_ADDR_MIRROR_FLIP, mirror_flip_type);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv4003_write_reg failed\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef __CV4003_CTRL_H__
#define __CV4003_CTRL_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CV4003_I2C_ADDR 0x6a
#define CV4003_ADDR_BYTE 2
#define CV4003_DATA_BYTE 1
// cv4003 specs list
typedef enum {
CV4003_4M_LINEAR_MODE = 1, // 2560x1440
CV4003_1M_LINEAR_MODE = 2, // 1280x720
} cv4003_specs;
//#define USE_PREROLL_INFO
xmedia_s32 cv4003_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr);
xmedia_s32 cv4003_i2c_exit(xmedia_u32 dev);
xmedia_s32 cv4003_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data);
xmedia_s32 cv4003_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data);
xmedia_s32 cv4003_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en);
xmedia_s32 cv4003_init_image(xmedia_u32 dev, xmedia_u8 img_mode);
xmedia_s32 cv4003_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr);
#ifdef USE_PREROLL_INFO
xmedia_s32 cv4003_preroll_720p_write_cis2psram_init(xmedia_u32 dev);
xmedia_s32 cv4003_get_preroll_psram_final_addr(xmedia_u32 dev);
#endif
#ifdef __cplusplus
}
#endif
#endif //__CV4003_CTRL_H__
+301
View File
@@ -0,0 +1,301 @@
#ifndef __CV4003_EX_H__
#define __CV4003_EX_H__
#ifdef __cplusplus
extern "C" {
#endif
// Piris attr
static const xmedia_isp_piris_attr g_cv4003_piris_attr = {
0,
1,
94,
62,
// Step-F number mapping table. Must be from small to large. F1.0 is 1024 and F32.0 is 1
{ 30, 35, 40, 45, 50, 56, 61, 67, 73, 79, 85, 92, 98, 105, 112, 120, 127, 135, 143, 150, 158,
166, 174, 183, 191, 200, 208, 217, 225, 234, 243, 252, 261, 270, 279, 289, 298, 307, 316, 325, 335, 344,
353, 362, 372, 381, 390, 399, 408, 417, 426, 435, 444, 453, 462, 470, 478, 486, 493, 500, 506, 512 },
XMEDIA_ISP_IRIS_F_NO_1_4,
XMEDIA_ISP_IRIS_F_NO_5_6
};
static const xmedia_isp_bnr_attr g_cv4003_bnr = {
1, //enable
2, //ainr_pos_switch
1, //coring_pos_switch
0, //noise_reserve_enable
{102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,103,104,105,106,107,108,108,108,108,108,108,108,108,108,108,108,115,115,115,115,123,123,123,123,131,131,131,131,138,138,138,138,146,146,146,146,154,154,154,154,161,161}, //noise_reserve_lut
3200, //noise_profile_thd
{0.0006806309000,-0.0030143851000,0.0000002512000,0.0000299657000,0.0069275983000}, //noise_profile_coef0
{0.0006806309000,-0.0030143851000,0.0000002512000,0.0000299657000,0.0069275983000}, //noise_profile_coef1
0, //snr_wdr_comp_en
1, //tnr_enable
1, //tnr_luma_comp_enable
0, //tnr_wdr_comp_enable
0, //op_type
{
16, //iso_num
{100,200,400,800,1600,3200,6400,12800,25600,51200,102400,204800,409600,819200,1638400,3276800}, //iso_level
{
{256,256,256,256}, //snr_coarse_str[0]
{256,256,256,256}, //snr_coarse_str[1]
{256,256,256,256}, //snr_coarse_str[2]
{256,256,256,256}, //snr_coarse_str[3]
{256,256,256,256}, //snr_coarse_str[4]
{286,286,286,286}, //snr_coarse_str[5]
{320,320,320,320}, //snr_coarse_str[6]
{256,256,256,256}, //snr_coarse_str[7]
{256,256,256,256}, //snr_coarse_str[8]
{256,256,256,256}, //snr_coarse_str[9]
{256,256,256,256}, //snr_coarse_str[10]
{256,256,256,256}, //snr_coarse_str[11]
{256,256,256,256}, //snr_coarse_str[12]
{256,256,256,256}, //snr_coarse_str[13]
{256,256,256,256}, //snr_coarse_str[14]
{256,256,256,256}, //snr_coarse_str[15]
}, //snr_coarse_str
{128,128,64,32,30,40,60,64,32,32,32,32,32,32,32,32}, //snr_coring_wgt
{
{256,256,216,216,164,164,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[0]
{256,256,216,216,164,164,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[1]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[2]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[3]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[4]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[5]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[6]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[7]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[8]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[9]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[10]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[11]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[12]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[13]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[14]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str[15]
}, //snr_luma_nr_str
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //snr_center_luma_mode
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //snr_center_tnr_luma_mode
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //snr_wdr_comp_scl
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_noise_min
{128,128,100,100,86,86,86,86,168,238,256,256,64,64,64,64}, //tnr_bayer_str
{32,32,32,32,32,32,32,48,60,64,64,64,64,32,32,32}, //tnr_md_thd_low
{64,64,64,64,64,64,64,138,158,164,164,164,164,64,64,64}, //tnr_md_thd_high
{512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}, //tnr_wgt_min
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //tnr_min_ratio
{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, //tnr_mot_bld_thd_low
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32}, //tnr_mot_bld_thd_high
{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, //tnr_edge_md_thd_low
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32}, //tnr_edge_md_thd_high
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_flat_md_scl
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_edge_md_scl
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //tnr_md_mode
{1017,1017,1017,1017,1017,1017,1017,1017,1017,1017,1017,1017,1017,1017,1017,1017}, //tnr_luma_md_thd_low
{2033,2033,2033,2033,2033,2033,2033,2033,2033,2033,2033,2033,2033,2033,2033,2033}, //tnr_luma_md_thd_high
{256,256,256,256,256,180,128,256,256,256,256,256,256,256,256,256}, //tnr_dark_md_scl
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_bright_md_scl
{
{144,144,144}, //tnr_mot_scl[0]
{144,144,144}, //tnr_mot_scl[1]
{144,144,144}, //tnr_mot_scl[2]
{144,144,144}, //tnr_mot_scl[3]
{144,144,144}, //tnr_mot_scl[4]
{144,144,144}, //tnr_mot_scl[5]
{144,144,144}, //tnr_mot_scl[6]
{144,144,144}, //tnr_mot_scl[7]
{144,144,144}, //tnr_mot_scl[8]
{144,144,144}, //tnr_mot_scl[9]
{144,144,144}, //tnr_mot_scl[10]
{144,144,144}, //tnr_mot_scl[11]
{144,144,144}, //tnr_mot_scl[12]
{144,144,144}, //tnr_mot_scl[13]
{144,144,144}, //tnr_mot_scl[14]
{144,144,144}, //tnr_mot_scl[15]
}, //tnr_mot_scl
{31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}, //tnr_var_scl
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //tnr_mot_noise_luma_thd_low
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_mot_noise_luma_thd_high
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_mot_noise_dark_scl
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_mot_noise_bright_scl
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_mot_dpc_str
{
{360,512,1280,1536}, //tnr_mot_convg_thd[0]
{360,512,1280,1536}, //tnr_mot_convg_thd[1]
{360,512,1280,1536}, //tnr_mot_convg_thd[2]
{360,512,1280,1536}, //tnr_mot_convg_thd[3]
{360,512,1280,1536}, //tnr_mot_convg_thd[4]
{360,512,1280,1536}, //tnr_mot_convg_thd[5]
{360,512,1280,1536}, //tnr_mot_convg_thd[6]
{360,512,1280,1536}, //tnr_mot_convg_thd[7]
{360,512,1280,1536}, //tnr_mot_convg_thd[8]
{360,512,1280,1536}, //tnr_mot_convg_thd[9]
{360,512,1280,1536}, //tnr_mot_convg_thd[10]
{360,512,1280,1536}, //tnr_mot_convg_thd[11]
{360,512,1280,1536}, //tnr_mot_convg_thd[12]
{360,512,1280,1536}, //tnr_mot_convg_thd[13]
{360,512,1280,1536}, //tnr_mot_convg_thd[14]
{360,512,1280,1536}, //tnr_mot_convg_thd[15]
}, //tnr_mot_convg_thd
{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256}, //tnr_mot_noise_scl
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //tnr_mot_noise_scl_high
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //tnr_dpc_en
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //tnr_dp_mode
{384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384}, //tnr_dp_thd_rb
{384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384}, //tnr_dp_thd_g
{512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}, //tnr_dp_luma_thd_low
{768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768}, //tnr_dp_luma_thd_high
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_dp_thd_low_dark_scl
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_dp_thd_high_dark_scl
{
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[0]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[1]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[2]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[3]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[4]
{48,48,48,64,64,64,100,100,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[5]
{32,32,32,64,64,64,100,100,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[6]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[7]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[8]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[9]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[10]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[11]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[12]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[13]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[14]
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio[15]
}, //tnr_luma_ratio
{512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}, //tnr_wdr_comp_scl
}, //auto_attr
{
{256,256,256,256}, //snr_coarse_str
0, //snr_coring_wgt
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //snr_luma_nr_str
0, //snr_center_luma_mode
0, //snr_center_tnr_luma_mode
0, //snr_wdr_comp_scl
256, //tnr_noise_min
512, //tnr_bayer_str
32, //tnr_md_thd_low
64, //tnr_md_thd_high
512, //tnr_wgt_min
256, //tnr_min_ratio
16, //tnr_mot_bld_thd_low
32, //tnr_mot_bld_thd_high
16, //tnr_edge_md_thd_low
32, //tnr_edge_md_thd_high
256, //tnr_flat_md_scl
256, //tnr_edge_md_scl
0, //tnr_md_mode
256, //tnr_luma_md_thd_low
512, //tnr_luma_md_thd_high
256, //tnr_dark_md_scl
256, //tnr_bright_md_scl
{144,144,144}, //tnr_mot_scl
32, //tnr_var_scl
128, //tnr_mot_noise_luma_thd_low
256, //tnr_mot_noise_luma_thd_high
256, //tnr_mot_noise_dark_scl
256, //tnr_mot_noise_bright_scl
64, //tnr_mot_dpc_str
{360,512,1280,1536}, //tnr_mot_convg_thd
256, //tnr_mot_noise_scl
0, //tnr_mot_noise_scl_high
1, //tnr_dpc_en
0, //tnr_dp_mode
384, //tnr_dp_thd_rb
384, //tnr_dp_thd_g
128, //tnr_dp_luma_thd_low
256, //tnr_dp_luma_thd_high
256, //tnr_dp_thd_low_dark_scl
256, //tnr_dp_thd_high_dark_scl
{128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128}, //tnr_luma_ratio
0, //tnr_wdr_comp_scl
}, //manual_attr
{
{64,64}, //wdr_frame_str
}, //wdr
};
static const xmedia_isp_awb_ccm g_cv4003_awb_ccm = {
4,
{
{
6200,
{
475, 33060, 73,
32856, 470, 32894,
32798, 32887, 405
},
},
{
5300,
{
436, 33027, 79,
32858, 353, 32775,
23, 33097, 562
},
},
{
4200,
{
483, 33001, 6,
32844, 448, 32884,
10, 32907, 385
},
},
{
2500,
{
481, 33048, 55,
32911, 435, 32804,
16, 33108, 580
},
},
},
};
static const xmedia_isp_awb_ccm g_cv4003_awb_wdr_ccm = {
4,
{
{
6175,
{ 440, 32967, 15, 32852, 424, 32852, 11, 33014, 491 },
},
{
4990,
{ 443, 32969, 14, 32860, 423, 32843, 13, 33044, 519 },
},
{
3865,
{ 450, 32973, 11, 32857, 407, 32830, 18, 33031, 501 },
},
{
2450,
{ 458, 32977, 7, 32853, 389, 32816, 24, 33018, 482 },
},
},
};
static const xmedia_isp_awb_agc_table g_cv4003_awb_agc_table = {
// bvalid
1,
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
/* saturation */
/* 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 */
{128,128,128,128,115,115,115,115,105,105,105,96,86,86,86,86}
};
static const xmedia_isp_awb_agc_table g_cv4003_awb_wdr_agc_table = {
// bvalid
1,
// saturation
{100,100,100,100,90,80,70,60,55,55,50,50,50,50,45,40}
};
#ifdef __cplusplus
}
#endif
#endif
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+20
View File
@@ -0,0 +1,20 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_cv8001
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/../include
SDK_USR_CFLAGS += -I.
AT := @
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
+4
View File
@@ -0,0 +1,4 @@
SRCS-y += cv8001.c
SRCS-y += cv8001_ctrl.c
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
#ifndef __CV8001_H__
#define __CV8001_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CV8001_VMAX_8M_LINEAR 4380 // 10bit
#define CV8001_EXP_OFFSET_LINEAR 4
// CV8001 Register Address
#define CV8001_REG_ADDR_EXP_H 0x3060
#define CV8001_REG_ADDR_EXP_M 0x3061
#define CV8001_REG_ADDR_EXP_L 0x3062
#define CV8001_REG_ADDR_GAIN_1 0x3164
#define CV8001_REG_ADDR_VMAX_H 0x3028
#define CV8001_REG_ADDR_VMAX_M 0x3029
#define CV8001_REG_ADDR_VMAX_L 0x302a
typedef enum {
CV8001_REG_EXP_H_IDX = 0,
CV8001_REG_EXP_M_IDX,
CV8001_REG_EXP_L_IDX,
CV8001_REG_AGAIN_1_IDX,
CV8001_REG_VMAX_H_IDX,
CV8001_REG_VMAX_M_IDX,
CV8001_REG_VMAX_L_IDX,
CV8001_REG_MAX_NUM,
} cv8001_reg_index;
extern sensor_context *g_cv8001_ctx[XMEDIA_SENSOR_DEV_MAX_NUM];
#define CV8001_GET_CONTEXT(dev, sns_ctx) sns_ctx = g_cv8001_ctx[dev]
xmedia_s32 cv8001_get_max_fps(xmedia_u8 img_mode, xmedia_float *max_fps);
#ifdef __cplusplus
}
#endif
#endif // __CV8001_H__
+262
View File
@@ -0,0 +1,262 @@
#include <stdio.h>
#include <string.h>
#include "i2c_dev.h"
#include "cv8001.h"
#include "cv8001_ctrl.h"
#define CV8001_REG_ADDR_MIRROR_FLIP 0x3034
SENSOR_PRIORITY_DATA static xmedia_s32 g_cv8001_i2c_fd[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
SENSOR_PRIORITY_DATA static xmedia_s32 g_cv8001_i2c_addr[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
SENSOR_PRIORITY_FUNC static void cv8001_delay_ms(int ms)
{
sleep_us(ms * 1000);
}
//目前序列实际帧率只有20
SENSOR_PRIORITY_FUNC static xmedia_s32 cv8001_2lane_linear_3840x2160_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= cv8001_write_reg(dev, 0x3401, 0x01);
ret |= cv8001_write_reg(dev, 0x3915, 0x00);
ret |= cv8001_write_reg(dev, 0x3220, 0x08);
ret |= cv8001_write_reg(dev, 0x3185, 0x03);
ret |= cv8001_write_reg(dev, 0x318A, 0x03);
// W4K
ret |= cv8001_write_reg(dev, 0x3020, 0x04);
ret |= cv8001_write_reg(dev, 0x3040, 0x01);
// H
ret |= cv8001_write_reg(dev, 0x3048, 0x08);
ret |= cv8001_write_reg(dev, 0x3049, 0x00);
ret |= cv8001_write_reg(dev, 0x304A, 0x00);
ret |= cv8001_write_reg(dev, 0x304B, 0x0F);
// V
ret |= cv8001_write_reg(dev, 0x3044, 0x04);
ret |= cv8001_write_reg(dev, 0x3045, 0x00);
ret |= cv8001_write_reg(dev, 0x3046, 0x70);
ret |= cv8001_write_reg(dev, 0x3047, 0x08);
//adjust1
ret |= cv8001_write_reg(dev, 0x3041, 0x00);
ret |= cv8001_write_reg(dev, 0x3b68, 0x00);
ret |= cv8001_write_reg(dev, 0x3b69, 0x00);
ret |= cv8001_write_reg(dev, 0x3b6a, 0xff);
ret |= cv8001_write_reg(dev, 0x3b6b, 0x01);
//adjust2
ret |= cv8001_write_reg(dev, 0x387D, 0x3F);
ret |= cv8001_write_reg(dev, 0x397a, 0x08);
ret |= cv8001_write_reg(dev, 0x3804, 0x14);
ret |= cv8001_write_reg(dev, 0x3587, 0x2a);
ret |= cv8001_write_reg(dev, 0x3348, 0x00);
ret |= cv8001_write_reg(dev, 0x31AC, 0xC8);
ret |= cv8001_write_reg(dev, 0x35EC, 0x08);
ret |= cv8001_write_reg(dev, 0x3220, 0x08);
ret |= cv8001_write_reg(dev, 0x3b75, 0x00);
ret |= cv8001_write_reg(dev, 0x3b5E, 0x01);
ret |= cv8001_write_reg(dev, 0x3a10, 0x0A);
ret |= cv8001_write_reg(dev, 0x3a11, 0x0A);
//adjust
ret |= cv8001_write_reg(dev, 0x3a92, 0x56);
ret |= cv8001_write_reg(dev, 0x3914, 0x2E);
ret |= cv8001_write_reg(dev, 0x3908, 0x4A);
ret |= cv8001_write_reg(dev, 0x302C, 0x3B);
ret |= cv8001_write_reg(dev, 0x302D, 0x01);
ret |= cv8001_write_reg(dev, 0x316C, 0x02);
ret |= cv8001_write_reg(dev, 0x3686, 0x03);
ret |= cv8001_write_reg(dev, 0x36b8, 0x00);
ret |= cv8001_write_reg(dev, 0x36b6, 0x00);
//adjust3
ret |= cv8001_write_reg(dev, 0x36C0, 0x00);
ret |= cv8001_write_reg(dev, 0x36C5, 0x02);
//adjust4
ret |= cv8001_write_reg(dev, 0x36B6, 0x02);
ret |= cv8001_write_reg(dev, 0x35DF, 0x00);
ret |= cv8001_write_reg(dev, 0x35C4, 0x09);
ret |= cv8001_write_reg(dev, 0x3685, 0x01);
//adjust5
ret |= cv8001_write_reg(dev, 0x3A86, 0x01);
ret |= cv8001_write_reg(dev, 0x3A88, 0x07);
ret |= cv8001_write_reg(dev, 0x3A8C, 0x3C);
ret |= cv8001_write_reg(dev, 0x3B19, 0x0A);
ret |= cv8001_write_reg(dev, 0x3B1C, 0x2B);
ret |= cv8001_write_reg(dev, 0x3518, 0x6A);
ret |= cv8001_write_reg(dev, 0x3519, 0x00);
ret |= cv8001_write_reg(dev, 0x351A, 0x08);
ret |= cv8001_write_reg(dev, 0x3852, 0x00);
ret |= cv8001_write_reg(dev, 0x36AA, 0x00);
ret |= cv8001_write_reg(dev, 0x3000, 0x00);
cv8001_delay_ms(5); // delay 5 ms
ret |= cv8001_write_reg(dev, 0x0100, 0x01);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv8001_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("=== CV8001_24MInput_MIPI_2lane_10bit_3840x2160_30fps init success!==============\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_init_image(xmedia_u32 dev, xmedia_u8 image_mode)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
switch(image_mode) {
case CV8001_8M_LINEAR_MODE:
ret = cv8001_2lane_linear_3840x2160_init(dev);
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
return ret;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
if (g_cv8001_i2c_fd[dev] < 0) {
SENSOR_PRINT("Sensor dev [%d], i2c not open. please init i2c at first.\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_set_slave_addr(g_cv8001_i2c_fd[dev], slave_addr);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
i2c_close(g_cv8001_i2c_fd[dev]);
g_cv8001_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_FAILURE;
}
g_cv8001_i2c_addr[dev] = slave_addr;
SENSOR_PRINT("Sensor dev [%d] set slave addr 0x%x success.\n", dev, slave_addr);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr)
{
xmedia_s32 ret;
if (g_cv8001_i2c_fd[dev] >= 0) {
SENSOR_PRINT("====== Sensor dev [%d], i2c already init !=======\n", dev);
return XMEDIA_SUCCESS;
}
if (i2c_dev == SENSOR_I2C_INVALID) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor i2c dev invalid! Please set i2c dev at first!\n");
return XMEDIA_ERRCODE_NOT_CONFIG;
}
g_cv8001_i2c_fd[dev] = i2c_open(i2c_dev);
if (g_cv8001_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "Open /dev/i2c_drv-%u error!\n", i2c_dev);
return XMEDIA_ERRCODE_OPEN_FAILED;
}
ret = cv8001_set_slave_addr(dev, i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
SENSOR_PRINT("====== i2c[%d] init success!=======\n", i2c_dev);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_i2c_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
ret = i2c_close(g_cv8001_i2c_fd[dev]);
if(ret < 0 ) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] close i2c failed!\n", dev);
return ret;
}
g_cv8001_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data)
{
xmedia_s32 ret;
xmedia_u8 buf[CV8001_DATA_BYTE];
if (g_cv8001_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_read(g_cv8001_i2c_fd[dev], g_cv8001_i2c_addr[dev], addr, CV8001_ADDR_BYTE, buf, CV8001_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] read i2c addr [0x%X] failed!\n", dev, addr);
return ret;
}
*data = buf[0]; //CV8001_DATA_BYTE == 1
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data)
{
xmedia_u32 idx = 0;
xmedia_s32 ret;
xmedia_u8 buf[8];
if (g_cv8001_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
buf[idx] = data & 0xff;
ret = i2c_write(g_cv8001_i2c_fd[dev], g_cv8001_i2c_addr[dev], buf, CV8001_ADDR_BYTE + CV8001_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_WRITE error!\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 cv8001_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 mirror_flip_type;
cv8001_read_reg(dev, CV8001_REG_ADDR_MIRROR_FLIP, &mirror_flip_type);
if (mirror_en){
mirror_flip_type |= 0x01;
} else {
mirror_flip_type &= 0xFE;
}
if (flip_en){
mirror_flip_type |= 0x02;
} else {
mirror_flip_type &= 0xFD;
}
ret = cv8001_write_reg(dev, CV8001_REG_ADDR_MIRROR_FLIP, mirror_flip_type);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "cv8001_write_reg failed\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef __CV8001_CTRL_H__
#define __CV8001_CTRL_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CV8001_I2C_ADDR 0x6a
#define CV8001_ADDR_BYTE 2
#define CV8001_DATA_BYTE 1
// cv8001 specs list
typedef enum {
CV8001_8M_LINEAR_MODE = 1, // 3840x2160
} cv8001_specs;
xmedia_s32 cv8001_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr);
xmedia_s32 cv8001_i2c_exit(xmedia_u32 dev);
xmedia_s32 cv8001_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data);
xmedia_s32 cv8001_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data);
xmedia_s32 cv8001_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en);
xmedia_s32 cv8001_init_image(xmedia_u32 dev, xmedia_u8 img_mode);
xmedia_s32 cv8001_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr);
#ifdef __cplusplus
}
#endif
#endif //__CV8001_CTRL_H__
+90
View File
@@ -0,0 +1,90 @@
#ifndef __CV8001_EX_H__
#define __CV8001_EX_H__
#ifdef __cplusplus
extern "C" {
#endif
// Piris attr
static const xmedia_isp_piris_attr g_cv8001_piris_attr = {
0,
1,
94,
62,
// Step-F number mapping table. Must be from small to large. F1.0 is 1024 and F32.0 is 1
{ 30, 35, 40, 45, 50, 56, 61, 67, 73, 79, 85, 92, 98, 105, 112, 120, 127, 135, 143, 150, 158,
166, 174, 183, 191, 200, 208, 217, 225, 234, 243, 252, 261, 270, 279, 289, 298, 307, 316, 325, 335, 344,
353, 362, 372, 381, 390, 399, 408, 417, 426, 435, 444, 453, 462, 470, 478, 486, 493, 500, 506, 512 },
XMEDIA_ISP_IRIS_F_NO_1_4,
XMEDIA_ISP_IRIS_F_NO_5_6
};
static const xmedia_isp_awb_ccm g_cv8001_awb_ccm = {
5,
{
{
7504,
{ 428,32914,32794,32853,482,32909,10,32963,441},
},
{
6536,
{ 435,32918,32797,32853,479,32906,13,32975,450},
},
{
5074,
{ 433,32896,32817,32864,483,32899,15,33003,476},
},
{
4065,
{ 463,32932,32811,32864,467,32883,25,33063,526 },
},
{
2811,
{ 480,32898,32862,32880,482,32882,30,33204,662},
},
},
};
static const xmedia_isp_awb_ccm g_cv8001_awb_wdr_ccm = {
4,
{
{
6175,
{ 440, 32967, 15, 32852, 424, 32852, 11, 33014, 491 },
},
{
4990,
{ 443, 32969, 14, 32860, 423, 32843, 13, 33044, 519 },
},
{
3865,
{ 450, 32973, 11, 32857, 407, 32830, 18, 33031, 501 },
},
{
2450,
{ 458, 32977, 7, 32853, 389, 32816, 24, 33018, 482 },
},
},
};
static const xmedia_isp_awb_agc_table g_cv8001_awb_agc_table = {
// bvalid
1,
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
// saturation
{128,128,128,128,128,128,128,128,128,110,110,100,100,100,100,100}, //sat
};
static const xmedia_isp_awb_agc_table g_cv8001_awb_wdr_agc_table = {
// bvalid
1,
// saturation
{100,100,100,100,90,80,70,60,55,55,50,50,50,50,45,40}
};
#ifdef __cplusplus
}
#endif
#endif
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+18
View File
@@ -0,0 +1,18 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_gc2053
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I.
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,4 @@
SRCS-y += gc2053.c
SRCS-y += gc2053_ctrl.c
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
#ifndef __GC2053_H__
#define __GC2053_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define GC2053_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080)
/*****SC2235 Register Address*****/
#define GC2053_REG_EXP_ADDR_L 0x04 // Shutter-time[7:0]
#define GC2053_REG_EXP_ADDR_H 0x03 // Shutter-time[13:8]
#define GC2053_REG_AGAIN_ADDR_L 0xb3 // Analog-gain[7:0]
#define GC2053_REG_AGAIN_ADDR_H 0xb4 // Analog-gain[9:8]
#define GC2053_REG_DGAIN_ADDR_L 0xb9 // digital-gain[5:0]
#define GC2053_REG_DGAIN_ADDR_H 0xb8 // digital-gain[11:6]
#define GC2053_REG_AUTO_PREGAIN_ADDR_L 0xb2 // auto-pregain-gain[5:0]
#define GC2053_REG_AUTO_PREGAIN_ADDR_H 0xb1 // auto-pregain-gain[9:6]
#define GC2053_REG_STATUS_ADDR 0x90 // slow shutter via framerate or exptime
#define GC2053_REG_VMAX_ADDR_L 0x42 // Vmax[7:0]
#define GC2053_REG_VMAX_ADDR_H 0x41 // Vmax[13:8]
#define GC2053_REG_PRBS_MODE_ADDR 0x38
#define GC2053_REG_OPTICAL_BLACK_ADDR 0x7c
#define GC2053_VMAX_1080P30_LINEAR 0x465
typedef enum{
GC2053_REG_EXP_L = 0,
GC2053_REG_EXP_H,
GC2053_REG_AGC_L,
GC2053_REG_AGC_H,
GC2053_REG_DGC_L,
GC2053_REG_DGC_H,
GC2053_REG_PREGAIN_L,
GC2053_REG_PREGAIN_H,
GC2053_REG_STATUS,
GC2053_REG_VMAX_H, // 必须得先配置 vmax 高位寄存器,然后再配置低位寄存器
GC2053_REG_VMAX_L,
GC2053_REG_L_MAX_NUM,
//short frame reg info from here
GC2053_S_REG_EXP_L = GC2053_REG_L_MAX_NUM,
GC2053_S_REG_EXP_H,
GC2053_REG_PRBS_MODE,
GC2053_REG_OPTICAL_BLACK,
GC2053_REG_MAX_NUM
}gc2053_reg_info;
#define GC2053_FULL_LINES_MAX 0x3FFF
#ifdef __cplusplus
}
#endif
#endif //__GC2053_H__
+892
View File
@@ -0,0 +1,892 @@
#include <stdio.h>
#include <string.h>
#include "i2c_dev.h"
#include "gc2053.h"
#include "gc2053_ctrl.h"
#define GC2053_REG_ADDR_MIRROR_FLIP 0x0017
SENSOR_PRIORITY_DATA static xmedia_s32 g_gc2053_i2c_fd[XMEDIA_SENSOR_DEV_MAX_NUM] = { [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] =
SENSOR_I2C_INVALID };
SENSOR_PRIORITY_DATA static xmedia_s32 g_gc2053_i2c_addr[XMEDIA_SENSOR_DEV_MAX_NUM] = { [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] =
SENSOR_I2C_INVALID };
#ifdef FPGA
#ifdef GC2053_DVP
static xmedia_s32 gc2053_dvp_linear_1920X1080_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= gc2053_write_reg(dev,0xfe ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0xf2 ,0x00);
ret |= gc2053_write_reg(dev,0xf3 ,0x0f);
ret |= gc2053_write_reg(dev,0xf4 ,0x36);
ret |= gc2053_write_reg(dev,0xf5 ,0xc0);
ret |= gc2053_write_reg(dev,0xf6 ,0x44);
ret |= gc2053_write_reg(dev,0xf7 ,0x01);
ret |= gc2053_write_reg(dev,0xf8 ,0x2c);
ret |= gc2053_write_reg(dev,0xf9 ,0x42);
ret |= gc2053_write_reg(dev,0xfc ,0x8e);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0x87 ,0x18);
ret |= gc2053_write_reg(dev,0xee ,0x30);
ret |= gc2053_write_reg(dev,0xd0 ,0xb7);
ret |= gc2053_write_reg(dev,0x03 ,0x04);
ret |= gc2053_write_reg(dev,0x04 ,0x60);
ret |= gc2053_write_reg(dev,0x05 ,0x05); //line length
ret |= gc2053_write_reg(dev,0x06 ,0x28);
ret |= gc2053_write_reg(dev,0x07 ,0x00);//VBlank
ret |= gc2053_write_reg(dev,0x08 ,0x11);
ret |= gc2053_write_reg(dev,0x09 ,0x00);
ret |= gc2053_write_reg(dev,0x0a ,0x02);
ret |= gc2053_write_reg(dev,0x0b ,0x00);
ret |= gc2053_write_reg(dev,0x0c ,0x02);
ret |= gc2053_write_reg(dev,0x0d ,0x04);//valid line time
ret |= gc2053_write_reg(dev,0x0e ,0x40);
ret |= gc2053_write_reg(dev,0x12 ,0xe2);
ret |= gc2053_write_reg(dev,0x13 ,0x16);
ret |= gc2053_write_reg(dev,0x19 ,0x0a);
ret |= gc2053_write_reg(dev,0x21 ,0x1c);
ret |= gc2053_write_reg(dev,0x28 ,0x0a);
ret |= gc2053_write_reg(dev,0x29 ,0x24);
ret |= gc2053_write_reg(dev,0x2b ,0x04);
ret |= gc2053_write_reg(dev,0x32 ,0xf8);
ret |= gc2053_write_reg(dev,0x37 ,0x03);
ret |= gc2053_write_reg(dev,0x39 ,0x15);
ret |= gc2053_write_reg(dev,0x43 ,0x07);
ret |= gc2053_write_reg(dev,0x44 ,0x40);
ret |= gc2053_write_reg(dev,0x46 ,0x0b);
ret |= gc2053_write_reg(dev,0x4b ,0x20);
ret |= gc2053_write_reg(dev,0x4e ,0x08);
ret |= gc2053_write_reg(dev,0x55 ,0x20);
ret |= gc2053_write_reg(dev,0x66 ,0x05);
ret |= gc2053_write_reg(dev,0x67 ,0x05);
ret |= gc2053_write_reg(dev,0x77 ,0x01);
ret |= gc2053_write_reg(dev,0x78 ,0x00);
ret |= gc2053_write_reg(dev,0x7c ,0x93);
ret |= gc2053_write_reg(dev,0x8c ,0x12);
ret |= gc2053_write_reg(dev,0x8d ,0x92);
ret |= gc2053_write_reg(dev,0x90 ,0x00);
ret |= gc2053_write_reg(dev,0x41 ,0x04);//Frame length c35
ret |= gc2053_write_reg(dev,0x42 ,0x65);
ret |= gc2053_write_reg(dev,0x9d ,0x10);
ret |= gc2053_write_reg(dev,0xce ,0x7c);
ret |= gc2053_write_reg(dev,0xd2 ,0x41);
ret |= gc2053_write_reg(dev,0xd3 ,0xdc);
ret |= gc2053_write_reg(dev,0xe6 ,0x50);
ret |= gc2053_write_reg(dev,0xb6 ,0xc0);
ret |= gc2053_write_reg(dev,0xb0 ,0x70);
ret |= gc2053_write_reg(dev,0xb1 ,0x01);
ret |= gc2053_write_reg(dev,0xb2 ,0x00);
ret |= gc2053_write_reg(dev,0xb3 ,0x00);
ret |= gc2053_write_reg(dev,0xb4 ,0x00);
ret |= gc2053_write_reg(dev,0xb8 ,0x01);
ret |= gc2053_write_reg(dev,0xb9 ,0x00);
ret |= gc2053_write_reg(dev,0x26 ,0x30);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x40 ,0x23);
ret |= gc2053_write_reg(dev,0x55 ,0x07);
ret |= gc2053_write_reg(dev,0x60 ,0x40);
ret |= gc2053_write_reg(dev,0xfe ,0x04);
ret |= gc2053_write_reg(dev,0x14 ,0x78);
ret |= gc2053_write_reg(dev,0x15 ,0x78);
ret |= gc2053_write_reg(dev,0x16 ,0x78);
ret |= gc2053_write_reg(dev,0x17 ,0x78);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x92 ,0x00);
ret |= gc2053_write_reg(dev,0x94 ,0x03);
ret |= gc2053_write_reg(dev,0x95 ,0x04);//out_window
ret |= gc2053_write_reg(dev,0x96 ,0x38);
ret |= gc2053_write_reg(dev,0x97 ,0x07);
ret |= gc2053_write_reg(dev,0x98 ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x01 ,0x05);
ret |= gc2053_write_reg(dev,0x02 ,0x89);
ret |= gc2053_write_reg(dev,0x04 ,0x01);
ret |= gc2053_write_reg(dev,0x07 ,0xa6);
ret |= gc2053_write_reg(dev,0x08 ,0xa9);
ret |= gc2053_write_reg(dev,0x09 ,0xa8);
ret |= gc2053_write_reg(dev,0x0a ,0xa7);
ret |= gc2053_write_reg(dev,0x0b ,0xff);
ret |= gc2053_write_reg(dev,0x0c ,0xff);
ret |= gc2053_write_reg(dev,0x0f ,0x00);
ret |= gc2053_write_reg(dev,0x50 ,0x1c);
ret |= gc2053_write_reg(dev,0x89 ,0x03);
ret |= gc2053_write_reg(dev,0xfe ,0x04);
ret |= gc2053_write_reg(dev,0x28 ,0x86);
ret |= gc2053_write_reg(dev,0x29 ,0x86);
ret |= gc2053_write_reg(dev,0x2a ,0x86);
ret |= gc2053_write_reg(dev,0x2b ,0x68);
ret |= gc2053_write_reg(dev,0x2c ,0x68);
ret |= gc2053_write_reg(dev,0x2d ,0x68);
ret |= gc2053_write_reg(dev,0x2e ,0x68);
ret |= gc2053_write_reg(dev,0x2f ,0x68);
ret |= gc2053_write_reg(dev,0x30 ,0x4f);
ret |= gc2053_write_reg(dev,0x31 ,0x68);
ret |= gc2053_write_reg(dev,0x32 ,0x67);
ret |= gc2053_write_reg(dev,0x33 ,0x66);
ret |= gc2053_write_reg(dev,0x34 ,0x66);
ret |= gc2053_write_reg(dev,0x35 ,0x66);
ret |= gc2053_write_reg(dev,0x36 ,0x66);
ret |= gc2053_write_reg(dev,0x37 ,0x66);
ret |= gc2053_write_reg(dev,0x38 ,0x62);
ret |= gc2053_write_reg(dev,0x39 ,0x62);
ret |= gc2053_write_reg(dev,0x3a ,0x62);
ret |= gc2053_write_reg(dev,0x3b ,0x62);
ret |= gc2053_write_reg(dev,0x3c ,0x62);
ret |= gc2053_write_reg(dev,0x3d ,0x62);
ret |= gc2053_write_reg(dev,0x3e ,0x62);
ret |= gc2053_write_reg(dev,0x3f ,0x62);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x9a ,0x06);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0x7b ,0x2a);
ret |= gc2053_write_reg(dev,0x23 ,0x2d);
ret |= gc2053_write_reg(dev,0xfe ,0x03);
ret |= gc2053_write_reg(dev,0x01 ,0x20);
ret |= gc2053_write_reg(dev,0x02 ,0x56);
ret |= gc2053_write_reg(dev,0x03 ,0xb2);
ret |= gc2053_write_reg(dev,0x12 ,0x80);
ret |= gc2053_write_reg(dev,0x13 ,0x07);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0x3e ,0x40);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "gc2053_write_reg failed\n");
return XMEDIA_FAILURE;
}
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("==========Galaxycore GC2053_1080P_6.6FPS_10BIT_LINEAR_Init_OK!!!!================\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
#else
static xmedia_s32 gc2053_2lane_linear_1920x1080_init(xmedia_u32 dev)
{
SENSOR_PRINT("========================================================================================\n");
SENSOR_PRINT("==================================== GC2053 LINEAR NOT SUPPORT! ========================\n");
SENSOR_PRINT("========================================================================================\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
#endif
#else
#ifdef GC2053_DVP
static xmedia_s32 gc2053_dvp_linear_1920X1080_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= gc2053_write_reg(dev,0xfe ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0xf2 ,0x00);
ret |= gc2053_write_reg(dev,0xf3 ,0x0f);
ret |= gc2053_write_reg(dev,0xf4 ,0x36);
ret |= gc2053_write_reg(dev,0xf5 ,0xc0);
ret |= gc2053_write_reg(dev,0xf6 ,0x44);
ret |= gc2053_write_reg(dev,0xf7 ,0x01);
ret |= gc2053_write_reg(dev,0xf8 ,0x2c);
ret |= gc2053_write_reg(dev,0xf9 ,0x42);
ret |= gc2053_write_reg(dev,0xfc ,0x8e);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0x87 ,0x18);
ret |= gc2053_write_reg(dev,0xee ,0x30);
ret |= gc2053_write_reg(dev,0xd0 ,0xb7);
ret |= gc2053_write_reg(dev,0x03 ,0x04);
ret |= gc2053_write_reg(dev,0x04 ,0x60);
ret |= gc2053_write_reg(dev,0x05 ,0x05); //line length
ret |= gc2053_write_reg(dev,0x06 ,0x28);
ret |= gc2053_write_reg(dev,0x07 ,0x00);//VBlank
ret |= gc2053_write_reg(dev,0x08 ,0x11);
ret |= gc2053_write_reg(dev,0x09 ,0x00);
ret |= gc2053_write_reg(dev,0x0a ,0x02);
ret |= gc2053_write_reg(dev,0x0b ,0x00);
ret |= gc2053_write_reg(dev,0x0c ,0x02);
ret |= gc2053_write_reg(dev,0x0d ,0x04);//valid line time
ret |= gc2053_write_reg(dev,0x0e ,0x40);
ret |= gc2053_write_reg(dev,0x12 ,0xe2);
ret |= gc2053_write_reg(dev,0x13 ,0x16);
ret |= gc2053_write_reg(dev,0x19 ,0x0a);
ret |= gc2053_write_reg(dev,0x21 ,0x1c);
ret |= gc2053_write_reg(dev,0x28 ,0x0a);
ret |= gc2053_write_reg(dev,0x29 ,0x24);
ret |= gc2053_write_reg(dev,0x2b ,0x04);
ret |= gc2053_write_reg(dev,0x32 ,0xf8);
ret |= gc2053_write_reg(dev,0x37 ,0x03);
ret |= gc2053_write_reg(dev,0x39 ,0x15);
ret |= gc2053_write_reg(dev,0x43 ,0x07);
ret |= gc2053_write_reg(dev,0x44 ,0x40);
ret |= gc2053_write_reg(dev,0x46 ,0x0b);
ret |= gc2053_write_reg(dev,0x4b ,0x20);
ret |= gc2053_write_reg(dev,0x4e ,0x08);
ret |= gc2053_write_reg(dev,0x55 ,0x20);
ret |= gc2053_write_reg(dev,0x66 ,0x05);
ret |= gc2053_write_reg(dev,0x67 ,0x05);
ret |= gc2053_write_reg(dev,0x77 ,0x01);
ret |= gc2053_write_reg(dev,0x78 ,0x00);
ret |= gc2053_write_reg(dev,0x7c ,0x93);
ret |= gc2053_write_reg(dev,0x8c ,0x12);
ret |= gc2053_write_reg(dev,0x8d ,0x92);
ret |= gc2053_write_reg(dev,0x90 ,0x00);
ret |= gc2053_write_reg(dev,0x41 ,0x04);
ret |= gc2053_write_reg(dev,0x42 ,0x65);
ret |= gc2053_write_reg(dev,0x9d ,0x10);
ret |= gc2053_write_reg(dev,0xce ,0x7c);
ret |= gc2053_write_reg(dev,0xd2 ,0x41);
ret |= gc2053_write_reg(dev,0xd3 ,0xdc);
ret |= gc2053_write_reg(dev,0xe6 ,0x50);
ret |= gc2053_write_reg(dev,0xb6 ,0xc0);
ret |= gc2053_write_reg(dev,0xb0 ,0x70);
ret |= gc2053_write_reg(dev,0xb1 ,0x01);
ret |= gc2053_write_reg(dev,0xb2 ,0x00);
ret |= gc2053_write_reg(dev,0xb3 ,0x00);
ret |= gc2053_write_reg(dev,0xb4 ,0x00);
ret |= gc2053_write_reg(dev,0xb8 ,0x01);
ret |= gc2053_write_reg(dev,0xb9 ,0x00);
ret |= gc2053_write_reg(dev,0x26 ,0x30);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x40 ,0x23);
ret |= gc2053_write_reg(dev,0x55 ,0x07);
ret |= gc2053_write_reg(dev,0x60 ,0x40);
ret |= gc2053_write_reg(dev,0xfe ,0x04);
ret |= gc2053_write_reg(dev,0x14 ,0x78);
ret |= gc2053_write_reg(dev,0x15 ,0x78);
ret |= gc2053_write_reg(dev,0x16 ,0x78);
ret |= gc2053_write_reg(dev,0x17 ,0x78);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x92 ,0x00);
ret |= gc2053_write_reg(dev,0x94 ,0x03);
ret |= gc2053_write_reg(dev,0x95 ,0x04);//out_window
ret |= gc2053_write_reg(dev,0x96 ,0x38);
ret |= gc2053_write_reg(dev,0x97 ,0x07);
ret |= gc2053_write_reg(dev,0x98 ,0x80);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x01 ,0x05);
ret |= gc2053_write_reg(dev,0x02 ,0x89);
ret |= gc2053_write_reg(dev,0x04 ,0x01);
ret |= gc2053_write_reg(dev,0x07 ,0xa6);
ret |= gc2053_write_reg(dev,0x08 ,0xa9);
ret |= gc2053_write_reg(dev,0x09 ,0xa8);
ret |= gc2053_write_reg(dev,0x0a ,0xa7);
ret |= gc2053_write_reg(dev,0x0b ,0xff);
ret |= gc2053_write_reg(dev,0x0c ,0xff);
ret |= gc2053_write_reg(dev,0x0f ,0x00);
ret |= gc2053_write_reg(dev,0x50 ,0x1c);
ret |= gc2053_write_reg(dev,0x89 ,0x03);
ret |= gc2053_write_reg(dev,0xfe ,0x04);
ret |= gc2053_write_reg(dev,0x28 ,0x86);
ret |= gc2053_write_reg(dev,0x29 ,0x86);
ret |= gc2053_write_reg(dev,0x2a ,0x86);
ret |= gc2053_write_reg(dev,0x2b ,0x68);
ret |= gc2053_write_reg(dev,0x2c ,0x68);
ret |= gc2053_write_reg(dev,0x2d ,0x68);
ret |= gc2053_write_reg(dev,0x2e ,0x68);
ret |= gc2053_write_reg(dev,0x2f ,0x68);
ret |= gc2053_write_reg(dev,0x30 ,0x4f);
ret |= gc2053_write_reg(dev,0x31 ,0x68);
ret |= gc2053_write_reg(dev,0x32 ,0x67);
ret |= gc2053_write_reg(dev,0x33 ,0x66);
ret |= gc2053_write_reg(dev,0x34 ,0x66);
ret |= gc2053_write_reg(dev,0x35 ,0x66);
ret |= gc2053_write_reg(dev,0x36 ,0x66);
ret |= gc2053_write_reg(dev,0x37 ,0x66);
ret |= gc2053_write_reg(dev,0x38 ,0x62);
ret |= gc2053_write_reg(dev,0x39 ,0x62);
ret |= gc2053_write_reg(dev,0x3a ,0x62);
ret |= gc2053_write_reg(dev,0x3b ,0x62);
ret |= gc2053_write_reg(dev,0x3c ,0x62);
ret |= gc2053_write_reg(dev,0x3d ,0x62);
ret |= gc2053_write_reg(dev,0x3e ,0x62);
ret |= gc2053_write_reg(dev,0x3f ,0x62);
ret |= gc2053_write_reg(dev,0xfe ,0x01);
ret |= gc2053_write_reg(dev,0x9a ,0x06);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0x7b ,0x2a);
ret |= gc2053_write_reg(dev,0x23 ,0x2d);
ret |= gc2053_write_reg(dev,0xfe ,0x03);
ret |= gc2053_write_reg(dev,0x01 ,0x20);
ret |= gc2053_write_reg(dev,0x02 ,0x56);
ret |= gc2053_write_reg(dev,0x03 ,0xb2);
ret |= gc2053_write_reg(dev,0x12 ,0x80);
ret |= gc2053_write_reg(dev,0x13 ,0x07);
ret |= gc2053_write_reg(dev,0xfe ,0x00);
ret |= gc2053_write_reg(dev,0x3e ,0x40);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "gc2053_write_reg failed\n");
return XMEDIA_FAILURE;
}
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("==========Galaxycore GC2053_1080P_25FPS_12BIT_LINEAR_Init_OK!!!!=================\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
#else
SENSOR_PRIORITY_FUNC static xmedia_s32 gc2053_2lane_linear_1920x1080_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= gc2053_write_reg(dev, 0xfe, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0xf2, 0x00);
ret |= gc2053_write_reg(dev, 0xf3, 0x00);
ret |= gc2053_write_reg(dev, 0xf4, 0x36);
ret |= gc2053_write_reg(dev, 0xf5, 0xc0);
ret |= gc2053_write_reg(dev, 0xf6, 0x84);
ret |= gc2053_write_reg(dev, 0xf7, 0x11);
ret |= gc2053_write_reg(dev, 0xf8, 0x3e);
ret |= gc2053_write_reg(dev, 0xf9, 0x82);
ret |= gc2053_write_reg(dev, 0xfc, 0x8e);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0x87, 0x18);
ret |= gc2053_write_reg(dev, 0xee, 0x30);
ret |= gc2053_write_reg(dev, 0xd0, 0xb7);
ret |= gc2053_write_reg(dev, 0x03, 0x04);
ret |= gc2053_write_reg(dev, 0x04, 0x60);
ret |= gc2053_write_reg(dev, 0x05, 0x04);
ret |= gc2053_write_reg(dev, 0x06, 0x4c);
ret |= gc2053_write_reg(dev, 0x07, 0x00);
ret |= gc2053_write_reg(dev, 0x08, 0x11);
ret |= gc2053_write_reg(dev, 0x09, 0x00);
ret |= gc2053_write_reg(dev, 0x0a, 0x02);
ret |= gc2053_write_reg(dev, 0x0b, 0x00);
ret |= gc2053_write_reg(dev, 0x0c, 0x02);
ret |= gc2053_write_reg(dev, 0x0d, 0x04);
ret |= gc2053_write_reg(dev, 0x0e, 0x40);
ret |= gc2053_write_reg(dev, 0x12, 0xe2);
ret |= gc2053_write_reg(dev, 0x13, 0x16);
ret |= gc2053_write_reg(dev, 0x19, 0x0a);
ret |= gc2053_write_reg(dev, 0x21, 0x1c);
ret |= gc2053_write_reg(dev, 0x28, 0x0a);
ret |= gc2053_write_reg(dev, 0x29, 0x24);
ret |= gc2053_write_reg(dev, 0x2b, 0x04);
ret |= gc2053_write_reg(dev, 0x32, 0xf8);
ret |= gc2053_write_reg(dev, 0x37, 0x03);
ret |= gc2053_write_reg(dev, 0x39, 0x15);
ret |= gc2053_write_reg(dev, 0x43, 0x07);
ret |= gc2053_write_reg(dev, 0x44, 0x40);
ret |= gc2053_write_reg(dev, 0x46, 0x0b);
ret |= gc2053_write_reg(dev, 0x4b, 0x20);
ret |= gc2053_write_reg(dev, 0x4e, 0x08);
ret |= gc2053_write_reg(dev, 0x55, 0x20);
ret |= gc2053_write_reg(dev, 0x66, 0x05);
ret |= gc2053_write_reg(dev, 0x67, 0x05);
ret |= gc2053_write_reg(dev, 0x77, 0x01);
ret |= gc2053_write_reg(dev, 0x78, 0x00);
ret |= gc2053_write_reg(dev, 0x7c, 0x93);
ret |= gc2053_write_reg(dev, 0x8c, 0x12);
ret |= gc2053_write_reg(dev, 0x8d, 0x92);
ret |= gc2053_write_reg(dev, 0x90, 0x00);
ret |= gc2053_write_reg(dev, 0x41, 0x04);
ret |= gc2053_write_reg(dev, 0x42, 0x65);
ret |= gc2053_write_reg(dev, 0x9d, 0x10);
ret |= gc2053_write_reg(dev, 0xce, 0x7c);
ret |= gc2053_write_reg(dev, 0xd2, 0x41);
ret |= gc2053_write_reg(dev, 0xd3, 0xdc);
ret |= gc2053_write_reg(dev, 0xe6, 0x50);
ret |= gc2053_write_reg(dev, 0xb6, 0xc0);
ret |= gc2053_write_reg(dev, 0xb0, 0x70);
ret |= gc2053_write_reg(dev, 0xb1, 0x01);
ret |= gc2053_write_reg(dev, 0xb2, 0x00);
ret |= gc2053_write_reg(dev, 0xb3, 0x00);
ret |= gc2053_write_reg(dev, 0xb4, 0x00);
ret |= gc2053_write_reg(dev, 0xb8, 0x01);
ret |= gc2053_write_reg(dev, 0xb9, 0x00);
ret |= gc2053_write_reg(dev, 0x26, 0x30);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x40, 0x23);
ret |= gc2053_write_reg(dev, 0x55, 0x07);
ret |= gc2053_write_reg(dev, 0x60, 0x40);
ret |= gc2053_write_reg(dev, 0xfe, 0x04);
ret |= gc2053_write_reg(dev, 0x14, 0x78);
ret |= gc2053_write_reg(dev, 0x15, 0x78);
ret |= gc2053_write_reg(dev, 0x16, 0x78);
ret |= gc2053_write_reg(dev, 0x17, 0x78);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x92, 0x01);
ret |= gc2053_write_reg(dev, 0x94, 0x04);
ret |= gc2053_write_reg(dev, 0x95, 0x04);
ret |= gc2053_write_reg(dev, 0x96, 0x38);
ret |= gc2053_write_reg(dev, 0x97, 0x07);
ret |= gc2053_write_reg(dev, 0x98, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x83, 0x01);
ret |= gc2053_write_reg(dev, 0x87, 0x50);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x01, 0x05);
ret |= gc2053_write_reg(dev, 0x02, 0x89);
ret |= gc2053_write_reg(dev, 0x04, 0x00);
ret |= gc2053_write_reg(dev, 0x07, 0xa6);
ret |= gc2053_write_reg(dev, 0x08, 0xa9);
ret |= gc2053_write_reg(dev, 0x09, 0xa8);
ret |= gc2053_write_reg(dev, 0x0a, 0xa7);
ret |= gc2053_write_reg(dev, 0x0b, 0xff);
ret |= gc2053_write_reg(dev, 0x0c, 0xff);
ret |= gc2053_write_reg(dev, 0x0f, 0x00);
ret |= gc2053_write_reg(dev, 0x50, 0x1c);
ret |= gc2053_write_reg(dev, 0x89, 0x03);
ret |= gc2053_write_reg(dev, 0xfe, 0x04);
ret |= gc2053_write_reg(dev, 0x28, 0x86);
ret |= gc2053_write_reg(dev, 0x29, 0x86);
ret |= gc2053_write_reg(dev, 0x2a, 0x86);
ret |= gc2053_write_reg(dev, 0x2b, 0x68);
ret |= gc2053_write_reg(dev, 0x2c, 0x68);
ret |= gc2053_write_reg(dev, 0x2d, 0x68);
ret |= gc2053_write_reg(dev, 0x2e, 0x68);
ret |= gc2053_write_reg(dev, 0x2f, 0x68);
ret |= gc2053_write_reg(dev, 0x30, 0x4f);
ret |= gc2053_write_reg(dev, 0x31, 0x68);
ret |= gc2053_write_reg(dev, 0x32, 0x67);
ret |= gc2053_write_reg(dev, 0x33, 0x66);
ret |= gc2053_write_reg(dev, 0x34, 0x66);
ret |= gc2053_write_reg(dev, 0x35, 0x66);
ret |= gc2053_write_reg(dev, 0x36, 0x66);
ret |= gc2053_write_reg(dev, 0x37, 0x66);
ret |= gc2053_write_reg(dev, 0x38, 0x62);
ret |= gc2053_write_reg(dev, 0x39, 0x62);
ret |= gc2053_write_reg(dev, 0x3a, 0x62);
ret |= gc2053_write_reg(dev, 0x3b, 0x62);
ret |= gc2053_write_reg(dev, 0x3c, 0x62);
ret |= gc2053_write_reg(dev, 0x3d, 0x62);
ret |= gc2053_write_reg(dev, 0x3e, 0x62);
ret |= gc2053_write_reg(dev, 0x3f, 0x62);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x9a, 0x06);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0x7b, 0x2a);
ret |= gc2053_write_reg(dev, 0x23, 0x2d);
ret |= gc2053_write_reg(dev, 0xfe, 0x03);
ret |= gc2053_write_reg(dev, 0x01, 0x27);
ret |= gc2053_write_reg(dev, 0x02, 0x56);
ret |= gc2053_write_reg(dev, 0x03, 0x8e);
ret |= gc2053_write_reg(dev, 0x12, 0x80);
ret |= gc2053_write_reg(dev, 0x13, 0x07);
ret |= gc2053_write_reg(dev, 0x15, 0x10);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0x3e, 0x91);
/* 76上可运行的版本,72上不能正常出图
ret |= gc2053_write_reg(dev, 0xfe, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0xf2, 0x00);
ret |= gc2053_write_reg(dev, 0xf3, 0x00);
ret |= gc2053_write_reg(dev, 0xf4, 0x36);
ret |= gc2053_write_reg(dev, 0xf5, 0xc0);
ret |= gc2053_write_reg(dev, 0xf6, 0x44);
ret |= gc2053_write_reg(dev, 0xf7, 0x01);
ret |= gc2053_write_reg(dev, 0xf8, 0x2c);
ret |= gc2053_write_reg(dev, 0xf9, 0x42);
ret |= gc2053_write_reg(dev, 0xfc, 0x8e);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0x87, 0x18);
ret |= gc2053_write_reg(dev, 0xee, 0x30);
ret |= gc2053_write_reg(dev, 0xd0, 0xb7);
ret |= gc2053_write_reg(dev, 0x03, 0x04);
ret |= gc2053_write_reg(dev, 0x04, 0x60);
ret |= gc2053_write_reg(dev, 0x05, 0x04);//line length
ret |= gc2053_write_reg(dev, 0x06, 0x4c);
ret |= gc2053_write_reg(dev, 0x07, 0x00);
ret |= gc2053_write_reg(dev, 0x08, 0x11);
ret |= gc2053_write_reg(dev, 0x0a, 0x02);
ret |= gc2053_write_reg(dev, 0x0c, 0x02);
ret |= gc2053_write_reg(dev, 0x0d, 0x04);//win_height
ret |= gc2053_write_reg(dev, 0x0e, 0x40);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x83, 0x01);
ret |= gc2053_write_reg(dev, 0x87, 0x51);
ret |= gc2053_write_reg(dev, 0xfe, 0x03);
ret |= gc2053_write_reg(dev, 0x01, 0x27);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0x3e, 0x91);
ret |= gc2053_write_reg(dev, 0x12, 0xe2);
ret |= gc2053_write_reg(dev, 0x13, 0x16);
ret |= gc2053_write_reg(dev, 0x19, 0x0a);
ret |= gc2053_write_reg(dev, 0x28, 0x0a);
ret |= gc2053_write_reg(dev, 0x2b, 0x04);
ret |= gc2053_write_reg(dev, 0x37, 0x03);
ret |= gc2053_write_reg(dev, 0x43, 0x07);
ret |= gc2053_write_reg(dev, 0x44, 0x40);
ret |= gc2053_write_reg(dev, 0x46, 0x0b);
ret |= gc2053_write_reg(dev, 0x4b, 0x20);
ret |= gc2053_write_reg(dev, 0x4e, 0x08);
ret |= gc2053_write_reg(dev, 0x55, 0x20);
ret |= gc2053_write_reg(dev, 0x77, 0x01);
ret |= gc2053_write_reg(dev, 0x78, 0x00);
ret |= gc2053_write_reg(dev, 0x7c, 0x93);
ret |= gc2053_write_reg(dev, 0x8d, 0x92);
ret |= gc2053_write_reg(dev, 0x90, 0x00);
ret |= gc2053_write_reg(dev, 0x41, 0x04);
ret |= gc2053_write_reg(dev, 0x42, 0x65);
ret |= gc2053_write_reg(dev, 0xce, 0x7c);
ret |= gc2053_write_reg(dev, 0xd2, 0x41);
ret |= gc2053_write_reg(dev, 0xd3, 0xdc);
ret |= gc2053_write_reg(dev, 0xe6, 0x50);
ret |= gc2053_write_reg(dev, 0xb6, 0xc0);
ret |= gc2053_write_reg(dev, 0xb0, 0x70);
ret |= gc2053_write_reg(dev, 0x26, 0x30);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x55, 0x07);
//dither
ret |= gc2053_write_reg(dev, 0x58, 0x00); //default 0x80
ret |= gc2053_write_reg(dev, 0x04, 0x00);
ret |= gc2053_write_reg(dev, 0x94, 0x03);
ret |= gc2053_write_reg(dev, 0x97, 0x07); //out_x_size
ret |= gc2053_write_reg(dev, 0x98, 0x80);
ret |= gc2053_write_reg(dev, 0xfe, 0x04);
ret |= gc2053_write_reg(dev, 0x14, 0x78);
ret |= gc2053_write_reg(dev, 0x15, 0x78);
ret |= gc2053_write_reg(dev, 0x16, 0x78);
ret |= gc2053_write_reg(dev, 0x17, 0x78);
ret |= gc2053_write_reg(dev, 0xfe, 0x01);
ret |= gc2053_write_reg(dev, 0x9a, 0x06);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
ret |= gc2053_write_reg(dev, 0x7b, 0x2a);
ret |= gc2053_write_reg(dev, 0x23, 0x2d);
ret |= gc2053_write_reg(dev, 0xfe, 0x03);
ret |= gc2053_write_reg(dev, 0x02, 0x56);
ret |= gc2053_write_reg(dev, 0x03, 0xb6);
ret |= gc2053_write_reg(dev, 0x12, 0x80);
ret |= gc2053_write_reg(dev, 0x13, 0x07);
ret |= gc2053_write_reg(dev, 0x15, 0x12);
ret |= gc2053_write_reg(dev, 0xfe, 0x00);
*/
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "gc2053_write_reg failed\n");
return XMEDIA_FAILURE;
}
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("==========Galaxycore GC2053_1080P_30FPS_10BIT_LINEAR_Init_OK!====================\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
#if 0
static xmedia_s32 gc2053_2lane_wdr_1920x1080_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret |= gc2053_write_reg(dev,0xfe, 0x80);
ret |= gc2053_write_reg(dev,0xfe, 0x80);
ret |= gc2053_write_reg(dev,0xfe, 0x80);
ret |= gc2053_write_reg(dev,0xfe, 0x00);
ret |= gc2053_write_reg(dev,0xf2, 0x00);
ret |= gc2053_write_reg(dev,0xf3, 0x00);
ret |= gc2053_write_reg(dev,0xf4, 0x36);
ret |= gc2053_write_reg(dev,0xf5, 0xc0);
ret |= gc2053_write_reg(dev,0xf6, 0x44);
ret |= gc2053_write_reg(dev,0xf7, 0x01);
ret |= gc2053_write_reg(dev,0xf8, 0x2c);
ret |= gc2053_write_reg(dev,0xf9, 0x42);
ret |= gc2053_write_reg(dev,0xfc, 0x8e);
ret |= gc2053_write_reg(dev,0xfe, 0x00);
ret |= gc2053_write_reg(dev,0x87, 0x18);
ret |= gc2053_write_reg(dev,0xee, 0x30);
ret |= gc2053_write_reg(dev,0xd0, 0xb7);
ret |= gc2053_write_reg(dev,0x03, 0x04);
ret |= gc2053_write_reg(dev,0x04, 0x60);
ret |= gc2053_write_reg(dev,0x05, 0x04);
ret |= gc2053_write_reg(dev,0x06, 0x4c);
ret |= gc2053_write_reg(dev,0x07, 0x00);
ret |= gc2053_write_reg(dev,0x08, 0x11);
ret |= gc2053_write_reg(dev,0x0a, 0x02);
ret |= gc2053_write_reg(dev,0x0c, 0x02);
ret |= gc2053_write_reg(dev,0x0d, 0x04);//win_height
ret |= gc2053_write_reg(dev,0x0e, 0x40);
ret |= gc2053_write_reg(dev,0x12, 0xe2);
ret |= gc2053_write_reg(dev,0x13, 0x16);
ret |= gc2053_write_reg(dev,0x19, 0x0a);
ret |= gc2053_write_reg(dev,0x28, 0x0a);
ret |= gc2053_write_reg(dev,0x2b, 0x04);
ret |= gc2053_write_reg(dev,0x37, 0x03);
ret |= gc2053_write_reg(dev,0x43, 0x07);
ret |= gc2053_write_reg(dev,0x44, 0x40);
ret |= gc2053_write_reg(dev,0x46, 0x0b);
ret |= gc2053_write_reg(dev,0x4b, 0x20);
ret |= gc2053_write_reg(dev,0x4e, 0x08);
ret |= gc2053_write_reg(dev,0x55, 0x20);
ret |= gc2053_write_reg(dev,0x77, 0x01);
ret |= gc2053_write_reg(dev,0x78, 0x00);
ret |= gc2053_write_reg(dev,0x7c, 0x93);
ret |= gc2053_write_reg(dev,0x8d, 0x92);
ret |= gc2053_write_reg(dev,0x90, 0x00);
ret |= gc2053_write_reg(dev,0x41, 0x04);//VTS
ret |= gc2053_write_reg(dev,0x42, 0x65);
ret |= gc2053_write_reg(dev,0xce, 0x7c);
ret |= gc2053_write_reg(dev,0xd2, 0x41);
ret |= gc2053_write_reg(dev,0xd3, 0xdc);
ret |= gc2053_write_reg(dev,0xe6, 0x38);
ret |= gc2053_write_reg(dev,0xb6, 0xc0);
ret |= gc2053_write_reg(dev,0xb0, 0x70);
ret |= gc2053_write_reg(dev,0x26, 0x20);
ret |= gc2053_write_reg(dev,0xfe, 0x04);
ret |= gc2053_write_reg(dev,0xe0, 0x18);
ret |= gc2053_write_reg(dev,0xfe, 0x01);
ret |= gc2053_write_reg(dev,0x55, 0x07);
ret |= gc2053_write_reg(dev,0x58, 0x00);
ret |= gc2053_write_reg(dev,0xfe, 0x04);
ret |= gc2053_write_reg(dev,0x14, 0x78);
ret |= gc2053_write_reg(dev,0x15, 0x78);
ret |= gc2053_write_reg(dev,0x16, 0x78);
ret |= gc2053_write_reg(dev,0x17, 0x78);
ret |= gc2053_write_reg(dev,0xfe, 0x01);
ret |= gc2053_write_reg(dev,0x04, 0x00);
ret |= gc2053_write_reg(dev,0x94, 0x03);
ret |= gc2053_write_reg(dev,0x97, 0x07);
ret |= gc2053_write_reg(dev,0x98, 0x80);
ret |= gc2053_write_reg(dev,0x9a, 0x06);
ret |= gc2053_write_reg(dev,0x40, 0x03);
ret |= gc2053_write_reg(dev,0x42, 0x20);
ret |= gc2053_write_reg(dev,0x46, 0x4f);
ret |= gc2053_write_reg(dev,0x47, 0x40);
ret |= gc2053_write_reg(dev,0x4f, 0x02);
ret |= gc2053_write_reg(dev,0x50, 0x3a);
ret |= gc2053_write_reg(dev,0x51, 0x1d);
ret |= gc2053_write_reg(dev,0xfe, 0x00);
ret |= gc2053_write_reg(dev,0x7b, 0x2a);
ret |= gc2053_write_reg(dev,0x23, 0x2d);
ret |= gc2053_write_reg(dev,0xfe, 0x03);
ret |= gc2053_write_reg(dev,0x01, 0x27);
ret |= gc2053_write_reg(dev,0x02, 0x56);
ret |= gc2053_write_reg(dev,0x03, 0xb6);
ret |= gc2053_write_reg(dev,0x12, 0x80);
ret |= gc2053_write_reg(dev,0x13, 0x07);
ret |= gc2053_write_reg(dev,0x15, 0x12);
ret |= gc2053_write_reg(dev,0xfe, 0x00);
ret |= gc2053_write_reg(dev,0x3e, 0x91);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "gc2053_write_reg failed\n");
return XMEDIA_FAILURE;
}
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("==========Galaxycore GC2053_1080P_30FPS_10BIT_WDR_Init_OK!=======================\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
#endif
#endif
#endif
static xmedia_void gc2053_slave_init(xmedia_u32 dev)
{
// gc2053_write_reg(dev, 0xfe, 0x00);
// gc2053_write_reg(dev, 0x7f, 0x9d);
// gc2053_write_reg(dev, 0x82, 0x0a);
// gc2053_write_reg(dev, 0x83, 0x0b);
// gc2053_write_reg(dev, 0x84, 0x80);
// gc2053_write_reg(dev, 0x85, 0x51);
// gc2053_write_reg(dev, 0x86, 0x00);
// gc2053_write_reg(dev, 0x87, 0x13);
// gc2053_write_reg(dev, 0x88, 0x00);
// gc2053_write_reg(dev, 0x89, 0x04);
// gc2053_write_reg(dev, 0x8a, 0x00);
// gc2053_write_reg(dev, 0x8b, 0x12);
// gc2053_write_reg(dev, 0xfe, 0x00);
gc2053_write_reg(dev, 0xfe, 0x00);
gc2053_write_reg(dev, 0x7f, 0x09);
gc2053_write_reg(dev, 0x82, 0x0a);
gc2053_write_reg(dev, 0x83, 0x0b);
gc2053_write_reg(dev, 0x84, 0x80);
gc2053_write_reg(dev, 0x85, 0x51);
SENSOR_PRINT("====== gc2053 slave setting init success!=======\n");
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_init_image(xmedia_u32 dev, xmedia_u8 image_mode, xmedia_sensor_work_mode work_mode)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
switch(image_mode) {
case GC2053_2M_10BIT_LINEAR_MODE:
#ifdef GC2053_DVP
ret = gc2053_dvp_linear_1920X1080_init(dev);
break;
#else
ret = gc2053_2lane_linear_1920x1080_init(dev);
break;
#endif
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
if (work_mode == XMEDIA_SENSOR_WORK_MODE_SLAVE && image_mode == GC2053_2M_10BIT_LINEAR_MODE) {
gc2053_slave_init(dev);
}
return ret;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
if (g_gc2053_i2c_fd[dev] < 0) {
SENSOR_PRINT("Sensor dev [%d], i2c not open. please init i2c at first.\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_set_slave_addr(g_gc2053_i2c_fd[dev], slave_addr);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
i2c_close(g_gc2053_i2c_fd[dev]);
g_gc2053_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_FAILURE;
}
g_gc2053_i2c_addr[dev] = slave_addr;
SENSOR_PRINT("Sensor dev [%d] set slave addr 0x%x success.\n", dev, slave_addr);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr)
{
xmedia_s32 ret;
if (g_gc2053_i2c_fd[dev] >= 0) {
SENSOR_PRINT("====== Sensor dev [%d], i2c already init !=======\n", dev);
return XMEDIA_SUCCESS;
}
if (i2c_dev == SENSOR_I2C_INVALID) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor i2c dev invalid! Please set i2c dev at first!\n");
return XMEDIA_ERRCODE_NOT_CONFIG;
}
g_gc2053_i2c_fd[dev] = i2c_open(i2c_dev);
if (g_gc2053_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "Open /dev/i2c_drv-%u error!\n", i2c_dev);
return XMEDIA_ERRCODE_OPEN_FAILED;
}
ret = gc2053_set_slave_addr(dev, i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
SENSOR_PRINT("====== i2c[%d] init success!=======\n", i2c_dev);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_i2c_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
ret = i2c_close(g_gc2053_i2c_fd[dev]);
if(ret < 0 ){
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] close i2c failed!\n", dev);
return ret;
}
g_gc2053_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_read_reg(xmedia_u32 dev, xmedia_u32 addr,xmedia_u32 *data)
{
xmedia_s32 ret;
xmedia_u8 buf[GC2053_DATA_BYTE];
if (g_gc2053_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_read(g_gc2053_i2c_fd[dev], g_gc2053_i2c_addr[dev], addr, GC2053_ADDR_BYTE, buf, GC2053_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] read i2c addr [0x%X] failed!\n", dev, addr);
return ret;
}
*data = buf[0]; //GC2053_DATA_BYTE == 1
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data)
{
xmedia_s32 idx = 0;
xmedia_u8 buf[GC2053_ADDR_BYTE + GC2053_DATA_BYTE];
xmedia_s32 ret = 0;
if (g_gc2053_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not open!\n", dev);
return XMEDIA_FAILURE;
}
// if (GC2053_ADDR_BYTE == 2) {
// buf[idx] = (addr >> 8) & 0xff;
// idx++;
// buf[idx] = addr & 0xff;
// idx++;
// } else {
buf[idx] = addr & 0xFF; //GC2053_ADDR_BYTE == 1
idx++;
// }
// if (GC2053_DATA_BYTE == 2) {
// buf[idx] = (data >> 8) & 0xff;
// idx++;
// buf[idx] = data & 0xff;
// idx++;
// } else {
buf[idx] = data & 0xFF; //GC2053_DATA_BYTE == 1
// idx++;
// }
ret = i2c_write(g_gc2053_i2c_fd[dev], g_gc2053_i2c_addr[dev], buf, GC2053_ADDR_BYTE + GC2053_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_WRITE error!\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2053_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en)
{
xmedia_s32 ret;
xmedia_u32 mirror_flip_type;
gc2053_read_reg(dev, GC2053_REG_ADDR_MIRROR_FLIP, &mirror_flip_type);
if (mirror_en) {
mirror_flip_type |= 0x01;
} else {
mirror_flip_type &= 0xFE;
}
if (flip_en) {
mirror_flip_type |= 0x02;
} else {
mirror_flip_type &= 0xFD;
}
ret = gc2053_write_reg(dev, GC2053_REG_ADDR_MIRROR_FLIP, mirror_flip_type);
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "sc8238_write_reg failed\n");
}
return XMEDIA_SUCCESS;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef __GC2053_CTRL_H__
#define __GC2053_CTRL_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define GC2053_I2C_ADDR 0x6e
#define GC2053_ADDR_BYTE 1
#define GC2053_DATA_BYTE 1
//#define GC2053_DVP //DVP模式下需定义此宏,MIPI模式则不需要定义此宏
// gc2053 specs list
#define GC2053_2M_10BIT_LINEAR_MODE 1
xmedia_s32 gc2053_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr);
xmedia_s32 gc2053_i2c_exit(xmedia_u32 dev);
xmedia_s32 gc2053_read_reg(xmedia_u32 dev, xmedia_u32 addr,xmedia_u32 *data);
xmedia_s32 gc2053_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data);
xmedia_s32 gc2053_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en);
xmedia_s32 gc2053_init_image(xmedia_u32 dev, xmedia_u8 img_mode, xmedia_sensor_work_mode work_mode);
xmedia_s32 gc2053_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr);
#ifdef __cplusplus
}
#endif
#endif
+171
View File
@@ -0,0 +1,171 @@
// Piris attr
static const xmedia_isp_piris_attr g_gc2053_piris_attr = {
0,
1,
94,
62,
// Step-F number mapping table. Must be from small to large. F1.0 is 1024 and F32.0 is 1
{30, 35, 40, 45, 50, 56, 61, 67, 73, 79, 85, 92, 98, 105, 112, 120, 127, 135, 143, 150, 158,
166, 174, 183, 191, 200, 208, 217, 225, 234, 243, 252, 261, 270, 279, 289, 298, 307, 316, 325, 335, 344,
353, 362, 372, 381, 390, 399, 408, 417, 426, 435, 444, 453, 462, 470, 478, 486, 493, 500, 506, 512},
XMEDIA_ISP_IRIS_F_NO_1_4,
XMEDIA_ISP_IRIS_F_NO_5_6
};
static const xmedia_isp_awb_ccm g_gc2053_awb_ccm = {
4,
{
{
6240,
{
0x023B, 0x8121, 0x801A,
0x8062, 0x0230, 0x80CE,
0x8001, 0x8106, 0x0207
},
},
{
4950,
{
656, 33122, 32814,
32887, 551, 32944,
5, 33119, 602
},
},
{
3930,
{
0x02AC, 0x816B, 0x8041,
0x807C, 0x0209, 0x808D,
0x000F, 0x8176, 0x0267
},
},
{
2810,
{
0x022E, 0x8143, 0x0015,
0x807D, 0x01D8, 0x805B,
0x0019, 0x82D2, 0x03B9
},
},
{
1600,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
{
1400,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
{
1000,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
},
};
static const xmedia_isp_awb_agc_table g_gc2053_awb_agc_table = {
// bvalid
1,
// saturation
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
{ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 }
};
static const xmedia_isp_awb_ccm g_gc2053_awb_wdr_ccm = {
3,
{
{
6240,
{
0x01C8, 0x80B6, 0x8012,
0x8032, 0x0184, 0x8052,
0x8003, 0x809B, 0x019E
},
},
{
3930,
{
0x0229, 0x80F2, 0x8037,
0x8049, 0x0186, 0x803D,
0x0002, 0x80C2, 0x01C0
},
},
{
2810,
{
0x01CB, 0x80B0, 0x801B,
0x8048, 0x0189, 0x8041,
0x0004, 0x8144, 0x0240
},
},
{
2100,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
{
1600,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
{
1400,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
{
1000,
{
0x0100, 0x0000, 0x0000,
0x0000, 0x0100, 0x0000,
0x0000, 0x0000, 0x0100
},
},
},
};
static const xmedia_isp_awb_agc_table g_gc2053_awb_wdr_agc_table = {
// bvalid
1,
// saturation
//{ 90, 90, 85, 75, 70, 65, 65, 65, 60, 60, 60, 60, 60, 60, 60, 60 }
{ 75, 75, 70, 70, 70, 65, 65, 65, 60, 60, 60, 60, 60, 60, 60, 60 }
};
+5
View File
@@ -0,0 +1,5 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+21
View File
@@ -0,0 +1,21 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_gc2083
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/../include
SDK_USR_CFLAGS += -I.
AT := @
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,2 @@
SRCS-y += gc2083.c
SRCS-y += gc2083_ctrl.c
File diff suppressed because it is too large Load Diff
+71
View File
@@ -0,0 +1,71 @@
#ifndef __GC2083_H__
#define __GC2083_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
// sensor fps mode
#define GC2083_FULL_LINES_MAX 0x3FFF
#define GC2083_VMAX_2M_LINEAR 1125
#define GC2083_EXP_OFFSET_LINEAR 2
#define GC2083_S_EXP_MAX_DEFAULT_1620P 0xcc
// the value of the gc2083 exposure register is in half line units, (<< 1) for AE calculation, (>> 1) for EXP reg
#define GC2083_EXP_SHIFT 1
#define GC2083_REG_ADDR_EXP_H 0x0d04
#define GC2083_REG_ADDR_EXP_L 0x0d03
#define GC2083_REG_ADDR_AGAIN_1 0x00d0
#define GC2083_REG_ADDR_AGAIN_2 0x0155
#define GC2083_REG_ADDR_AGAIN_3 0x0410
#define GC2083_REG_ADDR_AGAIN_4 0x0411
#define GC2083_REG_ADDR_AGAIN_5 0x0412
#define GC2083_REG_ADDR_AGAIN_6 0x0413
#define GC2083_REG_ADDR_AGAIN_7 0x0414
#define GC2083_REG_ADDR_AGAIN_8 0x0415
#define GC2083_REG_ADDR_AGAIN_9 0x0416
#define GC2083_REG_ADDR_AGAIN_10 0x0417
#define GC2083_REG_ADDR_AGAIN_11 0x00b8
#define GC2083_REG_ADDR_AGAIN_12 0x00b9
#define GC2083_REG_ADDR_AGAIN_13 0x031d
#define GC2083_REG_ADDR_AGAIN_14 0x0dc1
#define GC2083_REG_ADDR_AGAIN_15 0x031d
#define GC2083_REG_ADDR_DGAIN_H 0x00b1
#define GC2083_REG_ADDR_DGAIN_L 0x00b2
#define GC2083_REG_ADDR_VMAX_H 0x0d41
#define GC2083_REG_ADDR_VMAX_L 0x0d42
typedef enum {
GC2083_REG_EXP_H = 0,
GC2083_REG_EXP_L,
GC2083_REG_AGAIN_1,
GC2083_REG_AGAIN_2,
GC2083_REG_AGAIN_3,
GC2083_REG_AGAIN_4,
GC2083_REG_AGAIN_5,
GC2083_REG_AGAIN_6,
GC2083_REG_AGAIN_7,
GC2083_REG_AGAIN_8,
GC2083_REG_AGAIN_9,
GC2083_REG_AGAIN_10,
GC2083_REG_AGAIN_11,
GC2083_REG_AGAIN_12,
GC2083_REG_AGAIN_13,
GC2083_REG_AGAIN_14,
GC2083_REG_AGAIN_15,
GC2083_REG_DGAIN_H,
GC2083_REG_DGAIN_L,
GC2083_REG_VMAX_H, // VMAX_H需先于VMAX_L更新
GC2083_REG_VMAX_L,
GC2083_REG_MAX_NUM
} gc2083_reg_info;
#ifdef __cplusplus
}
#endif
#endif // __GC2083_H__
+360
View File
@@ -0,0 +1,360 @@
#include <stdio.h>
#include <string.h>
#include "i2c_dev.h"
#include "gc2083.h"
#include "gc2083_ctrl.h"
SENSOR_PRIORITY_DATA static xmedia_s32 g_gc2083_i2c_addr[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
SENSOR_PRIORITY_DATA static xmedia_s32 g_gc2083_i2c_fd[XMEDIA_SENSOR_DEV_MAX_NUM] =
{ [0 ...(XMEDIA_SENSOR_DEV_MAX_NUM - 1)] = SENSOR_I2C_INVALID };
/*
* 函数功能: gc2083 MIPI 2lane 1080p线性模式初始化序列 - 1920x1080x30fps
* 函数参数:
* dev - sensor 设备号
* 返回值:
*
*/
SENSOR_PRIORITY_FUNC static xmedia_s32 gc2083_2lane_linear_1920x1080_init(xmedia_u32 dev)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
//system
ret |= gc2083_write_reg(dev, 0x03fe, 0xf0);
ret |= gc2083_write_reg(dev, 0x03fe, 0xf0);
ret |= gc2083_write_reg(dev, 0x03fe, 0xf0);
ret |= gc2083_write_reg(dev, 0x03fe, 0x00);
ret |= gc2083_write_reg(dev, 0x03f2, 0x00);
ret |= gc2083_write_reg(dev, 0x03f3, 0x00);
ret |= gc2083_write_reg(dev, 0x03f4, 0x36);
ret |= gc2083_write_reg(dev, 0x03f5, 0xc0);
ret |= gc2083_write_reg(dev, 0x03f6, 0x24);
ret |= gc2083_write_reg(dev, 0x03f7, 0x01);
ret |= gc2083_write_reg(dev, 0x03f8, 0x2c);
ret |= gc2083_write_reg(dev, 0x03f9, 0x43);
ret |= gc2083_write_reg(dev, 0x03fc, 0x8e);
ret |= gc2083_write_reg(dev, 0x0381, 0x07);
ret |= gc2083_write_reg(dev, 0x00d7, 0x29);
//CISCTL & ANALOG
ret |= gc2083_write_reg(dev, 0x0d6d, 0x18);
ret |= gc2083_write_reg(dev, 0x00d5, 0x03);
ret |= gc2083_write_reg(dev, 0x0082, 0x01);
ret |= gc2083_write_reg(dev, 0x0db3, 0xd4);
ret |= gc2083_write_reg(dev, 0x0db0, 0x0d);
ret |= gc2083_write_reg(dev, 0x0db5, 0x96);
ret |= gc2083_write_reg(dev, 0x0d03, 0x02);
ret |= gc2083_write_reg(dev, 0x0d04, 0x02);
ret |= gc2083_write_reg(dev, 0x0d05, 0x05);
ret |= gc2083_write_reg(dev, 0x0d06, 0xba);
ret |= gc2083_write_reg(dev, 0x0d07, 0x00);
ret |= gc2083_write_reg(dev, 0x0d08, 0x11);
ret |= gc2083_write_reg(dev, 0x0d09, 0x00);
ret |= gc2083_write_reg(dev, 0x0d0a, 0x02);
ret |= gc2083_write_reg(dev, 0x000b, 0x00);
ret |= gc2083_write_reg(dev, 0x000c, 0x02);
ret |= gc2083_write_reg(dev, 0x0d0d, 0x04);
ret |= gc2083_write_reg(dev, 0x0d0e, 0x40);
ret |= gc2083_write_reg(dev, 0x000f, 0x07);
ret |= gc2083_write_reg(dev, 0x0010, 0x90);
ret |= gc2083_write_reg(dev, 0x0017, 0x0c);
ret |= gc2083_write_reg(dev, 0x0d73, 0x92);
ret |= gc2083_write_reg(dev, 0x0076, 0x00);
ret |= gc2083_write_reg(dev, 0x0d76, 0x00);
ret |= gc2083_write_reg(dev, 0x0d41, 0x04);
ret |= gc2083_write_reg(dev, 0x0d42, 0x65);
ret |= gc2083_write_reg(dev, 0x0d7a, 0x10);
ret |= gc2083_write_reg(dev, 0x0d19, 0x31);
ret |= gc2083_write_reg(dev, 0x0d25, 0x0b);
ret |= gc2083_write_reg(dev, 0x0d20, 0x60);
ret |= gc2083_write_reg(dev, 0x0d27, 0x03);
ret |= gc2083_write_reg(dev, 0x0d29, 0x60);
ret |= gc2083_write_reg(dev, 0x0d43, 0x10);
ret |= gc2083_write_reg(dev, 0x0d49, 0x10);
ret |= gc2083_write_reg(dev, 0x0d55, 0x18);
ret |= gc2083_write_reg(dev, 0x0dc2, 0x44);
ret |= gc2083_write_reg(dev, 0x0058, 0x3c);
ret |= gc2083_write_reg(dev, 0x00d8, 0x68);
ret |= gc2083_write_reg(dev, 0x00d9, 0x14);
ret |= gc2083_write_reg(dev, 0x00da, 0xc1);
ret |= gc2083_write_reg(dev, 0x0050, 0x18);
ret |= gc2083_write_reg(dev, 0x0db6, 0x3d);
ret |= gc2083_write_reg(dev, 0x00d2, 0xbc);
ret |= gc2083_write_reg(dev, 0x0d66, 0x42);
ret |= gc2083_write_reg(dev, 0x008c, 0x07);
ret |= gc2083_write_reg(dev, 0x008d, 0xff);
//gain
ret |= gc2083_write_reg(dev, 0x007a, 0x50); //global gain
ret |= gc2083_write_reg(dev, 0x00d0, 0x00);
ret |= gc2083_write_reg(dev, 0x0dc1, 0x00);
//isp
ret |= gc2083_write_reg(dev, 0x0102, 0xa9); //89
ret |= gc2083_write_reg(dev, 0x0158, 0x00);
ret |= gc2083_write_reg(dev, 0x0107, 0xa6);
ret |= gc2083_write_reg(dev, 0x0108, 0xa9);
ret |= gc2083_write_reg(dev, 0x0109, 0xa8);
ret |= gc2083_write_reg(dev, 0x010a, 0xa7);
ret |= gc2083_write_reg(dev, 0x010b, 0xff);
ret |= gc2083_write_reg(dev, 0x010c, 0xff);
ret |= gc2083_write_reg(dev, 0x0428, 0x86);//84
ret |= gc2083_write_reg(dev, 0x0429, 0x86);//84
ret |= gc2083_write_reg(dev, 0x042a, 0x86);//84
ret |= gc2083_write_reg(dev, 0x042b, 0x68);//84
ret |= gc2083_write_reg(dev, 0x042c, 0x68);//84
ret |= gc2083_write_reg(dev, 0x042d, 0x68);//84
ret |= gc2083_write_reg(dev, 0x042e, 0x68);//83
ret |= gc2083_write_reg(dev, 0x042f, 0x68);//82
ret |= gc2083_write_reg(dev, 0x0430, 0x4f);//82
ret |= gc2083_write_reg(dev, 0x0431, 0x68);//82
ret |= gc2083_write_reg(dev, 0x0432, 0x67);//82
ret |= gc2083_write_reg(dev, 0x0433, 0x66);//82
ret |= gc2083_write_reg(dev, 0x0434, 0x66);//82
ret |= gc2083_write_reg(dev, 0x0435, 0x66);//82
ret |= gc2083_write_reg(dev, 0x0436, 0x66);//64
ret |= gc2083_write_reg(dev, 0x0437, 0x66);//68
ret |= gc2083_write_reg(dev, 0x0438, 0x62);
ret |= gc2083_write_reg(dev, 0x0439, 0x62);
ret |= gc2083_write_reg(dev, 0x043a, 0x62);
ret |= gc2083_write_reg(dev, 0x043b, 0x62);
ret |= gc2083_write_reg(dev, 0x043c, 0x62);
ret |= gc2083_write_reg(dev, 0x043d, 0x62);
ret |= gc2083_write_reg(dev, 0x043e, 0x62);
ret |= gc2083_write_reg(dev, 0x043f, 0x62);
//dark sun
ret |= gc2083_write_reg(dev, 0x0077, 0x01); //01 settle_en
ret |= gc2083_write_reg(dev, 0x0078, 0x65); //settle_exp_th
ret |= gc2083_write_reg(dev, 0x0079, 0x04); //settle_exp_th
ret |= gc2083_write_reg(dev, 0x0067, 0xa0); //settle_ref_th
ret |= gc2083_write_reg(dev, 0x0054, 0xff); //settle_sig_th
ret |= gc2083_write_reg(dev, 0x0055, 0x02); //settle_sig_th
ret |= gc2083_write_reg(dev, 0x0056, 0x00); //settle_colgain_th
ret |= gc2083_write_reg(dev, 0x0057, 0x04); //settle_colgain_th
ret |= gc2083_write_reg(dev, 0x005a, 0xff); //settle_data_value
ret |= gc2083_write_reg(dev, 0x005b, 0x07); //settle_data_value
//blk
ret |= gc2083_write_reg(dev, 0x0026, 0x01);
ret |= gc2083_write_reg(dev, 0x0152, 0x02);
ret |= gc2083_write_reg(dev, 0x0153, 0x50);
ret |= gc2083_write_reg(dev, 0x0155, 0x93);
ret |= gc2083_write_reg(dev, 0x0410, 0x16);
ret |= gc2083_write_reg(dev, 0x0411, 0x16);
ret |= gc2083_write_reg(dev, 0x0412, 0x16);
ret |= gc2083_write_reg(dev, 0x0413, 0x16);
ret |= gc2083_write_reg(dev, 0x0414, 0x6f);
ret |= gc2083_write_reg(dev, 0x0415, 0x6f);
ret |= gc2083_write_reg(dev, 0x0416, 0x6f);
ret |= gc2083_write_reg(dev, 0x0417, 0x6f);
ret |= gc2083_write_reg(dev, 0x04e0, 0x18);
//window
ret |= gc2083_write_reg(dev, 0x0192, 0x02);
ret |= gc2083_write_reg(dev, 0x0194, 0x02);
ret |= gc2083_write_reg(dev, 0x0195, 0x04);
ret |= gc2083_write_reg(dev, 0x0196, 0x38);
ret |= gc2083_write_reg(dev, 0x0197, 0x07);
ret |= gc2083_write_reg(dev, 0x0198, 0x80);
//DVP & MIPI
ret |= gc2083_write_reg(dev, 0x0201, 0x27); //20//27[6:5]clkctr [2]phy-lane1_en [1]phy-lane0_en [0]phy_clk_en
ret |= gc2083_write_reg(dev, 0x0202, 0x53); //56//[7:6]data1ctr [5:4]data0ctr [3:0]mipi_diff
//b2//b6[7]clklane_p2s_sel [6:5]data0hs_ph [4]data0_delay1s [3]clkdelay1s [2]mipi_en [1:0]clkhs_ph
ret |= gc2083_write_reg(dev, 0x0203, 0xce);
ret |= gc2083_write_reg(dev, 0x0204, 0x40);
ret |= gc2083_write_reg(dev, 0x0212, 0x07);
ret |= gc2083_write_reg(dev, 0x0213, 0x80); //LWC
ret |= gc2083_write_reg(dev, 0x0215, 0x12); //[1:0]clk_lane_mode
ret |= gc2083_write_reg(dev, 0x0229, 0x05);
ret |= gc2083_write_reg(dev, 0x0237, 0x03);
//91//40//91[7]lane_ena [6]DVPBUF_ena [5]ULPEna [4]MIPI_ena [3]mipi_set_auto_disable
//[2]RAW8_mode [1]ine_sync_mode [0]double_lane_enff 03fe 00
ret |= gc2083_write_reg(dev, 0x023e, 0x99);
printf("===Galaxycore GC2083_1080P_30FPS_10BIT_LINEAR_Init_OK!===\n");
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "gc2083_write_reg failed\n");
return XMEDIA_FAILURE;
} else {
SENSOR_PRINT("=================================================================================\n");
SENSOR_PRINT("===== GC2083_27MInput_MIPI_2lane_10bit_1920x1080_30fps linear init success!======\n");
SENSOR_PRINT("=================================================================================\n");
return XMEDIA_SUCCESS;
}
}
static xmedia_void gc2083_slave_init(xmedia_u32 dev)
{
gc2083_write_reg(dev, 0x0068, 0x93);
gc2083_write_reg(dev, 0x0069, 0x00);
gc2083_write_reg(dev, 0x0d67, 0x00);
gc2083_write_reg(dev, 0x0d69, 0x30);
gc2083_write_reg(dev, 0x0d6a, 0x08);
gc2083_write_reg(dev, 0x0d6b, 0x70);
gc2083_write_reg(dev, 0x0d6c, 0x00);
gc2083_write_reg(dev, 0x0d6d, 0x13);
gc2083_write_reg(dev, 0x0d6e, 0x00);
gc2083_write_reg(dev, 0x0d6f, 0x04);
gc2083_write_reg(dev, 0x0d70, 0x00);
gc2083_write_reg(dev, 0x0d71, 0x12);
SENSOR_PRINT("====== GC2083 slave setting init success!=======\n");
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_init_image(xmedia_u32 dev, xmedia_u8 image_mode, xmedia_sensor_work_mode work_mode)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
switch(image_mode) {
case GC2083_2M_10BIT_LINEAR_MODE:
ret = gc2083_2lane_linear_1920x1080_init(dev);
break;
default:
SENSOR_TRACE(MODULE_DBG_ERR, "Not support, please check image param!\n");
return XMEDIA_ERRCODE_NOT_SUPPORT;
}
if (work_mode == XMEDIA_SENSOR_WORK_MODE_SLAVE && image_mode == GC2083_2M_10BIT_LINEAR_MODE) {
gc2083_slave_init(dev);
}
return ret;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr)
{
xmedia_s32 ret;
if (g_gc2083_i2c_fd[dev] < 0) {
SENSOR_PRINT("Sensor dev [%d], i2c not open. please init i2c at first.\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_set_slave_addr(g_gc2083_i2c_fd[dev], slave_addr);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_SLAVE_FORCE error!\n");
i2c_close(g_gc2083_i2c_fd[dev]);
g_gc2083_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_FAILURE;
}
g_gc2083_i2c_addr[dev] = slave_addr;
SENSOR_PRINT("Sensor dev [%d] set slave addr 0x%x success.\n", dev, slave_addr);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr)
{
xmedia_s32 ret;
if (g_gc2083_i2c_fd[dev] >= 0) {
SENSOR_PRINT("====== Sensor dev [%d], i2c already init !=======\n", dev);
return XMEDIA_SUCCESS;
}
if (i2c_dev == SENSOR_I2C_INVALID) {
SENSOR_TRACE(MODULE_DBG_ERR, "Sensor i2c dev invalid! Please set i2c dev at first!\n");
return XMEDIA_ERRCODE_NOT_CONFIG;
}
g_gc2083_i2c_fd[dev] = i2c_open(i2c_dev);
if (g_gc2083_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "Open /dev/i2c_drv-%u error!\n", i2c_dev);
return XMEDIA_ERRCODE_OPEN_FAILED;
}
ret = gc2083_set_slave_addr(dev, i2c_addr);
SENSOR_CHECK_RET_RETURN(ret);
SENSOR_PRINT("====== i2c[%d] init success!=======\n", i2c_dev);
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_i2c_exit(xmedia_u32 dev)
{
xmedia_s32 ret;
ret = i2c_close(g_gc2083_i2c_fd[dev]);
if(ret < 0 ) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] close i2c failed!\n", dev);
return ret;
}
g_gc2083_i2c_fd[dev] = SENSOR_I2C_INVALID;
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data)
{
xmedia_s32 ret;
xmedia_u8 buf[GC2083_DATA_BYTE];
if (g_gc2083_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
ret = i2c_read(g_gc2083_i2c_fd[dev], g_gc2083_i2c_addr[dev], addr, GC2083_ADDR_BYTE, buf, GC2083_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d] read i2c addr [0x%X] failed!\n", dev, addr);
return ret;
}
*data = buf[0]; //GC2083_DATA_BYTE == 1
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data)
{
xmedia_u32 idx = 0;
xmedia_s32 ret;
xmedia_u8 buf[8];
if (g_gc2083_i2c_fd[dev] < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "sensor dev[%d]'s i2c is not init!\n", dev);
return XMEDIA_ERRCODE_NOT_INIT;
}
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
buf[idx] = data & 0xff;
ret = i2c_write(g_gc2083_i2c_fd[dev], g_gc2083_i2c_addr[dev], buf, GC2083_ADDR_BYTE + GC2083_DATA_BYTE);
if (ret < 0) {
SENSOR_TRACE(MODULE_DBG_ERR, "I2C_WRITE error!\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
SENSOR_PRIORITY_FUNC xmedia_s32 gc2083_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en)
{
xmedia_s32 ret = 0;
if ((!mirror_en) && (!flip_en)) {
ret |= gc2083_write_reg(dev, 0x0015, 0x00);
ret |= gc2083_write_reg(dev, 0x0d15, 0x00);
ret |= gc2083_write_reg(dev, 0x0192, 0x02);
} else if((mirror_en) && (!flip_en)) {
ret |= gc2083_write_reg(dev, 0x0015, 0x01);
ret |= gc2083_write_reg(dev, 0x0d15, 0x00);
ret |= gc2083_write_reg(dev, 0x0192, 0x02);
} else if((!mirror_en) && (flip_en)) {
ret |= gc2083_write_reg(dev, 0x0015, 0x00);
ret |= gc2083_write_reg(dev, 0x0d15, 0x02);
ret |= gc2083_write_reg(dev, 0x0192, 0x03);
} else {
ret |= gc2083_write_reg(dev, 0x0015, 0x01);
ret |= gc2083_write_reg(dev, 0x0d15, 0x02);
ret |= gc2083_write_reg(dev, 0x0192, 0x03);
}
if (ret != XMEDIA_SUCCESS) {
SENSOR_TRACE(MODULE_DBG_ERR, "gc2083_write_reg failed\n");
}
return XMEDIA_SUCCESS;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef __GC2083_CTRL_H__
#define __GC2083_CTRL_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define GC2083_I2C_ADDR 0x6E
#define GC2083_ADDR_BYTE 2
#define GC2083_DATA_BYTE 1
// gc2083 specs list
#define GC2083_2M_10BIT_LINEAR_MODE 1
xmedia_s32 gc2083_i2c_init(xmedia_u32 dev, xmedia_s8 i2c_dev, xmedia_u32 i2c_addr);
xmedia_s32 gc2083_i2c_exit(xmedia_u32 dev);
xmedia_s32 gc2083_read_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 *data);
xmedia_s32 gc2083_write_reg(xmedia_u32 dev, xmedia_u32 addr, xmedia_u32 data);
xmedia_s32 gc2083_init_image(xmedia_u32 dev, xmedia_u8 image_mode, xmedia_sensor_work_mode work_mode);
xmedia_s32 gc2083_set_mirror_flip(xmedia_u32 dev, xmedia_bool mirror_en, xmedia_bool flip_en);
xmedia_s32 gc2083_set_slave_addr(xmedia_u32 dev, xmedia_u32 slave_addr);
#ifdef __cplusplus
}
#endif
#endif //__GC2083_CTRL_H__
+84
View File
@@ -0,0 +1,84 @@
#ifndef __GC2083_EX_H__
#define __GC2083_EX_H__
#ifdef __cplusplus
extern "C" {
#endif
// Piris attr
static const xmedia_isp_piris_attr g_gc2083_piris_attr = {
0,
1,
94,
62,
// Step-F number mapping table. Must be from small to large. F1.0 is 1024 and F32.0 is 1
{30, 35, 40, 45, 50, 56, 61, 67, 73, 79, 85, 92, 98, 105, 112, 120, 127, 135, 143, 150, 158,
166, 174, 183, 191, 200, 208, 217, 225, 234, 243, 252, 261, 270, 279, 289, 298, 307, 316, 325, 335, 344,
353, 362, 372, 381, 390, 399, 408, 417, 426, 435, 444, 453, 462, 470, 478, 486, 493, 500, 506, 512},
XMEDIA_ISP_IRIS_F_NO_1_4,
XMEDIA_ISP_IRIS_F_NO_5_6
};
static const xmedia_isp_awb_ccm g_gc2083_awb_ccm = {
4,
{
{
6150,
{
0x01F3, 0x80E1, 0x8012,
0x8054, 0x019E, 0x804A,
0x8001, 0x80E2, 0x01E3
},
},
{
4850,
{
0x01F6, 0x80D2, 0x8024,
0x805C, 0x01A5, 0x8049,
0x8005, 0x80FE, 0x0203
},
},
{
3650,
{
0x01E6, 0x805E, 0x8088,
0x809A, 0x01FB, 0x8061,
0x8024, 0x80FE, 0x0222
},
},
{
2650,
{
0x01F9, 0x80D5, 0x8024,
0x8082, 0x01A9, 0x8027,
0x802D, 0x821A, 0x0347
},
},
}
};
static const xmedia_isp_awb_agc_table g_gc2083_awb_agc_ir_table = {
// bvalid
1,
// saturation
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
static const xmedia_isp_awb_agc_table g_gc2083_awb_agc_table = {
// bvalid
1,
// saturation
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
{120,120,115,110,100,90,95,90,72,64,56,56,56,56,56,56}
};
#ifdef __cplusplus
}
#endif
#endif
+5
View File
@@ -0,0 +1,5 @@
ifneq ($(MCU), )
include Makefile.riscv
else
include Makefile.linux
endif
+19
View File
@@ -0,0 +1,19 @@
ISP_DIR := $(shell cd ../.. && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include $(ISP_DIR)/sensor/plat.mk
LIB_NAME := libsns_gc20b3
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -I.
$(info SRCS=$(SRCS))
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,4 @@
SRCS-y += gc20b3.c
SRCS-y += gc20b3_ctrl.c
File diff suppressed because it is too large Load Diff
+54
View File
@@ -0,0 +1,54 @@
#ifndef __GC20B3_H__
#define __GC20B3_H__
#include "sns_comm.h"
#ifdef __cplusplus
extern "C" {
#endif
#define GC20B3_VMAX_2M_LINEAR 1125
#define GC20B3_FULL_LINES_MAX 0x3FFF
// GC20B3 Register Address
#define GC20B3_REG_ADDR_EXP_H 0x0d03 //BIT[13:8]
#define GC20B3_REG_ADDR_EXP_L 0x0d04 //BIT[7:0]
#define GC20B3_REG_ADDR_AGC_L 0x00d0 //BIT[7:0]
#define GC20B3_REG_ADDR_AGC_H 0x0dc1 //BIT[0]
#define GC20B3_REG_ADDR_AGC3 0x00b8
#define GC20B3_REG_ADDR_AGC4 0x00b9
#define GC20B3_REG_ADDR_AGC5 0x0058
#define GC20B3_REG_ADDR_COL_GC_H 0x0080
#define GC20B3_REG_ADDR_COL_GC_L 0x0155
#define GC20B3_REG_ADDR_DGC_H 0x00b1 //BIT[3:0]
#define GC20B3_REG_ADDR_DGC_L 0x00b2 //BIT[7:2]
#define GC20B3_REG_ADDR_VMAX_H 0x0d41 //BIT[13:8]
#define GC20B3_REG_ADDR_VMAX_L 0x0d42 //BIT[7:0]
#define GC20B3_EXP_OFFSET 8
typedef enum {
GC20B3_REG_EXP_H = 0,
GC20B3_REG_EXP_L,
GC20B3_REG_AGC_L,
GC20B3_REG_AGC_H,
GC20B3_REG_AGC3,
GC20B3_REG_AGC4,
GC20B3_REG_AGC5,
GC20B3_REG_COL_GC_H,
GC20B3_REG_COL_GC_L,
GC20B3_REG_DGC_H,
GC20B3_REG_DGC_L,
GC20B3_REG_VMAX_H,
GC20B3_REG_VMAX_L,
GC20B3_REG_L_MAX_NUM,
} gc20b3_reg_index;
#ifdef __cplusplus
}
#endif
#endif // __GC20B3_H__

Some files were not shown because too many files have changed in this diff Show More