|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <hal.h> |
|
17 #include <hal_data.h> |
|
18 |
|
19 #include "tavsrcTimer.h" |
|
20 #include "tavsrc.h" |
|
21 |
|
22 static const TUint KMillion = 1000000; |
|
23 |
|
24 CAdaptiveHighResPeriodic* CAdaptiveHighResPeriodic::NewL(MAdaptiveHighResPeriodicClient& aClient) |
|
25 { |
|
26 CAdaptiveHighResPeriodic* p = new (ELeave) CAdaptiveHighResPeriodic(aClient); |
|
27 CleanupStack::PushL(p); |
|
28 p->ConstructL(); |
|
29 CleanupStack::Pop(p); |
|
30 return p; |
|
31 } |
|
32 |
|
33 CAdaptiveHighResPeriodic::~CAdaptiveHighResPeriodic() |
|
34 { |
|
35 Cancel(); |
|
36 } |
|
37 |
|
38 CAdaptiveHighResPeriodic::CAdaptiveHighResPeriodic(MAdaptiveHighResPeriodicClient& aClient) |
|
39 : CTimer(EPriorityStandard+1), iClient(aClient) |
|
40 { |
|
41 CActiveScheduler::Add(this); |
|
42 } |
|
43 |
|
44 void CAdaptiveHighResPeriodic::ConstructL() |
|
45 { |
|
46 CTimer::ConstructL(); |
|
47 |
|
48 HAL::Get(HALData::EFastCounterFrequency, iFastCounterFreq); |
|
49 HAL::Get(HALData::EFastCounterCountsUp, iFastCounterIncreases); |
|
50 |
|
51 RDebug::Printf("Timer HAL: FC Freq %d", iFastCounterFreq); |
|
52 |
|
53 if (iFastCounterIncreases) |
|
54 { |
|
55 RDebug::Printf("Timer HAL: FC increases"); |
|
56 } |
|
57 else |
|
58 { |
|
59 RDebug::Printf("Timer HAL: FC decreases"); |
|
60 } |
|
61 |
|
62 iFastCounterFreqUs = (TReal)iFastCounterFreq / KMillion; |
|
63 } |
|
64 |
|
65 |
|
66 void CAdaptiveHighResPeriodic::Start(TTimeIntervalMicroSeconds32 aInterval) |
|
67 { |
|
68 RDebug::Printf("*** Start Timer"); |
|
69 iInterval = aInterval; |
|
70 |
|
71 // calculate the number of fast counter ticks for the interval |
|
72 TReal intervalInCounts = iInterval.Int()*iFastCounterFreqUs; |
|
73 TInt countChangeExpected = (TInt) intervalInCounts; |
|
74 |
|
75 // store any extra fractions of fast counter ticks |
|
76 iExtraCounts = intervalInCounts - countChangeExpected; |
|
77 |
|
78 iIntendedCountOnCallback = iFastCounterIncreases |
|
79 ? User::FastCounter() + countChangeExpected |
|
80 : User::FastCounter() - countChangeExpected; |
|
81 |
|
82 StartTimer(aInterval); |
|
83 } |
|
84 |
|
85 void CAdaptiveHighResPeriodic::RunL() |
|
86 { |
|
87 User::LeaveIfError(iStatus.Int()); |
|
88 iClient.TimerEvent(*this); |
|
89 |
|
90 if (!IsActive()) |
|
91 { |
|
92 TUint endCount = User::FastCounter(); |
|
93 |
|
94 // are we fast or slow? positive = late, negative = early |
|
95 TInt varianceCount = iFastCounterIncreases |
|
96 ? (TInt)((endCount - iIntendedCountOnCallback)) |
|
97 : (TInt)((iIntendedCountOnCallback - endCount)); |
|
98 |
|
99 // convert count to microsecs |
|
100 TInt varianceUs = varianceCount/iFastCounterFreqUs; |
|
101 |
|
102 TInt nextInterval = iInterval.Int() - varianceUs; // in musecs |
|
103 |
|
104 if (nextInterval < 0) |
|
105 { |
|
106 nextInterval = 0; |
|
107 } |
|
108 |
|
109 // calculate the number of fast counter ticks for the interval |
|
110 TReal intervalInCounts = nextInterval*iFastCounterFreqUs; |
|
111 TInt countChangeExpected = (TInt) intervalInCounts; |
|
112 |
|
113 // update extra fractions of fast counter ticks |
|
114 iExtraCounts += intervalInCounts - countChangeExpected; |
|
115 |
|
116 if (iExtraCounts >= 1) |
|
117 { |
|
118 // we have more than a whole tick, do the adjustment |
|
119 countChangeExpected++; |
|
120 iExtraCounts--; |
|
121 nextInterval = countChangeExpected/iFastCounterFreqUs; |
|
122 } |
|
123 |
|
124 iIntendedCountOnCallback = iFastCounterIncreases |
|
125 ? User::FastCounter() + countChangeExpected |
|
126 : User::FastCounter() - countChangeExpected; |
|
127 |
|
128 StartTimer(nextInterval); |
|
129 } |
|
130 } |
|
131 |
|
132 TInt CAdaptiveHighResPeriodic::RunError(TInt aError) |
|
133 { |
|
134 iClient.TimerError(*this, aError); |
|
135 return KErrNone; |
|
136 } |
|
137 |
|
138 void CAdaptiveHighResPeriodic::SetInterval(TTimeIntervalMicroSeconds32 aInterval) |
|
139 { |
|
140 iInterval = aInterval; |
|
141 } |
|
142 |
|
143 void CAdaptiveHighResPeriodic::StartTimer(TTimeIntervalMicroSeconds32 aInterval) |
|
144 { |
|
145 HighRes(aInterval); |
|
146 } |