kernel/eka/include/drivers/comm.h
changeset 0 a41df078684a
--- /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