📄 camif.c
字号:
Uart_Printf("ERROR: out of the prescaler range: SrcSize/DstSize = %d(< 64)\n",SrcSize/DstSize);
while(1);
}
else if(SrcSize>=32*DstSize) {
*ratio=32;
*shift=5;
}
else if(SrcSize>=16*DstSize) {
*ratio=16;
*shift=4;
}
else if(SrcSize>=8*DstSize) {
*ratio=8;
*shift=3;
}
else if(SrcSize>=4*DstSize) {
*ratio=4;
*shift=2;
}
else if(SrcSize>=2*DstSize) {
*ratio=2;
*shift=1;
}
else {
*ratio=1;
*shift=0;
}
}
/********************************************************
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;
}
if(mode&CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT) {
camPviewStatus=CAM_STARTED;
rCIPRSCCTRL|=CAM_PVIEW_SACLER_START_BIT;
}
if(mode&CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT) {
camCodecStatus=CAM_STARTED;
rCICOSCCTRL|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT;
}
rCIIMGCPT|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|mode;
}
void CamCaptureStop(void)
{
camCodecStatus=CAM_STOP_ISSUED;
camPviewStatus=CAM_STOP_ISSUED;
}
void _CamCodecStopHw(void)
{
rCICOSCCTRL &= ~CAM_CODEC_SACLER_START_BIT; //stop codec scaler.
rCIIMGCPT &= ~CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT; //stop capturing for codec scaler.
if(!(rCIIMGCPT & CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT))
rCIIMGCPT &= ~CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT; //stop capturing for preview scaler if needed.
rCICOCTRL |= (1<<2); //Enable last IRQ at the end of frame capture.
//NOTE:LastIrqEn bit should be set after clearing CAPTURE_ENABLE_BIT & SCALER_START_BIT
}
void _CamPviewStopHw(void)
{
rCIPRSCCTRL &= ~CAM_PVIEW_SACLER_START_BIT; //stop preview scaler.
rCIIMGCPT &= ~CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT; //stop capturing for preview scaler.
if(!(rCIIMGCPT&CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT))
rCIIMGCPT &= ~CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT; //stop capturing for codec scaler if needed.
rCIPRCTRL |= (1<<2); //Enable last IRQ at the end of frame capture.
//NOTE:LastIrqEn bit should be set after clearing CAPTURE_ENABLE_BIT & SCALER_START_BIT
}
void __irq CamIsr(void)
{
U32 completedFrameIndex;
if (rSUBSRCPND&BIT_SUB_CAM_C)
{
//Uart_Printf("[C]");
rGPFDAT ^= 1<<5; //hzh
CamCodecIntMask();
rSUBSRCPND |= BIT_SUB_CAM_C;
ClearPending(BIT_CAM);
switch(camCodecStatus) {
case CAM_STOP_ISSUED:
_CamCodecStopHw();
camCodecStatus=CAM_LAST_CAPTURING;
Uart_Printf("cr=%x\n", rCICOCTRL);
//Uart_Printf("cS1\n");
break;
case CAM_LAST_CAPTURING:
camCodecStatus=CAM_STOPPED;
CamCodecIntMask();
//Uart_Printf("cS2\n");
return;
case CAM_STARTED:
flagCaptured_C = 1;
// _CamCodecStopHw();
if(camTestMode&CAM_TEST_MODE_CODEC) {
if(camCodecCaptureCount>0)
completedFrameIndex=(((rCICOSTATUS>>26)&0x3)+4-2)%4;
//Uart_Printf("FrameIndex:%d\n",completedFrameIndex);
}
else {
//Uart_Printf("Just Capturing without display");
}
break;
case CAM_CODEC_SCALER_BYPASS_STATE:
//Uart_Printf("cBP\n");
break;
default:
break;
}
CamCodecIntUnmask();
camCodecCaptureCount++;
}
else
{
//Uart_Printf("[P]");
rGPFDAT ^= 1<<4; //hzh
CamPreviewIntMask();
rSUBSRCPND |= BIT_SUB_CAM_P;
ClearPending(BIT_CAM) ;
switch(camPviewStatus) {
case CAM_STOP_ISSUED:
_CamPviewStopHw();
camPviewStatus=CAM_LAST_CAPTURING;
Uart_Printf("pr=%x\n", rCIPRCTRL);
//Uart_Printf("pS1\n");
break;
case CAM_LAST_CAPTURING:
camPviewStatus=CAM_STOPPED;
CamPreviewIntMask();
//Uart_Printf("pS2\n");
return;
case CAM_STARTED:
flagCaptured_P = 1;
if(camTestMode&CAM_TEST_MODE_PVIEW) {
if(camPviewCaptureCount >0)
completedFrameIndex=(((rCIPRSTATUS>>26)&0x3)+4-2)%4;
//Uart_Printf("FrameIndex:%d\n",completedFrameIndex);
}
else {
//Uart_Printf("Preview Image Captured\n");
}
default:
break;
}
CamPreviewIntUnmask();
camPviewCaptureCount++;
}
}
/******************************************************************************
* *
* camera interface interrupts & controls *
* *
******************************************************************************/
U32 Conv_YCbCr_Rgb(U8 y0, U8 y1, U8 cb0, U8 cr0) // second solution... by junon
{
// bit order is
// YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0].
int r0, g0, b0, r1, g1, b1;
U32 rgb0, rgb1, rgb;
#if 1 // 4 frames/s @192MHz, 12MHz ; 6 frames/s @450MHz, 12MHz
r0 = YCbCrtoR(y0, cb0, cr0);
g0 = YCbCrtoG(y0, cb0, cr0);
b0 = YCbCrtoB(y0, cb0, cr0);
r1 = YCbCrtoR(y1, cb0, cr0);
g1 = YCbCrtoG(y1, cb0, cr0);
b1 = YCbCrtoB(y1, cb0, cr0);
#endif
if (r0>255 ) r0 = 255;
if (r0<0) r0 = 0;
if (g0>255 ) g0 = 255;
if (g0<0) g0 = 0;
if (b0>255 ) b0 = 255;
if (b0<0) b0 = 0;
if (r1>255 ) r1 = 255;
if (r1<0) r1 = 0;
if (g1>255 ) g1 = 255;
if (g1<0) g1 = 0;
if (b1>255 ) b1 = 255;
if (b1<0) b1 = 0;
// 5:6:5 16bit format
rgb0 = (((U16)r0>>3)<<11) | (((U16)g0>>2)<<5) | (((U16)b0>>3)<<0); //RGB565.
rgb1 = (((U16)r1>>3)<<11) | (((U16)g1>>2)<<5) | (((U16)b1>>3)<<0); //RGB565.
rgb = (rgb1<<16) | rgb0;
return(rgb);
}
void Display_Cam_Image(U32 size_x, U32 size_y)
{
U8 *buffer_y, *buffer_cb, *buffer_cr;
U8 y0,y1,cb0,cr0;
int r0,r1,g0,g1,b0,b1;
U32 rgb_data0, rgb_data1;
U32 x, y;
int temp;
if (CAM_CODEC_4PP)
temp = (((rCICOSTATUS>>26)&0x3)+4-2)%4; // current frame memory block
else
temp = 4;
//Uart_Printf("Current Frame memory %d\n", temp);
switch (temp) // current frame mem - 2
{
case 0:
buffer_y = (U8 *)rCICOYSA1;
buffer_cb = (U8 *)rCICOCBSA1;
buffer_cr = (U8 *)rCICOCRSA1;
break;
case 1:
buffer_y = (U8 *)rCICOYSA2;
buffer_cb = (U8 *)rCICOCBSA2;
buffer_cr = (U8 *)rCICOCRSA2;
break;
case 2:
buffer_y = (U8 *)rCICOYSA3;
buffer_cb = (U8 *)rCICOCBSA3;
buffer_cr = (U8 *)rCICOCRSA3;
break;
case 3:
buffer_y = (U8 *)rCICOYSA4;
buffer_cb = (U8 *)rCICOCBSA4;
buffer_cr = (U8 *)rCICOCRSA4;
break;
default :
buffer_y = (U8 *)rCICOYSA1;
buffer_cb = (U8 *)rCICOCBSA1;
buffer_cr = (U8 *)rCICOCRSA1;
break;
}
//Uart_Printf("End setting : Y-0x%x, Cb-0x%x, Cr-0x%x\n", buffer_y, buffer_cb, buffer_cr);
#if 0
// for checking converting time
rGPGCON = (rGPGCON&~(1<<23))|(1<<22); //EINT19 -> GPG11 output
rGPGUP |= (1<<11);
rGPGDAT &= ~(1<<11);
Delay(90);
rGPGDAT |=(1<<11);
rgb_data0 = 0;
#endif
#if CAM_CODEC_OUTPUT==CAM_CCIR420
for (y=0;y<size_y;y++) // YCbCr 4:2:0 format
{
for (x=0;x<size_x;x+=2)
{
rgb_data0 = Conv_YCbCr_Rgb(*buffer_y++, *buffer_y++, *buffer_cb++, *buffer_cr++);
frameBuffer16BitTft240320[y][x/2] = rgb_data0;
if ( (x==(size_x-2)) && ((y%2)==0) ) // when x is last pixel & y is even number
{
buffer_cb -= size_x/2;
buffer_cr -= size_x/2;
}
}
}
#else
for (y=0;y<size_y;y++) // YCbCr 4:2:2 format
{
for (x=0;x<size_x;x+=2)
{
rgb_data0 = Conv_YCbCr_Rgb(*buffer_y++, *buffer_y++, *buffer_cb++, *buffer_cr++);
//frameBuffer16BitTft240320[y][x/2] = rgb_data0;
//--- hzh
//frameBuffer16BitTft240320是32位的数组!!!
//in HWSWP=1 16BPP mode d0~d15 is 1st pixel, d16~d31 is 2nd
//in HWSWP=0 16BPP mode d0~d15 is 2nd pixel, d16~d31 is 1st
// U16 lt;
//Uart_Printf("%x,%x\n", *buffer_cb, *buffer_cr);
//测试只输出Y(亮度)
// lt = (*buffer_y++)>>3;
// rgb_data0 = ((lt<<11)|(lt<<5)|(lt))<<16; //1st pixel
// lt = (*buffer_y++)>>3;
// rgb_data0 |= (lt<<11)|(lt<<5)|(lt); //2nd pixel
//测试只输出U
// lt = (*buffer_cb)>>3;
// rgb_data0 = ((lt<<11)|(lt<<5)|(lt))<<16; //1st pixel
// lt = (*buffer_cb++)>>3;
// rgb_data0 |= (lt<<11)|(lt<<5)|(lt); //2nd pixel
//测试只输出V
// lt = (*buffer_cr)>>3;
// rgb_data0 = ((lt<<11)|(lt<<5)|(lt))<<16; //1st pixel
// lt = (*buffer_cr++)>>3;
// rgb_data0 |= (lt<<11)|(lt<<5)|(lt); //2nd pixel
//测试ov9650固定输出U=0x1f,V=0x70的模式
// rgb_data0 = *buffer_y++<<24; //1st pixel
// rgb_data0 |= *buffer_cb++<<16;
// rgb_data0 |= *buffer_y++<<8; //2nd pixel
// rgb_data0 |= *buffer_cr++;
// rgb_data0 &= ~0xff00f800;
// rgb_data0 |= 0x0700;
//测试ov9650输出RGB565格式
// rgb_data0 = *buffer_y++<<24; //1st pixel
// rgb_data0 |= *buffer_cb++<<16;
// rgb_data0 |= *buffer_y++<<8; //2nd pixel
// rgb_data0 |= *buffer_cr++;
//RGB高低交换
// rgb_data0 = *buffer_cb++<<24; //1st pixel
// rgb_data0 |= *buffer_y++<<16;
// rgb_data0 |= *buffer_cr++<<8; //2nd pixel
// rgb_data0 |= *buffer_y++;
// rgb_data0 &= 0xf800f800; //red only
// rgb_data0 &= 0x07e007e0; //green only
// rgb_data0 &= 0x001f001f; //blue only
LCD_BUFFER_CAM[y][x/2] = rgb_data0;
//Uart_Printf("%08x\n", rgb_data0);
//---
}
}
#endif
// memcpy((unsigned char*)0x30100000, frameBuffer16BitTft240320, 320*240*2); // QCIF=178*144*2
#if 0
rGPGDAT &= ~(1<<11);
Delay(30);
rGPGDAT |=(1<<11);
rGPGCON = (rGPGCON&~(1<<22))|(1<<23); // GPG11 output -> EINT19
#endif
}
#if 0
void Display_Cam_Image(int offset_x, int offset_y, int size_x, int size_y)
{
U8* CamFrameAddr, LcdFrameAddr;
int i, temp;
Lcd_MoveViewPort(offset_x, offset_y, USED_LCD_TYPE);
switch(camPviewCaptureCount%4)
{
case 2 :
temp = rCIPRCLRSA1;
break;
case 3 :
temp = rCIPRCLRSA2;
break;
case 0 :
temp = rCIPRCLRSA3;
break;
case 1 :
default:
temp = rCIPRCLRSA4;
break;
}
*CamFrameAddr = temp;
*LcdFrameAddr = LCD_BUFFER_CAM;
for(i=0;i<size_y;i++)
{
memcpy(LcdFrameAddr, CamFrameAddr, size_x*2);
*LcdFrameAddr += size_x*4; // added virtual screen
*CamFrameAddr += size_x*2;
}
}
#endif
void Test_CamPreview(void)
{
U8 flag;
U32 i,j,k,value;
Uart_Printf("\nNow Start Camera Preview\n");
//camera global variables
camTestMode=CAM_TEST_MODE_PVIEW;
camCodecCaptureCount=0;
camPviewCaptureCount=0;
camPviewStatus=CAM_STOPPED;
camCodecStatus=CAM_STOPPED;
flagCaptured_P=0;
LCD_LTS350Q1_PE1_Init() ;
//Uart_Printf( "Any key to continue...\n" ) ; Uart_Getch() ;
/*
for( i = 0 ; i < SCR_YSIZE_TFT_240320 ; i++ )
{
for( j = 0 ; j < SCR_XSIZE_TFT_240320 ; j++ )
{
if( j<81 ) LCD_BUFFER_CAM[i][j] = 0x001f ; //blue
else if ( (j>80) && (j<161) ) LCD_BUFFER_CAM[i][j] = 0x07e0; //green
else if ( j>160 ) LCD_BUFFER_CAM[i][j] = 0xf800; //red
}
}
*/
// Paint_Bmp( 0, 0, 240, 320, xyx_240_320 ) ;
//Paint_Bmp(220,0,240,320,ucdragon_240_100);
Paint_Bmp(0,100,240,320,ucdragon_240_100);
Uart_Printf( "preview sc control = %x\n" , rCIPRSCCTRL ) ;
// Initialize Camera interface
switch(USED_CAM_TYPE)
{
case CAM_S5X532 : // defualt for test : data-falling edge, ITU601, YCbCr
CamInit(640, 480, 240, 320, 112, 20, CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
break;
case CAM_S5X3A1 : // defualt for test : data-falling edge, YCbCr
CamInit(640, 480, 240, 320, 120, 100, CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
rCISRCFMT = rCISRCFMT & ~(1<<31); // ITU656
// rCIGCTRL &= ~(1<<26); // inverse PCLK, test pattern
break;
//--- add by hzh
case CAM_OV7620:
CamInit(640, 480, 240, 180, 0, 0, CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
break;
//---
default :
CamInit(640, 480, 240, 320, 0, 0, CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
break;
}
Uart_Printf("preview sc control = %x\n", rCIPRSCCTRL);
// Start Capture
rSUBSRCPND |= BIT_SUB_CAM_C|BIT_SUB_CAM_P;
ClearPending(BIT_CAM);
pISR_CAM = (U32)CamIsr;
CamPreviewIntUnmask();
CamCaptureStart(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT);
Uart_Printf("Press 'ESC' key to exit!\n");
while (1)
{
if (flagCaptured_P)
{
flagCaptured_P = 0;
// Uart_Printf("Enter Cam A port, count = %d\n",camCodecCaptureCount);
}
if ( Uart_GetKey() == ESC_KEY ) break;
}
CamCaptureStop();
Uart_Printf("\nWait until the current frame capture is completed.\n");
while(camPviewStatus!=CAM_STOPPED)
if (Uart_GetKey()== '\r') break;
Uart_Printf("CIS format = %x\n", rCISRCFMT);
Uart_Printf("image cap = %x\n", rCIIMGCPT);
Uart_Printf("preview sc control = %x\n", rCIPRSCCTRL);
Uart_Printf("preview control = %x\n", rCIPRCTRL);
Uart_Printf("codec sc control = %x\n", rCICOSCCTRL);
Uart_Printf("codec control = %x\n", rCICOCTRL);
Uart_Printf("pr addr1 = %x\n", rCIPRCLRSA1);
Uart_Printf("pr addr2 = %x\n", rCIPRCLRSA2);
Uart_Printf("camCodecCaptureCount=%d\n",camCodecCaptureCount);
Uart_Printf("camPviewCaptureCount=%d\n",camPviewCaptureCount);
// CamPreviewIntMask();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -