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