os/kernelhwsrv/bsptemplate/asspandvariant/template_assp/pa_usbc.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// template\template_assp\pa_usbc.h
sl@0
    15
// Platform-dependent USB client controller layer (USB PSL).
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
sl@0
    20
#ifndef __PA_USBC_H__
sl@0
    21
#define __PA_USBC_H__
sl@0
    22
sl@0
    23
sl@0
    24
// This is the header file for the implementation of the USB driver PSL layer for an imaginary USB client
sl@0
    25
// (device) controller.
sl@0
    26
// For simplicity's sake we assume the following endpoint layout of the controller.
sl@0
    27
// We have 5 endpoints in total - two Bulk endpoints (IN and OUT), two Isochronous endpoint (IN and OUT),
sl@0
    28
// one Interrupt endpoint (IN), and of course endpoint zero (Ep0).
sl@0
    29
//
sl@0
    30
// This is the mapping of "Hardware Endpoint Numbers" to "Real Endpoints" (and thus is also
sl@0
    31
// used as the array index for our local TTemplateAsspUsbcc::iEndpoints[]):
sl@0
    32
//
sl@0
    33
//	0 -	 0 (Ep0 OUT)
sl@0
    34
//	0 -	 1 (Ep0 IN)
sl@0
    35
//	1 -	 3 (Bulk  IN, Address 0x11, -> EpAddr2Idx(0x11) =  3)
sl@0
    36
//	2 -	 4 (Bulk OUT, Address 0x02, -> EpAddr2Idx(0x02) =  4)
sl@0
    37
//	3 -	 7 (Iso   IN, Address 0x13, -> EpAddr2Idx(0x13) =  7)
sl@0
    38
//	4 -	 8 (Iso  OUT, Address 0x04, -> EpAddr2Idx(0x04) =  8)
sl@0
    39
//	5 - 11 (Int   IN, Address 0x15, -> EpAddr2Idx(0x15) = 11)
sl@0
    40
//
sl@0
    41
// For the reason why this is so (or rather for the perhaps not so obvious system behind it),
sl@0
    42
// see the comment at the beginning of \e32\drivers\usbcc\ps_usbc.cpp and also the structure
sl@0
    43
// DeviceEndpoints[] at the top of pa_usbc.cpp.
sl@0
    44
sl@0
    45
// The total number of endpoints in our local endpoint array:
sl@0
    46
static const TInt KUsbTotalEndpoints = 12;
sl@0
    47
sl@0
    48
// The numbers used in the following macros are 'aRealEndpoint's (i.e. array indices):
sl@0
    49
#define IS_VALID_ENDPOINT(x)	((x) > 0 && (x) < KUsbTotalEndpoints)
sl@0
    50
#define IS_OUT_ENDPOINT(x)		((x) == 0 || (x) == 4 || (x) == 8)
sl@0
    51
#define IS_IN_ENDPOINT(x)		((x) == 1 || (x) == 3 || (x) == 7 || (x) == 11)
sl@0
    52
#define IS_BULK_IN_ENDPOINT(x)	((x) == 3)
sl@0
    53
#define IS_BULK_OUT_ENDPOINT(x) ((x) == 4)
sl@0
    54
#define IS_BULK_ENDPOINT(x)		(IS_BULK_IN_ENDPOINT(x) || IS_BULK_OUT_ENDPOINT(x))
sl@0
    55
#define IS_ISO_IN_ENDPOINT(x)	((x) == 7)
sl@0
    56
#define IS_ISO_OUT_ENDPOINT(x)	((x) == 8)
sl@0
    57
#define IS_ISO_ENDPOINT(x)		(IS_ISO_IN_ENDPOINT(x) || IS_ISO_OUT_ENDPOINT(x))
sl@0
    58
#define IS_INT_IN_ENDPOINT(x)	((x) == 11)
sl@0
    59
sl@0
    60
// This takes as an index the TTemplateAsspUsbcc::iEndpoints index (== aRealEndpoint) 0..11
sl@0
    61
// and returns the hardware endpoint number 0..5 (note that not all input indices are valid;
sl@0
    62
// these will return -1):
sl@0
    63
static const TInt TemplateAsspEndpoints[KUsbTotalEndpoints] =
sl@0
    64
	{0, 0, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5};
sl@0
    65
sl@0
    66
// And here is a function to use the above array:
sl@0
    67
static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint)
sl@0
    68
	{
sl@0
    69
	if (IS_VALID_ENDPOINT(aRealEndpoint)) return TemplateAsspEndpoints[aRealEndpoint];
sl@0
    70
	else return -1;
sl@0
    71
	}
sl@0
    72
sl@0
    73
// Endpoint max packet sizes
sl@0
    74
static const TInt KEp0MaxPktSz = 16;						// Control
sl@0
    75
static const TInt KIntMaxPktSz = 8;							// Interrupt
sl@0
    76
static const TInt KBlkMaxPktSz = 64;						// Bulk
sl@0
    77
static const TInt KIsoMaxPktSz = 256;						// Isochronous
sl@0
    78
static const TInt KEp0MaxPktSzMask = KUsbEpSize16;			// Control
sl@0
    79
static const TInt KIntMaxPktSzMask = KUsbEpSize8;			// Interrupt
sl@0
    80
static const TInt KBlkMaxPktSzMask = KUsbEpSize64;			// Bulk
sl@0
    81
static const TInt KIsoMaxPktSzMask = KUsbEpSize256;			// Isochronous
sl@0
    82
sl@0
    83
// 1 ms (i.e. the shortest delay possible with the sort of timer used) seems to give
sl@0
    84
// the best results, both for Bulk and Iso, and also (in the USBRFLCT test program)
sl@0
    85
// both for loop tests as well as unidirectional transfers.
sl@0
    86
static const TInt KRxTimerTimeout = 1;						// milliseconds
sl@0
    87
sl@0
    88
// Used in descriptors
sl@0
    89
static const TUint16 KUsbVendorId	= KUsbVendorId_Symbian;	// Symbian
sl@0
    90
static const TUint16 KUsbProductId	= 0x0666;				// bogus...
sl@0
    91
static const TUint16 KUsbDevRelease = 0x0100;				// bogus... (BCD!)
sl@0
    92
static const TUint16 KUsbLangId		= 0x0409;				// English (US) Language ID
sl@0
    93
sl@0
    94
// String descriptor default values
sl@0
    95
static const wchar_t KStringManufacturer[] = L"Nokia Corporation and/or its subsidiary(-ies).";
sl@0
    96
static const wchar_t KStringProduct[]	   = L"Template USB Test Driver";
sl@0
    97
static const wchar_t KStringSerialNo[]	   = L"0123456789";
sl@0
    98
static const wchar_t KStringConfig[]	   = L"First and Last and Always";
sl@0
    99
sl@0
   100
sl@0
   101
// We use our own Ep0 state enum:
sl@0
   102
enum TEp0State
sl@0
   103
	{
sl@0
   104
	EP0_IDLE = 0,											// These identifiers don't conform to
sl@0
   105
	EP0_OUT_DATA_PHASE = 1,									// Symbian's coding standard... ;)
sl@0
   106
	EP0_IN_DATA_PHASE = 2,
sl@0
   107
	EP0_END_XFER = 3,
sl@0
   108
	};
sl@0
   109
sl@0
   110
sl@0
   111
class TTemplateAsspUsbcc;
sl@0
   112
// The lowest level endpoint abstraction
sl@0
   113
struct TEndpoint
sl@0
   114
	{
sl@0
   115
	TEndpoint();
sl@0
   116
	static void RxTimerCallback(TAny* aPtr);
sl@0
   117
	// data
sl@0
   118
	TTemplateAsspUsbcc* iController;						// pointer to controller object
sl@0
   119
	union
sl@0
   120
		{
sl@0
   121
		TUint8* iRxBuf;										// where to store /
sl@0
   122
		const TUint8* iTxBuf;								// from where to send
sl@0
   123
		};
sl@0
   124
	union
sl@0
   125
		{
sl@0
   126
		TInt iReceived;										// bytes already rx'ed /
sl@0
   127
		TInt iTransmitted;									// bytes already tx'ed
sl@0
   128
		};
sl@0
   129
	TInt iLength;											// number of bytes to be transferred
sl@0
   130
	TBool iZlpReqd;											// ZeroLengthPacketRequired
sl@0
   131
	TBool iNoBuffer;										// no data buffer was available when it was needed
sl@0
   132
	TBool iDisabled;										// dto but stronger
sl@0
   133
	TInt iPackets;											// number of packets rx'ed or tx'ed
sl@0
   134
	TInt iLastError;										//
sl@0
   135
	TUsbcRequestCallback* iRequest;							//
sl@0
   136
	NTimer iRxTimer;										//
sl@0
   137
	TBool iRxTimerSet;										// true if iRxTimer is running
sl@0
   138
	TBool iRxMoreDataRcvd;									// true if after setting timer data have arrived
sl@0
   139
	TUsbcPacketArray* iPacketIndex;							// actually TUsbcPacketArray (*)[]
sl@0
   140
	TUsbcPacketArray* iPacketSize;							// actually TUsbcPacketArray (*)[]
sl@0
   141
	};
sl@0
   142
sl@0
   143
sl@0
   144
// The hardware driver object proper
sl@0
   145
class TTemplate;
sl@0
   146
class TTemplateAsspUsbcc : public DUsbClientController
sl@0
   147
	{
sl@0
   148
friend void TEndpoint::RxTimerCallback(TAny*);
sl@0
   149
sl@0
   150
public:
sl@0
   151
	TTemplateAsspUsbcc();
sl@0
   152
	TInt Construct();
sl@0
   153
	virtual ~TTemplateAsspUsbcc();
sl@0
   154
	virtual void DumpRegisters();
sl@0
   155
sl@0
   156
private:
sl@0
   157
	virtual TInt SetDeviceAddress(TInt aAddress);
sl@0
   158
	virtual TInt ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo);
sl@0
   159
	virtual TInt DeConfigureEndpoint(TInt aRealEndpoint);
sl@0
   160
	virtual TInt AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource);
sl@0
   161
	virtual TInt DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource);
sl@0
   162
	virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const;
sl@0
   163
	virtual TInt OpenDmaChannel(TInt aRealEndpoint);
sl@0
   164
	virtual void CloseDmaChannel(TInt aRealEndpoint);
sl@0
   165
	virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback);
sl@0
   166
	virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback);
sl@0
   167
	virtual TInt CancelEndpointRead(TInt aRealEndpoint);
sl@0
   168
	virtual TInt CancelEndpointWrite(TInt aRealEndpoint);
sl@0
   169
	virtual TInt SetupEndpointZeroRead();
sl@0
   170
	virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd = EFalse);
sl@0
   171
	virtual TInt SendEp0ZeroByteStatusPacket();
sl@0
   172
	virtual TInt StallEndpoint(TInt aRealEndpoint);
sl@0
   173
	virtual TInt ClearStallEndpoint(TInt aRealEndpoint);
sl@0
   174
	virtual TInt EndpointStallStatus(TInt aRealEndpoint) const;
sl@0
   175
	virtual TInt EndpointErrorStatus(TInt aRealEndpoint) const;
sl@0
   176
	virtual TInt ResetDataToggle(TInt aRealEndpoint);
sl@0
   177
	virtual TInt SynchFrameNumber() const;
sl@0
   178
	virtual void SetSynchFrameNumber(TInt aFrameNumber);
sl@0
   179
	virtual TInt StartUdc();
sl@0
   180
	virtual TInt StopUdc();
sl@0
   181
	virtual TInt UdcConnect();
sl@0
   182
	virtual TInt UdcDisconnect();
sl@0
   183
	virtual TBool UsbConnectionStatus() const;
sl@0
   184
	virtual TBool UsbPowerStatus() const;
sl@0
   185
	virtual TBool DeviceSelfPowered() const;
sl@0
   186
	virtual const TUsbcEndpointCaps* DeviceEndpointCaps() const;
sl@0
   187
	virtual TInt DeviceTotalEndpoints() const;
sl@0
   188
	virtual TBool SoftConnectCaps() const;
sl@0
   189
	virtual TBool DeviceStateChangeCaps() const;
sl@0
   190
	virtual void Suspend();
sl@0
   191
	virtual void Resume();
sl@0
   192
	virtual void Reset();
sl@0
   193
	virtual TInt SignalRemoteWakeup();
sl@0
   194
	virtual void Ep0ReadSetupPktProceed();
sl@0
   195
	virtual void Ep0ReceiveProceed();
sl@0
   196
	virtual TDfcQue* DfcQ(TInt aUnit);
sl@0
   197
sl@0
   198
private:
sl@0
   199
	// general
sl@0
   200
	void EnableEndpointInterrupt(TInt aEndpoint);
sl@0
   201
	void DisableEndpointInterrupt(TInt aEndpoint);
sl@0
   202
	void ClearEndpointInterrupt(TInt aEndpoint);
sl@0
   203
	void InitialiseUdcRegisters();
sl@0
   204
	void UdcEnable();
sl@0
   205
	void UdcDisable();
sl@0
   206
	TInt SetupUdcInterrupt();
sl@0
   207
	void ReleaseUdcInterrupt();
sl@0
   208
	void UdcInterruptService();
sl@0
   209
	void EndpointIntService(TInt aEndpoint);
sl@0
   210
	TInt ResetIntService();
sl@0
   211
	void SuspendIntService();
sl@0
   212
	void ResumeIntService();
sl@0
   213
	void SofIntService();
sl@0
   214
	static void UdcIsr(TAny* aPtr);
sl@0
   215
	static TInt UsbClientConnectorCallback(TAny* aPtr);
sl@0
   216
	// endpoint zero
sl@0
   217
	void Ep0IntService();
sl@0
   218
	void Ep0ReadSetupPkt();
sl@0
   219
	void Ep0Receive();
sl@0
   220
	void Ep0Transmit();
sl@0
   221
	void Ep0EndXfer();
sl@0
   222
	void Ep0Cancel();
sl@0
   223
	void Ep0PrematureStatusOut();
sl@0
   224
	void Ep0StatusIn();
sl@0
   225
	void Ep0NextState(TEp0State aNextState);
sl@0
   226
	// endpoint n with n != 0
sl@0
   227
	void BulkTransmit(TInt aEndpoint);
sl@0
   228
	void BulkReceive(TInt aEndpoint);
sl@0
   229
	void BulkReadRxFifo(TInt aEndpoint);
sl@0
   230
	void IsoTransmit(TInt aEndpoint);
sl@0
   231
	void IsoReceive(TInt aEndpoint);
sl@0
   232
	void IsoReadRxFifo(TInt aEndpoint);
sl@0
   233
	void IntTransmit(TInt aEndpoint);
sl@0
   234
	void RxComplete(TEndpoint* aEndpoint);
sl@0
   235
	void StopRxTimer(TEndpoint* aEndpoint);
sl@0
   236
sl@0
   237
private:
sl@0
   238
	// general
sl@0
   239
	TBool iSoftwareConnectable;
sl@0
   240
	TBool iCableDetectable;
sl@0
   241
	TBool iCableConnected;
sl@0
   242
	TBool iBusIsPowered;
sl@0
   243
	TBool iInitialized;
sl@0
   244
	TInt (*iUsbClientConnectorCallback)(TAny *);
sl@0
   245
	TemplateAssp* iAssp;
sl@0
   246
	// endpoint zero
sl@0
   247
	TBool iEp0Configured;
sl@0
   248
	TEp0State iEp0State;
sl@0
   249
	// endpoints n
sl@0
   250
	TEndpoint iEndpoints[KUsbTotalEndpoints];				// for how this is indexed, see top of pa_usbc.cpp
sl@0
   251
	};
sl@0
   252
sl@0
   253
sl@0
   254
#endif // __PA_USBC_H__