author | mikek |
Sun, 27 Jun 2010 21:43:55 +0100 | |
branch | GCC_SURGE |
changeset 181 | bd8f1e65581b |
parent 0 | a41df078684a |
permissions | -rw-r--r-- |
// 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 <platform.h> #include <kernel/kpower.h> #include <d32comm.h> #include <e32ver.h> // 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<TUint>* 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 <drivers/comm.inl> #endif