📄 camif.c
字号:
//====================================================================
// 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 + -