doubao_chat/apps/common/camera/byd30a2/byd30a2.c

380 lines
8.6 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 "byd30a2.h"
#include "gpio.h"
#include "generic/jiffies.h"
#include "device/iic.h"
#include "device/device.h"
#include "app_config.h"
#ifdef CONFIG_VIDEO_ENABLE
static void *iic = NULL;
static u8 BYD30A2_reset_io[2] = {-1, -1};
static u8 BYD30A2_power_io[2] = {-1, -1};
/*
#if (CONFIG_VIDEO_IMAGE_W > 240)
#define BYD30A2_DEVP_INPUT_W 128
#define BYD30A2_DEVP_INPUT_H 160
#else
#define BYD30A2_DEVP_INPUT_W CONFIG_VIDEO_IMAGE_W
#define BYD30A2_DEVP_INPUT_H CONFIG_VIDEO_IMAGE_H
#endif
*/
#define BYD30A2_DEVP_INPUT_W 240//128
#define BYD30A2_DEVP_INPUT_H 320//176
#define BYD30A2_WRCMD 0xdc
#define BYD30A2_RDCMD 0xdd
#define CONFIG_INPUT_FPS 15//30
#define DELAY_TIME 10
struct reginfo {
u8 reg;
u8 val;
};
static const struct reginfo sensor_init_data[] = {
0xf2, 0x01, //软复位
0x15, 0x80,
0x6b, 0x73,
0x04, 0x00,
0x06, 0x26,
0x08, 0x07,
0x1c, 0x12,
0x1e, 0x26,
0x1f, 0x01,
0x20, 0x20,
0x21, 0x20,
0x34, 0x02,
0x35, 0x02,
0x36, 0x21,
0x37, 0x13,
#if (CONFIG_INPUT_FPS == 15)
0xca, 0x02, //15ps
#else
0xca, 0x03, //30ps
#endif
//分辨率设置
#define START_ADDRW 0
#define START_ADDRH 0
#define END_ADDRW (BYD30A2_DEVP_INPUT_W + START_ADDRW)
#define END_ADDRH (BYD30A2_DEVP_INPUT_H + START_ADDRH)
//(END_ADDRW <= 248 || END_ADDRH <= 328)
0x17, START_ADDRW,
0x18, END_ADDRW,
0x19, START_ADDRH,
0x1a, (END_ADDRH >> 1) & 0xFF,
0x12, 0x13 | ((END_ADDRH & 0x1) << 7), //MTK:20 ZX:10 RDA:40 //only YUV_Y NO have UV*/
//0x12,0x10 | ((END_ADDRH & 0x1) << 7),//MTK:20 ZX:10 RDA:40*/
0xcb, 0x22,
0xcc, 0x89,
0xcd, 0x4c,
0xce, 0x6b,
0xcf, 0x90,
0xa0, 0x8e,
0x01, 0x1b,
0x02, 0x1d,
0x13, 0x08,
0x87, 0x13,
0x8a, 0x33,
0x8b, 0x08,
0x70, 0x1f,
0x71, 0x40,
0x72, 0x0a,
0x73, 0x62,
0x74, 0xa2,
0x75, 0xbf,
0x76, 0x02,
0x77, 0xcc,
0x40, 0x32,
0x41, 0x28,
0x42, 0x26,
0x43, 0x1d,
0x44, 0x1a,
0x45, 0x14,
0x46, 0x11,
0x47, 0x0f,
0x48, 0x0e,
0x49, 0x0d,
0x4B, 0x0c,
0x4C, 0x0b,
0x4E, 0x0a,
0x4F, 0x09,
0x50, 0x09,
0x24, 0x50,
0x25, 0x36,
0x80, 0x00,
0x81, 0x20,
0x82, 0x40,
0x83, 0x30,
0x84, 0x50,
0x85, 0x30,
0x86, 0xD8,
0x89, 0x45,
0x8f, 0x81,
0x91, 0xff,
0x92, 0x08,
0x94, 0x82,
0x95, 0xfd,
0x9a, 0x20,
0x9e, 0xbc,
0xf0, 0x83,//动态帧率关闭 0x8f打开
0x51, 0x06,
0x52, 0x25,
0x53, 0x2b,
0x54, 0x0F,
0x57, 0x2A,
0x58, 0x22,
0x59, 0x2c,
0x23, 0x33,
0xa0, 0x8f,
0xa1, 0x93,
0xa2, 0x0f,
0xa3, 0x2a,
0xa4, 0x08,
0xa5, 0x26,
0xa7, 0x80,
0xa8, 0x80,
0xa9, 0x1e,
0xaa, 0x19,
0xab, 0x18,
0xae, 0x50,
0xaf, 0x04,
0xc8, 0x10,
0xc9, 0x15,
0xd3, 0x0c,
0xd4, 0x16,
0xee, 0x06,
0xef, 0x04,
0x55, 0x34,
0x56, 0x9c,
0xb1, 0x98,
0xb2, 0x98,
0xb3, 0xc4,
0xb4, 0x0C,
0x00, 0x40,
0x13, 0x07,
};
static s32 BYD30A2_set_output_size(u16 *width, u16 *height, u8 *freq);
static unsigned char wrBYD30A2Reg(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, BYD30A2_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 rdBYD30A2Reg(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, BYD30A2_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, BYD30A2_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 BYD30A2_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++) {
wrBYD30A2Reg(sensor_init_data[i].reg, sensor_init_data[i].val);
}
}
static s32 BYD30A2_set_output_size(u16 *width, u16 *height, u8 *freq)
{
u16 liv_width = *width;
u16 liv_height = *height;
return 0;
}
static s32 BYD30A2_power_ctl(u8 isp_dev, u8 is_work)
{
return 0;
}
static s32 BYD30A2_ID_check(void)
{
int ret;
u16 pid = 0x00;
u8 id0, id1;
ret = rdBYD30A2Reg(0xfc, &id0);
rdBYD30A2Reg(0xfd, &id1);
pid = (u16)((id0 << 8) | id1);
printf("BYD30A2 Sensor ID : 0x%x\n", pid);
if (pid != 0x3b02) {
return -1;
}
return 0;
}
static void BYD30A2_powerio_ctl(u32 _power_gpio, u32 on_off)
{
gpio_direction_output(_power_gpio, on_off);
}
static void BYD30A2_reset(u8 isp_dev)
{
u8 res_io;
u8 powd_io;
u8 id = 0;
puts("BYD30A2 reset\n");
if (isp_dev == ISP_DEV_0) {
res_io = (u8)BYD30A2_reset_io[0];
powd_io = (u8)BYD30A2_power_io[0];
} else {
res_io = (u8)BYD30A2_reset_io[1];
powd_io = (u8)BYD30A2_power_io[1];
}
if (powd_io != (u8) - 1) {
BYD30A2_powerio_ctl((u32)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);
}
}
static s32 BYD30A2_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);
}
BYD30A2_reset_io[isp_dev] = (u8)_reset_gpio;
BYD30A2_power_io[isp_dev] = (u8)_power_gpio;
}
if (iic == NULL) {
printf("BYD30A2 iic open err!!!\n\n");
return -1;
}
BYD30A2_reset(isp_dev);
if (0 != BYD30A2_ID_check()) {
dev_close(iic);
iic = NULL;
printf("-------not BYD30A2------\n\n");
return -1;
}
printf("-------hello BYD30A2------\n\n");
return 0;
}
static s32 BYD30A2_init(u8 isp_dev, u16 *width, u16 *height, u8 *format, u8 *frame_freq)
{
puts("\n\n BYD30A2 \n\n");
if (0 != BYD30A2_check(isp_dev, 0, 0)) {
return -1;
}
BYD30A2_config_SENSOR(width, height, format, frame_freq);
return 0;
}
void set_rev_sensor_BYD30A2(u16 rev_flag)
{
if (!rev_flag) {
wrBYD30A2Reg(0x1e, 0x30);
} else {
wrBYD30A2Reg(0x1e, 0x00);
}
}
u16 BYD30A2_dvp_rd_reg(u16 addr)
{
u8 val;
rdBYD30A2Reg((u8)addr, &val);
return val;
}
void BYD30A2_dvp_wr_reg(u16 addr, u16 val)
{
wrBYD30A2Reg((u8)addr, (u8)val);
}
// *INDENT-OFF*
REGISTER_CAMERA1(BYD30A2) = {
.logo = "BYD30A2",
.isp_dev = ISP_DEV_NONE,
.in_format = SEN_IN_FORMAT_UYVY,
.mbus_type = SEN_MBUS_PARALLEL,
.mbus_config = 0,//SEN_MBUS_DATA_WIDTH_8B | SEN_MBUS_HSYNC_ACTIVE_HIGH | SEN_MBUS_PCLK_SAMPLE_FALLING | SEN_MBUS_VSYNC_ACTIVE_HIGH,
.sync_config = 0,//WL82/AC791才可以H-V SYNC互换,请留意
.fps = CONFIG_INPUT_FPS,
.out_fps = CONFIG_INPUT_FPS,
.sen_size = {BYD30A2_DEVP_INPUT_W, BYD30A2_DEVP_INPUT_H},
.cap_fps = CONFIG_INPUT_FPS,
.sen_cap_size = {BYD30A2_DEVP_INPUT_W, BYD30A2_DEVP_INPUT_H},
.ops = {
.avin_fps = NULL,
.avin_valid_signal = NULL,
.avin_mode_det = NULL,
.sensor_check = BYD30A2_check,
.init = BYD30A2_init,
.set_size_fps = BYD30A2_set_output_size,
.power_ctrl = BYD30A2_power_ctl,
.sleep = NULL,
.wakeup = NULL,
.write_reg = BYD30A2_dvp_wr_reg,
.read_reg = BYD30A2_dvp_rd_reg,
.set_sensor_reverse = set_rev_sensor_BYD30A2,
}
};
#endif