📄 camera.cpp
字号:
#include <windows.h>
#include <nkintr.h>
//#include <oalintr.h>
#include <pm.h>
#include "pmplatform.h"
#include <ceddk.h>
#include <s3c2440a.h>
#include <bsp.h>
#include "camif.h"
#include "camera.h"
#include "s5x532.h"
#define PM_MSG 0
#define I2C_MSG 0
#define MSG_EN_1 0
#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 S3C2440A_IOPORT_REG *s2440IOP = NULL;
volatile S3C2440A_CAM_REG *s2440CAM = NULL;
volatile S3C2440A_INTR_REG *s2440INT = NULL;
volatile S3C2440A_CLKPWR_REG *s2440PWR = 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)
//#define DRIVER_PREVIEW_ENABLE 2 // 0: onTimeTek, 1: Preview, 2:Samsung Camcorder
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_CAM; // Determined by SMDK2440 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 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 PrDstWidth, U32 PrDstHeight,
U32 WinHorOffset, U32 WinVerOffset, U32 CoFrameBuffer, U32 PrFrameBuffer);
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 = S3C2440A_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 ) {
RETAILMSG(1, (TEXT("I2CWrite ERROR: %u \r\n"), 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 (CIS_TYPE == CIS_S5X3A1)
for(i=0; i<(sizeof(S5X3A1_YCbCr8bit)/2); i++)
{
//HW_WriteRegisters(&S5X3A1_YCbCr8bit[i][1], S5X3A1_YCbCr8bit[i][0], 1);
HW_WriteRegisters(pCIS, &S5X3A1_YCbCr8bit[i][1], S5X3A1_YCbCr8bit[i][0], 1);
}
#elif (CIS_TYPE == CIS_S5X3AA)
for(i=0; i<(sizeof(S5X3AA_YCbCr8bit)/2); i++)
{
//HW_WriteRegisters(&S5X3AA_YCbCr8bit[i][1], S5X3AA_YCbCr8bit[i][0], 1);
HW_WriteRegisters(pCIS, &S5X3AA_YCbCr8bit[i][1], S5X3AA_YCbCr8bit[i][0], 1);
}
#endif
/*
for(i=0; i<(sizeof(S5X532_YCbCr8bit_TV)/2); i++){
RETAILMSG(I2C_MSG,(TEXT("num:%d "),i));
//Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
HW_WriteRegisters(pCIS, &S5X532_YCbCr8bit_TV[i][1], S5X532_YCbCr8bit_TV[i][0], 1);
//Sleep(1);
}
*/
#if 0
i = 0;
HW_WriteRegisters(pCIS, &S5X532_YCbCr8bit_TV[i][1], S5X532_YCbCr8bit_TV[i][0], 1);
do
{
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
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
s2440PWR->CAMDIVN = (s2440PWR->CAMDIVN & ~(0x1f)) | (1<<4) | (divide & 0xf); // CAMCLK is divided..
camclk = 48000000/(((s2440PWR->CAMDIVN&0xf) + 1)*2);
//RETAILMSG(1,(TEXT("CAM clock:%d\r\n"),camclk));
}
void Camif_Capture(int cap_a, int cap_b)
{
//RETAILMSG(1,(_T("Camif_Capture(%d, %d)\r\n"), cap_a, cap_b));
// S3C2440A
s2440CAM->CIIMGCPT &= ~(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT);
if(cap_b == CAPTURE_ON)
{
//Codec capture start
s2440CAM->CICOSCCTRL |=(CAM_CODEC_SACLER_START_BIT);
s2440CAM->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
else if (cap_b == CAPTURE_OFF)
{
s2440CAM->CICOSCCTRL &= ~(CAM_CODEC_SACLER_START_BIT);
s2440CAM->CIIMGCPT &= ~(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
if(cap_a == CAPTURE_ON)
{
// Preview capture Start
s2440CAM->CIPRSCCTRL |=(CAM_PVIEW_SACLER_START_BIT);
s2440CAM->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT);
}
else if (cap_a == CAPTURE_OFF)
{
s2440CAM->CIPRSCCTRL &= ~(CAM_PVIEW_SACLER_START_BIT);
s2440CAM->CIIMGCPT &= ~(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT);
}
if ((cap_a == CAPTURE_ON) || (cap_b == CAPTURE_ON))
{
s2440CAM->CIIMGCPT |= (CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT);
}
}
void CamInterface_PowerDown(void)
{
RETAILMSG(PM_MSG, (_T("CamInterface_PowerDown()\r\n")));
// Camera clock off
CamClockOn(FALSE);
// GPIO control
// for power down mode, gpio goes to input mode
s2440IOP->GPJCON = (s2440IOP->GPJCON & ~(0xffffff)) | 0x555555; // CAM IO setup except CAMRESET
s2440IOP->GPJDAT = s2440IOP->GPJDAT & ~(0xfff); // CAM IO DATA pin setup except CAMRESET
s2440IOP->GPJUP = (s2440IOP->GPJUP | 0xfff); // CAM IO PullUp setup except CAMRESET
//s2440IOP->GPJCON = (s2440IOP->GPJCON & ~(0x3<<22)) | (0x0<<22); // CAMCLKOUT -> input
}
void CamInterface_PowerUp(void)
{
RETAILMSG(PM_MSG, (_T("CamInterface_PowerUp()\r\n")));
// GPIO control
s2440IOP->GPJCON = (s2440IOP->GPJCON & ~(0xffffff)) | 0xaaaaaa; // CAM IO setup except CAMRESET
s2440IOP->GPJDAT = s2440IOP->GPJDAT & ~(0xfff); // CAM IO DATA pin setup except CAMRESET
s2440IOP->GPJUP = (s2440IOP->GPJUP | 0xfff); // CAM IO PullUp setup except CAMRESET
//s2440IOP->GPJCON = (s2440IOP->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)
{
RETAILMSG(0,(TEXT("[CAM_HW] InterruptThread : Waiting For a Single Object\n\r")));
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
s2440INT->INTSUBMSK &= ~(( 1 << IRQ_SUB_CAM_P )|( 1 << IRQ_SUB_CAM_C ));
s2440INT->INTMSK &= ~( 1 << IRQ_CAM );
continue;
}
#endif
if (dwCause == WAIT_OBJECT_0) // LJY PWR
{
Lock();
__try
{
if (s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_C ))
{
frame_count++;
cam_intr |= ( 1 << IRQ_SUB_CAM_C );
s2440INT->SUBSRCPND = (1<<IRQ_SUB_CAM_C);
s2440INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_C);
//RETAILMSG(1,(_T("CAM_C, ts %d\r\n"), GetTickCount()));
}
if (s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_P ))
{
cam_intr |= ( 1 << IRQ_SUB_CAM_P );
s2440INT->SUBSRCPND = (1<<IRQ_SUB_CAM_P);
s2440INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_P);
//RETAILMSG(1,(_T("CAM_P, ts %d\r\n"), GetTickCount()));
}
if (((s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_C )) == 0) && ((s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_P )) == 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_SUB_CAM_P ))
{
// display the image
if (DRIVER_PREVIEW_ENABLE == 1)
Display_Cam_Image(0,54,PREVIEW_X, PREVIEW_Y, PORT_A);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -