|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\include\drivers\comm.h |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 #ifndef __M32COMM_H__ |
|
24 #define __M32COMM_H__ |
|
25 #include <platform.h> |
|
26 #include <kernel/kpower.h> |
|
27 #include <d32comm.h> |
|
28 #include <e32ver.h> |
|
29 // |
|
30 const TInt KCommsMajorVersionNumber=1; |
|
31 const TInt KCommsMinorVersionNumber=1; |
|
32 const TInt KCommsBuildVersionNumber=KE32BuildVersionNumber; |
|
33 // |
|
34 const TInt KDefaultRxBufferSize=0x800; |
|
35 const TInt KTxBufferSize=0x400; |
|
36 const TInt KMaxHighWaterMark=0x080; |
|
37 // |
|
38 /** |
|
39 @publishedPartner |
|
40 @released |
|
41 */ |
|
42 const TUint KReceiveIsrParityError=0x10000000; |
|
43 |
|
44 /** |
|
45 @publishedPartner |
|
46 @released |
|
47 */ |
|
48 const TUint KReceiveIsrFrameError=0x20000000; |
|
49 |
|
50 /** |
|
51 @publishedPartner |
|
52 @released |
|
53 */ |
|
54 const TUint KReceiveIsrOverrunError=0x40000000; |
|
55 |
|
56 /** |
|
57 @publishedPartner |
|
58 @released |
|
59 */ |
|
60 const TUint KReceiveIsrBreakError=0x80000000; |
|
61 |
|
62 const TUint KReceiveIsrMaskError=0xF0000000; |
|
63 // |
|
64 const TInt KTxNoChar=-1; |
|
65 // |
|
66 const TUint KReceiveIsrTermChar=0x80000000; |
|
67 const TUint KReceiveIsrMaskComplete=0xf0000000; |
|
68 const TUint KReceiveIsrShift=24; |
|
69 const TUint KReceiveIsrShiftedMask=0x0f; |
|
70 |
|
71 /** |
|
72 @publishedPartner |
|
73 @released |
|
74 */ |
|
75 const TUint KDTEInputSignals=(KSignalCTS|KSignalDSR|KSignalDCD|KSignalRNG); |
|
76 |
|
77 /** |
|
78 @publishedPartner |
|
79 @released |
|
80 |
|
81 An enumeration listing the stopping modes supported by this driver, to be passed to the Stop function. |
|
82 */ |
|
83 enum TStopMode |
|
84 { |
|
85 /** |
|
86 Stopping due to normal operational reasons. |
|
87 */ |
|
88 EStopNormal, |
|
89 /** |
|
90 Stopping due to system power down. |
|
91 */ |
|
92 EStopPwrDown, |
|
93 /** |
|
94 Emergency stop. Deprecated. |
|
95 */ |
|
96 EStopEmergency |
|
97 }; |
|
98 |
|
99 |
|
100 class DChannelComm; |
|
101 |
|
102 /** |
|
103 @publishedPartner |
|
104 @released |
|
105 |
|
106 An abstract class for a serial comm PDD. |
|
107 */ |
|
108 class DComm : public DBase |
|
109 { |
|
110 public: |
|
111 /** |
|
112 Starts receiving characters. |
|
113 @return KErrNone if successful; otherwise one of the other system wide error codes. |
|
114 */ |
|
115 virtual TInt Start() =0; |
|
116 |
|
117 /** |
|
118 Stops receiving characters. |
|
119 @param aMode The stopping reason as one of TStopMode. |
|
120 @see TStopMode |
|
121 */ |
|
122 virtual void Stop(TStopMode aMode) =0; |
|
123 |
|
124 /** |
|
125 Starts or stop the uart breaking. |
|
126 @param aState ETrue to enable break signal(LCR) and EFalse disable break signal(LCR). |
|
127 */ |
|
128 virtual void Break(TBool aState) =0; |
|
129 |
|
130 /** |
|
131 Starts transmitting characters. |
|
132 */ |
|
133 virtual void EnableTransmit() =0; |
|
134 |
|
135 /** |
|
136 Read and translate the modem control lines. |
|
137 @return State changes. |
|
138 For Example: |
|
139 RTS, DSR, RI, Carrier Detect. |
|
140 */ |
|
141 virtual TUint Signals() const =0; |
|
142 |
|
143 /** |
|
144 Set signals. |
|
145 @param aSetMask A bit mask for those modem control signals which are to be asserted. |
|
146 @param aClearMask A bit mask for those modem control signals which are to be de-asserted. |
|
147 Each bit in the bit masks above corresponds to a modem control signal. |
|
148 Bits are defined as one of: |
|
149 KSignalCTS |
|
150 KSignalDSR |
|
151 KSignalDCD |
|
152 KSignalRNG |
|
153 KSignalRTS |
|
154 KSignalDTR |
|
155 KSignalBreak |
|
156 |
|
157 */ |
|
158 virtual void SetSignals(TUint aSetMask,TUint aClearMask) =0; |
|
159 |
|
160 /** |
|
161 Validates a new configuration. |
|
162 @param aConfig Const reference to the comms configuration structure; to hold the configuration settings for serial comm port. |
|
163 @return KErrNone if successful; otherwise one of the other system wide error codes. |
|
164 @see TCommConfigV01 |
|
165 */ |
|
166 virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const =0; |
|
167 |
|
168 /** |
|
169 Configures the hardware device. This is device specific API, that provides functionality to configure the uart. |
|
170 @param aConfig configuration settings for the device. |
|
171 @see TCommConfigV01 |
|
172 */ |
|
173 virtual void Configure(TCommConfigV01 &aConfig) =0; |
|
174 |
|
175 /** |
|
176 Gets the capabilities of the comm PDD. |
|
177 @param aCaps On return this descriptor should have been filled with capabilities. |
|
178 */ |
|
179 virtual void Caps(TDes8 &aCaps) const =0; |
|
180 |
|
181 /** |
|
182 Checks the configuration. |
|
183 @param aConfig A reference to the structure TCommConfigV01 with configuration to check. |
|
184 @see TCommConfigV01 |
|
185 */ |
|
186 virtual void CheckConfig(TCommConfigV01& aConfig)=0; |
|
187 |
|
188 /** |
|
189 Disable all IRQs. |
|
190 @return The state of the interrupts before disable, which is used to restore the interrupt state. |
|
191 */ |
|
192 virtual TInt DisableIrqs()=0; |
|
193 |
|
194 /** |
|
195 Restore IRQs to the passed level. |
|
196 @param aIrq The level to restore the IRQs to. |
|
197 */ |
|
198 virtual void RestoreIrqs(TInt aIrq)=0; |
|
199 |
|
200 /** |
|
201 Returns a pointer to the DFC queue that should be used by the comm LDD. |
|
202 @param aUnit Unit for which the DfcQ is retrieved. |
|
203 @return A Pointer to the DFC queue that should be used by the USB LDD. |
|
204 @see TDfcQue |
|
205 */ |
|
206 virtual TDfcQue* DfcQ(TInt aUnit)=0; |
|
207 |
|
208 /** |
|
209 Checks power status. |
|
210 @return ETrue if status is good, EFalse otherwise. |
|
211 */ |
|
212 inline TBool PowerGood(); |
|
213 inline void SetCurrent(TInt aCurrent); |
|
214 inline void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff); |
|
215 inline TInt TransmitIsr(); |
|
216 inline void CheckTxBuffer(); |
|
217 inline void StateIsr(TUint aSignals); |
|
218 inline TBool Transmitting(); |
|
219 public: |
|
220 /** |
|
221 Pointer to the logical channel object which is derived from DLogicChannel. |
|
222 */ |
|
223 DChannelComm *iLdd; |
|
224 /** |
|
225 A Boolean flag to indicate when transmission is in progress [ETrue=(Trasnmission in progress)]. |
|
226 */ |
|
227 TBool iTransmitting; |
|
228 }; |
|
229 |
|
230 /** |
|
231 @internalComponent |
|
232 */ |
|
233 class DDeviceComm : public DLogicalDevice |
|
234 { |
|
235 public: |
|
236 DDeviceComm(); |
|
237 virtual TInt Install(); |
|
238 virtual void GetCaps(TDes8 &aDes) const; |
|
239 virtual TInt Create(DLogicalChannelBase*& aChannel); |
|
240 }; |
|
241 |
|
242 |
|
243 // |
|
244 // TClientSingleBufferRequest |
|
245 // |
|
246 class TClientSingleBufferRequest |
|
247 { |
|
248 public: |
|
249 TClientSingleBufferRequest() |
|
250 { |
|
251 Reset(); |
|
252 } |
|
253 ~TClientSingleBufferRequest() |
|
254 { |
|
255 if (iBufReq) |
|
256 Kern::DestroyClientBufferRequest(iBufReq); |
|
257 Reset(); |
|
258 } |
|
259 void Reset() |
|
260 { |
|
261 iBufReq = NULL; |
|
262 iBuf = NULL; |
|
263 iLen = 0; |
|
264 } |
|
265 TInt Create() |
|
266 { |
|
267 if (iBufReq) |
|
268 return KErrNone; |
|
269 TInt r = Kern::CreateClientBufferRequest(iBufReq, 1, TClientBufferRequest::EPinVirtual); |
|
270 return r; |
|
271 } |
|
272 TInt Setup(TRequestStatus* aStatus, TAny* aDes, TInt aLen=0) |
|
273 { |
|
274 TInt r = iBufReq->Setup(iBuf, aStatus, aDes); |
|
275 if (r == KErrNone) |
|
276 iLen = aLen; |
|
277 return r; |
|
278 } |
|
279 TInt SetupFromPtr(TRequestStatus* aStatus, TLinAddr aPtr, TInt aLen) |
|
280 { |
|
281 TInt r = iBufReq->Setup(iBuf, aStatus, aPtr, aLen); |
|
282 iLen = aLen; |
|
283 return r; |
|
284 } |
|
285 void Complete(DThread* aClient, TInt aReason) |
|
286 { |
|
287 if (iBufReq) |
|
288 { |
|
289 iBuf = NULL; |
|
290 Kern::QueueBufferRequestComplete(aClient, iBufReq, aReason); |
|
291 } |
|
292 } |
|
293 TClientBufferRequest* iBufReq; |
|
294 TClientBuffer* iBuf; |
|
295 TInt iLen; |
|
296 }; |
|
297 |
|
298 class DCommPowerHandler; |
|
299 /** |
|
300 @internalComponent |
|
301 */ |
|
302 class DChannelComm : public DLogicalChannel |
|
303 { |
|
304 public: |
|
305 enum TState {EOpen,EActive,EClosed}; |
|
306 enum TRequest {ERx=1, ETx=2, ESigChg=4, EBreak=8, EAll=0xff}; |
|
307 |
|
308 DChannelComm(); |
|
309 ~DChannelComm(); |
|
310 virtual void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff); |
|
311 virtual void CheckTxBuffer(); |
|
312 virtual void StateIsr(TUint aSignals); |
|
313 virtual TInt TransmitIsr(); |
|
314 virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); |
|
315 |
|
316 /** @publishedPartner |
|
317 @released */ |
|
318 virtual void UpdateSignals(TUint aSignals); |
|
319 inline void SetStatus(TState aStatus); |
|
320 virtual TInt SendMsg(TMessageBase* aMsg); |
|
321 protected: |
|
322 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
323 virtual void HandleMsg(TMessageBase* aMsg); |
|
324 void DoCancel(TInt aMask); |
|
325 TInt DoControl(TInt aId, TAny* a1, TAny* a2); |
|
326 void DoRequest(TInt aId, TAny* a1, TAny* a2); |
|
327 void DoPowerUp(); |
|
328 void Start(); |
|
329 TInt Shutdown(); |
|
330 void BreakOn(); |
|
331 void BreakOff(); |
|
332 void AssertFlowControl(); |
|
333 void ReleaseFlowControl(); |
|
334 TInt SetRxBufferSize(TInt aSize); |
|
335 void ResetBuffers(TBool aResetTx); |
|
336 void DoDrainRxBuffer(TInt aEndIndex); |
|
337 void DoFillTxBuffer(); |
|
338 void DoCompleteRx(); |
|
339 void DoCompleteTx(); |
|
340 void Complete(TInt aMask, TInt aReason); |
|
341 inline void DrainRxBuffer() { iRxDrainDfc.Add(); } |
|
342 inline void RxComplete(); |
|
343 inline void TxComplete(); |
|
344 protected: |
|
345 inline void EnableTransmit(); |
|
346 inline TInt IsLineFail(TUint aFailSignals); |
|
347 inline TInt PddStart(); |
|
348 inline void Stop(TStopMode aMode); |
|
349 inline void PddBreak(TBool aState); |
|
350 inline TUint Signals() const; |
|
351 inline void SetSignals(TUint aSetMask,TUint aClearMask); |
|
352 inline TInt ValidateConfig(const TCommConfigV01 &aConfig) const; |
|
353 inline void PddConfigure(TCommConfigV01 &aConfig); |
|
354 inline void PddCaps(TDes8 &aCaps) const; |
|
355 inline void PddCheckConfig(TCommConfigV01& aConfig); |
|
356 inline TBool Transmitting(); |
|
357 private: |
|
358 static void PowerUpDfc(TAny* aPtr); |
|
359 static void PowerDownDfc(TAny* aPtr); |
|
360 static void DrainRxDfc(TAny* aPtr); |
|
361 static void FillTxDfc(TAny* aPtr); |
|
362 static void CompleteRxDfc(TAny* aPtr); |
|
363 static void CompleteTxDfc(TAny* aPtr); |
|
364 static void TimerDfcFn(TAny* aPtr); |
|
365 static void SigNotifyDfc(TAny* aPtr); |
|
366 void TimerDfc(); |
|
367 static void MsCallBack(TAny* aPtr); |
|
368 inline TBool IsTerminator(TUint8 aChar); |
|
369 inline void SetTerminator(TUint8 aChar); |
|
370 inline TInt RxCount(); |
|
371 inline TInt TxCount(); |
|
372 inline TBool AreAnyPending() const; |
|
373 void InitiateRead(TInt aLength); |
|
374 void InitiateWrite(); |
|
375 void DoSigNotify(); |
|
376 void UpdateAndProcessSignals(); |
|
377 |
|
378 |
|
379 TUint FailSignals(TUint aHandshake); |
|
380 TUint HoldSignals(TUint aHandshake); |
|
381 TUint FlowControlSignals(TUint aHandshake); |
|
382 TUint AutoSignals(TUint aHandshake); |
|
383 TInt SetConfig(TCommConfigV01& aConfig); |
|
384 void CheckOutputHeld(); |
|
385 void RestartDelayedTransmission(); |
|
386 |
|
387 static void FinishBreak(TAny* aSelf); // Called when timer indicating break should finish expires |
|
388 void QueueFinishBreakDfc(); // Called to queue dfc to finish break |
|
389 static void FinishBreakDfc(TAny* aSelf); // Dfc called to finish break |
|
390 void FinishBreakImplementation(TInt aError); // Actual implementation to finish break |
|
391 |
|
392 public: |
|
393 // Port configuration |
|
394 TCommConfigV01 iConfig; |
|
395 |
|
396 /** @publishedPartner |
|
397 @released */ |
|
398 TUint iRxXonChar; |
|
399 |
|
400 /** @publishedPartner |
|
401 @released */ |
|
402 TUint iRxXoffChar; |
|
403 |
|
404 TInt TurnaroundSet(TUint aNewTurnaroundMilliSeconds); |
|
405 TBool TurnaroundStopTimer(); |
|
406 TInt TurnaroundClear(); |
|
407 TInt RestartTurnaroundTimer(); |
|
408 static void TurnaroundStartDfc(TAny* aSelf); |
|
409 void TurnaroundStartDfcImplementation(TBool inIsr); |
|
410 static void TurnaroundTimeout(TAny* aSelf); |
|
411 void TurnaroundTimeoutImplementation(); |
|
412 |
|
413 // General items |
|
414 DThread* iClient; |
|
415 DCommPowerHandler* iPowerHandler; |
|
416 TDfc iPowerUpDfc; |
|
417 TDfc iPowerDownDfc; |
|
418 TState iStatus; |
|
419 TDfc iRxDrainDfc; |
|
420 TDfc iRxCompleteDfc; |
|
421 TDfc iTxFillDfc; |
|
422 TDfc iTxCompleteDfc; |
|
423 TDfc iTimerDfc; |
|
424 TDfc iSigNotifyDfc; |
|
425 TUint iFlags; // |
|
426 TUint iSignals; // State of handshake lines |
|
427 TUint iFailSignals; // 1 bit means line low causes line fail error |
|
428 TUint iHoldSignals; // 1 bit means line low halts TX |
|
429 TUint iFlowControlSignals; // 1 bit means signal is used for RX flow control |
|
430 TUint iAutoSignals; // 1 bit means signal is high when channel is open |
|
431 TUint8 iTerminatorMask[32]; // 1 bit means character is a terminator |
|
432 TUint8 iStandby; // ETrue means the machine is transiting to/from standby |
|
433 TUint8 iMsgHeld; // ETrue means a message has been held up waiting the end of from standby transition |
|
434 |
|
435 // Min Turnaround time between Rx and Tx |
|
436 TUint iTurnaroundMicroSeconds; // delay after a receive before transmission in us |
|
437 TUint iTurnaroundMinMilliSeconds; // delay after a receive before transmission in ms |
|
438 TUint iTurnaroundTimerStartTime; // stores the start time of the turnaround timer. |
|
439 TUint8 iTurnaroundTimerStartTimeValid; // stores turnaround timer status 0 after boot, 1 if the timestamp is valid, and 2 if invalid |
|
440 TUint8 iTurnaroundTimerRunning; // a receive has started the timer |
|
441 TUint8 iTurnaroundTransmitDelayed; // a transmission is held until time elapses after a receive |
|
442 TUint8 iSpare; |
|
443 NTimer iTurnaroundTimer; // used to delay transmission after a receive |
|
444 TDfc iTurnaroundDfc; // used in interrupt space, to trigger a call in user space |
|
445 |
|
446 // RX buffer related items |
|
447 TUint8 *iRxCharBuf; // stores received characters |
|
448 TInt iRxBufSize; // Size of the LDD receive buffer. |
|
449 TUint8 *iRxErrorBuf; // stores received character error status |
|
450 volatile TInt iRxPutIndex; // Index for next RX char to be stored |
|
451 TInt iRxGetIndex; // Index for next RX char to be retrieved |
|
452 TInt iFlowControlLowerThreshold; // release flow control threshold |
|
453 TInt iFlowControlUpperThreshold; // assert flow control threshold |
|
454 TInt iRxDrainThreshold; // drain rx buffer before completion threshold |
|
455 TInt iRxBufCompleteIndex; // One after last char to be forwarded due to completion |
|
456 TBool iInputHeld; // TRUE if we have asserted flow control |
|
457 |
|
458 // RX client related items |
|
459 TClientSingleBufferRequest iRxBufReq; |
|
460 TInt iRxDesPos; // pos of next char to be stored in client descriptor |
|
461 TUint8 iRxOutstanding; // TRUE if a client read is outstanding |
|
462 TUint8 iNotifyData; // TRUE if data available notifier outstanding |
|
463 TInt iRxError; |
|
464 NTimer iTimer; // timer for ReadOneOrMore |
|
465 TInt iTimeout; // timeout period for ReadOneOrMore |
|
466 TInt iRxOneOrMore; |
|
467 |
|
468 // TX buffer related items |
|
469 TUint8 *iTxBuffer; // stores characters awaiting transmission |
|
470 TInt iTxPutIndex; // Index for next TX char to be stored |
|
471 volatile TInt iTxGetIndex; // Index for next TX char to be output |
|
472 TInt iTxBufSize; |
|
473 TInt iTxFillThreshold; // fill tx buffer threshold |
|
474 TInt iOutputHeld; // bits set if peer has asserted flow control |
|
475 TInt iJamChar; // character to jam into TX output stream |
|
476 |
|
477 // TX client related items |
|
478 TClientSingleBufferRequest iTxBufReq; |
|
479 TInt iTxDesPos; // pos of next char to be fetched from client descriptor |
|
480 TBool iTxOutstanding; // TRUE if a client write is outstanding |
|
481 TInt iTxError; |
|
482 |
|
483 // Signal change notification |
|
484 TUint iNotifiedSignals; |
|
485 TUint iSigNotifyMask; |
|
486 TClientDataRequest<TUint>* iSignalsReq; |
|
487 |
|
488 // hackery |
|
489 TVirtualPinObject* iPinObjSetConfig; |
|
490 TInt iReceived; |
|
491 |
|
492 // Break related items |
|
493 TInt iBreakTimeMicroSeconds; |
|
494 TTickLink iBreakTimer; // Used to time how long the break should last for |
|
495 TDfc iBreakDfc; |
|
496 TClientRequest* iBreakStatus; |
|
497 TBool iBreakDelayedTx; |
|
498 TBool iTurnaroundBreakDelayed; |
|
499 |
|
500 TSpinLock iLock; |
|
501 }; |
|
502 |
|
503 /** |
|
504 @internalComponent |
|
505 */ |
|
506 class DCommPowerHandler : public DPowerHandler |
|
507 { |
|
508 public: // from DPOwerHandler |
|
509 void PowerUp(); |
|
510 void PowerDown(TPowerState); |
|
511 public: |
|
512 DCommPowerHandler(DChannelComm* aChannel); |
|
513 public: |
|
514 DChannelComm* iChannel; |
|
515 }; |
|
516 |
|
517 #include <drivers/comm.inl> |
|
518 |
|
519 #endif |