doubao_chat/apps/common/camera/gc6133_spi/gc6133.c

405 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

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

#include "asm/iic.h"
#include "asm/isp_dev.h"
#include "gpio.h"
#include "generic/jiffies.h"
#include "device/iic.h"
#include "device/device.h"
#include "app_config.h"
#ifdef CONFIG_VIDEO_ENABLE
#define GC6133_DEVP_MAX_W 244
#define GC6133_DEVP_MAX_H 328
#if (CONFIG_VIDEO_IMAGE_W > GC6133_DEVP_MAX_W)
#define GC6133_DEVP_INPUT_W GC6133_DEVP_MAX_W
#define GC6133_DEVP_INPUT_H GC6133_DEVP_MAX_H
#else
#define GC6133_DEVP_INPUT_W CONFIG_VIDEO_IMAGE_W
#define GC6133_DEVP_INPUT_H CONFIG_VIDEO_IMAGE_H
#endif
#ifdef CONFIG_VIDEO1_ENABLE /*开启video1则使用video1分辨率*/
#undef GC6133_DEVP_INPUT_W
#undef GC6133_DEVP_INPUT_H
#ifdef CONFIG_VIDEO1_IMAGE_W
#define GC6133_DEVP_INPUT_W CONFIG_VIDEO1_IMAGE_W
#define GC6133_DEVP_INPUT_H CONFIG_VIDEO1_IMAGE_H
#else
#define GC6133_DEVP_INPUT_W 240
#define GC6133_DEVP_INPUT_H 320
#endif
#endif
#define CONFIG_INPUT_FPS 12
static void *iic = NULL;
static u8 GC6133_reset_io[2] = {-1, -1};
static u8 GC6133_power_io[2] = {-1, -1};
#define GC6133_WRCMD 0x80
#define GC6133_RDCMD 0x81
#define GC6133_1WIRE_MODE 1
#define DELAY_TIME 10
static s32 GC6133_set_output_size(u16 *width, u16 *height, u8 *freq);
struct reginfo {
u8 reg;
u8 val;
};
static const struct reginfo sensor_init_data[] = {
/////////////////////////////////////////////////////
////////////////////// SYS //////////////////////
/////////////////////////////////////////////////////
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xf1, 0x03}, //output enable
{0xf6, 0x00},
{0xfa, 0x10},
{0xfc, 0x12}, //clock enable
{0xfe, 0x00}, //Page select
////////////////////////////////////////////////////
/////////////// ANALOG & CISCTL ////////////////
////////////////////////////////////////////////////
{0x0d, 0x30},
{0x12, 0xc8},
{0x14, 0x54}, //dark CFA
{0x15, 0x32}, //1:sdark 0:ndark
{0x16, 0x04},
{0x17, 0x19},
{0x1d, 0xb9},
{0x7a, 0x00},
{0x7b, 0x14},
{0x7d, 0x36},
////////////////////////////////////////////////////
///////////////////// ISP //////////////////////
////////////////////////////////////////////////////
{0x20, 0x7e},
{0x22, 0xf0},
{0x24, 0x54}, //output_format
{0x26, 0x87}, //[5]Y_switch [4]UV_switch [2]skin_en
////////////////////////////////////////////////////
///////////////////// BLK //////////////////////
////////////////////////////////////////////////////
{0x2a, 0x2f},
{0x37, 0x46}, //[4:0]blk_select_row
{0x39, ((GC6133_DEVP_MAX_H - GC6133_DEVP_INPUT_H) / 2 - 2) & 0xff},
{0x3a, 0x80 | ((GC6133_DEVP_MAX_W - GC6133_DEVP_INPUT_W) / 2 - 2) & 0xff},
{0x3b, (GC6133_DEVP_INPUT_H >> 8) & 0xff},
{0x3c, GC6133_DEVP_INPUT_H & 0xff},
{0x3e, GC6133_DEVP_INPUT_W & 0xff},
////////////////////////////////////////////////////
///////////////////// GAIN /////////////////////
////////////////////////////////////////////////////
{0x3f, 0x10}, //global gain
////////////////////////////////////////////////////
///////////////////// DNDD /////////////////////
////////////////////////////////////////////////////
{0x52, 0x4f},
{0x53, 0x81},
{0x54, 0x43},
{0x56, 0x78},
////////////////////////////////////////////////////
///////////////////// ASDE /////////////////////
////////////////////////////////////////////////////
{0x5b, 0x60}, //dd&ee th
{0x5c, 0x80}, //60/OT_th
////////////////////////////////////////////////////
//////////////////// INTPEE ////////////////////
////////////////////////////////////////////////////
{0x63, 0x14}, //edge effect
////////////////////////////////////////////////////
///////////////////// CC ///////////////////////
////////////////////////////////////////////////////
{0x65, 0x13}, //Y
{0x66, 0x26},
{0x67, 0x07},
{0x68, 0xf5}, //Cb
{0x69, 0xea},
{0x6a, 0x21},
{0x6b, 0x21}, //Cr
{0x6c, 0xe4},
{0x6d, 0xfb},
////////////////////////////////////////////////////
///////////////////// YCP //////////////////////
////////////////////////////////////////////////////
{0x81, 0x30}, //cb
{0x82, 0x30}, //cr
{0x83, 0x48}, //luma contrast
{0x8d, 0x78}, //edge dec sa
{0x8e, 0x25}, //autogray
////////////////////////////////////////////////////
///////////////////// AEC //////////////////////
////////////////////////////////////////////////////
{0x90, 0x3c},
{0x92, 0x40}, //target
{0x9d, 0x65}, //flicker step
{0x9e, 0x63}, //[7:4]margin
{0x9f, 0xf2}, //exp_level 3f2
{0xa3, 0x30}, //pregain
{0xa4, 0x01},
////////////////////////////////////////////////////
///////////////////// AWB //////////////////////
////////////////////////////////////////////////////
{0xb1, 0x1e}, //Y_to_C_diff
{0xb3, 0x20}, //C_max
{0xbd, 0x70}, //R_limit
{0xbe, 0x58}, //G_limit
{0xbf, 0x80}, //B_limit
////////////////////////////////////////////////////
/////////////////// Banding ////////////////////
////////////////////////////////////////////////////
{0x03, 0x01},
{0x04, 0x2f},
{0x01, 0x02}, //hb
{0x02, 0x02}, //vb
{0x0f, 0x01},
////////////////////////////////////////////////////
///////////////////// SPI //////////////////////
////////////////////////////////////////////////////
{0xfe, 0x02},
{0x01, 0x00}, //spi disable
{0x02, 0x80}, //ddr_mode
{0x03, 0x20},
{0x04, 0x30}, //[5]width x2 [3:0]frequency divider
{0x09, 0x08},
{0x0a, 0x00}, //yuv:00 raw8:02
{0x13, 0x10}, //fifo_prog_full_level
{0x20, 0xab},
{0x21, 0x80},
{0x22, 0x9d},
{0x23, 0xb6},
{0x24, 0x01}, //[1]sck_always [0]BT656
{0x25, 0xff},
{0x26, 0x00},
{0x27, 0x00},
{0x28, 0x03}, //clock_div_spi
{0x01, 0x01}, //spi enable
{0xfe, 0x00},
};
static unsigned char GC6133_wrReg(unsigned char regID, unsigned char regDat)
{
u8 ret = 1;
dev_ioctl(iic, IIC_IOCTL_START, 0);
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, GC6133_WRCMD)) {
ret = 0;
printf("iic write err!!! line : %d \n", __LINE__);
goto exit;
}
delay(DELAY_TIME);
if (dev_ioctl(iic, IIC_IOCTL_TX, regID)) {
ret = 0;
printf("iic write err!!! line : %d \n", __LINE__);
goto exit;
}
delay(DELAY_TIME);
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_STOP_BIT, regDat)) {
ret = 0;
printf("iic write err!!! line : %d \n", __LINE__);
goto exit;
}
delay(DELAY_TIME);
exit:
dev_ioctl(iic, IIC_IOCTL_STOP, 0);
return ret;
}
static unsigned char GC6133_rdReg(unsigned char regID, unsigned char *regDat)
{
u8 ret = 1;
dev_ioctl(iic, IIC_IOCTL_START, 0);
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, GC6133_WRCMD)) {
ret = 0;
printf("iic write err!!! line : %d \n", __LINE__);
goto exit;
}
delay(DELAY_TIME);
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_STOP_BIT, regID)) {
ret = 0;
printf("iic write err!!! line : %d \n", __LINE__);
goto exit;
}
delay(DELAY_TIME);
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, GC6133_RDCMD)) {
ret = 0;
printf("iic write err!!! line : %d \n", __LINE__);
goto exit;
}
delay(DELAY_TIME);
dev_ioctl(iic, IIC_IOCTL_RX_WITH_STOP_BIT, (u32)regDat);
exit:
dev_ioctl(iic, IIC_IOCTL_STOP, 0);
return ret;
}
static void GC6133_config_SENSOR(u16 *width, u16 *height, u8 *format, u8 *frame_freq)
{
int i;
for (i = 0; i < sizeof(sensor_init_data) / sizeof(sensor_init_data[0]); i++) {
GC6133_wrReg(sensor_init_data[i].reg, sensor_init_data[i].val);
}
}
static s32 GC6133_set_output_size(u16 *width, u16 *height, u8 *freq)
{
return 0;
}
static s32 GC6133_ID_check(void)
{
u8 pid = 0;
GC6133_rdReg(0xf0, &pid);
delay(4000);
GC6133_rdReg(0xf0, &pid);
delay(4000);
printf("GC6133 Sensor ID : 0x%x \n", pid);
if (pid != 0xba) {
return -1;
}
return 0;
}
void GC6133_powerio_ctl(u32 _power_gpio, u32 on_off)
{
gpio_direction_output(_power_gpio, on_off);
}
static void GC6133_reset(u8 isp_dev)
{
u8 res_io;
u8 powd_io;
u8 id = 0;
puts("GC6133 reset\n");
if (isp_dev == ISP_DEV_0) {
res_io = GC6133_reset_io[0];
powd_io = GC6133_power_io[0];
} else {
res_io = GC6133_reset_io[1];
powd_io = GC6133_power_io[1];
}
if (powd_io != (u8) - 1) {
GC6133_powerio_ctl(powd_io, 0);
}
if (res_io != (u8) - 1) {
gpio_direction_output(res_io, 1);
gpio_direction_output(res_io, 0);
os_time_dly(1);
gpio_direction_output(res_io, 1);
}
}
void close_sensor2_iic()
{
if (iic) {
dev_close(iic);
iic = NULL;
}
}
s32 GC6133_check(u8 isp_dev, u32 _reset_gpio, u32 _power_gpio)
{
if (!iic) {
if (isp_dev == ISP_DEV_0) {
iic = dev_open("iic0", 0);
} else {
iic = dev_open("iic1", 0);
}
GC6133_reset_io[isp_dev] = (u8)_reset_gpio;
GC6133_power_io[isp_dev] = (u8)_power_gpio;
}
if (iic == NULL) {
printf("GC6133 iic open err!!!\n\n");
return -1;
}
GC6133_reset(isp_dev);
if (0 != GC6133_ID_check()) {
printf("-------not GC6133------\n\n");
dev_close(iic);
iic = NULL;
return -1;
}
printf("-------hello GC6133------\n\n");
return 0;
}
s32 GC6133_init(u8 isp_dev, u16 *width, u16 *height, u8 *format, u8 *frame_freq)
{
puts("\n\n GC6133_init \n\n");
if (0 != GC6133_check(isp_dev, 0, 0)) {
return -1;
}
GC6133_config_SENSOR(width, height, format, frame_freq);
return 0;
}
void set_rev_sensor_GC6133(u16 rev_flag)
{
if (!rev_flag) {
GC6133_wrReg(0x17, 0x17);
} else {
GC6133_wrReg(0x17, 0x14);
}
}
u16 GC6133_dvp_rd_reg(u16 addr)
{
u8 val;
GC6133_rdReg((u8)addr, &val);
return val;
}
void GC6133_dvp_wr_reg(u16 addr, u16 val)
{
GC6133_wrReg((u8)addr, (u8)val);
}
// *INDENT-OFF*
REGISTER_CAMERA1(GC6133) = { //注意这里是SPI摄像头
.logo = "GC6133",
.isp_dev = ISP_DEV_1,//对应的IIC设备
.in_format = SEN_IN_FORMAT_UYVY,
.mbus_type = SEN_MBUS_BT656,
#if GC6133_1WIRE_MODE
.mbus_config = SEN_MBUS_DATA_WIDTH_1B | SEN_MBUS_PCLK_SAMPLE_FALLING,
#else
.mbus_config = SEN_MBUS_DATA_WIDTH_2B | SEN_MBUS_PCLK_SAMPLE_FALLING,
#endif
.sync_config = 0,//WL82/AC791才可以H-V SYNC互换,请留意
.fps = CONFIG_INPUT_FPS,
.out_fps = CONFIG_INPUT_FPS,
.sen_size = {GC6133_DEVP_INPUT_W, GC6133_DEVP_INPUT_H},
.cap_fps = CONFIG_INPUT_FPS,
.sen_cap_size = {GC6133_DEVP_INPUT_W, GC6133_DEVP_INPUT_H},
.ops = {
.avin_fps = NULL,
.avin_valid_signal = NULL,
.avin_mode_det = NULL,
.sensor_check = GC6133_check,
.init = GC6133_init,
.set_size_fps = GC6133_set_output_size,
.power_ctrl = NULL,
.sleep = NULL,
.wakeup = NULL,
.write_reg = GC6133_dvp_wr_reg,
.read_reg = GC6133_dvp_rd_reg,
.set_sensor_reverse = set_rev_sensor_GC6133,
}
};
#endif