bluetooth/gavdp/test/tavsrcTimer.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/gavdp/test/tavsrcTimer.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,146 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+//
+
+#include <hal.h>
+#include <hal_data.h>
+
+#include "tavsrcTimer.h"
+#include "tavsrc.h"
+
+static const TUint KMillion = 1000000;
+
+CAdaptiveHighResPeriodic* CAdaptiveHighResPeriodic::NewL(MAdaptiveHighResPeriodicClient& aClient)
+	{
+	CAdaptiveHighResPeriodic* p = new (ELeave) CAdaptiveHighResPeriodic(aClient);
+	CleanupStack::PushL(p);
+	p->ConstructL();
+	CleanupStack::Pop(p);
+	return p;
+	}
+	
+CAdaptiveHighResPeriodic::~CAdaptiveHighResPeriodic()
+	{
+	Cancel();
+	}
+
+CAdaptiveHighResPeriodic::CAdaptiveHighResPeriodic(MAdaptiveHighResPeriodicClient& aClient)
+: CTimer(EPriorityStandard+1), iClient(aClient)
+	{
+	CActiveScheduler::Add(this);
+	}
+	
+void CAdaptiveHighResPeriodic::ConstructL()
+	{
+	CTimer::ConstructL();
+	
+	HAL::Get(HALData::EFastCounterFrequency, iFastCounterFreq);
+	HAL::Get(HALData::EFastCounterCountsUp, iFastCounterIncreases);
+
+	RDebug::Printf("Timer HAL: FC Freq %d", iFastCounterFreq);
+	
+	if (iFastCounterIncreases)
+		{
+		RDebug::Printf("Timer HAL: FC increases");
+		}
+	else
+		{
+		RDebug::Printf("Timer HAL: FC decreases");
+		}
+
+	iFastCounterFreqUs = (TReal)iFastCounterFreq / KMillion;
+	}
+	
+	
+void CAdaptiveHighResPeriodic::Start(TTimeIntervalMicroSeconds32 aInterval)
+	{
+	RDebug::Printf("*** Start Timer");
+	iInterval = aInterval;
+
+	// calculate the number of fast counter ticks for the interval
+	TReal intervalInCounts = iInterval.Int()*iFastCounterFreqUs;		
+	TInt countChangeExpected = (TInt) intervalInCounts;
+
+	// store any extra fractions of fast counter ticks
+	iExtraCounts = intervalInCounts - countChangeExpected;
+
+	iIntendedCountOnCallback = iFastCounterIncreases
+								? User::FastCounter() + countChangeExpected
+								: User::FastCounter() - countChangeExpected;
+
+	StartTimer(aInterval);
+	}
+	
+void CAdaptiveHighResPeriodic::RunL()
+	{
+	User::LeaveIfError(iStatus.Int());
+	iClient.TimerEvent(*this);
+
+	if (!IsActive())
+		{
+		TUint endCount = User::FastCounter();
+
+		// are we fast or slow? positive = late, negative = early
+		TInt varianceCount = iFastCounterIncreases
+				? (TInt)((endCount - iIntendedCountOnCallback))
+				: (TInt)((iIntendedCountOnCallback - endCount));
+
+		// convert count to microsecs
+		TInt varianceUs = varianceCount/iFastCounterFreqUs;
+
+		TInt nextInterval = iInterval.Int() - varianceUs; // in musecs
+
+		if (nextInterval < 0)
+			{
+			nextInterval = 0;
+			}
+
+		// calculate the number of fast counter ticks for the interval
+		TReal intervalInCounts = nextInterval*iFastCounterFreqUs;		
+		TInt countChangeExpected = (TInt) intervalInCounts;
+
+		// update extra fractions of fast counter ticks
+		iExtraCounts += intervalInCounts - countChangeExpected;
+
+		if (iExtraCounts >= 1)
+			{
+			// we have more than a whole tick, do the adjustment
+			countChangeExpected++;
+			iExtraCounts--;
+			nextInterval = countChangeExpected/iFastCounterFreqUs;
+			}
+
+		iIntendedCountOnCallback = iFastCounterIncreases
+									? User::FastCounter() + countChangeExpected
+									: User::FastCounter() - countChangeExpected;
+		
+		StartTimer(nextInterval);
+		}
+	}
+	
+TInt CAdaptiveHighResPeriodic::RunError(TInt aError)
+	{
+	iClient.TimerError(*this, aError);
+	return KErrNone;
+	}
+
+void CAdaptiveHighResPeriodic::SetInterval(TTimeIntervalMicroSeconds32 aInterval)
+	{
+	iInterval = aInterval;
+	}
+	
+void CAdaptiveHighResPeriodic::StartTimer(TTimeIntervalMicroSeconds32 aInterval)
+	{
+	HighRes(aInterval);
+	}