⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.cpp

📁 S3C24A0的完整BSP包,对开发此芯片的开发者很有用.
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#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 + -