--- /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 <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