diff -r 000000000000 -r a41df078684a kernel/eka/include/drivers/comm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/include/drivers/comm.h Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,519 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// e32\include\drivers\comm.h +// +// + +/** + @file + @internalComponent +*/ + +#ifndef __M32COMM_H__ +#define __M32COMM_H__ +#include +#include +#include +#include +// +const TInt KCommsMajorVersionNumber=1; +const TInt KCommsMinorVersionNumber=1; +const TInt KCommsBuildVersionNumber=KE32BuildVersionNumber; +// +const TInt KDefaultRxBufferSize=0x800; +const TInt KTxBufferSize=0x400; +const TInt KMaxHighWaterMark=0x080; +// +/** + @publishedPartner + @released +*/ +const TUint KReceiveIsrParityError=0x10000000; + +/** + @publishedPartner + @released +*/ +const TUint KReceiveIsrFrameError=0x20000000; + +/** + @publishedPartner + @released +*/ +const TUint KReceiveIsrOverrunError=0x40000000; + +/** + @publishedPartner + @released +*/ +const TUint KReceiveIsrBreakError=0x80000000; + +const TUint KReceiveIsrMaskError=0xF0000000; +// +const TInt KTxNoChar=-1; +// +const TUint KReceiveIsrTermChar=0x80000000; +const TUint KReceiveIsrMaskComplete=0xf0000000; +const TUint KReceiveIsrShift=24; +const TUint KReceiveIsrShiftedMask=0x0f; + +/** + @publishedPartner + @released +*/ +const TUint KDTEInputSignals=(KSignalCTS|KSignalDSR|KSignalDCD|KSignalRNG); + +/** + @publishedPartner + @released + + An enumeration listing the stopping modes supported by this driver, to be passed to the Stop function. +*/ +enum TStopMode + { + /** + Stopping due to normal operational reasons. + */ + EStopNormal, + /** + Stopping due to system power down. + */ + EStopPwrDown, + /** + Emergency stop. Deprecated. + */ + EStopEmergency + }; + + +class DChannelComm; + +/** + @publishedPartner + @released + + An abstract class for a serial comm PDD. +*/ +class DComm : public DBase + { +public: + /** + Starts receiving characters. + @return KErrNone if successful; otherwise one of the other system wide error codes. + */ + virtual TInt Start() =0; + + /** + Stops receiving characters. + @param aMode The stopping reason as one of TStopMode. + @see TStopMode + */ + virtual void Stop(TStopMode aMode) =0; + + /** + Starts or stop the uart breaking. + @param aState ETrue to enable break signal(LCR) and EFalse disable break signal(LCR). + */ + virtual void Break(TBool aState) =0; + + /** + Starts transmitting characters. + */ + virtual void EnableTransmit() =0; + + /** + Read and translate the modem control lines. + @return State changes. + For Example: + RTS, DSR, RI, Carrier Detect. + */ + virtual TUint Signals() const =0; + + /** + Set signals. + @param aSetMask A bit mask for those modem control signals which are to be asserted. + @param aClearMask A bit mask for those modem control signals which are to be de-asserted. + Each bit in the bit masks above corresponds to a modem control signal. + Bits are defined as one of: + KSignalCTS + KSignalDSR + KSignalDCD + KSignalRNG + KSignalRTS + KSignalDTR + KSignalBreak + + */ + virtual void SetSignals(TUint aSetMask,TUint aClearMask) =0; + + /** + Validates a new configuration. + @param aConfig Const reference to the comms configuration structure; to hold the configuration settings for serial comm port. + @return KErrNone if successful; otherwise one of the other system wide error codes. + @see TCommConfigV01 + */ + virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const =0; + + /** + Configures the hardware device. This is device specific API, that provides functionality to configure the uart. + @param aConfig configuration settings for the device. + @see TCommConfigV01 + */ + virtual void Configure(TCommConfigV01 &aConfig) =0; + + /** + Gets the capabilities of the comm PDD. + @param aCaps On return this descriptor should have been filled with capabilities. + */ + virtual void Caps(TDes8 &aCaps) const =0; + + /** + Checks the configuration. + @param aConfig A reference to the structure TCommConfigV01 with configuration to check. + @see TCommConfigV01 + */ + virtual void CheckConfig(TCommConfigV01& aConfig)=0; + + /** + Disable all IRQs. + @return The state of the interrupts before disable, which is used to restore the interrupt state. + */ + virtual TInt DisableIrqs()=0; + + /** + Restore IRQs to the passed level. + @param aIrq The level to restore the IRQs to. + */ + virtual void RestoreIrqs(TInt aIrq)=0; + + /** + Returns a pointer to the DFC queue that should be used by the comm LDD. + @param aUnit Unit for which the DfcQ is retrieved. + @return A Pointer to the DFC queue that should be used by the USB LDD. + @see TDfcQue + */ + virtual TDfcQue* DfcQ(TInt aUnit)=0; + + /** + Checks power status. + @return ETrue if status is good, EFalse otherwise. + */ + inline TBool PowerGood(); + inline void SetCurrent(TInt aCurrent); + inline void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff); + inline TInt TransmitIsr(); + inline void CheckTxBuffer(); + inline void StateIsr(TUint aSignals); + inline TBool Transmitting(); +public: + /** + Pointer to the logical channel object which is derived from DLogicChannel. + */ + DChannelComm *iLdd; + /** + A Boolean flag to indicate when transmission is in progress [ETrue=(Trasnmission in progress)]. + */ + TBool iTransmitting; + }; + +/** +@internalComponent +*/ +class DDeviceComm : public DLogicalDevice + { +public: + DDeviceComm(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + + +// +// TClientSingleBufferRequest +// +class TClientSingleBufferRequest +{ +public: + TClientSingleBufferRequest() + { + Reset(); + } + ~TClientSingleBufferRequest() + { + if (iBufReq) + Kern::DestroyClientBufferRequest(iBufReq); + Reset(); + } + void Reset() + { + iBufReq = NULL; + iBuf = NULL; + iLen = 0; + } + TInt Create() + { + if (iBufReq) + return KErrNone; + TInt r = Kern::CreateClientBufferRequest(iBufReq, 1, TClientBufferRequest::EPinVirtual); + return r; + } + TInt Setup(TRequestStatus* aStatus, TAny* aDes, TInt aLen=0) + { + TInt r = iBufReq->Setup(iBuf, aStatus, aDes); + if (r == KErrNone) + iLen = aLen; + return r; + } + TInt SetupFromPtr(TRequestStatus* aStatus, TLinAddr aPtr, TInt aLen) + { + TInt r = iBufReq->Setup(iBuf, aStatus, aPtr, aLen); + iLen = aLen; + return r; + } + void Complete(DThread* aClient, TInt aReason) + { + if (iBufReq) + { + iBuf = NULL; + Kern::QueueBufferRequestComplete(aClient, iBufReq, aReason); + } + } + TClientBufferRequest* iBufReq; + TClientBuffer* iBuf; + TInt iLen; +}; + +class DCommPowerHandler; +/** +@internalComponent +*/ +class DChannelComm : public DLogicalChannel + { +public: + enum TState {EOpen,EActive,EClosed}; + enum TRequest {ERx=1, ETx=2, ESigChg=4, EBreak=8, EAll=0xff}; + + DChannelComm(); + ~DChannelComm(); + virtual void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff); + virtual void CheckTxBuffer(); + virtual void StateIsr(TUint aSignals); + virtual TInt TransmitIsr(); + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); + + /** @publishedPartner + @released */ + virtual void UpdateSignals(TUint aSignals); + inline void SetStatus(TState aStatus); + virtual TInt SendMsg(TMessageBase* aMsg); +protected: + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void HandleMsg(TMessageBase* aMsg); + void DoCancel(TInt aMask); + TInt DoControl(TInt aId, TAny* a1, TAny* a2); + void DoRequest(TInt aId, TAny* a1, TAny* a2); + void DoPowerUp(); + void Start(); + TInt Shutdown(); + void BreakOn(); + void BreakOff(); + void AssertFlowControl(); + void ReleaseFlowControl(); + TInt SetRxBufferSize(TInt aSize); + void ResetBuffers(TBool aResetTx); + void DoDrainRxBuffer(TInt aEndIndex); + void DoFillTxBuffer(); + void DoCompleteRx(); + void DoCompleteTx(); + void Complete(TInt aMask, TInt aReason); + inline void DrainRxBuffer() { iRxDrainDfc.Add(); } + inline void RxComplete(); + inline void TxComplete(); +protected: + inline void EnableTransmit(); + inline TInt IsLineFail(TUint aFailSignals); + inline TInt PddStart(); + inline void Stop(TStopMode aMode); + inline void PddBreak(TBool aState); + inline TUint Signals() const; + inline void SetSignals(TUint aSetMask,TUint aClearMask); + inline TInt ValidateConfig(const TCommConfigV01 &aConfig) const; + inline void PddConfigure(TCommConfigV01 &aConfig); + inline void PddCaps(TDes8 &aCaps) const; + inline void PddCheckConfig(TCommConfigV01& aConfig); + inline TBool Transmitting(); +private: + static void PowerUpDfc(TAny* aPtr); + static void PowerDownDfc(TAny* aPtr); + static void DrainRxDfc(TAny* aPtr); + static void FillTxDfc(TAny* aPtr); + static void CompleteRxDfc(TAny* aPtr); + static void CompleteTxDfc(TAny* aPtr); + static void TimerDfcFn(TAny* aPtr); + static void SigNotifyDfc(TAny* aPtr); + void TimerDfc(); + static void MsCallBack(TAny* aPtr); + inline TBool IsTerminator(TUint8 aChar); + inline void SetTerminator(TUint8 aChar); + inline TInt RxCount(); + inline TInt TxCount(); + inline TBool AreAnyPending() const; + void InitiateRead(TInt aLength); + void InitiateWrite(); + void DoSigNotify(); + void UpdateAndProcessSignals(); + + + TUint FailSignals(TUint aHandshake); + TUint HoldSignals(TUint aHandshake); + TUint FlowControlSignals(TUint aHandshake); + TUint AutoSignals(TUint aHandshake); + TInt SetConfig(TCommConfigV01& aConfig); + void CheckOutputHeld(); + void RestartDelayedTransmission(); + + static void FinishBreak(TAny* aSelf); // Called when timer indicating break should finish expires + void QueueFinishBreakDfc(); // Called to queue dfc to finish break + static void FinishBreakDfc(TAny* aSelf); // Dfc called to finish break + void FinishBreakImplementation(TInt aError); // Actual implementation to finish break + +public: + // Port configuration + TCommConfigV01 iConfig; + + /** @publishedPartner + @released */ + TUint iRxXonChar; + + /** @publishedPartner + @released */ + TUint iRxXoffChar; + + TInt TurnaroundSet(TUint aNewTurnaroundMilliSeconds); + TBool TurnaroundStopTimer(); + TInt TurnaroundClear(); + TInt RestartTurnaroundTimer(); + static void TurnaroundStartDfc(TAny* aSelf); + void TurnaroundStartDfcImplementation(TBool inIsr); + static void TurnaroundTimeout(TAny* aSelf); + void TurnaroundTimeoutImplementation(); + + // General items + DThread* iClient; + DCommPowerHandler* iPowerHandler; + TDfc iPowerUpDfc; + TDfc iPowerDownDfc; + TState iStatus; + TDfc iRxDrainDfc; + TDfc iRxCompleteDfc; + TDfc iTxFillDfc; + TDfc iTxCompleteDfc; + TDfc iTimerDfc; + TDfc iSigNotifyDfc; + TUint iFlags; // + TUint iSignals; // State of handshake lines + TUint iFailSignals; // 1 bit means line low causes line fail error + TUint iHoldSignals; // 1 bit means line low halts TX + TUint iFlowControlSignals; // 1 bit means signal is used for RX flow control + TUint iAutoSignals; // 1 bit means signal is high when channel is open + TUint8 iTerminatorMask[32]; // 1 bit means character is a terminator + TUint8 iStandby; // ETrue means the machine is transiting to/from standby + TUint8 iMsgHeld; // ETrue means a message has been held up waiting the end of from standby transition + + // Min Turnaround time between Rx and Tx + TUint iTurnaroundMicroSeconds; // delay after a receive before transmission in us + TUint iTurnaroundMinMilliSeconds; // delay after a receive before transmission in ms + TUint iTurnaroundTimerStartTime; // stores the start time of the turnaround timer. + TUint8 iTurnaroundTimerStartTimeValid; // stores turnaround timer status 0 after boot, 1 if the timestamp is valid, and 2 if invalid + TUint8 iTurnaroundTimerRunning; // a receive has started the timer + TUint8 iTurnaroundTransmitDelayed; // a transmission is held until time elapses after a receive + TUint8 iSpare; + NTimer iTurnaroundTimer; // used to delay transmission after a receive + TDfc iTurnaroundDfc; // used in interrupt space, to trigger a call in user space + + // RX buffer related items + TUint8 *iRxCharBuf; // stores received characters + TInt iRxBufSize; // Size of the LDD receive buffer. + TUint8 *iRxErrorBuf; // stores received character error status + volatile TInt iRxPutIndex; // Index for next RX char to be stored + TInt iRxGetIndex; // Index for next RX char to be retrieved + TInt iFlowControlLowerThreshold; // release flow control threshold + TInt iFlowControlUpperThreshold; // assert flow control threshold + TInt iRxDrainThreshold; // drain rx buffer before completion threshold + TInt iRxBufCompleteIndex; // One after last char to be forwarded due to completion + TBool iInputHeld; // TRUE if we have asserted flow control + + // RX client related items + TClientSingleBufferRequest iRxBufReq; + TInt iRxDesPos; // pos of next char to be stored in client descriptor + TUint8 iRxOutstanding; // TRUE if a client read is outstanding + TUint8 iNotifyData; // TRUE if data available notifier outstanding + TInt iRxError; + NTimer iTimer; // timer for ReadOneOrMore + TInt iTimeout; // timeout period for ReadOneOrMore + TInt iRxOneOrMore; + + // TX buffer related items + TUint8 *iTxBuffer; // stores characters awaiting transmission + TInt iTxPutIndex; // Index for next TX char to be stored + volatile TInt iTxGetIndex; // Index for next TX char to be output + TInt iTxBufSize; + TInt iTxFillThreshold; // fill tx buffer threshold + TInt iOutputHeld; // bits set if peer has asserted flow control + TInt iJamChar; // character to jam into TX output stream + + // TX client related items + TClientSingleBufferRequest iTxBufReq; + TInt iTxDesPos; // pos of next char to be fetched from client descriptor + TBool iTxOutstanding; // TRUE if a client write is outstanding + TInt iTxError; + + // Signal change notification + TUint iNotifiedSignals; + TUint iSigNotifyMask; + TClientDataRequest* iSignalsReq; + + // hackery + TVirtualPinObject* iPinObjSetConfig; + TInt iReceived; + + // Break related items + TInt iBreakTimeMicroSeconds; + TTickLink iBreakTimer; // Used to time how long the break should last for + TDfc iBreakDfc; + TClientRequest* iBreakStatus; + TBool iBreakDelayedTx; + TBool iTurnaroundBreakDelayed; + + TSpinLock iLock; + }; + +/** +@internalComponent +*/ +class DCommPowerHandler : public DPowerHandler + { +public: // from DPOwerHandler + void PowerUp(); + void PowerDown(TPowerState); +public: + DCommPowerHandler(DChannelComm* aChannel); +public: + DChannelComm* iChannel; + }; + +#include + +#endif