📄 camif.c
字号:
/************************************************************
File Name : camif.c
Descriptions
-S3C2460 camera test routines & basic libraries
History
- July 23, 2003. Draft Version 0.0 by purnnamu
- Janualy 15, 2004. Modifed by Boaz
Copyright (c) 2004 SAMSUNG Electronics.
# However, Anybody can use this code without our permission.
*************************************************************/
#include <ctype.h>
#include "def.h"
#include "2460addr.h"
#include "2460lib.h"
#include "camif.h"
#include "post.h"
#include "lcdlib.h"
#include "glib.h"
#include "imagedef.h"
#include "camproset.h"
#include "PLL.h"
#define TEST_DETAIL_EN (TRUE)
//#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 unsigned int camTestMode;
volatile unsigned int camCodecCaptureCount;
volatile unsigned int camPviewCaptureCount;
volatile unsigned int camCodecStatus;
volatile unsigned int camPviewStatus;
volatile unsigned int amount;
volatile unsigned int cameraDone;
volatile unsigned int camCodecDataValid;
volatile unsigned int camPviewDataValid;
volatile unsigned int camCodecDispX = 240;
volatile unsigned int camCodecDispY = 320;
volatile unsigned int camPviewDispX = 240;
volatile unsigned int camPviewDispY = 320;
volatile unsigned int postMode;
volatile unsigned int postStart1;
volatile unsigned int postEnd1;
volatile unsigned int postStart2;
volatile unsigned int postEnd2;
extern unsigned int CAMTYPE, CAMSIZE, CAMIICID;
volatile unsigned int regCIPRSCPRERATIO, regCIPRSCPREDST, regCIPRSCCTRL, regCIWDOFST;
unsigned int camCodecInput, camCodecOutput, camPviewOutput;
unsigned int cscDone;
static unsigned int save_rGPBCON, save_rGPBPU, save_rGPCCON, save_rGPCPU, save_rSPCON; // for setting Camif Port
//static PPOST_CONFIG _pPostCfgIsr;
//static unsigned int freeBufStartAddr=NULL;
void CalculateBurstSize(unsigned int dstHSize,unsigned int *mainBurstSize,unsigned int *RemainedBurstSize);
void __irq Camif_Post_Isr(void);
void Test_CamPreviewTestQVGADisplay(void);
void Test_CamCodecPostTestQVGADisplay(void);
void Display_Cam_Image(unsigned int size_x, unsigned int size_y);
void Display_Prv_Image(int size_x, int size_y);
void CamCaptureStart(unsigned int mode);
void CamCaptureStop(void);
void _CamPviewStopHw(void);
void _CamCodecStopHw(void);
void _CamCodecSetLastIrq(void);
void _CamPviewSetLastIrq(void);
unsigned int Conv_YCbCr_Rgb(unsigned char y0, unsigned char y1, unsigned char cb0, unsigned char cr0);
void SetCAMClockDivider(int divn);
void CamSelectPort(unsigned char port);
void SetCamifPort(void);
void ReturnCamifPort(void);
void * camera_function[][2]=
{
(void *)Test_CamPreviewTestQVGADisplay, "PreviewTest ",
(void *)Test_CamCodecPostTestQVGADisplay, "CodecPostTest ",
(void *)Camera_WriteByte, "IIC Write Byte ",
(void *)Camera_ReadByte, "IIC Read Byte ",
(void *)Camera_WriteBlock, "IIC Write Block ",
(void *)Camera_ReadBlock, "IIC Read Block ",
(void *)CamDemoDisplay, "Camera Demo(532) ",
0,0
};
void CameraDisplayFunction(void)
{
int i;
rPRIORITY1 &= ~(0x7);
rPRIORITY1 |= 0x2;
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 Ch21_CAMERA(void)
{
int i;
printf("\n----Test of Camera Interface----\n");
// Camif Initializtion
SetCamifPort();
camCodecOutput=CAM_CCIR420;
camCodecInput=CAM_CCIR420;
camPviewOutput=CAM_RGB16B;
printf("Select camif port\n");
printf("0:Port A, 1:Port B\n");
printf("Choose one [D=0]:");
i=GetIntNum();
CamSelectPort(i);
printf("Select camera type\n");
printf("0:S5X532, 1:OV7620 8bit, 2:OV7620 16bit, 3:S5X3A1, 4:S5K3AA(SXGA) \n");
printf("Choose one [D=0]:");
i=GetIntNum();
switch(i) {
case 1:
CAMTYPE=CAM_OV7620;
CAMIICID=0x42;
break;
case 2:
CAMTYPE=CAM_OV7620_16;
CAMIICID=0x42;
break;
case 3:
CAMTYPE=CAM_S5X3A1;
CAMIICID=0x5a;
break;
case 4:
CAMTYPE=CAM_S5K3AA;
CAMIICID=0x5a;
break;
default:
CAMTYPE=CAM_S5X532;
CAMIICID=0x5a;
break;
}
printf("Select camera size\n");
printf("0:VGA(640x480), 1:SXGA(1280x1024), 2:1 Mega(1152x864)\n");
printf("Choose one [D=0]:");
i=GetIntNum();
switch(i) {
case 1:
CAMSIZE=SXGA_XSIZE;
break;
case 2:
CAMSIZE=MEGA1_XSIZE;
break;
case 3:
CAMSIZE=MEGA2_XSIZE;
break;
default:
CAMSIZE=VGA_XSIZE;
break;
}
printf("Select camera clcok source\n");
printf(" 0:UPLL clk(96MHz), 1:External clock source, 2:HCLK\n");
printf("Choose one [D=0]:");
i=GetIntNum();
switch(i) {
case 1 :
rCLKSRCCON = (rCLKSRCCON & ~(1<<13) & ~(1<<5)); // 12 MHz
break;
case 2 :
rCLKSRCCON |= (1<<13);
break;
default :
rCLKSRCCON = (rCLKSRCCON & ~(1<<13))|(1<<5);
SetUPLL( 72, 3, 1); // 96MHz
break;
}
printf("Select camera clcok divider\n");
printf("Choose one [Input Clock/n, n=1~16, D=4]:"); // 24MHz
i=GetIntNum();
if ((i>=1)&&(i<=16))
SetCAMClockDivider(i-1);
else
SetCAMClockDivider(3); // UPLL/(CAMCLK_DIV+1)
CamReset();
CameraModuleSetting();
printf("module set\n");
while(1) {
CameraDisplayFunction();
printf("\nSelect(-1 to exit): ");
i = GetIntNum();
//printf("IN:%d.\n\n", i);
if(i==-1) break;
if(i>=0 && (i<(sizeof(camera_function)/8)) )
( (void (*)(void)) (camera_function[i][0]) )(); // execute selected function.
}
CamIIC_close();
ReturnCamifPort();
}
void SetCamifPort(void)
{
//Push Camif GPIO port configuration
save_rGPBCON = rGPBCON;
save_rGPBPU = rGPBPU;
save_rGPCCON = rGPCCON;
save_rGPCPU = rGPCPU;
save_rSPCON = rSPCON;
//Configure Camif port
rGPBCON = 0x2AAAAAA; // Camif A enable [24:0]
rGPBPU = 0x1FFF; // Camif A port pull-up disable [12:0]
rGPCCON = 0x2AAAAAA; // Camif B enable [24:0]
// rGPCCON = 0x0; // Camif B enable [24:0]
rGPCPU = 0x1FFF; // Camif B port pull-up disable [12:0]
}
void ReturnCamifPort(void)
{
rGPBCON = save_rGPBCON;
rGPBPU = save_rGPBPU;
rGPCCON = save_rGPCCON;
rGPCPU = save_rGPCPU;
rSPCON = save_rSPCON;
}
void CamSelectPort(unsigned char port)
{
CamIIC_open();
if (port != 1) // select port A
{
rCIGCTRL |= (1<<29);
rSPCON &= ~(1);
Wr_SingleIIC(0xE0,0x4);
}
else // select port B
{
rCIGCTRL &= ~(1<<29);
rSPCON |= (1);
Wr_SingleIIC(0xE0,0x5);
}
}
/********************************************************
CamCaptureStart - Start camera capture operation.
Description:
- mode= CAM_CODEC_CAPTURE_ENABLE_BIT or CAM_PVIEW_CAPTURE_ENABLE_BIT or both
*/
void CamCaptureStart(unsigned int mode)
{
if(mode&CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT) {
camCodecStatus=CAM_STARTED;
rCICOSCCTRL|=CAM_CODEC_SACLER_START_BIT;
}
if(mode&CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT) {
camPviewStatus=CAM_STARTED;
rCIPRSCCTRL|=CAM_PVIEW_SACLER_START_BIT;
}
rCIIMGCPT|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|mode;
}
void CamCaptureStop(void)
{
camCodecStatus=CAM_STOP_ISSUED;
camPviewStatus=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); //stop capturing for codec scaler and global capture.
}
void _CamPviewSetLastIrq(void)
{
rCIPRCTRL|=(1<<2); // Bit of LastIRQEn_Pr is cleared automatically.
}
void _CamPviewStopHw(void)
{
rCIPRSCCTRL&=~CAM_PVIEW_SACLER_START_BIT; //stop preview scaler.
rCIIMGCPT&=~(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT); //stop capturing for preview scaler and global capture.
}
/******************************************************************************
* *
* camera interface initialization *
* *
******************************************************************************/
void CamReset()
{
//rCLKDIVN=(rCLKDIVN&~(0xf<<8))|(0x1<<8);
rCIGCTRL|= (1<<31); //camera I/F soft reset
Delay(1);
rCIGCTRL&= ~(1<<31);
// rCIGCTRL|=(1<<26); // XciPCLK Polarity setting
switch(CAMTYPE) {
case CAM_OV7620:
case CAM_OV7620_16:
rCIGCTRL |= ((1<<30)|(1<<23)); //external camera reset assertion (OV7620=high active)
Delay(50);
rCIGCTRL &= ~((1<<30)|(1<<23)); //external camera reset deassertion
break;
case CAM_S5X532:
case CAM_S5X3A1:
case CAM_S5K3AA:
default:
rCIGCTRL &= ~((1<<30)|(1<<23)); //external camera reset assertion (S5X433,AU70H=low active)
Delay(100);
rCIGCTRL |= ((1<<30)|(1<<23)); //external camera reset deassertion
Delay(400);
break;
}
}
void SetCAMClockDivider(int divn) // MCLK = UPLL output/(CAMCLKdiv+1)
{
rCLKDIVCON = (rCLKDIVCON & ~(0xf<<8))|(divn<<8);
}
/******************************************************************************
* *
* camera interface interrupts & controls *
* *
******************************************************************************/
void __irq Camif_Post_Isr(void)
{
unsigned int completedFrameIndex;
rINTSUBMSK2 |= BIT_SUB_CAMIF_C|BIT_SUB_CAMIF_P|BIT_SUB_POST;
rINTMSK |= BIT_CAMIF_BLOCK_POST;
ClearPending(BIT_CAMIF_BLOCK_POST);
if (rSUBSRCPND2 & BIT_SUB_POST) // post
{
rMODE &= ~(1<<6);//Clear Source in POST Processor
rSUBSRCPND2 = BIT_SUB_POST;
// printf("t");
postProcessingDone=1;
// if (postMode & POST_OUT_RGB24B) factor = 4;
// else factor = 2;
if ( rLCDCON1 & (1<<21) ) // dual buffering - framebuffer2
{
// printf("t1");
rLCDCON1 &= ~(1<<21); // framebuffer1
rADDRStart_RGB = postStart2;
rADDREnd_RGB = postEnd2;
}
else // framebuffer1
{
// printf("t2");
rLCDCON1 |= (1<<21); // framebuffer2
rADDRStart_RGB = postStart1;
rADDREnd_RGB = postEnd1;
}
}
if (rSUBSRCPND2 & BIT_SUB_CAMIF_C) // codec
{
rSUBSRCPND2 = BIT_SUB_CAMIF_C;
//printf("0x%x, 0x%x\n", rCICOSTATUS&0xe0000000, rCIPRSTATUS&0xc0000000);
printf("c");
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(camTestMode&CAM_TEST_MODE_CODEC_POST) {
if(camCodecCaptureCount>0) {
camCodecDataValid=1;
if((postProcessingDone==0) && (camCodecCaptureCount>1)) {
printf("ERROR:Post not completed yet.\n");
}
completedFrameIndex=(((rCICOSTATUS>>26)&0x3)+4-2)%4;
PostStartProcessing(completedFrameIndex);
}
}
else {
if(camCodecCaptureCount>0) camCodecDataValid=1;
}
break;
case CAM_CODEC_SCALER_BYPASS_STATE:
break;
default:
break;
}
camCodecCaptureCount++;
}
if (rSUBSRCPND2 & BIT_SUB_CAMIF_P) // preview
{
rSUBSRCPND2 = BIT_SUB_CAMIF_P;
printf("p");
completedFrameIndex=(((rCIPRSTATUS>>26)&0x3)+4-2)%4;
//printf("0x%x, 0x%x, %d\n", rCICOSTATUS&0xe0000000, rCIPRSTATUS&0xc0000000, completedFrameIndex);
switch(camPviewStatus) {
case CAM_STOP_ISSUED:
_CamPviewSetLastIrq();
camPviewStatus=CAM_LASTIRQ_ISSUED;
break;
case CAM_LASTIRQ_ISSUED:
_CamPviewStopHw();
camPviewStatus=CAM_LAST_CAPTURING;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -