kernel/eka/drivers/iic/iic_channel.cpp
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
equal deleted inserted replaced
43:c1f20ce4abcf 44:3e88ff8f41d5
   127 		}
   127 		}
   128 	}
   128 	}
   129 
   129 
   130 void DIicBusChannelMaster::CompleteRequest(TInt aResult)
   130 void DIicBusChannelMaster::CompleteRequest(TInt aResult)
   131 	{
   131 	{
   132 	// Ensure the timeout timer has been cancelled
       
   133 	CancelTimeOut();
       
   134 
       
   135 	TIicBusTransaction* nextTrans=NextTrans(iCurrentTransaction);
   132 	TIicBusTransaction* nextTrans=NextTrans(iCurrentTransaction);
   136 
   133 
   137 	if((aResult != KErrNone)||(nextTrans == NULL))
   134 	if((aResult != KErrNone)||(nextTrans == NULL))
   138 		EndTransaction(iTransaction,aResult,iTransaction->iCallback);
   135 		EndTransaction(iTransaction,aResult,iTransaction->iCallback);
   139 	else
   136 	else
   357 		}
   354 		}
   358 	}
   355 	}
   359 
   356 
   360 void DIicBusChannelMaster::CancelTimeOut()
   357 void DIicBusChannelMaster::CancelTimeOut()
   361 	{
   358 	{
   362 	// Silently cancel the timer and associated DFC
       
   363 	//
       
   364 	// NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
       
   365 	// TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
       
   366 	//
       
   367 	iTimeoutTimer.Cancel();
   359 	iTimeoutTimer.Cancel();
   368 	iSlaveTimeoutDfc->Cancel();
       
   369 	}
   360 	}
   370 
   361 
   371 void DIicBusChannelMaster::Complete(TInt aResult, TIicBusTransaction* aTransaction) //Completes a kernel message and receive the next one
   362 void DIicBusChannelMaster::Complete(TInt aResult, TIicBusTransaction* aTransaction) //Completes a kernel message and receive the next one
   372 	{
   363 	{
   373 	__KTRACE_OPT(KIIC, Kern::Printf("MsgB::Complete %08x, %d",this,aResult));
   364 	__KTRACE_OPT(KIIC, Kern::Printf("MsgB::Complete %08x, %d",this,aResult));
   488 		return KErrAccessDenied;
   479 		return KErrAccessDenied;
   489 
   480 
   490 	r=SetNotificationTrigger(0);			// Attempt to clear notification requests
   481 	r=SetNotificationTrigger(0);			// Attempt to clear notification requests
   491 	if((r!=KErrNone)&&(r!=KErrTimedOut))	// KErrTimedOut refers to an earlier transaction, and is for information only
   482 	if((r!=KErrNone)&&(r!=KErrTimedOut))	// KErrTimedOut refers to an earlier transaction, and is for information only
   492 		return r;
   483 		return r;
   493 	StopTimer();
   484 	iTimeoutTimer.Cancel();
   494 	r=DoRequest(EPowerDown);
   485 	r=DoRequest(EPowerDown);
   495 	if(r == KErrNone)
   486 	if(r == KErrNone)
   496 		{
   487 		{
   497 		TInt intState=__SPIN_LOCK_IRQSAVE(iSpinLock);
   488 		TInt intState=__SPIN_LOCK_IRQSAVE(iSpinLock);
   498 		iClient=NULL;
   489 		iClient=NULL;
   895 		}
   886 		}
   896 	}
   887 	}
   897 
   888 
   898 void DIicBusChannelSlave::StopTimer()
   889 void DIicBusChannelSlave::StopTimer()
   899 	{
   890 	{
   900 	// Silently cancel the timer and associated DFC
       
   901 	//
       
   902 	// NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
       
   903 	// TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
       
   904 	//
       
   905 	iTimeoutTimer.Cancel();
   891 	iTimeoutTimer.Cancel();
   906 	iClientTimeoutDfc->Cancel();
       
   907 	}
   892 	}
   908 
   893 
   909 TInt DIicBusChannelSlave::UpdateReqTrig(TInt8& aCbTrigVal, TInt& aCallbackRet)
   894 TInt DIicBusChannelSlave::UpdateReqTrig(TInt8& aCbTrigVal, TInt& aCallbackRet)
   910 	{
   895 	{
   911     __KTRACE_OPT(KIIC, Kern::Printf("UpdateReqTrig"));
   896     __KTRACE_OPT(KIIC, Kern::Printf("UpdateReqTrig"));
   914 	iAccumTrig |= iNotif->iTrigger;	// Update the accumulated event history, regardless of if the trigger was requested
   899 	iAccumTrig |= iNotif->iTrigger;	// Update the accumulated event history, regardless of if the trigger was requested
   915 
   900 
   916 	if(iNotif->iTrigger & EGeneralBusError)
   901 	if(iNotif->iTrigger & EGeneralBusError)
   917 		{
   902 		{
   918 		// In the event of a bus error, always cancel the timer and call the Client callback
   903 		// In the event of a bus error, always cancel the timer and call the Client callback
   919 		StopTimer();
   904 		nextSteps |= (EStopTimer | EInvokeCb);
   920 		iTimerState = EInactive;
   905 		iTimerState = EInactive;
   921 		nextSteps = EInvokeCb;
       
   922 		aCallbackRet = KErrGeneral;
   906 		aCallbackRet = KErrGeneral;
   923 		}
   907 		}
   924 	else if(iNotif->iTrigger == EAsyncCaptChan)
   908 	else if(iNotif->iTrigger == EAsyncCaptChan)
   925 		{
   909 		{
   926 		// For asynchronous channel capture, no timers are involved - just call the Client callback
   910 		// For asynchronous channel capture, no timers are involved - just call the Client callback
   927 		nextSteps = EInvokeCb;
   911 		nextSteps |= EInvokeCb;
   928 		aCallbackRet = KErrCompletion;
   912 		aCallbackRet = KErrCompletion;
   929 		}
   913 		}
   930 	else if((iNotif->iTrigger & iReqTrig) != 0)
   914 	else if((iNotif->iTrigger & iReqTrig) != 0)
   931 		{
   915 		{
   932 		// If a requested Rx event has occurred, clear all Rx flags from the requested triggers (similarly for Tx)
   916 		// If a requested Rx event has occurred, clear all Rx flags from the requested triggers (similarly for Tx)
   961 			// The next state in the state machine depends on if all the requested events have occurred
   945 			// The next state in the state machine depends on if all the requested events have occurred
   962 			if(iReqTrig == 0)
   946 			if(iReqTrig == 0)
   963 				{
   947 				{
   964 				// All triggers required have occurred, so transition to state EWaitForClient
   948 				// All triggers required have occurred, so transition to state EWaitForClient
   965 				iTimerState = EWaitForClient;
   949 				iTimerState = EWaitForClient;
   966 				StopTimer();
   950 				nextSteps |= (EStopTimer | EInvokeCb | EStartTimer);
   967 				nextSteps = (EInvokeCb | EStartTimer);
       
   968 				}
   951 				}
   969 			else
   952 			else
   970 				{
   953 				{
   971 				// The Client can request both Rx an Tx triggers; if only one has occurred, must wait for
   954 				// The Client can request both Rx an Tx triggers; if only one has occurred, must wait for
   972 				// the Master to generate the other - so remain in this state, do not cancel the timer or
   955 				// the Master to generate the other - so remain in this state, do not cancel the timer or
  1001 		TInt8 callbackTrig=0;
   984 		TInt8 callbackTrig=0;
  1002 		TInt callbackRet=0;
   985 		TInt callbackRet=0;
  1003 		TInt nextSteps = UpdateReqTrig(callbackTrig, callbackRet);
   986 		TInt nextSteps = UpdateReqTrig(callbackTrig, callbackRet);
  1004 		if(nextSteps & EStopTimer)
   987 		if(nextSteps & EStopTimer)
  1005 			{
   988 			{
  1006 			__ASSERT_DEBUG(NULL, Kern::Fault(KIicChannelPanic,__LINE__));
   989 			iTimeoutTimer.Cancel();
  1007 			}
   990 			}
  1008 		if(nextSteps & EInvokeCb)
   991 		if(nextSteps & EInvokeCb)
  1009 			{
   992 			{
  1010 			(notif->iCallback)(notif->iChannelId, (TInt)callbackRet, callbackTrig, notif->iRxWords, notif->iTxWords, notif->iParam);
   993 			(notif->iCallback)(notif->iChannelId, (TInt)callbackRet, callbackTrig, notif->iRxWords, notif->iTxWords, notif->iParam);
  1011 			// Callback now processed, so re-initialise callback object members
   994 			// Callback now processed, so re-initialise callback object members