1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/comm.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,519 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\drivers\comm.h
1.18 +//
1.19 +//
1.20 +
1.21 +/**
1.22 + @file
1.23 + @internalComponent
1.24 +*/
1.25 +
1.26 +#ifndef __M32COMM_H__
1.27 +#define __M32COMM_H__
1.28 +#include <platform.h>
1.29 +#include <kernel/kpower.h>
1.30 +#include <d32comm.h>
1.31 +#include <e32ver.h>
1.32 +//
1.33 +const TInt KCommsMajorVersionNumber=1;
1.34 +const TInt KCommsMinorVersionNumber=1;
1.35 +const TInt KCommsBuildVersionNumber=KE32BuildVersionNumber;
1.36 +//
1.37 +const TInt KDefaultRxBufferSize=0x800;
1.38 +const TInt KTxBufferSize=0x400;
1.39 +const TInt KMaxHighWaterMark=0x080;
1.40 +//
1.41 +/**
1.42 + @publishedPartner
1.43 + @released
1.44 +*/
1.45 +const TUint KReceiveIsrParityError=0x10000000;
1.46 +
1.47 +/**
1.48 + @publishedPartner
1.49 + @released
1.50 +*/
1.51 +const TUint KReceiveIsrFrameError=0x20000000;
1.52 +
1.53 +/**
1.54 + @publishedPartner
1.55 + @released
1.56 +*/
1.57 +const TUint KReceiveIsrOverrunError=0x40000000;
1.58 +
1.59 +/**
1.60 + @publishedPartner
1.61 + @released
1.62 +*/
1.63 +const TUint KReceiveIsrBreakError=0x80000000;
1.64 +
1.65 +const TUint KReceiveIsrMaskError=0xF0000000;
1.66 +//
1.67 +const TInt KTxNoChar=-1;
1.68 +//
1.69 +const TUint KReceiveIsrTermChar=0x80000000;
1.70 +const TUint KReceiveIsrMaskComplete=0xf0000000;
1.71 +const TUint KReceiveIsrShift=24;
1.72 +const TUint KReceiveIsrShiftedMask=0x0f;
1.73 +
1.74 +/**
1.75 + @publishedPartner
1.76 + @released
1.77 +*/
1.78 +const TUint KDTEInputSignals=(KSignalCTS|KSignalDSR|KSignalDCD|KSignalRNG);
1.79 +
1.80 +/**
1.81 + @publishedPartner
1.82 + @released
1.83 +
1.84 + An enumeration listing the stopping modes supported by this driver, to be passed to the Stop function.
1.85 +*/
1.86 +enum TStopMode
1.87 + {
1.88 + /**
1.89 + Stopping due to normal operational reasons.
1.90 + */
1.91 + EStopNormal,
1.92 + /**
1.93 + Stopping due to system power down.
1.94 + */
1.95 + EStopPwrDown,
1.96 + /**
1.97 + Emergency stop. Deprecated.
1.98 + */
1.99 + EStopEmergency
1.100 + };
1.101 +
1.102 +
1.103 +class DChannelComm;
1.104 +
1.105 +/**
1.106 + @publishedPartner
1.107 + @released
1.108 +
1.109 + An abstract class for a serial comm PDD.
1.110 +*/
1.111 +class DComm : public DBase
1.112 + {
1.113 +public:
1.114 + /**
1.115 + Starts receiving characters.
1.116 + @return KErrNone if successful; otherwise one of the other system wide error codes.
1.117 + */
1.118 + virtual TInt Start() =0;
1.119 +
1.120 + /**
1.121 + Stops receiving characters.
1.122 + @param aMode The stopping reason as one of TStopMode.
1.123 + @see TStopMode
1.124 + */
1.125 + virtual void Stop(TStopMode aMode) =0;
1.126 +
1.127 + /**
1.128 + Starts or stop the uart breaking.
1.129 + @param aState ETrue to enable break signal(LCR) and EFalse disable break signal(LCR).
1.130 + */
1.131 + virtual void Break(TBool aState) =0;
1.132 +
1.133 + /**
1.134 + Starts transmitting characters.
1.135 + */
1.136 + virtual void EnableTransmit() =0;
1.137 +
1.138 + /**
1.139 + Read and translate the modem control lines.
1.140 + @return State changes.
1.141 + For Example:
1.142 + RTS, DSR, RI, Carrier Detect.
1.143 + */
1.144 + virtual TUint Signals() const =0;
1.145 +
1.146 + /**
1.147 + Set signals.
1.148 + @param aSetMask A bit mask for those modem control signals which are to be asserted.
1.149 + @param aClearMask A bit mask for those modem control signals which are to be de-asserted.
1.150 + Each bit in the bit masks above corresponds to a modem control signal.
1.151 + Bits are defined as one of:
1.152 + KSignalCTS
1.153 + KSignalDSR
1.154 + KSignalDCD
1.155 + KSignalRNG
1.156 + KSignalRTS
1.157 + KSignalDTR
1.158 + KSignalBreak
1.159 +
1.160 + */
1.161 + virtual void SetSignals(TUint aSetMask,TUint aClearMask) =0;
1.162 +
1.163 + /**
1.164 + Validates a new configuration.
1.165 + @param aConfig Const reference to the comms configuration structure; to hold the configuration settings for serial comm port.
1.166 + @return KErrNone if successful; otherwise one of the other system wide error codes.
1.167 + @see TCommConfigV01
1.168 + */
1.169 + virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const =0;
1.170 +
1.171 + /**
1.172 + Configures the hardware device. This is device specific API, that provides functionality to configure the uart.
1.173 + @param aConfig configuration settings for the device.
1.174 + @see TCommConfigV01
1.175 + */
1.176 + virtual void Configure(TCommConfigV01 &aConfig) =0;
1.177 +
1.178 + /**
1.179 + Gets the capabilities of the comm PDD.
1.180 + @param aCaps On return this descriptor should have been filled with capabilities.
1.181 + */
1.182 + virtual void Caps(TDes8 &aCaps) const =0;
1.183 +
1.184 + /**
1.185 + Checks the configuration.
1.186 + @param aConfig A reference to the structure TCommConfigV01 with configuration to check.
1.187 + @see TCommConfigV01
1.188 + */
1.189 + virtual void CheckConfig(TCommConfigV01& aConfig)=0;
1.190 +
1.191 + /**
1.192 + Disable all IRQs.
1.193 + @return The state of the interrupts before disable, which is used to restore the interrupt state.
1.194 + */
1.195 + virtual TInt DisableIrqs()=0;
1.196 +
1.197 + /**
1.198 + Restore IRQs to the passed level.
1.199 + @param aIrq The level to restore the IRQs to.
1.200 + */
1.201 + virtual void RestoreIrqs(TInt aIrq)=0;
1.202 +
1.203 + /**
1.204 + Returns a pointer to the DFC queue that should be used by the comm LDD.
1.205 + @param aUnit Unit for which the DfcQ is retrieved.
1.206 + @return A Pointer to the DFC queue that should be used by the USB LDD.
1.207 + @see TDfcQue
1.208 + */
1.209 + virtual TDfcQue* DfcQ(TInt aUnit)=0;
1.210 +
1.211 + /**
1.212 + Checks power status.
1.213 + @return ETrue if status is good, EFalse otherwise.
1.214 + */
1.215 + inline TBool PowerGood();
1.216 + inline void SetCurrent(TInt aCurrent);
1.217 + inline void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff);
1.218 + inline TInt TransmitIsr();
1.219 + inline void CheckTxBuffer();
1.220 + inline void StateIsr(TUint aSignals);
1.221 + inline TBool Transmitting();
1.222 +public:
1.223 + /**
1.224 + Pointer to the logical channel object which is derived from DLogicChannel.
1.225 + */
1.226 + DChannelComm *iLdd;
1.227 + /**
1.228 + A Boolean flag to indicate when transmission is in progress [ETrue=(Trasnmission in progress)].
1.229 + */
1.230 + TBool iTransmitting;
1.231 + };
1.232 +
1.233 +/**
1.234 +@internalComponent
1.235 +*/
1.236 +class DDeviceComm : public DLogicalDevice
1.237 + {
1.238 +public:
1.239 + DDeviceComm();
1.240 + virtual TInt Install();
1.241 + virtual void GetCaps(TDes8 &aDes) const;
1.242 + virtual TInt Create(DLogicalChannelBase*& aChannel);
1.243 + };
1.244 +
1.245 +
1.246 +//
1.247 +// TClientSingleBufferRequest
1.248 +//
1.249 +class TClientSingleBufferRequest
1.250 +{
1.251 +public:
1.252 + TClientSingleBufferRequest()
1.253 + {
1.254 + Reset();
1.255 + }
1.256 + ~TClientSingleBufferRequest()
1.257 + {
1.258 + if (iBufReq)
1.259 + Kern::DestroyClientBufferRequest(iBufReq);
1.260 + Reset();
1.261 + }
1.262 + void Reset()
1.263 + {
1.264 + iBufReq = NULL;
1.265 + iBuf = NULL;
1.266 + iLen = 0;
1.267 + }
1.268 + TInt Create()
1.269 + {
1.270 + if (iBufReq)
1.271 + return KErrNone;
1.272 + TInt r = Kern::CreateClientBufferRequest(iBufReq, 1, TClientBufferRequest::EPinVirtual);
1.273 + return r;
1.274 + }
1.275 + TInt Setup(TRequestStatus* aStatus, TAny* aDes, TInt aLen=0)
1.276 + {
1.277 + TInt r = iBufReq->Setup(iBuf, aStatus, aDes);
1.278 + if (r == KErrNone)
1.279 + iLen = aLen;
1.280 + return r;
1.281 + }
1.282 + TInt SetupFromPtr(TRequestStatus* aStatus, TLinAddr aPtr, TInt aLen)
1.283 + {
1.284 + TInt r = iBufReq->Setup(iBuf, aStatus, aPtr, aLen);
1.285 + iLen = aLen;
1.286 + return r;
1.287 + }
1.288 + void Complete(DThread* aClient, TInt aReason)
1.289 + {
1.290 + if (iBufReq)
1.291 + {
1.292 + iBuf = NULL;
1.293 + Kern::QueueBufferRequestComplete(aClient, iBufReq, aReason);
1.294 + }
1.295 + }
1.296 + TClientBufferRequest* iBufReq;
1.297 + TClientBuffer* iBuf;
1.298 + TInt iLen;
1.299 +};
1.300 +
1.301 +class DCommPowerHandler;
1.302 +/**
1.303 +@internalComponent
1.304 +*/
1.305 +class DChannelComm : public DLogicalChannel
1.306 + {
1.307 +public:
1.308 + enum TState {EOpen,EActive,EClosed};
1.309 + enum TRequest {ERx=1, ETx=2, ESigChg=4, EBreak=8, EAll=0xff};
1.310 +
1.311 + DChannelComm();
1.312 + ~DChannelComm();
1.313 + virtual void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff);
1.314 + virtual void CheckTxBuffer();
1.315 + virtual void StateIsr(TUint aSignals);
1.316 + virtual TInt TransmitIsr();
1.317 + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
1.318 +
1.319 + /** @publishedPartner
1.320 + @released */
1.321 + virtual void UpdateSignals(TUint aSignals);
1.322 + inline void SetStatus(TState aStatus);
1.323 + virtual TInt SendMsg(TMessageBase* aMsg);
1.324 +protected:
1.325 + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.326 + virtual void HandleMsg(TMessageBase* aMsg);
1.327 + void DoCancel(TInt aMask);
1.328 + TInt DoControl(TInt aId, TAny* a1, TAny* a2);
1.329 + void DoRequest(TInt aId, TAny* a1, TAny* a2);
1.330 + void DoPowerUp();
1.331 + void Start();
1.332 + TInt Shutdown();
1.333 + void BreakOn();
1.334 + void BreakOff();
1.335 + void AssertFlowControl();
1.336 + void ReleaseFlowControl();
1.337 + TInt SetRxBufferSize(TInt aSize);
1.338 + void ResetBuffers(TBool aResetTx);
1.339 + void DoDrainRxBuffer(TInt aEndIndex);
1.340 + void DoFillTxBuffer();
1.341 + void DoCompleteRx();
1.342 + void DoCompleteTx();
1.343 + void Complete(TInt aMask, TInt aReason);
1.344 + inline void DrainRxBuffer() { iRxDrainDfc.Add(); }
1.345 + inline void RxComplete();
1.346 + inline void TxComplete();
1.347 +protected:
1.348 + inline void EnableTransmit();
1.349 + inline TInt IsLineFail(TUint aFailSignals);
1.350 + inline TInt PddStart();
1.351 + inline void Stop(TStopMode aMode);
1.352 + inline void PddBreak(TBool aState);
1.353 + inline TUint Signals() const;
1.354 + inline void SetSignals(TUint aSetMask,TUint aClearMask);
1.355 + inline TInt ValidateConfig(const TCommConfigV01 &aConfig) const;
1.356 + inline void PddConfigure(TCommConfigV01 &aConfig);
1.357 + inline void PddCaps(TDes8 &aCaps) const;
1.358 + inline void PddCheckConfig(TCommConfigV01& aConfig);
1.359 + inline TBool Transmitting();
1.360 +private:
1.361 + static void PowerUpDfc(TAny* aPtr);
1.362 + static void PowerDownDfc(TAny* aPtr);
1.363 + static void DrainRxDfc(TAny* aPtr);
1.364 + static void FillTxDfc(TAny* aPtr);
1.365 + static void CompleteRxDfc(TAny* aPtr);
1.366 + static void CompleteTxDfc(TAny* aPtr);
1.367 + static void TimerDfcFn(TAny* aPtr);
1.368 + static void SigNotifyDfc(TAny* aPtr);
1.369 + void TimerDfc();
1.370 + static void MsCallBack(TAny* aPtr);
1.371 + inline TBool IsTerminator(TUint8 aChar);
1.372 + inline void SetTerminator(TUint8 aChar);
1.373 + inline TInt RxCount();
1.374 + inline TInt TxCount();
1.375 + inline TBool AreAnyPending() const;
1.376 + void InitiateRead(TInt aLength);
1.377 + void InitiateWrite();
1.378 + void DoSigNotify();
1.379 + void UpdateAndProcessSignals();
1.380 +
1.381 +
1.382 + TUint FailSignals(TUint aHandshake);
1.383 + TUint HoldSignals(TUint aHandshake);
1.384 + TUint FlowControlSignals(TUint aHandshake);
1.385 + TUint AutoSignals(TUint aHandshake);
1.386 + TInt SetConfig(TCommConfigV01& aConfig);
1.387 + void CheckOutputHeld();
1.388 + void RestartDelayedTransmission();
1.389 +
1.390 + static void FinishBreak(TAny* aSelf); // Called when timer indicating break should finish expires
1.391 + void QueueFinishBreakDfc(); // Called to queue dfc to finish break
1.392 + static void FinishBreakDfc(TAny* aSelf); // Dfc called to finish break
1.393 + void FinishBreakImplementation(TInt aError); // Actual implementation to finish break
1.394 +
1.395 +public:
1.396 + // Port configuration
1.397 + TCommConfigV01 iConfig;
1.398 +
1.399 + /** @publishedPartner
1.400 + @released */
1.401 + TUint iRxXonChar;
1.402 +
1.403 + /** @publishedPartner
1.404 + @released */
1.405 + TUint iRxXoffChar;
1.406 +
1.407 + TInt TurnaroundSet(TUint aNewTurnaroundMilliSeconds);
1.408 + TBool TurnaroundStopTimer();
1.409 + TInt TurnaroundClear();
1.410 + TInt RestartTurnaroundTimer();
1.411 + static void TurnaroundStartDfc(TAny* aSelf);
1.412 + void TurnaroundStartDfcImplementation(TBool inIsr);
1.413 + static void TurnaroundTimeout(TAny* aSelf);
1.414 + void TurnaroundTimeoutImplementation();
1.415 +
1.416 + // General items
1.417 + DThread* iClient;
1.418 + DCommPowerHandler* iPowerHandler;
1.419 + TDfc iPowerUpDfc;
1.420 + TDfc iPowerDownDfc;
1.421 + TState iStatus;
1.422 + TDfc iRxDrainDfc;
1.423 + TDfc iRxCompleteDfc;
1.424 + TDfc iTxFillDfc;
1.425 + TDfc iTxCompleteDfc;
1.426 + TDfc iTimerDfc;
1.427 + TDfc iSigNotifyDfc;
1.428 + TUint iFlags; //
1.429 + TUint iSignals; // State of handshake lines
1.430 + TUint iFailSignals; // 1 bit means line low causes line fail error
1.431 + TUint iHoldSignals; // 1 bit means line low halts TX
1.432 + TUint iFlowControlSignals; // 1 bit means signal is used for RX flow control
1.433 + TUint iAutoSignals; // 1 bit means signal is high when channel is open
1.434 + TUint8 iTerminatorMask[32]; // 1 bit means character is a terminator
1.435 + TUint8 iStandby; // ETrue means the machine is transiting to/from standby
1.436 + TUint8 iMsgHeld; // ETrue means a message has been held up waiting the end of from standby transition
1.437 +
1.438 + // Min Turnaround time between Rx and Tx
1.439 + TUint iTurnaroundMicroSeconds; // delay after a receive before transmission in us
1.440 + TUint iTurnaroundMinMilliSeconds; // delay after a receive before transmission in ms
1.441 + TUint iTurnaroundTimerStartTime; // stores the start time of the turnaround timer.
1.442 + TUint8 iTurnaroundTimerStartTimeValid; // stores turnaround timer status 0 after boot, 1 if the timestamp is valid, and 2 if invalid
1.443 + TUint8 iTurnaroundTimerRunning; // a receive has started the timer
1.444 + TUint8 iTurnaroundTransmitDelayed; // a transmission is held until time elapses after a receive
1.445 + TUint8 iSpare;
1.446 + NTimer iTurnaroundTimer; // used to delay transmission after a receive
1.447 + TDfc iTurnaroundDfc; // used in interrupt space, to trigger a call in user space
1.448 +
1.449 + // RX buffer related items
1.450 + TUint8 *iRxCharBuf; // stores received characters
1.451 + TInt iRxBufSize; // Size of the LDD receive buffer.
1.452 + TUint8 *iRxErrorBuf; // stores received character error status
1.453 + volatile TInt iRxPutIndex; // Index for next RX char to be stored
1.454 + TInt iRxGetIndex; // Index for next RX char to be retrieved
1.455 + TInt iFlowControlLowerThreshold; // release flow control threshold
1.456 + TInt iFlowControlUpperThreshold; // assert flow control threshold
1.457 + TInt iRxDrainThreshold; // drain rx buffer before completion threshold
1.458 + TInt iRxBufCompleteIndex; // One after last char to be forwarded due to completion
1.459 + TBool iInputHeld; // TRUE if we have asserted flow control
1.460 +
1.461 + // RX client related items
1.462 + TClientSingleBufferRequest iRxBufReq;
1.463 + TInt iRxDesPos; // pos of next char to be stored in client descriptor
1.464 + TUint8 iRxOutstanding; // TRUE if a client read is outstanding
1.465 + TUint8 iNotifyData; // TRUE if data available notifier outstanding
1.466 + TInt iRxError;
1.467 + NTimer iTimer; // timer for ReadOneOrMore
1.468 + TInt iTimeout; // timeout period for ReadOneOrMore
1.469 + TInt iRxOneOrMore;
1.470 +
1.471 + // TX buffer related items
1.472 + TUint8 *iTxBuffer; // stores characters awaiting transmission
1.473 + TInt iTxPutIndex; // Index for next TX char to be stored
1.474 + volatile TInt iTxGetIndex; // Index for next TX char to be output
1.475 + TInt iTxBufSize;
1.476 + TInt iTxFillThreshold; // fill tx buffer threshold
1.477 + TInt iOutputHeld; // bits set if peer has asserted flow control
1.478 + TInt iJamChar; // character to jam into TX output stream
1.479 +
1.480 + // TX client related items
1.481 + TClientSingleBufferRequest iTxBufReq;
1.482 + TInt iTxDesPos; // pos of next char to be fetched from client descriptor
1.483 + TBool iTxOutstanding; // TRUE if a client write is outstanding
1.484 + TInt iTxError;
1.485 +
1.486 + // Signal change notification
1.487 + TUint iNotifiedSignals;
1.488 + TUint iSigNotifyMask;
1.489 + TClientDataRequest<TUint>* iSignalsReq;
1.490 +
1.491 + // hackery
1.492 + TVirtualPinObject* iPinObjSetConfig;
1.493 + TInt iReceived;
1.494 +
1.495 + // Break related items
1.496 + TInt iBreakTimeMicroSeconds;
1.497 + TTickLink iBreakTimer; // Used to time how long the break should last for
1.498 + TDfc iBreakDfc;
1.499 + TClientRequest* iBreakStatus;
1.500 + TBool iBreakDelayedTx;
1.501 + TBool iTurnaroundBreakDelayed;
1.502 +
1.503 + TSpinLock iLock;
1.504 + };
1.505 +
1.506 +/**
1.507 +@internalComponent
1.508 +*/
1.509 +class DCommPowerHandler : public DPowerHandler
1.510 + {
1.511 +public: // from DPOwerHandler
1.512 + void PowerUp();
1.513 + void PowerDown(TPowerState);
1.514 +public:
1.515 + DCommPowerHandler(DChannelComm* aChannel);
1.516 +public:
1.517 + DChannelComm* iChannel;
1.518 + };
1.519 +
1.520 +#include <drivers/comm.inl>
1.521 +
1.522 +#endif