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 |