navienginebsp/naviengine_assp/pa_usbc.h
changeset 0 5de814552237
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/navienginebsp/naviengine_assp/pa_usbc.h	Tue Sep 28 18:00:05 2010 +0100
@@ -0,0 +1,257 @@
+/*
+* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+* naviengine_assp\pa_usbc.h
+* Platform-dependent USB client controller layer (USB PSL).
+*
+*/
+
+
+
+
+#ifndef __PA_USBC_H__
+#define __PA_USBC_H__
+
+
+// This is the header file for the implementation of the USB driver PSL layer for an imaginary USB client
+// (device) controller.
+// For simplicity's sake we assume the following endpoint layout of the controller.
+// We have 5 endpoints in total - two Bulk endpoints (IN and OUT), two Isochronous endpoint (IN and OUT),
+// one Interrupt endpoint (IN), and of course endpoint zero (Ep0).
+//
+// This is the mapping of "Hardware Endpoint Numbers" to "Real Endpoints" (and thus is also
+// used as the array index for our local TNaviEngineAsspUsbcc::iEndpoints[]):
+//
+//	0 -	 0 (Ep0 OUT)
+//	0 -	 1 (Ep0 IN)
+//	1 -	 3 (Bulk  IN, Address 0x11, -> EpAddr2Idx(0x11) =  3)
+//	2 -	 4 (Bulk OUT, Address 0x02, -> EpAddr2Idx(0x02) =  4)
+//	3 -	 7 (Iso   IN, Address 0x13, -> EpAddr2Idx(0x13) =  7)
+//	4 -	 8 (Iso  OUT, Address 0x04, -> EpAddr2Idx(0x04) =  8)
+//	5 - 11 (Int   IN, Address 0x15, -> EpAddr2Idx(0x15) = 11)
+//
+// For the reason why this is so (or rather for the perhaps not so obvious system behind it),
+// see the comment at the beginning of \e32\drivers\usbcc\ps_usbc.cpp and also the structure
+// DeviceEndpoints[] at the top of pa_usbc.cpp.
+
+// The total number of endpoints in our local endpoint array:
+static const TInt KUsbTotalEndpoints = 12;
+
+// The numbers used in the following macros are 'aRealEndpoint's (i.e. array indices):
+#define IS_VALID_ENDPOINT(x)	((x) > 0 && (x) < KUsbTotalEndpoints)
+#define IS_OUT_ENDPOINT(x)		((x) == 0 || (x) == 4 || (x) == 8)
+#define IS_IN_ENDPOINT(x)		((x) == 1 || (x) == 3 || (x) == 7 || (x) == 11)
+#define IS_BULK_IN_ENDPOINT(x)	((x) == 3)
+#define IS_BULK_OUT_ENDPOINT(x) ((x) == 4)
+#define IS_BULK_ENDPOINT(x)		(IS_BULK_IN_ENDPOINT(x) || IS_BULK_OUT_ENDPOINT(x))
+#define IS_ISO_IN_ENDPOINT(x)	((x) == 7)
+#define IS_ISO_OUT_ENDPOINT(x)	((x) == 8)
+#define IS_ISO_ENDPOINT(x)		(IS_ISO_IN_ENDPOINT(x) || IS_ISO_OUT_ENDPOINT(x))
+#define IS_INT_IN_ENDPOINT(x)	((x) == 11)
+
+// This takes as an index the TNaviEngineAsspUsbcc::iEndpoints index (== aRealEndpoint) 0..11
+// and returns the hardware endpoint number 0..5 (note that not all input indices are valid;
+// these will return -1):
+static const TInt TemplateAsspEndpoints[KUsbTotalEndpoints] =
+	{0, 0, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5};
+
+// And here is a function to use the above array:
+static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint)
+	{
+	if (IS_VALID_ENDPOINT(aRealEndpoint)) return TemplateAsspEndpoints[aRealEndpoint];
+	else return -1;
+	}
+
+// Endpoint max packet sizes
+static const TInt KEp0MaxPktSz = 16;						// Control
+static const TInt KIntMaxPktSz = 8;							// Interrupt
+static const TInt KBlkMaxPktSz = 64;						// Bulk
+static const TInt KIsoMaxPktSz = 256;						// Isochronous
+static const TInt KEp0MaxPktSzMask = KUsbEpSize16;			// Control
+static const TInt KIntMaxPktSzMask = KUsbEpSize8;			// Interrupt
+static const TInt KBlkMaxPktSzMask = KUsbEpSize64;			// Bulk
+static const TInt KIsoMaxPktSzMask = KUsbEpSize256;			// Isochronous
+
+// 1 ms (i.e. the shortest delay possible with the sort of timer used) seems to give
+// the best results, both for Bulk and Iso, and also (in the USBRFLCT test program)
+// both for loop tests as well as unidirectional transfers.
+static const TInt KRxTimerTimeout = 1;						// milliseconds
+
+// Used in descriptors
+static const TUint16 KUsbVendorId	= KUsbVendorId_Symbian;	// Symbian
+static const TUint16 KUsbProductId	= 0x0666;				// bogus...
+static const TUint16 KUsbDevRelease = 0x0100;				// bogus... (BCD!)
+static const TUint16 KUsbLangId		= 0x0409;				// English (US) Language ID
+
+// String descriptor default values
+static const wchar_t KStringManufacturer[] = L"Symbian Software Ltd.";
+static const wchar_t KStringProduct[]	   = L"NE1_TBVariant USB Test Driver";
+static const wchar_t KStringSerialNo[]	   = L"0123456789";
+static const wchar_t KStringConfig[]	   = L"First and Last and Always";
+
+
+// We use our own Ep0 state enum:
+enum TEp0State
+	{
+	EP0_IDLE = 0,											// These identifiers don't conform to
+	EP0_OUT_DATA_PHASE = 1,									// Symbian's coding standard... ;)
+	EP0_IN_DATA_PHASE = 2,
+	EP0_END_XFER = 3,
+	};
+
+
+class TNaviEngineAsspUsbcc;
+// The lowest level endpoint abstraction
+struct TEndpoint
+	{
+	TEndpoint();
+	static void RxTimerCallback(TAny* aPtr);
+	// data
+	TNaviEngineAsspUsbcc* iController;						// pointer to controller object
+	union
+		{
+		TUint8* iRxBuf;										// where to store /
+		const TUint8* iTxBuf;								// from where to send
+		};
+	union
+		{
+		TInt iReceived;										// bytes already rx'ed /
+		TInt iTransmitted;									// bytes already tx'ed
+		};
+	TInt iLength;											// number of bytes to be transferred
+	TBool iZlpReqd;											// ZeroLengthPacketRequired
+	TBool iNoBuffer;										// no data buffer was available when it was needed
+	TBool iDisabled;										// dto but stronger
+	TInt iPackets;											// number of packets rx'ed or tx'ed
+	TInt iLastError;										//
+	TUsbcRequestCallback* iRequest;							//
+	NTimer iRxTimer;										//
+	TBool iRxTimerSet;										// true if iRxTimer is running
+	TBool iRxMoreDataRcvd;									// true if after setting timer data have arrived
+	TUsbcPacketArray* iPacketIndex;							// actually TUsbcPacketArray (*)[]
+	TUsbcPacketArray* iPacketSize;							// actually TUsbcPacketArray (*)[]
+	};
+
+
+// The hardware driver object proper
+class TNaviEngine;
+class TNaviEngineAsspUsbcc : public DUsbClientController
+	{
+friend void TEndpoint::RxTimerCallback(TAny*);
+
+public:
+	TNaviEngineAsspUsbcc();
+	TInt Construct();
+	virtual ~TNaviEngineAsspUsbcc();
+	virtual void DumpRegisters();
+
+private:
+	virtual TInt SetDeviceAddress(TInt aAddress);
+	virtual TInt ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo);
+	virtual TInt DeConfigureEndpoint(TInt aRealEndpoint);
+	virtual TInt AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource);
+	virtual TInt DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource);
+	virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const;
+	virtual TInt OpenDmaChannel(TInt aRealEndpoint);
+	virtual void CloseDmaChannel(TInt aRealEndpoint);
+	virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback);
+	virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback);
+	virtual TInt CancelEndpointRead(TInt aRealEndpoint);
+	virtual TInt CancelEndpointWrite(TInt aRealEndpoint);
+	virtual TInt SetupEndpointZeroRead();
+	virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd = EFalse);
+	virtual TInt SendEp0ZeroByteStatusPacket();
+	virtual TInt StallEndpoint(TInt aRealEndpoint);
+	virtual TInt ClearStallEndpoint(TInt aRealEndpoint);
+	virtual TInt EndpointStallStatus(TInt aRealEndpoint) const;
+	virtual TInt EndpointErrorStatus(TInt aRealEndpoint) const;
+	virtual TInt ResetDataToggle(TInt aRealEndpoint);
+	virtual TInt SynchFrameNumber() const;
+	virtual void SetSynchFrameNumber(TInt aFrameNumber);
+	virtual TInt StartUdc();
+	virtual TInt StopUdc();
+	virtual TInt UdcConnect();
+	virtual TInt UdcDisconnect();
+	virtual TBool UsbConnectionStatus() const;
+	virtual TBool UsbPowerStatus() const;
+	virtual TBool DeviceSelfPowered() const;
+	virtual const TUsbcEndpointCaps* DeviceEndpointCaps() const;
+	virtual TInt DeviceTotalEndpoints() const;
+	virtual TBool SoftConnectCaps() const;
+	virtual TBool DeviceStateChangeCaps() const;
+	virtual void Suspend();
+	virtual void Resume();
+	virtual void Reset();
+	virtual TInt SignalRemoteWakeup();
+	virtual void Ep0ReadSetupPktProceed();
+	virtual void Ep0ReceiveProceed();
+	virtual TDfcQue* DfcQ(TInt aUnit);
+
+private:
+	// general
+	void EnableEndpointInterrupt(TInt aEndpoint);
+	void DisableEndpointInterrupt(TInt aEndpoint);
+	void ClearEndpointInterrupt(TInt aEndpoint);
+	void InitialiseUdcRegisters();
+	void UdcEnable();
+	void UdcDisable();
+	TInt SetupUdcInterrupt();
+	void ReleaseUdcInterrupt();
+	void UdcInterruptService();
+	void EndpointIntService(TInt aEndpoint);
+	TInt ResetIntService();
+	void SuspendIntService();
+	void ResumeIntService();
+	void SofIntService();
+	static void UdcIsr(TAny* aPtr);
+	static TInt UsbClientConnectorCallback(TAny* aPtr);
+	// endpoint zero
+	void Ep0IntService();
+	void Ep0ReadSetupPkt();
+	void Ep0Receive();
+	void Ep0Transmit();
+	void Ep0EndXfer();
+	void Ep0Cancel();
+	void Ep0PrematureStatusOut();
+	void Ep0StatusIn();
+	void Ep0NextState(TEp0State aNextState);
+	// endpoint n with n != 0
+	void BulkTransmit(TInt aEndpoint);
+	void BulkReceive(TInt aEndpoint);
+	void BulkReadRxFifo(TInt aEndpoint);
+	void IsoTransmit(TInt aEndpoint);
+	void IsoReceive(TInt aEndpoint);
+	void IsoReadRxFifo(TInt aEndpoint);
+	void IntTransmit(TInt aEndpoint);
+	void RxComplete(TEndpoint* aEndpoint);
+	void StopRxTimer(TEndpoint* aEndpoint);
+
+private:
+	// general
+	TBool iSoftwareConnectable;
+	TBool iCableDetectable;
+	TBool iCableConnected;
+	TBool iBusIsPowered;
+	TBool iInitialized;
+	TInt (*iUsbClientConnectorCallback)(TAny *);
+	NaviEngineAssp* iAssp;
+	// endpoint zero
+	TBool iEp0Configured;
+	TEp0State iEp0State;
+	// endpoints n
+	TEndpoint iEndpoints[KUsbTotalEndpoints];				// for how this is indexed, see top of pa_usbc.cpp
+	};
+
+
+#endif // __PA_USBC_H__