⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 new_camif.c

📁 usbhostomapOMAP5910下摄像头的驱动程序
💻 C
字号:
#include "omap30.h"
#include "omap1510.h"
#include "new_camif.h"
#include "new_i2c.h"



#ifndef CAMERA_INT
	#define CAMERA_INT 1
#endif

volatile unsigned long* pCAMIF_CTRLCLOCK 	 = (unsigned long*)0xFFFB6800;
volatile unsigned long* pCAMIF_IT_STATUS 	 = (unsigned long*)0xFFFB6804;
volatile unsigned long* pCAMIF_MODE			 = (unsigned long*)0xFFFB6808;
volatile unsigned long* pCAMIF_STATUS        = (unsigned long*)0xFFFB680C;
volatile unsigned long* pCAMIF_CAMDATA       = (unsigned long*)0xFFFB6810;
volatile unsigned long* pCAMIF_GPIO			 = (unsigned long*)0xFFFB6814;
volatile unsigned long* pCAMIF_PEAK_COUNTER  = (unsigned long*)0xFFFB6818 ;

volatile unsigned char* pEpldCamPwr 		 = (unsigned char*)0x0800020C;

// clock register
volatile unsigned short * pARM_IDLECT2  = (unsigned short *) 0xFFFECE08;

//ARM_IDLECT2
#define EN_XORPC_CK		0x002

//clock reset peripheral pin
volatile unsigned short * pARM_RSTCT2  = (unsigned short *) 0xFFFECE14;

volatile unsigned short * pDMA_GCR	 	= (unsigned short *) 0xFFFEDC00 ;

//ARM_RSTCT2
#define PER_EN 		0x01;

#define ImageWidth  320
#define ImageHeight 240 

volatile unsigned short flgReady = 0x0000;
volatile unsigned short cdsa_u;

extern volatile short buffer_writable;
extern volatile short buffer_writen;

static int buf_one = 0;
static int buf_two = 0;

volatile unsigned char reg = 0, data;


/*---------------------------------------------------------------------------*/
void InitCamera(void)
{
	//CameraSetPowerState(cam_PowerOn);
	InitI2c();
	camif_init();
  	dma_init();
	camera_start() ;
	CameraI2CSettings();
	WaitForVsync();	
	cdsa_u = 0x1060;
	dma_setupcamif();
}

/*---------------------------------------------------------------------------*/
#if 0
void CameraSetPowerState(unsigned char ucCamPwr)
{
	if (ucCamPwr)
		*pEpldCamPwr &= ~0x4;
	else
		*pEpldCamPwr |= 0x4;
}
#endif 

/*---------------------------------------------------------------------------*/
void camif_init(void)
{
	// Camera interrupt
 
	INTH2_InitLevel(CAMERA_INT,
             		INTH_IRQ,                    // InterruptKind Irq or Fiq
             		INTH_HIGHEST_PRIORITY,            		 // priority
             		INTH_LOW_LEVEL_SENSITIVE);   // type level or edge
	INTH2_EnableOneIT(CAMERA_INT, INTH_IRQ);        
	
	//enable peripheral reset
	*pARM_RSTCT2 |= PER_EN;
	
	//enable peripheral clock
	*pARM_IDLECT2  |= EN_XORPC_CK; 
	
	// take camera out of reset
	*pCAMIF_GPIO = 0x00000001;
	{
		int i;
		for(i = 0; i < 1000; i++);
	}
	//asm("zzz: b zzz");	  
	*pCAMIF_GPIO = 0x00000000;	  
	
	// set mode register
	//Enable Vsync interrupt, enable DMA, set FIFO trigger =1, QCIF, not swapped
	//*pCAMIF_MODE = 0x00000312;  
	//Enable Vsync interrupt, enable DMA, set FIFO trigger =1, QVGA, not swapped
	// QVGA: 320*240
	*pCAMIF_MODE = 0x00000316;  
	
	//set clock control register
	//*pCAMIF_CTRLCLOCK = 0x000000F6; //External 48Mhz / 6 =   8 MHz
	// Enable LCLK, DPLL source(48M), internal interface clock, Disable EXCLK
       *pCAMIF_CTRLCLOCK = 0x000000E5; //External 48Mhz / 2 =  24 MHz
    //*pCAMIF_CTRLCLOCK = 0x000000F4; //External 48Mhz / 5 = 9.6 MHz
    //*pCAMIF_CTRLCLOCK = 0x000000B2; //Internal 12Mhz / 2 =   6 MHz 
    //*pCAMIF_CTRLCLOCK = 0x000000A0; //Internal 12Mhz / 1 =  12 MHz 
}

/*---------------------------------------------------------------------------*/
void camera_start(void)
{
	// Enable EXCLK
	*pCAMIF_CTRLCLOCK |= 0x00000010;		     
}

/*---------------------------------------------------------------------------*/
void CameraI2CSettings(void) 
{

char ret_val;
#if 1
while(ret_val=WriteI2c(CameraID, 0x12, 0xa4));//ov7620 datasheet  p30
	
	/* select sync output polarity */
	while(ret_val=WriteI2c(CameraID, 0x11, 0x40));

	/* Enable AGC, select 8 bit output format is YUYVYUYV
		select YCbCr data signal as video output
		also enable auto white balance. */
		//24->8a
	while(ret_val=WriteI2c(CameraID, 0x12, 0x14));
	
	//blue and red gain
	//while(ret_val=WriteI2c(CameraID, 0x02, 0x40));
	//while(ret_val=WriteI2c(CameraID, 0x01, 0x40));
//	while(ret_val=WriteI2c(CameraID, 0x1F, 0x20)); ///rgb565

//while(ret_val=WriteI2c(CameraID, 0x28, 0xa0));
	/* Select 8 bit data format and enable auto adjust mode */
	//while(ret_val=WriteI2c(CameraID, 0x13, 0x21));

	/* Select QVGA(320*240) output and RGB gamma on */
	while(ret_val=WriteI2c(CameraID, 0x14, 0x24));
	while(ret_val=WriteI2c(CameraID, 0x15, 0x0));
	while(ret_val=WriteI2c(CameraID, 0x2d, 0x95));
	
	//while(ret_val=WriteI2c(CameraID, 0x70, 0x83));
#endif
//ret_val=WriteI2c(CameraID, 0x12, 0x80);
//while(ret_val=WriteI2c(CameraID, 0x12, 0x0c));
//while(ret_val=WriteI2c(CameraID, 0x14, 0x24));
//while(ret_val=WriteI2c(CameraID, 0x20, 0xa0));
//while(ret_val=WriteI2c(CameraID, 0x18, 0x1a+(ImageWidth+8)/8));	
//while(ret_val=WriteI2c(CameraID, 0x1A, 0x03+(ImageHeight+8)/4));


#if 0
	while(ret_val=WriteI2c(CameraID, 0x12, 0xE0));
    while(ret_val=WriteI2c(CameraID, 0x12, 0x60));
    while(ret_val=WriteI2c(CameraID, 0x11, 0x81));//0x81
    while(ret_val=WriteI2c(CameraID, 0x0c, 0x28));
    while(ret_val=WriteI2c(CameraID, 0x2D, 0x2c))
    while(ret_val=WriteI2c(CameraID, 0x2E, 0x00))
    while(ret_val=WriteI2c(CameraID, 0x03, 0x40));
    while(ret_val=WriteI2c(CameraID, 0x01, 0x80));
    while(ret_val=WriteI2c(CameraID, 0x02, 0x80));
    while(ret_val=WriteI2c(CameraID, 0x04, 0xf0));
    while(ret_val=WriteI2c(CameraID, 0x09, 0x0e));
    while(ret_val=WriteI2c(CameraID, 0x32, 0x00));
    while(ret_val=WriteI2c(CameraID, 0x0d, 0x00));
    while(ret_val=WriteI2c(CameraID, 0x13, 0xf7));
    while(ret_val=WriteI2c(CameraID, 0x33, 0xc0));
    while(ret_val=WriteI2c(CameraID, 0x35, 0x90));
    while(ret_val=WriteI2c(CameraID, 0x36, 0x37));
    while(ret_val=WriteI2c(CameraID, 0x15, 0x22));

	while(ret_val=WriteI2c(CameraID, 0x17, 0x16));
	while(ret_val=WriteI2c(CameraID, 0x18, 0x16+(ImageWidth+8)/8));	
	while(ret_val=WriteI2c(CameraID, 0x19, 0x08));
	while(ret_val=WriteI2c(CameraID, 0x1A, 0x08+(ImageHeight+8)/4));
#endif
	
}

/*---------------------------------------------------------------------------*/
void dma_init(void)
{
	// SystemDMA init
	//DMA_SetupSystemDma(DMA_FREE_RUNNING);
	*pDMA_GCR = 0x0004;  // dma free running
	
/*	INTH2_InitLevel(DMA_CH0_INT,
             		INTH_IRQ,                    	 // InterruptKind Irq or Fiq
             		INTH_LOWEST_PRIORITY,            		 // priority
             		INTH_LOW_LEVEL_SENSITIVE);   	 // type level or edge
	INTH2_EnableOneIT(DMA_CH0_INT, INTH_IRQ);        */
}

/*---------------------------------------------------------------------------*/
void dma_setupcamif(void)
{
	if(buffer_writable&1)
	{
		cdsa_u = 0x1060;
		buffer_writen &= 0xFFFE; 
	}
	else if(buffer_writable&2)
	{
		cdsa_u = 0x1068;
		buffer_writen &= 0xFFFD; 
	}
	else
		return;
	*((unsigned short*)0xFFFED800) = 0x000E; //*DmaReg(0, DMA_CSDP) 	= 0x000E ;
	*((unsigned short*)0xFFFED802) = 0x4054; //*DmaReg(0, DMA_CCR)		= 0x4054 ;
	*((unsigned short*)0xFFFED804) = 0x0020; //*DmaReg(0, DMA_CICR)		= 0x0020 ;
	*((unsigned short*)0xFFFED808) = 0x6810; //*DmaReg(0, DMA_CSSA_L)	= 0x6810 ;
	*((unsigned short*)0xFFFED80A) = 0xFFFB; //*DmaReg(0, DMA_CSSA_U) 	= 0xFFFB ;
	*((unsigned short*)0xFFFED80C) = 0x0000; //*DmaReg(0, DMA_CDSA_L)   = 0x0000 ;
	*((unsigned short*)0xFFFED80E) = cdsa_u; //*DmaReg(0, DMA_CDSA_U) 	= 0x1006 ;
	*((unsigned short*)0xFFFED810) = (ImageWidth+8)/4*2; //*DmaReg(0, DMA_CEN)    	= 0x58   ; // 88 elements ;
	*((unsigned short*)0xFFFED812) = (ImageHeight+8)/4*4; //*DmaReg(0, DMA_CFN)    	= 0x90   ; // 144 frames
	*((unsigned short*)0xFFFED814) = 0x0000; //*DmaReg(0, DMA_CFI)      = 0x00   ; // frame index not used
	*((unsigned short*)0xFFFED816) = 0x0000; //*DmaReg(0, DMA_CEI)      = 0x00   ; // element index not used
       //start dma
	*((unsigned short*)0xFFFED802) |= 0x0080;//*DmaReg(0, DMA_CCR) |= 0x80 ;
}
/*---------------------------------------------------------------------------*/
void WaitForVsync(void)
{
	unsigned long v ;
	short i = 0 ;
	
	while(((*pCAMIF_STATUS) & 0x1) == 0) ;  // wait for VSYNC rising edge

	while(((*pCAMIF_STATUS) & 0x1) != 0) ; // wait for VSYNC falling edge
	
	for(i=0; i<128; i++)
	   v = *pCAMIF_CAMDATA ; // clean FIFO out
 
	*pCAMIF_PEAK_COUNTER = 0; // clear FIFO peak counter

}

/*---------------------------------------------------------------------------*/
void CAMERA_Service(void)
{
	unsigned long IntStatus = *pCAMIF_IT_STATUS ;
	unsigned short dma_ccr;
	int i, v;

 		
	if (IntStatus & 0x0001)
	{
		if (flgReady == 0x0000)
		{
			dma_ccr = *((unsigned short*)0xFFFED802);
			if(!(dma_ccr&0x0080)) {
				if(cdsa_u==0x1060)
				{
					buffer_writable &= 0xFFFE;
					buffer_writen = 1;
					buf_one ++;
				}
				else
				{
					buffer_writable &= 0xFFFD;
					buffer_writen = 2;
					buf_two ++;
				}
					
				// clean FIFO out, chenyue, 2004/07/12
				for(i=0; i<128; i++)
				   v = *pCAMIF_CAMDATA ; 
				// clean FIFO out, chenyue, 2004/07/12

				Mailbox_Write(ARM2DSP1, buffer_writen, 0);
					   
				dma_setupcamif();
				flgReady = 0xFFFF;
			}else
			   dma_ccr = *((unsigned short*)0xFFFED802);
		}
	}
	return;
}

unsigned int change_i2c = 0;
unsigned char subaddress;
unsigned char i2c_data;
/*---------------------------------------------------------------------------*/
void CaptureImage(void)
{
	int i = 0;
	while(i < 0x1fffffff)
	{
		if (change_i2c) {
			while(WriteI2c(CameraID, subaddress, i2c_data));
			change_i2c = 0;
		}
		if (flgReady==0xFFFF)
		{
			//DisplayImage();
			if(buffer_writable)
				flgReady = 0x0000; 
		}
		i++;
	}
	return;
}

/*---------------------------------------------------------------------------*/
#if 1
void DisplayImage(void)
{
  	short x, y ;
	
	unsigned char  *Src_Data;
	unsigned short *Dst_Data;
	unsigned char R, G1, G2, B ; 
	unsigned short p ;
	
	Src_Data = (unsigned char*)0x10600000;
	Dst_Data = (unsigned short*)0x10000000;
	Dst_Data += 16 + 240*88 + 16;
	
	
	for (y = 0 ; y < ImageHeight ; y++)
	{
		for (x = 0 ; x < ImageWidth/2 ; x++)
		{
			G2  = *Src_Data++ ;
			B   = *Src_Data++ ;
			G1  = *Src_Data++ ;
			R   = *Src_Data++ ;

			p = (R & 0xf8) << 8 ;
			p |= (G1 & 0xFC) <<3 ;
			p |= (B & 0xf8) >> 3 ;
			
			Dst_Data[(2*x)] = p ;
			
			p =  ((R & 0xf8) << 8) ;
			p |= ((G2 & 0xFC) <<3) ;
			p |= ((B & 0xf8) >> 3) ;
			
			Dst_Data[(2*x)+1] = p;
		}
		Src_Data += (320-176)*2;
		Dst_Data += (240);
	}
	
	return;	
}
#endif


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -