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

📄 camif.c

📁 三星2413芯片的测试代码,对进行驱动开发很有帮助.
💻 C
📖 第 1 页 / 共 2 页
字号:
//====================================================================
// File Name : camif.c
// Function  : S3C2413 Camera test code
// Date      : Apr. 21, 2006
// Version   : S3C2413
//====================================================================

#include <stdio.h>
#include <stdlib.h>

#include "def.h"
#include "2413addr.h"
#include "console.h"
#include "pll.h"

#include "camif.h"
#include "camproset.h"
#include "lcdlib.h"
#include "glib.h"

#define TEST_DETAIL_EN				(FALSE)

#define	YCbCrtoR(Y,Cb,Cr)	(1000*Y + 1371*(Cr-128))/1000
#define YCbCrtoG(Y,Cb,Cr)	(1000*Y - 336*(Cb-128) - 698*(Cr-128))/1000
#define	YCbCrtoB(Y,Cb,Cr)	(1000*Y + 1732*(Cb-128))/1000


volatile U32 camTestMode;
volatile U32 camCodecCaptureCount;
volatile U32 camCodecStatus;
volatile U32 amount;
volatile U32 cameraDone;
volatile U32 camCodecDataValid;

U32 CAMTYPE, CAMSIZE, CAMIICID;


volatile U32 regCIPRSCPRERATIO, regCIPRSCPREDST, regCIPRSCCTRL, regCIWDOFST;
U32 camCodecInput, camCodecOutput, camRgbOutput;
U32 cscDone;



void CalculateBurstSize(U32 dstHSize,U32 *mainBurstSize,U32 *RemainedBurstSize);
void __irq CamCodecIsr(void);


void Test_CamCodecPreviewQVGADisplay(void);
void Test_CamCodecQVGADisplay(void);
void Test_CamCodecQVGA(void);
void Display_Cam_Image(U32 size_x, U32 size_y);
void CamCaptureStart(U32 mode);
void CamCaptureStop(void);
void _CamCodecStopHw(void);
void _CamCodecSetLastIrq(void);
void CamPortInit(void);
void CamClockInit(void);
U32 Conv_YCbCr_Rgb(U8 y0, U8 y1, U8 cb0, U8 cr0);




void * camera_function[][2]=
{
	(void *)Test_CamCodecPreviewQVGADisplay,				"Test_CamCodecPreview 16bpp             ",
	(void *)Test_CamCodecQVGADisplay,		         		"Test_CamCodec Display 16bpp            ",
	(void *)Test_CamCodecQVGA,				         		"Test_CamCodec saved in memory          ",
	(void *)Camera_WriteBlock,								"IIC Write Block                        ",
	(void *)Camera_ReadBlock,								"IIC Read Block                         ",
	0,0
};

void CameraDisplayFunction(void)
{
	int i;

	i=0;	
	printf("\n\n");
	while(1)	{   //display menu
	    printf("%2d:%s",i,camera_function[i][1]);
	    i++;
	    if((int)(camera_function[i][0])==0) {
			printf("\n");
			break;
	    }
	    if((i%2)==0) printf("\n");
	}
}

void Ch22_Camera(void)
{
	int i;

	printf("\n----Test of Camera Interface----\n");

	CamPortInit();
	CamClockInit();

	printf("Select camera type\n");
	printf("0:S5K3AA VGA,   1:S5K3AA SXGA\n");
	printf("2:S5K3BAFB VGA, 3:S5K3BAFB SXGA,  4:S5K3BAFB UXGA\n");
	printf("Choose one:");
	i=GetIntNum();
	switch(i) {
		case 0:
			CAMTYPE=CAM_S5K3AA_VGA;
			CAMSIZE=VGA_XSIZE;
			CAMIICID=0x5a;
			printf("S5K3AA(VGA, ITU-T 601) Camera Module is selected!\n");
			break;
		case 1:
			CAMTYPE=CAM_S5K3AA_SXGA;
			CAMSIZE=SXGA_XSIZE;
			CAMIICID=0x5a;
			printf("S5K3AA(SXGA, ITU-T 656) Camera Module is selected!\n");
			break;
		case 2:
			CAMTYPE=CAM_S5K3BAFB_VGA;
			CAMSIZE=VGA_XSIZE;
			CAMIICID=0x5a;
			printf("S5K3BAFB(VGA, ITU-T 601) Camera Module is selected!\n");
			break;
		case 3:
			CAMTYPE=CAM_S5K3BAFB_SXGA;
			CAMSIZE=SXGA_XSIZE;
			CAMIICID=0x5a;
			printf("S5K3BAFB(SXGA, ITU-T 601) Camera Module is selected!\n");
			break;
		case 4:
			CAMTYPE=CAM_S5K3BAFB_UXGA;
			CAMSIZE=UXGA_XSIZE;
			CAMIICID=0x5a;
			printf("S5K3BAFB(UXGA, ITU-T 601) Camera Module is selected!\n");
			break;												
		default:
			CAMTYPE=CAM_S5K3AA_VGA;
			CAMSIZE=VGA_XSIZE;
			CAMIICID=0x5a;
			printf("S5K3AA(VGA, ITU-T 601) Camera Module is selected!\n");
			break;
	}


	rCIGCTRL|=(1<<31|1<<29);
	Delay(10);
	rCIGCTRL&=~(1<<31);

	//clock setting
	printf("Select camera clcok\n");
	printf(" 0:48Mhz,   1:32Mhz,   2:24Mhz,  3:19.2Mhz\n");
	printf(" 4:16Mhz    5:13.7Mhz, 6:12Mhz,  7:10.6Mhz\n");
	printf(" 8:9.6Mhz   9:8.7Mhz, 10:8Mhz,  11:7.3Mhz\n");
	printf("12:6.8Mhz  13:6.4Mhz, 14:6Mhz\n");
	printf("Choose one:");
	i=GetIntNum();
	if(i>=0 || i<= 14)
		rCLKDIVN=(rCLKDIVN&~(0xf<<16))|((i+1)<<16);
	else
		rCLKDIVN=(rCLKDIVN&~(0xf<<16))|((15)<<16);
	
	CamModuleReset();
	Delay(800);	
	CameraModuleSetting();
			
	while(1) {
		CameraDisplayFunction();
		printf("\nSelect(-1 to exit): ");
		i = GetIntNum();

		if(i==-1) break;
		
		if(i>=0 && (i<(sizeof(camera_function)/8)) ) 
	    	( (void (*)(void)) (camera_function[i][0]) )();	// execute selected function.
	}

}


/******************************************************************************
 *                                                                            *    
 *                   camera interface interrupts & controls                   *
 *                                                                            *     
 ******************************************************************************/

void __irq CamCodecIsr(void)
{

	U32 completedFrameIndex;

	ClearPending(BIT_CAM);
	switch(camCodecStatus) {
		case CAM_STOP_ISSUED:
			_CamCodecSetLastIrq();
			camCodecStatus=CAM_LASTIRQ_ISSUED;
			break;
		case CAM_LASTIRQ_ISSUED:
			_CamCodecStopHw();
			camCodecStatus=CAM_LAST_CAPTURING;
			break;			
		case CAM_LAST_CAPTURING:
			camCodecStatus=CAM_STOPPED;
			return;
		case CAM_STARTED:
			if(camCodecCaptureCount>0) camCodecDataValid=1;			
			break; 
		case CAM_CODEC_SCALER_BYPASS_STATE:
			break;
		default:
			break;
	}

    camCodecCaptureCount++;	 

}



/********************************************************
 CamCaptureStart - Start camera capture operation.
 
 Description:	
 - mode= CAM_CODEC_CAPTURE_ENABLE_BIT or CAM_PVIEW_CAPTURE_ENABLE_BIT or both
*****************************************************************/

void CamCaptureStart(U32 mode)
{ 
    
	if(mode&CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT) {
		camCodecStatus=CAM_STARTED;
		rCICOSCCTRL|=CAM_CODEC_SACLER_START_BIT;
		rCIIMGCPT|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT|(1<<24);		
	}
	else 
	{
		camCodecStatus=CAM_STARTED;
		rCIIMGCPT|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|(1<<24);		
		
	}
#if 0	
	rCIIMGCPT=(254<<10);
    rCIIMGCPT|=(1<<26)|(0<<25)|(1<<18)|(254<<10);    
	rCIIMGCPT|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT|(1<<24)|(1<<18)|(254<10);
#endif	
	
}

void CamCaptureStop(void)
{
	camCodecStatus=CAM_STOP_ISSUED;
}



void _CamCodecSetLastIrq(void)
{
	rCICOCTRL|=(1<<2); // Bit of LastIRQEn_Co is cleared automatically.  
}

void _CamCodecStopHw(void)
{
	rCICOSCCTRL&=~CAM_CODEC_SACLER_START_BIT; //stop codec scaler.
	rCIIMGCPT&=~(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT|(1<<24)); //stop capturing for codec scaler and global capture.
}


/******************************************************************************
 *                                                                            *    
 *                       camera interface initialization                      *
 *                                                                            *     
 ******************************************************************************/

void CamModuleReset()
{
	rCIGCTRL&= ~(1<<30);		
	Delay(30);
	rCIGCTRL |=(1<<30);	
}

void SetCAMClockDivider(int divn)
{
    rCLKDIVN= (rCLKDIVN & ~(0xf<<16))|(divn<<16);    
}

/* Description of Parameters
CoDstWidth: Destination Width of Codec Path
CoDstHeight: Destination Height of Codec Path
PrDstWidth: Destination Width of Preview Path
PrDstHeight: Destination Height of Preview Path
WinHorOffset: Size of Window Offset for Horizontal Direction
WinVerOffset: Size of Window Offset for Vertical Direction
CoFrameBuffer: Start Address for Codec DMA
PrFrameBuffer: Start Address for Previe DMA
*/
void CamInit(U32 CoDstWidth, U32 CoDstHeight, U32 WinHorOffset, U32 WinVerOffset, U32 FrameBuffer)
{
	U32 WinOfsEn;
	U32 divisor, multiplier;
	U32 MainBurstSizeY, RemainedBurstSizeY, MainBurstSizeC, RemainedBurstSizeC, MainBurstSizeRGB, RemainedBurstSizeRGB;
	U32 H_Shift, V_Shift, PreHorRatio, PreVerRatio, MainHorRatio, MainVerRatio;
	U32 SrcWidth, SrcHeight;
	U32 OrgSrcWidth, OrgSrcHeight;
	U32 ScaleUp_H_Co, ScaleUp_V_Co;

	//constraint for size setting is checked here.........

	//constant for calculating codec dma address
	if(camTestMode==CAM_TEST_MODE_PVIEW) 
	{
		if(camRgbOutput==CAM_RGB24B)
			multiplier=4;
		else if(camRgbOutput==CAM_RGB16B)
			multiplier=2;		
	}
	if(camTestMode==CAM_TEST_MODE_CODEC)
	{
		if(camCodecOutput==CAM_CCIR422)
			divisor=2;
		else if(camCodecOutput==CAM_CCIR420)
			divisor=4;
	}
	
	
	if(WinHorOffset==0 && WinVerOffset==0)
		WinOfsEn=0;
	else
		WinOfsEn=1;

	switch(CAMSIZE) {
		case VGA_XSIZE:
			OrgSrcWidth=VGA_XSIZE;
			OrgSrcHeight=VGA_YSIZE;
			break;
		case SXGA_XSIZE:
			OrgSrcWidth=SXGA_XSIZE;
			OrgSrcHeight=SXGA_YSIZE;
			break;
		case UXGA_XSIZE:
			OrgSrcWidth=UXGA_XSIZE;
			OrgSrcHeight=UXGA_YSIZE;
			break;
		default:
			OrgSrcWidth=VGA_XSIZE;
			OrgSrcHeight=VGA_YSIZE;
			break;
	}		
		

	SrcWidth=OrgSrcWidth-2*WinHorOffset;
	SrcHeight=OrgSrcHeight-2*WinVerOffset;

	printf("SrcWidth:%d, SrcHeight:%d\n", SrcWidth, SrcHeight);
	if(SrcWidth<=CoDstWidth) ScaleUp_H_Co=1;
	else ScaleUp_H_Co=0;		

	if(SrcHeight<=CoDstHeight) ScaleUp_V_Co=1;
	else ScaleUp_V_Co=0;		

	if(CAMTYPE >= CAM_S5K3BAFB_VGA)
		rCIGCTRL = (rCIGCTRL & ~(0x3<<27))|(1<<26|1<<25);
	else
		rCIGCTRL = (rCIGCTRL & ~(0x3<<27))|(1<<26);
	
	if(CAMTYPE == CAM_S5K3AA_VGA)
		rCISRCFMT=(CAM_ITU656<<31)|(0<<30)|(CAM_ITU601_8B<<29)|(OrgSrcWidth<<16)|(CAM_ORDER_CRYCBY<<14)|(OrgSrcHeight);
	else if(CAMTYPE == CAM_S5K3AA_SXGA)
		rCISRCFMT=(CAM_ITU656<<31)|(0<<30)|(CAM_ITU601_8B<<29)|(OrgSrcWidth<<16)|(CAM_ORDER_CBYCRY<<14)|(OrgSrcHeight);
	else
		rCISRCFMT=(CAM_ITU601<<31)|(0<<30)|(CAM_ITU601_8B<<29)|(OrgSrcWidth<<16)|(CAM_ORDER_YCRYCB<<14)|(OrgSrcHeight);
	rCIWDOFST=(WinOfsEn<<31)|(WinHorOffset<<16)|(WinVerOffset);
	rCIDOWSFT2=(WinHorOffset<<16)|(WinVerOffset);

	if(camTestMode==CAM_TEST_MODE_PVIEW) 
	{	
		if(CAM_PVIEW_PINGPONG) {
			rCICOYSA1=FrameBuffer;
			rCICOYSA2=rCICOYSA1+CoDstWidth*CoDstHeight*multiplier;
			rCICOYSA3=rCICOYSA2+CoDstWidth*CoDstHeight*multiplier;
			rCICOYSA4=rCICOYSA3+CoDstWidth*CoDstHeight*multiplier;
		}
		else {
			rCICOYSA1=FrameBuffer;
			rCICOYSA2=rCICOYSA1;
			rCICOYSA3=rCICOYSA1;
			rCICOYSA4=rCICOYSA1;
		}
		
		rCICOTRGFMT=(CAM_CCIR422<<31)|(CAM_CCIR422<<30)|(1<<29)|(CoDstWidth<<16)|(CAM_FLIP_NORMAL<<14)|(CoDstHeight);

		CalculateBurstSize(CoDstWidth*multiplier, &MainBurstSizeRGB, &RemainedBurstSizeRGB);		
		rCICOCTRL=((MainBurstSizeRGB/2)<<19)|((RemainedBurstSizeRGB/2)<<14);
		
		rCIIMGCPT=(1<<26|camRgbOutput<<25);	
		

	}
	if(camTestMode==CAM_TEST_MODE_CODEC)	
	{
		if(CAM_CODEC_PINGPONG) {			
			rCICOYSA1=FrameBuffer;
			rCICOYSA2=rCICOYSA1+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
			rCICOYSA3=rCICOYSA2+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
			rCICOYSA4=rCICOYSA3+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
		
			rCICOCBSA1=rCICOYSA1+CoDstWidth*CoDstHeight;
			rCICOCBSA2=rCICOYSA2+CoDstWidth*CoDstHeight;
			rCICOCBSA3=rCICOYSA3+CoDstWidth*CoDstHeight;
			rCICOCBSA4=rCICOYSA4+CoDstWidth*CoDstHeight;

			rCICOCRSA1=rCICOCBSA1+CoDstWidth*CoDstHeight/divisor;
			rCICOCRSA2=rCICOCBSA2+CoDstWidth*CoDstHeight/divisor;
			rCICOCRSA3=rCICOCBSA3+CoDstWidth*CoDstHeight/divisor;
			rCICOCRSA4=rCICOCBSA4+CoDstWidth*CoDstHeight/divisor;
		}
		else {
			rCICOYSA1=FrameBuffer;
			rCICOYSA2=rCICOYSA1;
			rCICOYSA3=rCICOYSA1;
			rCICOYSA4=rCICOYSA1;
		
			rCICOCBSA1=rCICOYSA1+CoDstWidth*CoDstHeight;
			rCICOCBSA2=rCICOCBSA1;
			rCICOCBSA3=rCICOCBSA1;
			rCICOCBSA4=rCICOCBSA1;

			rCICOCRSA1=rCICOCBSA1+CoDstWidth*CoDstHeight/divisor;
			rCICOCRSA2=rCICOCRSA1;
			rCICOCRSA3=rCICOCRSA1;
			rCICOCRSA4=rCICOCRSA1;
		}
		
		rCICOTRGFMT=(camCodecInput<<31)|(camCodecOutput<<30)|(0<<29)|(CoDstWidth<<16)|(CAM_FLIP_NORMAL<<14)|(CoDstHeight);

		CalculateBurstSize(CoDstWidth, &MainBurstSizeY, &RemainedBurstSizeY);
		CalculateBurstSize(CoDstWidth/2, &MainBurstSizeC, &RemainedBurstSizeC);
		rCICOCTRL=(MainBurstSizeY<<19)|(RemainedBurstSizeY<<14)|(MainBurstSizeC<<9)|(RemainedBurstSizeC<<4);		
		
		rCIIMGCPT=(0<<26);		
	}
	
	CalculatePrescalerRatioShift(SrcWidth, CoDstWidth, &PreHorRatio, &H_Shift);
	CalculatePrescalerRatioShift(SrcHeight, CoDstHeight, &PreVerRatio, &V_Shift);
	MainHorRatio=(SrcWidth<<8)/(CoDstWidth<<H_Shift);
	MainVerRatio=(SrcHeight<<8)/(CoDstHeight<<V_Shift);
    			
	rCICOSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio<<0);
	rCICOSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio); 
	rCICOSCCTRL=(CAM_SCALER_BYPASS_OFF<<31)|(ScaleUp_H_Co<<30)|(ScaleUp_V_Co<<29)|(MainHorRatio<<16)|(MainVerRatio);

	rCICOTAREA=CoDstWidth*CoDstHeight;
	
	rCICOCPTSEQ=0xffffffff;

		
	rCICOSCOS=0x0;
	

	//clear overflow because unintentional overflow may be existed...
	rCIWDOFST|=(1<<30)|(0xf<<12);
	rCIWDOFST&=~((1<<30)|(0xf<<12));	
	
	printf("CIGCTRL:0x%x\n", rCIGCTRL);

}



/********************************************************
 CalculateBurstSize - Calculate the busrt lengths
 
 Description:	
 - dstHSize: the number of the byte of H Size.
 
*/
void CalculateBurstSize(U32 hSize,U32 *mainBurstSize,U32 *remainedBurstSize)
{
	U32 tmp;	
	tmp=(hSize/4)%16;
	switch(tmp) {
		case 0:
			*mainBurstSize=16;
			*remainedBurstSize=16;
			break;
		case 4:
			*mainBurstSize=16;
			*remainedBurstSize=4;
			break;
		case 8:
			*mainBurstSize=16;
			*remainedBurstSize=8;
			break;
		default: 
			tmp=(hSize/4)%8;

⌨️ 快捷键说明

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