#include <stdint.h>
#include "system.h"
#include "../inc/sccb.h"
#include "../inc/ov5640af.h"
#include "../inc/ov5640.h"
#include "../inc/ov5640cfg.h"
#include "unistd.h"
#include "sys/alt_stdio.h"
#include "altera_avalon_uart_regs.h"
#include "altera_avalon_pio_regs.h"

uint8_t OV7xxx_Init(void)
{

	uint16_t VER;
	uint8_t PID;
	uint16_t CMOS_ID;
	uint16_t i=0;
	uint8_t CMOS_MODEL;
	SCCB_Init(40000, 0);        		//ʼSCCB IO
// 	if(SCCB_WR_Reg(0x12,0x80))return 1;	//λSCCB
//	usleep(50000);
//	//ȡƷͺ
	VER=SCCB_RD_Reg(0x30,0x0a);
	PID=SCCB_RD_Reg(0x30,0x0b);
	CMOS_ID = (VER<<8)|PID;
	if(CMOS_ID == 0x5640)
	{
		CMOS_MODEL = OV5640;
		//ʼ
		for(i=0;i<sizeof(ov5640_init_reg_tbl)/sizeof(ov5640_init_reg_tbl[0]);i++)
		{
			SCCB_WR_Reg(ov5640_init_reg_tbl[i][0],ov5640_init_reg_tbl[i][1],ov5640_init_reg_tbl[i][2]);
			usleep(2000);
		}

	}
	else
		CMOS_MODEL = UNKNOWN;

   	return CMOS_MODEL; 	//ok
}


uint8_t OV5640_Focus_Init(void)
{
	uint16_t i;
	uint16_t addr=0x8000;
	uint8_t state=0x8F;
	SCCB_WR_Reg(0x30, 0x00, 0x20);
	for(i=0;i<sizeof(OV5640_AF_Config);i++)
	{
		SCCB_WR_Reg(addr >> 8, addr & 0x00FF,OV5640_AF_Config[i]);
		addr++;
	}
	SCCB_WR_Reg(0x30, 0x22,0x00);
	SCCB_WR_Reg(0x30, 0x23,0x00);
	SCCB_WR_Reg(0x30, 0x24,0x00);
	SCCB_WR_Reg(0x30, 0x25,0x00);
	SCCB_WR_Reg(0x30, 0x26,0x00);
	SCCB_WR_Reg(0x30, 0x27,0x00);
	SCCB_WR_Reg(0x30, 0x28,0x00);
	SCCB_WR_Reg(0x30, 0x29,0x7f);
	SCCB_WR_Reg(0x30, 0x00,0x00);
	i=0;
	do
	{
		state=SCCB_RD_Reg(0x30, 0x29);
		usleep(5000);
		i++;
		if(i>1000)return 1;
	}while(state!=0x70);
	return 0;
}

uint8_t OV5640_Focus_Single(void)
{
	uint8_t temp;
	uint16_t retry=0;
	SCCB_WR_Reg(0x30, 0x22,0x03);		//
	while(1)
	{
		retry++;
		temp=SCCB_RD_Reg(0x30, 0x29);	//
		if(temp==0x10)break;		// focus completed
		usleep(5000);
		if(retry>1000)return 1;
	}
	return 0;
}

uint8_t OV5640_Focus_Constant(void)
{
	uint8_t temp=0;
	uint16_t retry=0;
	SCCB_WR_Reg(0x30, 0x23,0x01);
	SCCB_WR_Reg(0x30, 0x22,0x08);//
	do
	{
		temp=SCCB_RD_Reg(0x30, 0x23);
		retry++;
		if(retry>1000)return 2;
		usleep(5000);
	} while(temp!=0x00);
	SCCB_WR_Reg(0x30, 0x23,0x01);
	SCCB_WR_Reg(0x30, 0x22,0x04);//
	retry=0;
	do
	{
		temp=SCCB_RD_Reg(0x30, 0x23);
		retry++;
		if(retry>1000)return 2;
		usleep(5000);
	}while(temp!=0x00);//
	return 0;
}
