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