Files

728 lines
16 KiB
C

#include "sys_config.h"
#include "typesdef.h"
#include "lib/video/dvp/cmos_sensor/csi.h"
#include "lib/video/dvp/cmos_sensor/csi_V2.h"
#include "devid.h"
#include "hal/gpio.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "dev/vpp/hgvpp.h"
#include "dev/csi/hgdvp.h"
#include "lib/lcd/lcd.h"
#include "hal/jpeg.h"
#include "lib/video/isp/isp_dev.h"
#include "app_iic/app_iic.h"
#include "lib/video/vpp/vpp_dev.h"
#include "lib/heap/av_heap.h"
#ifdef PIN_FROM_PARAM
#include "pin_param.h"
#endif
#define RESET_HIGH() {gpio_set_val(rsn,1);}
#define RESET_LOW() {gpio_set_val(rsn,0);}
#define IIC_CLK 120000UL
uint8 u8SensorwriteID,u8SensorreadID;
uint8 u8Addrbytnum,u8Databytnum;
static uint8 g_byDevWriteAddr;
static uint8 g_byDevReadAddr;
_Sensor_Ident_ *devSensorInit=NULL;
SNSER snser;
struct dvp_device *dvp_test;
struct i2c_device *iic_test;
struct vpp_device *vpp_test;
static const _Sensor_Ident_ *devSensorInitTable[] = {
#if DEV_SENSOR_GC0308
&gc0308_init,
#endif
#if DEV_SENSOR_BF20A6
&bf20a6_init,
#endif
#if DEV_SENSOR_GC0309
&gc0309_init,
#endif
#if DEV_SENSOR_GC0311
&gc0311_init,
#endif
#if DEV_SENSOR_GC0312
&gc0312_init,
#endif
#if DEV_SENSOR_GC0328
&gc0328_init,
#endif
#if DEV_SENSOR_GC0329
&gc0329_init,
#endif
#if DEV_SENSOR_BF3A03
&bf3a03_init,
#endif
#if DEV_SENSOR_BF3703
&bf3703_init,
#endif
#if DEV_SENSOR_OV2640
&ov2640_init,
#endif
#if DEV_SENSOR_OV7725
&ov7725_init,
#endif
#if DEV_SENSOR_OV7670
&ov7670_init,
#endif
#if DEV_SENSOR_BF2013
&bf2013_init,
#endif
#if DEV_SENSOR_XC7016_H63
&xc7016_h63_init,
#endif
#if DEV_SENSOR_XC7011_H63
&xc7011_h63_init,
#endif
#if DEV_SENSOR_XC7011_GC1054
&xc7011_gc1054_init,
#endif
#if DEV_SENSOR_XCG532
&xcg532_init,
#endif
#if DEV_SENSOR_GC2145
&gc2145_init,
#endif
#if DEV_SENSOR_SP0718
&sp0718_init,
#endif
#if DEV_SENSOR_SP0A19
&sp0a19_init,
#endif
#if DEV_SENSOR_BF3720
&bf3720_init,
#endif
#if DEV_SENSOR_SC1346
&sc1346_init,
#endif
NULL,
};
static const _Sensor_Adpt_ *devSensorOPTable[] = {
#if DEV_SENSOR_GC0308
&gc0308_cmd,
#endif
#if DEV_SENSOR_BF20A6
&bf20a6_cmd,
#endif
#if DEV_SENSOR_GC0309
&gc0309_cmd,
#endif
#if DEV_SENSOR_GC0311
&gc0311_cmd,
#endif
#if DEV_SENSOR_GC0312
&gc0312_cmd,
#endif
#if DEV_SENSOR_GC0328
&gc0328_cmd,
#endif
#if DEV_SENSOR_GC0329
&gc0329_cmd,
#endif
#if DEV_SENSOR_BF3A03
&bf3a03_cmd,
#endif
#if DEV_SENSOR_BF3703
&bf3703_cmd,
#endif
#if DEV_SENSOR_OV2640
&ov2640_cmd,
#endif
#if DEV_SENSOR_OV7725
&ov7725_cmd,
#endif
#if DEV_SENSOR_OV7670
&ov7670_cmd,
#endif
#if DEV_SENSOR_BF2013
&bf2013_cmd,
#endif
#if DEV_SENSOR_XC7016_H63
&xc7016_h63_cmd,
#endif
#if DEV_SENSOR_XC7011_H63
&xc7011_h63_cmd,
#endif
#if DEV_SENSOR_XC7011_GC1054
&xc7011_gc1054_cmd,
#endif
#if DEV_SENSOR_XCG532
&xcg532_cmd,
#endif
#if DEV_SENSOR_GC2145
&gc2145_cmd,
#endif
#if DEV_SENSOR_SP0718
&sp0718_cmd,
#endif
#if DEV_SENSOR_SP0A19
&sp0a19_cmd,
#endif
#if DEV_SENSOR_BF3720
&bf3720_cmd,
#endif
#if DEV_SENSOR_SC1346
&sc1346_cmd,
#endif
};
const _Sensor_Ident_ null_init={0x00,0x00,0x00,0x00,0x00,0x00};
volatile uint8 mipi_dvp_devid0;
volatile uint8 mipi_dvp_devid1;
/*******************************************************************************
* Function Name : Delay_Cnt
* Description : delay cnt nop
* Input : nop number
* Output : None
* Return : None
*******************************************************************************/
extern void Delay_nopCnt(uint32 cnt);
/*******************************************************************************
* Function Name : sensor_reset
* Description : for sensor reset before start
* Input : nop number
* Output : None
* Return : None
*******************************************************************************/
__weak void sensor_reset(void){
uint8_t rsn,pdn;
pdn = PIN_DVP_PDN;//get_func_io("dvp", "PDN");
if(pdn != 255){
gpio_iomap_output(pdn,GPIO_IOMAP_OUTPUT);
gpio_set_val(pdn,0);
os_sleep_ms(100);
gpio_set_val(pdn,1);
os_sleep_ms(1);
gpio_set_val(pdn,1);
}
rsn = PIN_DVP_RESET;//get_func_io("dvp", "RSN");
if(rsn != 255){
gpio_iomap_output(rsn,GPIO_IOMAP_OUTPUT);
}
else{
os_sleep_ms(200);
return;
}
RESET_HIGH();
os_sleep_ms(50);
RESET_LOW();
os_sleep_ms(200);
RESET_HIGH();
os_sleep_ms(50);
}
void i2c_SetSetting(struct i2c_setting *p_i2c_setting)
{
if(!p_i2c_setting)
return;
g_byDevWriteAddr = p_i2c_setting->u8DevWriteAddr;
g_byDevReadAddr = p_i2c_setting->u8DevReadAddr;
return;
}
int sensorCheckId(uint8_t devid,const _Sensor_Ident_ *p_sensor_ident,const _Sensor_Adpt_ *p_sensor_adpt)
{
int8 u8Buf[3];
uint8_t tablebuf[16];
uint32 id= 0;
uint32 i = 0;
uint32 k = 0;
u8SensorwriteID = p_sensor_ident->w_cmd;
u8SensorreadID =p_sensor_ident->r_cmd;
u8Addrbytnum = p_sensor_ident->addr_num;
u8Databytnum = p_sensor_ident->data_num;
tablebuf[0] = p_sensor_ident->addr_num;
tablebuf[1] = p_sensor_ident->data_num;
//i2c_ioctl(p_iic,IIC_SET_DEVICE_ADDR,u8SensorwriteID>>1);
tablebuf[2] = u8SensorwriteID>>1;
//id = i2c_sensor_read(p_iic,u8Buf,p_sensor_ident->addr_num,p_sensor_ident->data_num,u8SensorwriteID,u8SensorreadID);
if(p_sensor_adpt->preset){
for(i=0;;i+=p_sensor_ident->data_num+p_sensor_ident->addr_num){
if((p_sensor_adpt->preset[i]==0xFF)&&(p_sensor_adpt->preset[i+1]==0xFF)){
os_printf("preset table num:%d\r\n",i);
break;
}
for(k = 0;k < (p_sensor_ident->addr_num + p_sensor_ident->data_num);k++){
tablebuf[3+k] = p_sensor_adpt->preset[i+k];
}
wake_up_iic_queue(devid,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(devid) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&p_sensor_adpt->preset[i],p_sensor_ident->addr_num, (int8*)&p_sensor_adpt->preset[i+p_sensor_ident->addr_num], p_sensor_ident->data_num);
}
}
u8Buf[0] = p_sensor_ident->id_reg;
if(p_sensor_ident->addr_num == 2)
{
u8Buf[0] = p_sensor_ident->id_reg>>8;
u8Buf[1] = p_sensor_ident->id_reg;
}
k = 0;
tablebuf[3+k] = u8Buf[0];
k++;
if(p_sensor_ident->addr_num == 2){
tablebuf[3+k] = u8Buf[1];
k++;
}
tablebuf[3+k] = tablebuf[4+k] = tablebuf[5+k] = tablebuf[6+k] = 0;
//i2c_read(p_iic,u8Buf,p_sensor_ident->addr_num,(int8*)&id,p_sensor_ident->data_num);
wake_up_iic_queue(devid,tablebuf,0,0,(uint8_t*)NULL);
while(iic_devid_finish(devid) != 1){
os_sleep_ms(1);
}
id = tablebuf[3+k] | (tablebuf[4+k]<<8) | (tablebuf[5+k]<<16) | (tablebuf[6+k]<<24);
os_printf("SID: %x, %x, %x, %x,%x\r\n",id,p_sensor_ident->id,u8SensorwriteID,u8SensorreadID,p_sensor_ident->id_reg);
if(id == p_sensor_ident->id){
iic_devid_set_addr(devid,u8SensorwriteID>>1);
return 1;
}
else
return -1;
}
/*******************************************************************************
* Function Name : Sensor_ReadRegister
* Description : read sensor register
* Input : *pbdata :sensor register addr
u8AddrLength:sensor register addr length
u8DataLength:sensor register data length
* Output : None
* Return : u32i2cReadResult:the result from sensor register
*******************************************************************************/
static _Sensor_Adpt_ * sensorAutoCheck(uint8_t devid,uint8 *init_buf)
{
uint8 i;
_Sensor_Adpt_ * devSensor_Struct=NULL;
for(i=0;devSensorInitTable[i] != NULL;i++)
{
sensor_reset();
if(sensorCheckId(devid,devSensorInitTable[i],devSensorOPTable[i])>=0)
{
os_printf("id =%x num:%d \n",devSensorInitTable[i]->id,i);
devSensorInit = (_Sensor_Ident_ *) devSensorInitTable[i];
//#if CMOS_AUTO_LOAD
// devSensor_Struct = sensor_adpt_load(devSensorInit->id,devSensorInit->w_cmd,devSensorInit->r_cmd,init_buf);
//#else
devSensor_Struct = (_Sensor_Adpt_ *) devSensorOPTable[i];
//#endif
break;
}
}
if(devSensor_Struct == NULL)
{
os_printf("Er: unkown!");
devSensorInit = (_Sensor_Ident_ *)&null_init;
return NULL; // index 0 is test only
}
return devSensor_Struct;
}
volatile uint8 yuv_buf_head[16]__attribute__ ((section(".sbss")));;
__psram_data uint8 psram_ybuf_src[IMAGE_H*IMAGE_W+IMAGE_H*IMAGE_W/2] __aligned(4);
//__psram_data uint8 psram_ubuf_src[IMAGE_H*IMAGE_W/4] __aligned(4);
//__psram_data uint8 psram_vbuf_src[IMAGE_H*IMAGE_W/4] __aligned(4);
__psram_data volatile uint8 psram_buf_head[16];
#if ONLY_Y
__psram_data uint8 psram_buf[IMAGE_H][IMAGE_W] __aligned(4);
#endif
__psram_data uint8 psram_buf_tail[2032];
volatile uint32 line_buf = 0;
extern volatile uint32 done_dvp;
volatile uint32 vs_isr;
volatile uint32 vpp_get_src = 0;
void dvp_line_isr(uint32 irq,uint32 image_h,uint32 param){
}
void dvp_fhfie_isr(uint32 irq,uint32 dev,uint32 param){
os_printf("fh\r\n");
}
void dvp_fovie_isr(uint32 irq,uint32 dev,uint32 param){
//dvp_vpp_reset();
os_printf("------------------------------------------------------------------------------dvp fv\r\n");
}
void dvp_sip_isr(uint32 irq,uint32 dev,uint32 param){
//dvp_vpp_reset();
os_printf("sip reset DVP\r\n");
}
void dvp_line_isr_test(uint32 irq,uint32 image_h,uint32 param){
return;
}
struct hgdvp_hw *dvp_watch;
bool csi_yuv_mode(){
struct i2c_device *iic_dev;
static _Sensor_Adpt_ *p_sensor_cmd = NULL;
struct i2c_setting i2c_setting;
int8 idbuf[8];
uint8_t itk=0;
uint32 i=0;
uint32 k = 0;
uint8 adr_num,dat_num;
uint8 sen_w_cmd,sen_r_cmd,id_c = 0;
uint16 image_w,image_h;
uint8_t tablebuf[16];
dvp_test = (struct dvp_device *)dev_get(HG_DVP_DEVID);
iic_dev = (struct i2c_device *)dev_get(HG_I2C1_DEVID);
dvp_init(dvp_test);
dvp_close(dvp_test);
//1:init iic
os_printf("csi_test start,iic init\r\n");
mipi_dvp_devid0 = register_iic_queue(iic_dev,MACRO_PIN(PIN_DVP0_IIC_CLK),MACRO_PIN(PIN_DVP0_IIC_SDA),0);
gpio_iomap_output(MACRO_PIN(PIN_DVP_MCLK), GPIO_IOMAP_OUT_DVP_MCLK_OUT);
os_printf("iic init finish,sensor reset & set sensor clk into 6M\r\n");
//2:init sensor
dvp_set_baudrate(dvp_test,6000000);
os_sleep_ms(3);
os_printf("set sensor finish ,Auto Check sensor id\r\n");
p_sensor_cmd = snser.p_sensor_cmd = sensorAutoCheck(mipi_dvp_devid0,NULL);
if(p_sensor_cmd == NULL){
// i2c_close(iic_test);
return FALSE;
}
sensor_info_add(SENSOR_TYPE_MASTER, (DUAL_EN) ? (ISP_INPUT_DAT_SRC_ORG_DMA) : (ISP_INPUT_DAT_SRC_DVP), (uint32)p_sensor_cmd->sensor_isp, mipi_dvp_devid0, u8SensorwriteID);
os_printf("Auto Check sensor id finish\r\n");
i2c_setting.u8DevWriteAddr = p_sensor_cmd->w_cmd;
i2c_setting.u8DevReadAddr = p_sensor_cmd->r_cmd;
i2c_SetSetting(&i2c_setting);
os_printf("mclk:%dMHz\r\n",p_sensor_cmd->mclk);
dvp_set_baudrate(dvp_test,p_sensor_cmd->mclk);
os_printf("init:%x u8Addrbytnum:%d,u8Databytnum:%d\r\n",(uint32)p_sensor_cmd->init,u8Addrbytnum,u8Databytnum);
if(p_sensor_cmd->init!=NULL)
{
os_printf("SENSER....init\r\n");
for(i=0;;i+=u8Addrbytnum+u8Databytnum)
{
if((p_sensor_cmd->init[i]==0xFF)&&(p_sensor_cmd->init[i+1]==0xFF)){
os_printf("init table num:%d\r\n",i);
break;
}
if((p_sensor_cmd->init[i]==0xFE)&&(p_sensor_cmd->init[i+1]==0xFE)){
if(p_sensor_cmd->init[i+2]==0x01){
os_sleep_ms(100);
}
}
else{
for(itk = 0;itk < u8Addrbytnum+u8Databytnum;itk++){
idbuf[itk] = p_sensor_cmd->init[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&idbuf[0], u8Addrbytnum, (int8*)&idbuf[u8Addrbytnum], u8Databytnum);
if(i==0)
{
os_sleep_ms(1);
}
}
}
if(p_sensor_cmd->p_xc7016_adapt.sensor_init_table != NULL)
{
adr_num = p_sensor_cmd->p_xc7016_adapt.addr_num;
dat_num = p_sensor_cmd->p_xc7016_adapt.data_num;
sen_w_cmd = u8SensorwriteID;
sen_r_cmd = u8SensorreadID;
u8SensorwriteID = p_sensor_cmd->p_xc7016_adapt.w_cmd;
u8SensorreadID = p_sensor_cmd->p_xc7016_adapt.r_cmd;
idbuf[0] = p_sensor_cmd->p_xc7016_adapt.id_reg;
//id_c = i2c_sensor_read(iic_test,idbuf,adr_num,dat_num,u8SensorwriteID,u8SensorreadID);
//i2c_ioctl(iic_test,IIC_SET_DEVICE_ADDR,u8SensorwriteID>>1);
tablebuf[0] = adr_num;
tablebuf[1] = dat_num;
tablebuf[2] = u8SensorwriteID>>1;
iic_devid_set_addr(mipi_dvp_devid0,u8SensorwriteID>>1);
k = 0;
tablebuf[3+k] = idbuf[0];
k++;
if(adr_num == 2){
tablebuf[3+k] = idbuf[1];
k++;
}
tablebuf[3+k] = tablebuf[4+k] = tablebuf[5+k] = tablebuf[6+k] = 0;
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,0,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_read(iic_test,idbuf,adr_num,(int8*)&id_c,dat_num);
id_c = tablebuf[3+k] | (tablebuf[4+k]<<8) | (tablebuf[5+k]<<16) | (tablebuf[6+k]<<24);
os_printf("\r\nchildren SID: %x %x %x\r\n",id_c,u8SensorwriteID,u8SensorreadID);
for(i=0;;i+=adr_num+dat_num)
{
if((p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i]==0xFF)&&(p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i+1]==0xFF)){
os_printf("sensor table num:%d\r\n",i);
break;
}
for(itk = 0;itk < adr_num+dat_num;itk++){
idbuf[itk] = p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&idbuf[0], adr_num, (int8*)&idbuf[adr_num], dat_num);
if(i==0)
{
os_sleep_ms(1);
}
}
u8SensorwriteID = sen_w_cmd;
u8SensorreadID = sen_r_cmd;
i2c_ioctl(iic_test,IIC_SET_DEVICE_ADDR,u8SensorwriteID>>1);
for(i=0;;i+=u8Addrbytnum+u8Databytnum)
{
if((p_sensor_cmd->p_xc7016_adapt.bypass_off[i]==0xFF)&&(p_sensor_cmd->p_xc7016_adapt.bypass_off[i+1]==0xFF)){
os_printf("bypass table num:%d\r\n",i);
break;
}
for(itk = 0;itk < u8Addrbytnum+u8Databytnum;itk++){
idbuf[itk] = p_sensor_cmd->p_xc7016_adapt.bypass_off[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&idbuf[0], u8Addrbytnum, (int8*)&idbuf[u8Addrbytnum], u8Databytnum);
if(i==0)
{
os_sleep_ms(1);
}
}
}
}
os_printf("SENSR ident ok:%d*%d\r\n",p_sensor_cmd->pixelw,p_sensor_cmd->pixelh);
#if SCEN_EN
image_h = p_sensor_cmd->pixelh/2;
image_w = p_sensor_cmd->pixelw/2;
#else
image_h = p_sensor_cmd->pixelh;
image_w = p_sensor_cmd->pixelw;
#endif
video_msg.dvp_iw = image_w;
video_msg.dvp_ih = image_h;
// video_msg.dvp_ow = image_w;
// video_msg.dvp_oh = image_h;
video_msg.dvp_type = 1;
video_msg.video_type_cur = ISP_VIDEO_0;
video_msg.video_type_last = ISP_VIDEO_0;
video_msg.video_num++;
//3:init csi
os_printf("csi init start --\r\n");
os_printf("csi set size ====>%d*%d\r\n",image_w,image_h);
dvp_set_vsync_rst_offline(dvp_test,0,30*1000/32);
#if SCEN_EN
dvp_set_half_size(dvp_test,1);
#endif
dvp_set_size(dvp_test,0,0,p_sensor_cmd->pixelw,p_sensor_cmd->pixelh);
dvp_set_hsync_polarity(dvp_test,p_sensor_cmd->hsyn);
dvp_set_vsync_polarity(dvp_test,p_sensor_cmd->vsyn);
dvp_set_format(dvp_test,IMAGE_FORMAT);
dvp_8BITS_map(dvp_test,0);
//dvp_set_exchange_d5_d6(dvp_test,0);
os_printf("csi IRQ init\r\n");
dvp_request_irq(dvp_test,HSIP_ISR, (dvp_irq_hdl )&dvp_sip_isr,0);
dvp_request_irq(dvp_test,FOVIE_ISR,(dvp_irq_hdl )&dvp_fovie_isr,0);
//dvp_open(dvp_test);
os_printf("csi IRQ init finish,start get data\r\n");
return TRUE;
}
bool csi_cfg(){
bool ret;
ret = csi_yuv_mode();
return ret;
}
bool csi_open(){
dvp_open(dvp_test);
return 1;
}
bool csi_close(){
dvp_close(dvp_test);
return 1;
}
void get_single_dvp(uint16_t *w,uint16_t *h)
{
if(w)
{
*w = video_msg.dvp_iw;
}
if(h)
{
*h = video_msg.dvp_ih;
}
return;
}