📄 camera.c
字号:
;/*********************************************************************
;* Project Name : S3C2443
;*
;* Copyright 2005 by Samsung Electronics, Inc.
;* All rights reserved.
;*
;* Project Description :
;* This software is only for verifying functions of the S3C2443
;* Anybody can use this code without our permission.
;**********************************************************************
;*
;* Description : Camera
;*
;* History
;* R0.0 (2006.8. ) : Y.C.Kwon draft
;*
;**********************************************************************/
//////////////////////////////////////
// Put this into system library or erase every 'Assert'. This is not necessary function.
//#include <stdio.h>
#define Assert(condition,message) {if (!(condition)) {printf(message);printf("%s(line %d)\n", __FILE__, __LINE__); }}
//////////////////////////////////////
#include "system.h"
#include "Camera.h"
// Chapter23 Camera Interface
#define FIMC_BASE (0x4d800000)
#if 0
#define rCISRCFMT (*(volatile unsigned *)(FIMC_BASE+0x00)) //Input Source Format
#define rCIWDOFST (*(volatile unsigned *)(FIMC_BASE+0x04)) //Window offset
#define rCIGCTRL (*(volatile unsigned *)(FIMC_BASE+0x08)) //Global control
#define rCIDOWSFT2 (*(volatile unsigned *)(FIMC_BASE+0x14)) //Window option 2
#define rCICOYSA1 (*(volatile unsigned *)(FIMC_BASE+0x18)) //Y1 frame start address for codec DMA
#define rCICOYSA2 (*(volatile unsigned *)(FIMC_BASE+0x1C)) //Y2 frame start address for codec DMA
#define rCICOYSA3 (*(volatile unsigned *)(FIMC_BASE+0x20)) //Y3 frame start address for codec DMA
#define rCICOYSA4 (*(volatile unsigned *)(FIMC_BASE+0x24)) //Y4 frame start address for codec DMA
#define rCICOCBSA1 (*(volatile unsigned *)(FIMC_BASE+0x28)) //Cb1 frame start address for codec DMA
#define rCICOCBSA2 (*(volatile unsigned *)(FIMC_BASE+0x2C)) //Cb2 frame start address for codec DMA
#define rCICOCBSA3 (*(volatile unsigned *)(FIMC_BASE+0x30)) //Cb3 frame start address for codec DMA
#define rCICOCBSA4 (*(volatile unsigned *)(FIMC_BASE+0x34)) //Cb4 frame start address for codec DMA
#define rCICOCRSA1 (*(volatile unsigned *)(FIMC_BASE+0x38)) //Cr1 frame start address for codec DMA
#define rCICOCRSA2 (*(volatile unsigned *)(FIMC_BASE+0x3C)) //Cr2 frame start address for codec DMA
#define rCICOCRSA3 (*(volatile unsigned *)(FIMC_BASE+0x40)) //Cr3 frame start address for codec DMA
#define rCICOCRSA4 (*(volatile unsigned *)(FIMC_BASE+0x44)) //Cr4 frame start address for codec DMA
#define rCICOTRGFMT (*(volatile unsigned *)(FIMC_BASE+0x48)) //Target image format of codex DMA
#define rCICOCTRL (*(volatile unsigned *)(FIMC_BASE+0x4C)) //Codec DMA comtrol
#define rCICOSCPRERATIO (*(volatile unsigned *)(FIMC_BASE+0x50)) //Codec pre-scaler ratio control
#define rCICOSCPREDST (*(volatile unsigned *)(FIMC_BASE+0x54)) //Codec pre-scaler desitination format
#define rCICOSCCTRL (*(volatile unsigned *)(FIMC_BASE+0x58)) //Codec main-scaler control
#define rCICOTAREA (*(volatile unsigned *)(FIMC_BASE+0x5C)) //Codec pre-scaler desination format
#define rCICOSTATUS (*(volatile unsigned *)(FIMC_BASE+0x64)) //Codec path status
#define rCIPRCLRSA1 (*(volatile unsigned *)(FIMC_BASE+0x6C)) //RGB 1st frame start address for preview DMA
#define rCIPRCLRSA2 (*(volatile unsigned *)(FIMC_BASE+0x70)) //RGB 1st frame start address for preview DMA
#define rCIPRCLRSA3 (*(volatile unsigned *)(FIMC_BASE+0x74)) //RGB 1st frame start address for preview DMA
#define rCIPRCLRSA4 (*(volatile unsigned *)(FIMC_BASE+0x78)) //RGB 1st frame start address for preview DMA
#define rCIPRTRGFMT (*(volatile unsigned *)(FIMC_BASE+0x7C)) //Target image format of Preview DMA
#define rCIPRCTRL (*(volatile unsigned *)(FIMC_BASE+0x80)) //Codec DMA comtrol
#define rCIPRSCPRERATIO (*(volatile unsigned *)(FIMC_BASE+0x84)) //Codec pre-scaler ratio control
#define rCIPRSCPREDST (*(volatile unsigned *)(FIMC_BASE+0x88)) //Codec pre-scaler desitination format
#define rCIPRSCCTRL (*(volatile unsigned *)(FIMC_BASE+0x8C)) //Codec main-scaler control
#define rCIPRTAREA (*(volatile unsigned *)(FIMC_BASE+0x90)) //Codec pre-scaler desination format
#define rCIPRSTATUS (*(volatile unsigned *)(FIMC_BASE+0x98)) //Codec path status
#define rCIIMGCPT (*(volatile unsigned *)(FIMC_BASE+0xA0)) //Imahe capture enable command
#define rCICOCPTSEQ (*(volatile unsigned *)(FIMC_BASE+0xA4)) //Codec dma capture sequence related
#define rCICOSCOS (*(volatile unsigned *)(FIMC_BASE+0xA8)) //Codec scan line offset related
#define rCIIMGEFF (*(volatile unsigned *)(FIMC_BASE+0xB0)) //Imahe Effects related
#define rCIMSYSA (*(volatile unsigned *)(FIMC_BASE+0xB4)) //MSDMA Y start address related
#define rCIMSCBSA (*(volatile unsigned *)(FIMC_BASE+0xB8)) //MSDMA Cb start address related
#define rCIMSCRSA (*(volatile unsigned *)(FIMC_BASE+0xBC)) //MSDMA Cr start address related
#define rCIMSYEND (*(volatile unsigned *)(FIMC_BASE+0xC0)) //MSDMA Y end address related
#define rCIMSCBEND (*(volatile unsigned *)(FIMC_BASE+0xC4)) //MSDMA Cb end address related
#define rCIMSCREND (*(volatile unsigned *)(FIMC_BASE+0xC8)) //MSDMA Cr end address related
#define rCIMSYOFF (*(volatile unsigned *)(FIMC_BASE+0xCC)) //MSDMA Y offset related
#define rCIMSCBOFF (*(volatile unsigned *)(FIMC_BASE+0xD0)) //MSDMA Cb offset related
#define rCIMSCROFF (*(volatile unsigned *)(FIMC_BASE+0xD4)) //MSDMA Cr offset related
#define rCIMSWIDTH (*(volatile unsigned *)(FIMC_BASE+0xD8)) //MSDMA source image width related
#define rCIMSCTRL (*(volatile unsigned *)(FIMC_BASE+0xDC)) //MSDMA cotrol
#endif
//*******************************************************************
//* Functions for Camera Interface
//*******************************************************************
void ResetCameraModule( void)
{
volatile int delay;
rCIGCTRL &= ~(1<<30);
for(delay=0;delay<1000000;delay++); // substitude this with Delay() function.
rCIGCTRL |= (1<<30);
for(delay=0;delay<1000000;delay++); // substitude this with Delay() function.
}
void EnableImageCapture( void)
{
rCIIMGCPT |= (1u<<31);
}
void DisableImageCapture( void)
{
rCIIMGCPT &= ~(1u<<31);
}
void ResetCameraInterface( void)
{
rCISRCFMT |= (1u<<31);
rCIGCTRL |= (1u<<31);
rCIGCTRL &= ~(1u<<31);
}
void SetCameraSourceFormat( unsigned int ITU601_656, unsigned int UVOffset, unsigned int Order422)
{
rCISRCFMT = (rCISRCFMT & ~((0x1<<31)|(0x1<<30)|(0x3<<14))) | (ITU601_656<<31)|(UVOffset<<30)|(Order422<<14);
}
void SetCameraSourceSize( unsigned int SourceHsize, unsigned int SourceVsize)
{
rCISRCFMT = (rCISRCFMT & ~((0x1fff<<16)|(0x1fff<<0))) | (SourceHsize<<16)|(SourceVsize);
}
void SetCameraInterfacePolarity( unsigned int InvPolPCLK, unsigned int InvPolVSYNC, unsigned int InvPolHREF)
{
rCIGCTRL = (rCIGCTRL & ~((1<<26)|(1<<25)|(1<<24))) | (InvPolPCLK<<26)|(InvPolVSYNC<<25)|(InvPolHREF<<24);
}
void SetCameraWindowOffset( unsigned int WinOfsEn, unsigned int WinHorOfst, unsigned int WinVerOfst, unsigned int WinHorOfst2, unsigned int WinVerOfst2)
{
rCIWDOFST = (rCIWDOFST & ~((0x1<<31)|(0x7ff<<16)|(0x7ff<<0))) | (WinOfsEn<<31)|(WinHorOfst<<16)|(WinVerOfst<<0);
rCIDOWSFT2 = (rCIDOWSFT2 & ~((0x7ff<<16)|(0x7ff<<0))) | (WinHorOfst2<<16)|(WinVerOfst2<<0);
}
void SetCameraTestPattern( unsigned int TestPattern)
{
rCIGCTRL = (rCIGCTRL & ~(0x3<<27)) | (TestPattern<<27);
}
void SetImageEffector( unsigned int IE_FIN, unsigned int PAT_Cb, unsigned int PAT_Cr)
{
rCIIMGEFF = (IE_FIN<<26)|(PAT_Cb<<13)|(PAT_Cr<<0);
}
void EnableOverflowIRQ( void)
{
rCIWDOFST |= (1<<30)|(1<<15)|(1<<14)|(1<<13)|(1<<12);
rCIWDOFST &= ~((1<<30)|(1<<15)|(1<<14)|(1<<13)|(1<<12));
rCIGCTRL |= (1<<22);
}
void DisableOverflowIRQ( void)
{
rCIGCTRL &= ~(1<<22);
}
static void CalculateBurstSize( unsigned int TargetImageSize, unsigned int *MainBurstLength, unsigned int *RemainedBurstLength)
{
switch((TargetImageSize>>2)&0xf) {
case 0 : *MainBurstLength = 16;
*RemainedBurstLength = 16;
break;
case 2 : *MainBurstLength = 16;
*RemainedBurstLength = 2;
break;
case 4 : *MainBurstLength = 16;
*RemainedBurstLength = 4;
break;
case 6 : *MainBurstLength = 4;
*RemainedBurstLength = 2;
break;
case 8 : *MainBurstLength = 16;
*RemainedBurstLength = 8;
break;
case 10 : *MainBurstLength = 8;
*RemainedBurstLength = 2;
break;
case 12 : *MainBurstLength = 8;
*RemainedBurstLength = 4;
break;
case 14 : *MainBurstLength = 4;
*RemainedBurstLength = 2;
break;
default : Assert(0,"Improper image size\n");
break;
}
}
static void CalculatePrescalerRatioShift( unsigned int SRC_Size, unsigned int DST_Size, unsigned int *Ratio,unsigned int *Shift)
{
if (SRC_Size>=64*DST_Size) { Assert(0,"Out of scale range.\n"); }
else if (SRC_Size>=32*DST_Size) { *Ratio=32; *Shift=5; }
else if (SRC_Size>=16*DST_Size) { *Ratio=16; *Shift=4; }
else if (SRC_Size>=8*DST_Size) { *Ratio=8; *Shift=3; }
else if (SRC_Size>=4*DST_Size) { *Ratio=4; *Shift=2; }
else if (SRC_Size>=2*DST_Size) { *Ratio=2; *Shift=1; }
else { *Ratio=1; *Shift=0; }
}
//*******************************************************************
//* Functions for Camera Codec Path
//*******************************************************************
void EnableImageCaptureCodec( void)
{
rCIIMGCPT |= (1<<30);
}
void DisableImageCaptureCodec( void)
{
rCIIMGCPT &= ~(1<<31);
}
void EnableCodecDMA( void)
{
rCIIMGCPT |= (1<<24);
}
void DisableCodecDMA( void)
{
rCIIMGCPT &= ~(1<<24);
}
static unsigned int GetCodecBytesPerPixel( unsigned int OutFormat, unsigned int Interleave)
{
unsigned int BytesPerPixel = 0;
switch(OutFormat)
{
case OutFormat_YCBCR420 :
BytesPerPixel = 1;
break;
case OutFormat_YCBCR422 :
if (Interleave==INTERLEAVE_OFF)
BytesPerPixel = 1;
else
BytesPerPixel = 2;
break;
case OutFormat_RGB16B :
BytesPerPixel = 2;
break;
case OutFormat_RGB24B :
BytesPerPixel = 4;
break;
}
return BytesPerPixel;
}
void SetCodecFormat( unsigned int InFormat, unsigned int OutFormat, unsigned int Interleave, unsigned int Order422)
{
rCICOTRGFMT &= ~((0x1<<31)|(0x1<<30)|(0x1<<29));
rCIIMGCPT &= ~((0x1<<26)|(0x1<<25));
switch(OutFormat)
{
case OutFormat_RGB16B :
Assert(!(Interleave==INTERLEAVE_OFF),"Interleave mode must be set in RGB mode.\n");
rCICOTRGFMT |= (InFormat<<31)|(0x1<<30)|(0x1<<29);
rCIIMGCPT |= (0x1<<26)|(0x0<<25);
break;
case OutFormat_RGB24B :
Assert(!(Interleave==INTERLEAVE_OFF),"Interleave mode must be set in RGB mode.\n");
rCICOTRGFMT |= (InFormat<<31)|(0x1<<30)|(0x1<<29);
rCIIMGCPT |= (0x1<<26)|(0x1<<25);
break;
case OutFormat_YCBCR420 :
Assert(!(Interleave==INTERLEAVE_ON),"Could not set Interleave mode in YCBCR420 output format.\n");
rCICOTRGFMT |= (InFormat<<31)|(0x0<<30)|(0x0<<29);
rCIIMGCPT |= (0x0<<26)|(0x0<<25);
break;
case OutFormat_YCBCR422 :
Assert(!(InFormat==InFormat_YCBCR420),"Could not set YCBCR422 output format when the input format is set as YCBCR420.\n");
rCICOTRGFMT |= (InFormat<<31)|(0x1<<30)|(Interleave<<29);
rCIIMGCPT |= (0x0<<26)|(0x0<<25);
break;
}
rCICOCTRL = (rCICOCTRL & ~(0x3)) | (Order422);
}
void SetCodecFrameBuffer( unsigned int FrameBuffer, unsigned int TargetHsize, unsigned int TargetVsize, unsigned int OutFormat, unsigned int Interleave)
{
unsigned int BytesPerPixel;
if (Interleave==INTERLEAVE_OFF)
{
if (OutFormat==OutFormat_YCBCR420)
{
rCICOYSA1 = FrameBuffer;
rCICOYSA2 = rCICOYSA1+TargetHsize*TargetVsize+(TargetHsize*TargetVsize/2);
rCICOYSA3 = rCICOYSA2+TargetHsize*TargetVsize+(TargetHsize*TargetVsize/2);
rCICOYSA4 = rCICOYSA3+TargetHsize*TargetVsize+(TargetHsize*TargetVsize/2);
rCICOCBSA1 = rCICOYSA1+TargetHsize*TargetVsize;
rCICOCBSA2 = rCICOYSA2+TargetHsize*TargetVsize;
rCICOCBSA3 = rCICOYSA3+TargetHsize*TargetVsize;
rCICOCBSA4 = rCICOYSA4+TargetHsize*TargetVsize;
rCICOCRSA1 = rCICOCBSA1+(TargetHsize*TargetVsize/4);
rCICOCRSA2 = rCICOCBSA2+(TargetHsize*TargetVsize/4);
rCICOCRSA3 = rCICOCBSA3+(TargetHsize*TargetVsize/4);
rCICOCRSA4 = rCICOCBSA4+(TargetHsize*TargetVsize/4);
} else { // OutFormat = YCBCR422
rCICOYSA1 = FrameBuffer;
rCICOYSA2 = rCICOYSA1+TargetHsize*TargetVsize*2;
rCICOYSA3 = rCICOYSA2+TargetHsize*TargetVsize*2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -