baseport/syborg/webcamera/webcamera_pdd.cpp
author Shimizu Satoshi <s_shimizu@isb.co.jp>
Mon, 18 Oct 2010 19:39:25 +0900
changeset 124 606eafc6d6a8
parent 52 0dfaca43d90e
permissions -rw-r--r--
Obtain an image of Webcamera from QEMU and add the Bitmap change display function.

/*
* Copyright (c) 2010 ISB.
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* ISB - initial contribution.
*
* Contributors:
*
* Description: USB driver for test
*
*/

#ifndef __devicePDD_H__
#include "webcamera_pdd.h"
#endif
//#include <webcamera_driver.h>

#define DP(format...) Kern::Printf(format)

//Name for PDD
_LIT(KWebcameraPddName,"WebcameraDevice.pdd");


DWebcameraPddFactory::DWebcameraPddFactory()
	{
	DP("DWebcameraPddFactory::DWebcameraPddFactory()");
	iVersion = TVersion(KCommsMajorVersionNumber, KCommsMinorVersionNumber, KCommsBuildVersionNumber);
	}

TInt DWebcameraPddFactory::Install()
	{
	DP("DWebcameraPddFactory::Install");
	return SetName(&KWebcameraPddName);
	}

void DWebcameraPddFactory::GetCaps(TDes8 &aDes) const
	{
	DP("DWebcameraPddFactory::GetCaps start");
	RWebcameraDevice::TCaps capsBuf;
	capsBuf.iVersion = iVersion;
	aDes.FillZ(aDes.MaxLength());
	TInt size = sizeof(capsBuf);
	if (size>aDes.MaxLength())
		{
		size=aDes.MaxLength();
		}
	aDes.Copy((TUint8*)&capsBuf, size);
	DP("DWebcameraPddFactory::GetCaps end");
	}

TInt DWebcameraPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
	{
	DP("DWebcameraPddFactory::Create start");
	DWebcameraDriver* pD = new DWebcameraDriver;
	aChannel = pD;
	TInt r = KErrNoMemory;
	if (pD)
		{
		r = pD->DoCreate(aUnit,anInfo);
		}
	DP("DWebcameraPddFactory::Create end");
	return r;
	}

TInt DWebcameraPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
	{
	DP("DWebcameraPddFactory::Validate start");
	if ((!Kern::QueryVersionSupported(iVersion,aVer)) ||
		(!Kern::QueryVersionSupported(aVer, TVersion(KMinimumLddMajorVersion, KMinimumLddMinorVersion, KMinimumLddBuild))))
		{
		return KErrNotSupported;
		}
	DP("DWebcameraPddFactory::Validate end");
	return KErrNone;
	}

DWebcameraDriver::DWebcameraDriver()
{
	DP("DWebcameraDriver::DWebcameraDriver start");
	DP("DWebcameraDriver::DWebcameraDriver end");
}

DWebcameraDriver::~DWebcameraDriver()
	{
	DP("DWebcameraDriver::~DWebcameraDriver start");
	CloseChunk(EWEBCAMERAINDEXADATABUF);
	Interrupt::Unbind(iIrq);
	DP("DWebcameraDriver::~DWebcameraDriver end");
	}

TInt DWebcameraDriver::DoCreate(TInt aUnit, const TDesC8* anInfo)
	{
	DP("DWebcameraDriver::DoCreate start");
	iPortAddr = KHwSVPWebcameraDevice;
	iIrq = EIrqWebamera;

	Interrupt::Bind(iIrq, Isr, this);
	DP("DWebcameraDriver::DoCreate end");
	return KErrNone;
	}

TInt DWebcameraDriver::PowerOn(TAny* aHeaderPtr)
	{

	iClient = &Kern::CurrentThread();
	((DObject*)iClient)->Open();

	TInt ret = CreateChunk(sizeof(iDataInfo), EWEBCAMERAINDEXHAHEADERBUF);
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_INFO, iPhysAddr[EWEBCAMERAINDEXHAHEADERBUF]);
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_INFOSIZE, sizeof(iDataInfo));
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_CONNECT,0x0);

	kumemget(&iDataInfo, iChunk[EWEBCAMERAINDEXHAHEADERBUF]->Base(), sizeof(TWebcameraDataInfo));

	//Process(Transaction) that parse iDataInfo.
	DWebCameraDescribe* bDescribe;
	bDescribe = new DWebCameraDescribe;
	iUvcData = bDescribe->ParseDataInfo(iDataInfo);
	delete bDescribe;

	//Store bUVC in TAny* aHeaderPtr.
	kumemget(aHeaderPtr, &iUvcData, sizeof(TWebcameraUVC));

	CloseChunk(EWEBCAMERAINDEXHAHEADERBUF);

	return ret;
	}

TInt DWebcameraDriver::InitViewFinder()
	{
	TInt ret = KErrNone;

	iClient = &Kern::CurrentThread();
	((DObject*)iClient)->Open();
	ret = CreateChunk(BUFSIZE, EWEBCAMERAINDEXADATABUF);

	return ret;
	}

TInt DWebcameraDriver::StartViewerFinder(TAny* aDataPtr, TInt aSize)
	{
	iType = 0;

	WriteReg(iPortAddr, WEBCAMERA_REG_DATA_TYPE, 0x0);
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_ADDR, iPhysAddr[EWEBCAMERAINDEXADATABUF]);
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_SIZE, aSize);
	WriteReg(iPortAddr, WEBCAMERA_REG_INT_ENABLE, 0x1);

	kumemget(aDataPtr, iChunk[EWEBCAMERAINDEXADATABUF]->Base(), aSize);

	Interrupt::Enable(iIrq);
	return KErrNone;
	}

void DWebcameraDriver::Stop(TUSBStopMode aMode)
	{
	WriteReg(iPortAddr, WEBCAMERA_REG_INT_ENABLE, 0x0);
	Interrupt::Disable(iIrq);
	}

void DWebcameraDriver::Disconnect()
	{
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_DISCONNECT, 0x0);
	Interrupt::Disable(iIrq);
	}

void DWebcameraDriver::Isr(TAny* aPtr)
	{
	((DWebcameraDriver*)aPtr)->receivedatacallback();
	}

void DWebcameraDriver::receivedatacallback()
	{
	TInt datasize = ReadReg(iPortAddr, WEBCAMERA_REG_DMA_SIZE);
	switch (iType)
		{
		case 0:
			iLdd->GetOneFlameComplete(datasize);
			break;
		default:
			DP("receivedatacallback error");
			break;
		}
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_ADDR, 0);
	WriteReg(iPortAddr, WEBCAMERA_REG_DMA_SIZE, 0);
	WriteReg(iPortAddr, WEBCAMERA_REG_INT_ENABLE, 0x0);
	}

/**
Chunk that used between PDD and USB.
*/
TInt DWebcameraDriver::CreateChunk(TInt aSize, TWebcameraIndex aIndex)
	{
	TLinAddr wChunkLinAddr;
	TUint32 wChunkMappingAttr;
	RWebcameraDevice::TChunkInfo chunkInfo;

	TChunkCreateInfo info;
	info.iType			= TChunkCreateInfo::ESharedKernelMultiple;
	info.iMaxSize		= aSize;
	info.iMapAttr		= EMapAttrFullyBlocking;
	info.iOwnsMemory	= ETrue;
	info.iDestroyedDfc	= NULL;

//Chunk Create
	iChunk[aIndex] = NULL;
	iPhysAddr[aIndex] = 0x0;
	TInt ret = Kern::ChunkCreate(info, iChunk[aIndex], wChunkLinAddr, wChunkMappingAttr);
	if (ret != KErrNone)
		{
		DP("Kern::ChunkCreate Err = %d",ret);
		}
	ret = Kern::ChunkCommitContiguous(iChunk[aIndex], 0, aSize, iPhysAddr[aIndex]);
	if (ret != KErrNone)
		{
		DP("Kern::ChunkCommitContiguous Err = %d",ret);
		}

//Chunk Open
	// Make handle to chunifo for current thread
	ret = Kern::MakeHandleAndOpen(iClient, iChunk[aIndex]);
	if (ret >= 0) 
		{
		chunkInfo.iChunkHandle = ret;
		ret = KErrNone;
		}

	if (ret != KErrNone)
		{
		memclr(&chunkInfo, sizeof(chunkInfo));
		}

	TInt result = Kern::ThreadRawWrite(iClient, &info, &chunkInfo, sizeof(chunkInfo), 0);
	if (result != KErrNone)
		{
		DP("Kern::ChunkCommitContiguous Err = %d",result);
		}
	return KErrNone;
	}

void DWebcameraDriver::CloseChunk(TWebcameraIndex aIndex)
	{
	Kern::ChunkClose(iChunk[aIndex]);
	Kern::SafeClose((DObject*&)iClient, NULL);
	}

DECLARE_STANDARD_PDD()
	{
	DP("DECLARE_STANDARD_PDD()");
	return new DWebcameraPddFactory;
	}