📄 camera.cpp
字号:
#include <windows.h>
#include <nkintr.h>
//#include <oalintr.h>
#include <pm.h>
#include "pmplatform.h"
#include <ceddk.h>
#include <s3c2413.h>
#include <bsp.h>
#include "camif.h"
#include "camera.h"
#include "s5x532.h"
#define PM_MSG 1
#define I2C_MSG 1
#define MSG_EN_1 1
#define MSG_EN_2 0
#define CAPTURE_TIME 30
#define CAM_CLOCK_OFF_ON_IDLE 1
#if (CAM_CLOCK_OFF_ON_IDLE == 1)
#define DISPLAY_THREAD_TIMEOUT 3000
#else
#define DISPLAY_THREAD_TIMEOUT INFINITE
#endif
#define U8 unsigned char
#define U16 unsigned short
#define U32 unsigned int
#define PORT_A 1
#define PORT_B 0
#define YCbCrtoR(Y,Cb,Cr) (1000*Y + 1540*(Cr-128))/1000
#define YCbCrtoG(Y,Cb,Cr) (1000*Y - 459*(Cb-128) - 183*(Cr-128))/1000
#define YCbCrtoB(Y,Cb,Cr) (1000*Y + 1856*(Cb-128))/1000
volatile S3C2413_IOPORT_REG *s2413IOP = NULL;
volatile S3C2413_CAM_REG *s2413CAM = NULL;
volatile S3C2413_INTR_REG *s2413INT = NULL;
volatile S3C2413_CLKPWR_REG *s2413PWR = NULL;
unsigned int dwDisplayTimeout = DISPLAY_THREAD_TIMEOUT;
BOOL bIdlePwrDown = FALSE;
unsigned char buffer_num=0xff; // ping pong buffer
//unsigned char image_size = 2; // 1: QCIF, 2:CIF (default)
unsigned char image_size = 1; // 1: QCIF, 2:CIF (default) by PHJ
unsigned char DRIVER_PREVIEW_ENABLE = 1; // 0: onTimeTek, 1: Preview, 2:Samsung Camcorder
unsigned int frame_count=0; // for MPEG4
DWORD Tick_GET_FRAME_CUR;
DWORD Tick_GET_FRAME_PREV;
DWORD Tick_COPY_FRAME;
CAMINFO sCAMINFO;
UINT32 g_CamIrq = IRQ_CAMIF; // Determined by SMDK2413 board layout.
UINT32 g_CamSysIntr = SYSINTR_UNDEFINED;
HANDLE CameraThread;
HANDLE CameraEvent;
static BOOL mInitialized = FALSE;
unsigned char codec_flag=0;
unsigned char rgb_flag=0;
unsigned int y_address,cb_address,cr_address;
unsigned int rgb_address;
// PingPong Memory Physical Address
PHYSICAL_ADDRESS g_PhysPreviewAddr;
PHYSICAL_ADDRESS g_PhysCodecAddr;
void CAM_WriteBlock(void);
void Virtual_Alloc(); // Virtual allocation
void Camera_Clock(unsigned char divide); // set default value
//void Camif_Capture(int cap_a, int cap_b); // A port, B port
void Camif_Capture(int cap_a ); // A port, B port
void Display_Cam_Image(U32 pos_x, U32 pos_y, U32 size_x, U32 size_y, U8 port);
void Display_Cam_Image2(U32 size_x, U32 size_y, U8 port);
void Copy_Cam_Image(U8 * pBufOut, U32 size_x, U32 size_y, U8 port);
void Samsung_camcoder(U8 *pBufOut);
void Samsung_camcoder_pr(U8 *pBufOut);
void Buffer_codec_info_update();
void Buffer_preview_info_update();
BOOL Cam_Init();
BOOL CamClockOn(BOOL bOnOff);
void CamInit(U32 CoDstWidth, U32 CoDstHeight, U32 WinHorOffset, U32 WinVerOffset, U32 CoFrameBuffer);
DWORD CameraCaptureThread(void);
BOOL InitInterruptThread();
CEDEVICE_POWER_STATE m_Dx;
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("CAMERA"), {
TEXT("0"),TEXT("1"),TEXT("2"),TEXT("3"),
TEXT("4"),TEXT("5"),TEXT("6"),TEXT("7"),
TEXT("8"),TEXT("9"),TEXT("10"),TEXT("11"),
TEXT("12"),TEXT("Function"),TEXT("Init"),TEXT("Error")},
0x8000 // Errors only, by default
};
#endif
PCIS_CONTEXT pCIS;
CRITICAL_SECTION m_Lock;
void Lock() {EnterCriticalSection(&m_Lock);}
void Unlock() {LeaveCriticalSection(&m_Lock);}
static void Delay(USHORT count)
{
volatile int i, j = 0;
volatile static int loop = S3C2413_FCLK/100000;
for(;count > 0;count--)
for(i=0;i < loop; i++) { j++; }
}
//
// Read PCF50606 registers directly into our cache
//
DWORD
HW_ReadRegisters(
PCIS_CONTEXT pCIS,
PUCHAR pBuff, // Optional buffer
UCHAR StartReg, // Start Register
DWORD nRegs // Number of Registers
)
{
DWORD dwErr;
EnterCriticalSection(&pCIS->RegCS);
// use the driver-to-driver call
dwErr = pCIS->fc.I2CRead(pCIS->fc.Context,
CAMERA_READ, // SlaveAddress
StartReg, // WordAddress
!pBuff ? (PUCHAR)&pCIS->Reg[StartReg] : pBuff,
nRegs);
if ( !dwErr ) {
} else {
RETAILMSG(1,(TEXT("I2CRead ERROR: %u \r\n"), dwErr));
//DEBUGMSG(ZONE_ERR,(TEXT("I2CRead ERROR: %u \r\n"), dwErr));
}
LeaveCriticalSection(&pCIS->RegCS);
return dwErr;
}
//
// Write PCF50606 registers directly from our cache
//
DWORD
HW_WriteRegisters(
PCIS_CONTEXT pCIS,
PUCHAR pBuff, // Optional buffer
UCHAR StartReg, // start register
DWORD nRegs // number of registers
)
{
DWORD dwErr;
EnterCriticalSection(&pCIS->RegCS);
// use the driver-to-driver call
dwErr = pCIS->fc.I2CWrite(pCIS->fc.Context,
CAMERA_WRITE, // SlaveAddress
StartReg, // WordAddress
!pBuff ? (PUCHAR)&pCIS->Reg[StartReg] : pBuff,
nRegs);
if ( dwErr ) {
//DEBUGMSG(ZONE_ERR, (TEXT("I2CWrite ERROR: %u \r\n"), dwErr));
}
LeaveCriticalSection(&pCIS->RegCS);
return dwErr;
}
void CAM_WriteBlock(void)
{
int i;
unsigned char rdata[256] = { 0, };
//int err = 0;
#if 1
for(i=0; i<(sizeof(S5X532_YCbCr8bit_TV)/2); i++){
RETAILMSG(0,(TEXT("num:%d "),i));
HW_WriteRegisters(pCIS, &S5X532_YCbCr8bit_TV[i][1], S5X532_YCbCr8bit_TV[i][0], 1);
// RETAILMSG(1, (TEXT("DATA : %xh"), S5X532_YCbCr8bit_TV[i][1]));
Sleep(1);
}
#if 0
i = 0;
HW_WriteRegisters(pCIS, &S5X532_YCbCr8bit_TV[i][1], S5X532_YCbCr8bit_TV[i][0], 1);
do
{
// RETAILMSG(1, (TEXT("WData[%d] = 0x% "), i, S5X532_YCbCr8bit_TV[i][1]));
i++;
HW_ReadRegisters(pCIS, &rdata[i], S5X532_YCbCr8bit_TV[i][0], 1);
RETAILMSG(1,(_T("rdata[%d] = 0x%X\r\n"), i, rdata[i]));
Sleep(1);
} while (i < 10);
#endif
#endif
RETAILMSG(1,(TEXT("Camera::Block TX Ended...\r\n")));
}
/********************************************************
CalculateBurstSize - Calculate the busrt lengths
Description:
- dstHSize: the number of the byte of H Size.
*/
void CalculateBurstSize(unsigned int hSize,unsigned int *mainBurstSize,unsigned int *remainedBurstSize)
{
unsigned int 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;
switch(tmp) {
case 0:
*mainBurstSize=8;
*remainedBurstSize=8;
break;
case 4:
*mainBurstSize=8;
*remainedBurstSize=4;
default:
*mainBurstSize=4;
tmp=(hSize/4)%4;
*remainedBurstSize= (tmp) ? tmp: 4;
break;
}
break;
}
}
/********************************************************
CalculatePrescalerRatioShift - none
Description:
- none
*/
void CalculatePrescalerRatioShift(unsigned int SrcSize, unsigned int DstSize, unsigned int *ratio,unsigned int *shift)
{
if(SrcSize>=64*DstSize) {
// Uart_Printf("ERROR: out of the prescaler range: SrcSize/DstSize = %d(< 64)\r\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;
}
}
void Camera_Clock(unsigned char divide)
{
unsigned int camclk;
// Set camera clock for camera processor
pCIS->pPWRRegs->CLKDIVN = (pCIS->pPWRRegs->CLKDIVN & ~(0xf<<16)) | (divide << 16); // CAMCLK is divided..
// camclk = 48000000/((pCIS->pPWRRegs->CLKDIVN&(0xf<<16)) + 1);
// jylee_20051104
camclk = 96000000/(((pCIS->pPWRRegs->CLKDIVN>>16)&0xf) + 1);
// RETAILMSG(1, (TEXT("Camera_clock : CLKDIVN = 0x%x, CAMCLK = %d\n"), pCIS->pPWRRegs->CLKDIVN, camclk));
// jylee_20051104
RETAILMSG(1, (TEXT("Camera_clock : CLKDIVN[19..16] = 0x%x, CAMCLK = %d\n"), (pCIS->pPWRRegs->CLKDIVN>>16)&0xf, camclk));
}
void Camif_Capture(int cap_a )
{
//RETAILMSG(1,(_T("Camif_Capture(%d )\r\n"), cap_a ));
// S3C2413A
pCIS->pCAMRegs->CIIMGCPT &= ~(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT);
// case 2440
/* if(cap_b == CAPTURE_ON)
{
//Codec capture start
s2413CAM->CICOSCCTRL |=(CAM_CODEC_SACLER_START_BIT);
s2413CAM->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
else if (cap_b == CAPTURE_OFF)
{
s2413CAM->CICOSCCTRL &= ~(CAM_CODEC_SACLER_START_BIT);
s2413CAM->CIIMGCPT &= ~(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
*/
if(cap_a == CAPTURE_ON)
{
// Preview capture Start
pCIS->pCAMRegs->CICOSCCTRL |=(CAM_CODEC_SACLER_START_BIT);
// pCIS->pCAMRegs->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
pCIS->pCAMRegs->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
else if (cap_a == CAPTURE_OFF)
{
pCIS->pCAMRegs->CICOSCCTRL &= ~(CAM_CODEC_SACLER_START_BIT);
pCIS->pCAMRegs->CIIMGCPT &= ~(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
}
void CamInterface_PowerDown(void)
{
// Camera clock off
CamClockOn(FALSE);
// GPIO control
// for power down mode, gpio goes to input mode
pCIS->pIORegs->GPJCON = (pCIS->pIORegs->GPJCON & ~(0xffffff)) | 0x555555; // CAM IO setup except CAMRESET
pCIS->pIORegs->GPJDAT = pCIS->pIORegs->GPJDAT & ~(0xfff); // CAM IO DATA pin setup except CAMRESET
pCIS->pIORegs->GPJDN = (pCIS->pIORegs->GPJDN | 0xfff); // CAM IO PullUp setup except CAMRESET
//pCIS->pIOReg->GPJCON = (pCIS->pIOReg->GPJCON & ~(0x3<<22)) | (0x0<<22); // CAMCLKOUT -> input
}
void CamInterface_PowerUp(void)
{
RETAILMSG(PM_MSG, (_T("CamInterface_PowerUp()\r\n")));
// GPIO control
pCIS->pIORegs->GPJCON = (pCIS->pIORegs->GPJCON & ~(0xffffff)) | 0xaaaaaa; // CAM IO setup except CAMRESET
pCIS->pIORegs->GPJDAT = pCIS->pIORegs->GPJDAT & ~(0xfff); // CAM IO DATA pin setup except CAMRESET
pCIS->pIORegs->GPJDN = (pCIS->pIORegs->GPJDN | 0xfff); // CAM IO PullUp setup except CAMRESET
//pCIS->pIOReg->GPJCON = (pCIS->pIOReg->GPJCON & ~(0x3<<22)) | (0x2<<22); // CAMCLKOUT -> input
Delay(10);
// Camera clock on
CamClockOn(TRUE);
Delay(100);
}
DWORD CameraCaptureThread(void)
{
unsigned char tmp=0;
static unsigned int time,old_time;
static unsigned int cam_intr;
DWORD dwCause; // LJY PWR040613
//dwDisplayTimeout = INFINITE;
SetProcPermissions((DWORD)-1);
while(TRUE)
{
dwCause = WaitForSingleObject(CameraEvent, dwDisplayTimeout);
// RETAILMSG(MSG_EN_1,(_T("CameraCaptureThread(%d)++\r\n"), frame_count));
#if 0
if (frame_count <= 2) {
//frame_count++;
// Enable camera interrupt
s2413INT->INTSUBMSK &= ~(( 1 << IRQ_SUB_CAM_P )|( 1 << IRQ_SUB_CAM_C ));
s2413INT->INTMSK &= ~( 1 << IRQ_CAM );
continue;
}
#endif
if (dwCause == WAIT_OBJECT_0) // LJY PWR
{
Lock();
__try
{
if (pCIS->pINTRegs->INTMSK & ( 1 << IRQ_CAMIF))
{
frame_count++;
cam_intr |= ( 1 << IRQ_CAMIF );
pCIS->pINTRegs->SRCPND = (1<<IRQ_CAMIF);
pCIS->pINTRegs->INTMSK &= ~(1<<IRQ_CAMIF);
//RETAILMSG(1,(_T("CAM_C, ts %d\r\n"), GetTickCount()));
}
if ((pCIS->pINTRegs->INTMSK & ( 1 << IRQ_CAMIF )) == 0)
{
// RETAILMSG(MSG_EN_1,(_T("[CAM]NOP\r\n")));
}
InterruptDone(g_CamSysIntr);
//time = GetTickCount();
//RETAILMSG(1,(TEXT("+time:%d\r\n"),(time - old_time)));
// Handle any interrupts on the input source
if (cam_intr & ( 1 << IRQ_CAMIF ))
{
// display the image
if (DRIVER_PREVIEW_ENABLE == 1)
Display_Cam_Image(0,54,PREVIEW_X, PREVIEW_Y, PORT_A);
// Display_Cam_Image(0,54,QCIF_XSIZE, QCIF_YSIZE, PORT_A);
// Buffer_preview_info_update();
cam_intr &= ~( 1 << IRQ_CAMIF );
// Delay(1);
}
// case 2440
/*
if (cam_intr & ( 1 << IRQ_SUB_CAM_C ))
{
Buffer_codec_info_update();
cam_intr &= ~( 1 << IRQ_SUB_CAM_C );
}
*/
// Enable camera interrupt
//s2413INT->INTSUBMSK &= ~(( 1 << IRQ_SUB_CAM_P )|( 1 << IRQ_SUB_CAM_C ));
//s2413INT->INTMSK &= ~( 1 << IRQ_CAM );
//old_time = GetTickCount();
//RETAILMSG(1,(TEXT("-time:%d\r\n"),(old_time-time)));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RETAILMSG(PM_MSG, (TEXT("Camera.DLL:InterruptThread() - EXCEPTION: %d"), GetExceptionCode()));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -