📄 camera.cpp
字号:
#include <windows.h>
#include <nkintr.h>
#include <oal_intr.h>
//#include <p2.h>
#include <pm.h>
#include "pmplatform.h"
#include "image_cfg.h"
#include "s3c24A0.h"
#include "camif.h"
#include "camera.h"
#include "s3c24a0_camera.h"
#define MSG_EN_1 0
#define MSG_EN_2 0
//#define RETAILMSG(a,b) RETAILMSG(RETAIL_ON,b)
#define DOTNET_DRIVER 1 // 0:PPC, 1:CE.NET
#define CAPTURE_TIME 30
#define DISPLAY_SCHEDULE 0
#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
#ifdef DEBUG
#define DBG_INIT 0x0001
#define DBG_OPEN 0x0002
#define DBG_READ 0x0004
#define DBG_WRITE 0x0008
#define DBG_CLOSE 0x0010
#define DBG_IOCTL 0x0020
#define DBG_THREAD 0x0040
#define DBG_EVENTS 0x0080
#define DBG_CRITSEC 0x0100
#define DBG_FLOW 0x0200
#define DBG_IR 0x0400
#define DBG_NOTHING 0x0800
#define DBG_ALLOC 0x1000
#define DBG_FUNCTION 0x2000
#define DBG_WARNING 0x4000
#define DBG_ERROR 0x8000
DBGPARAM dpCurSettings = {
TEXT("Camera"), {
TEXT("Init"),TEXT("Open"),TEXT("Read"),TEXT("Write"),
TEXT("Close"),TEXT("Ioctl"),TEXT("Thread"),TEXT("Events"),
TEXT("CritSec"),TEXT("FlowCtrl"),TEXT("Infrared"),TEXT("User Read"),
TEXT("Alloc"),TEXT("Function"),TEXT("Warning"),TEXT("Error")}, 0
};
#define ZONE_INIT DEBUGZONE(0)
#define ZONE_OPEN DEBUGZONE(1)
#define ZONE_READ DEBUGZONE(2)
#define ZONE_WRITE DEBUGZONE(3)
#define ZONE_CLOSE DEBUGZONE(4)
//#define ZONE_IOCTL DEBUGZONE(5)
#define ZONE_THREAD DEBUGZONE(6)
#define ZONE_EVENTS DEBUGZONE(7)
#define ZONE_CRITSEC DEBUGZONE(8)
#define ZONE_FLOW DEBUGZONE(9)
#define ZONE_IR DEBUGZONE(10)
#define ZONE_USR_READ DEBUGZONE(11)
#define ZONE_ALLOC DEBUGZONE(12)
#define ZONE_FUNCTION DEBUGZONE(13)
#define ZONE_WARN DEBUGZONE(14)
#define ZONE_ERROR DEBUGZONE(15)
#endif //DEBUG
volatile S3C24A0_IOPORT_REG *s24A0IOP = (S3C24A0_IOPORT_REG *)S3C24A0_BASE_REG_PA_IOPORT;
volatile S3C24A0_CAM_REG *s24A0CAM = (S3C24A0_CAM_REG *)S3C24A0_BASE_REG_PA_CAM;
volatile S3C24A0_INTR_REG *s24A0INT = (S3C24A0_INTR_REG *)S3C24A0_BASE_REG_PA_INTR;
volatile S3C24A0_CLKPWR_REG *s24A0PWR = (S3C24A0_CLKPWR_REG *)S3C24A0_BASE_REG_PA_CLOCK_POWER;
volatile S3C24A0_IICBUS_REG *s24A0IIC = (S3C24A0_IICBUS_REG *)S3C24A0_BASE_REG_PA_IICBUS;
static BOOL bPowered = FALSE;
static BOOL bClosed = TRUE;
unsigned int DisplayTime = INFINITE;
//unsigned char DisplayEnable=0;
//unsigned char buffer_num = 0xff; // ping pong buffer
unsigned char image_size = 2; // 1: QCIF, 2:CIF (default)
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;
HANDLE CameraThread;
HANDLE CameraEvent;
static BOOL mInitialized = FALSE;
DWORD gIntrCamera = SYSINTR_NOP;
unsigned char codec_flag =0;
unsigned char rgb_flag =0;
unsigned int y_address,cb_address,cr_address;
unsigned int rgb_address;
extern void Camera_Initialize();
extern void CamIIC_open(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 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 CamClockOn(BOOL bOnOff);
void CAM_WriteBlock();
void CamInit(U32 CoDstWidth, U32 CoDstHeight, U32 PrDstWidth, U32 PrDstHeight,
U32 WinHorOffset, U32 WinVerOffset, U32 CoFrameBuffer, U32 PrFrameBuffer);
DWORD CameraCaptureThread(LPVOID pvParam);
BOOL InitInterruptThread();
//Added by APR on 26 May 2004 for power management
#define RETAIL_ON 1
#define CAM_ACTIVITY_EVENT _T("PmActivityEvent_Camera")
#define CAM_ACTIVITY_KILL_EVENT _T("PmKillActivityEvent_Camera")
#define DEVICE_ACTIVITY_TIMEOUT 60000 //the time in milliseconds that the activity thread should wait
static CEDEVICE_POWER_STATE sCurrentDx;
#define LOCK(p) EnterCriticalSection(&((p)->csDevice));
#define UNLOCK(p) LeaveCriticalSection(&((p)->csDevice));
BOOL ActivateCamera(DWORD dwDeviceContext);
BOOL StartActivityThread(PCAM_INFO pCamInfo);
//
//CEDEVICE_POWER_STATE m_Dx;
PVOID Cam_RegAlloc(PVOID addr, INT sz)
{
PVOID reg;
reg = (PVOID)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_NOACCESS);
if (reg)
{
if (!VirtualCopy(reg, (PVOID)((UINT32)addr >> 8), sz, PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE ))
{
VirtualFree(reg, sz, MEM_RELEASE);
reg = NULL;
}
}
return reg;
}
static void Delay(USHORT count)
{
volatile int i, j = 0;
volatile static int loop = S3C24A0_FCLK/100000;
for(;count > 0;count--)
for(i=0;i < loop; i++) { j++; }
}
/********************************************************
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
s24A0PWR->CLKDIVN = (s24A0PWR->CLKDIVN & ~(0xf00)) | (divide << 8); // CAMCLK is divided..
camclk = 96000000L/(((s24A0PWR->CLKDIVN >> 8) & 0xf) + 1);
RETAILMSG(RETAIL_ON,(TEXT("CAM clock:%d\r\n"), camclk));
}
void Camif_Capture(int cap_a, int cap_b)
{
RETAILMSG(RETAIL_ON,(_T("Camif_Capture(%d, %d)\r\n"), cap_a, cap_b));
// S3C24A0A
s24A0CAM->CIIMGCPT &= ~(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT); //|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT)|(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT));
if(cap_b == CAPTURE_ON)
{
//Codec capture start
s24A0CAM->CICOSCCTRL |=(CAM_CODEC_SCALER_START_BIT);
s24A0CAM->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
else if (cap_b == CAPTURE_OFF)
{
s24A0CAM->CICOSCCTRL &= ~(CAM_CODEC_SCALER_START_BIT);
s24A0CAM->CIIMGCPT &= ~(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
}
if(cap_a == CAPTURE_ON)
{
RETAILMSG(RETAIL_ON,(TEXT("s24A0CAM->CIPRSCCTRL before = 0x%x\r\n"),s24A0CAM->CIPRSCCTRL));
// Preview capture Start
s24A0CAM->CIPRSCCTRL |= CAM_PVIEW_SCALER_START_BIT;
s24A0CAM->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT);
RETAILMSG(RETAIL_ON,(TEXT("s24A0CAM->CIPRSCCTRL after = 0x%x\r\n"),s24A0CAM->CIPRSCCTRL));
}
else if (cap_a == CAPTURE_OFF)
{
s24A0CAM->CIPRSCCTRL &= ~(CAM_PVIEW_SCALER_START_BIT);
s24A0CAM->CIIMGCPT &= ~(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT);
}
if ((cap_a == CAPTURE_ON) || (cap_b == CAPTURE_ON))
{
s24A0CAM->CIIMGCPT |= (CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT);
}
RETAILMSG(RETAIL_ON,(TEXT("s24A0CAM->CICOSCCTRL 0x%x\r\n"),s24A0CAM->CICOSCCTRL));
RETAILMSG(RETAIL_ON,(TEXT("s24A0CAM->CIPRSCCTRL 0x%x\r\n"),s24A0CAM->CIPRSCCTRL));
RETAILMSG(RETAIL_ON,(TEXT("s24A0CAM->CIIMGCPT 0x%x\r\n"),s24A0CAM->CIIMGCPT));
}
DWORD CameraCaptureThread(LPVOID pvParam)
{
unsigned char tmp=0;
static unsigned int time,old_time;
static unsigned int cam_intr;
//Added by APR 26 May 2004
PCAM_INFO pCamInf = (PCAM_INFO)pvParam;
HANDLE hCamActivityThread = NULL;
//
if(FALSE == bPowered)
{
//Reinitialize the camera after the power up
Cam_Init();
bPowered = TRUE;
}
while(1)
{
WaitForSingleObject(CameraEvent, DisplayTime);
//if( DisplayEnable )
{
frame_count++;
if (s24A0INT->SRCPND & BIT_CAMIF_C)
{
cam_intr |= BIT_CAMIF_C;
RETAILMSG(MSG_EN_1,(_T("CAM_C, ts %d\r\n"), GetTickCount()));
}
if (s24A0INT->SRCPND & BIT_CAMIF_P)
{
cam_intr |= BIT_CAMIF_P;
RETAILMSG(MSG_EN_1,(_T("CAM_P, ts %d\r\n"), GetTickCount()));
}
// EINT20 to measure time
// s24A0IOP->GPGDAT |= (1<<12);
// time = GetTickCount();
// RETAILMSG(RETAIL_ON,(TEXT("+time:%d\r\n"),(time - old_time)));
// delay for capture
//Sleep(CAPTURE_TIME); // polling mode
// display the image
if ((DRIVER_PREVIEW_ENABLE == 1) && (cam_intr & BIT_CAMIF_P))
Display_Cam_Image(64, 64, QCIF_XSIZE, QCIF_YSIZE, PORT_A);
if (cam_intr & BIT_CAMIF_C)
{
Buffer_codec_info_update();
cam_intr &= ~BIT_CAMIF_C;
}
#if 0
if (cam_intr & BIT_CAMIF_P)
{
Buffer_preview_info_update();
cam_intr &= ~BIT_CAMIF_P;
}
#endif
// EINT20 to measure time
// s24A0IOP->GPGDAT &= ~(1<<12);
// old_time = GetTickCount();
// RETAILMSG(MSG_EN_1,(TEXT("-time:%d\r\n"),(old_time-time)));
//Added by APR ++ for power management
LOCK(pCamInf);
hCamActivityThread = pCamInf->hActivityThread;
//if the activity thread is not started, start it
//to cater to the situation when application is running
//and was paused and device got powered down as such
if(NULL == hCamActivityThread)
{
//notify the PM to change the device state to full powered
DWORD dwStatus = DevicePowerNotify(_T("{A32942B7-920C-486b-B0E6-92A702A99B35}\\CIS1:"), (CEDEVICE_POWER_STATE)D0, POWER_NAME);
if(dwStatus != ERROR_SUCCESS)
RETAILMSG(RETAIL_ON, (TEXT("DevicePowerNotify in CameraCaptureThread (%u) failed %d \r\n"), 0, dwStatus));
//start the activity thread again
if(FALSE == StartActivityThread(pCamInf))
{
UNLOCK(pCamInf);
return 0; //failure to open device
}
}
//set the device activity event to prevent power down
SetEvent(pCamInf->hevCamActivity);
UNLOCK(pCamInf);
//APR --
}
InterruptDone(gIntrCamera);
}
}
void Virtual_Alloc()
{
// GPIO Virtual alloc
s24A0IOP = (volatile S3C24A0_IOPORT_REG*)Cam_RegAlloc((PVOID)S3C24A0_BASE_REG_PA_IOPORT, sizeof(S3C24A0_IOPORT_REG));
if(s24A0IOP == NULL)
{
RETAILMSG(RETAIL_ON,(TEXT("For s24A0IOP: VirtualAlloc failed!\r\n")));
}
// IIC Virtual alloc
s24A0IIC = (volatile S3C24A0_IICBUS_REG*)Cam_RegAlloc((PVOID)S3C24A0_BASE_REG_PA_IICBUS, sizeof(S3C24A0_IICBUS_REG));
if(s24A0IIC == NULL)
{
RETAILMSG(RETAIL_ON,(TEXT("For s24A0IIC: VirtualAlloc failed!\r\n")));
}
// Camera Virtual alloc
s24A0CAM = (volatile S3C24A0_CAM_REG*)Cam_RegAlloc((PVOID)S3C24A0_BASE_REG_PA_CAM, sizeof(S3C24A0_CAM_REG));
if(s24A0CAM == NULL)
{
RETAILMSG(RETAIL_ON,(TEXT("For s24A0CAM: VirtualAlloc failed!\r\n")));
}
// Interrupt Virtual alloc
s24A0INT = (volatile S3C24A0_INTR_REG *)Cam_RegAlloc((PVOID)S3C24A0_BASE_REG_PA_INTR, sizeof(S3C24A0_INTR_REG));
if(s24A0INT == NULL)
{
RETAILMSG(RETAIL_ON,(TEXT("For s24A0INT: VirtualAlloc failed!\r\n")));
}
// PWM clock Virtual alloc
s24A0PWR = (volatile S3C24A0_CLKPWR_REG*)Cam_RegAlloc((PVOID)S3C24A0_BASE_REG_PA_CLOCK_POWER, sizeof(S3C24A0_CLKPWR_REG));
if(s24A0PWR == NULL)
{
RETAILMSG(RETAIL_ON,(TEXT("For s24A0PWR: VirtualAlloc failed!\r\n")));
}
}
void Display_Cam_Image(U32 pos_x, U32 pos_y, U32 size_x, U32 size_y, U8 port)
{
U8 *buffer_rgb;
U32 y;
int temp;
//unsigned short *ptr = (unsigned short *)(FRAMEBUF_BASE+0x5dc0);
static unsigned short transfer_data[QCIF_XSIZE*QCIF_YSIZE];
static unsigned int time,old_time;
// if (port)
{
temp = (s24A0CAM->CIPRSTATUS>>26)&3;
temp = (temp + 2) % 4;
switch (temp)
{
case 0:
buffer_rgb = (U8 *)s24A0CAM->CIPRCLRSA1;
break;
case 1:
buffer_rgb = (U8 *)s24A0CAM->CIPRCLRSA2;
break;
case 2:
buffer_rgb = (U8 *)s24A0CAM->CIPRCLRSA3;
break;
case 3:
buffer_rgb = (U8 *)s24A0CAM->CIPRCLRSA4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -