1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/system/d_tick.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,686 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\system\d_tick.cpp
1.18 +// LDD for testing tick-based timers
1.19 +//
1.20 +//
1.21 +
1.22 +#include "platform.h"
1.23 +#include <assp.h>
1.24 +#if defined(__MEIG__)
1.25 +#include <cl7211.h>
1.26 +#elif defined(__MAWD__)
1.27 +#include <windermere.h>
1.28 +#elif defined(__MISA__)
1.29 +#include <sa1100.h>
1.30 +#elif defined(__MCOT__)
1.31 +#include <cotulla.h>
1.32 +#elif defined(__MI920__) || defined(__NI1136__)
1.33 +#include <integratorap.h>
1.34 +#elif defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
1.35 +#include <omap.h>
1.36 +#include <omap_timer.h>
1.37 +#elif defined(__WINS__)
1.38 +#include "nk_priv.h"
1.39 +#elif defined(__RVEMUBOARD__)
1.40 +#include <rvemuboard.h>
1.41 +#elif defined(__NE1_TB__)
1.42 +#include <upd35001_timer.h>
1.43 +#endif
1.44 +#include <kernel/kern_priv.h>
1.45 +#include "d_tick.h"
1.46 +#include "../misc/prbs.h"
1.47 +
1.48 +#if defined(__WINS__)
1.49 +typedef Int64 TCounter;
1.50 +typedef Int64 TDelta;
1.51 +#else
1.52 +typedef TUint TCounter;
1.53 +typedef TInt TDelta;
1.54 +#endif
1.55 +
1.56 +#if defined(__MISA__)|| defined(__MCOT__)
1.57 +inline TCounter TIMER()
1.58 + { return *(volatile TUint*)KHwRwOstOscr; }
1.59 +#endif
1.60 +#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
1.61 +inline TCounter TIMER()
1.62 + { return TOmapTimer::Timer3Value(); }
1.63 +#endif
1.64 +#ifdef __MAWD__
1.65 +inline TCounter TIMER()
1.66 + { return *(volatile TUint*)(KWindBaseAddress+KWindTimer1Value16)&0xffff; }
1.67 +#endif
1.68 +#ifdef __MEIG__
1.69 +inline TCounter TIMER()
1.70 + { return *(volatile TUint*)(KEigerBaseAddress+KEigerTimer1Data16)&0xffff; }
1.71 +#endif
1.72 +#if defined(__MI920__) || defined(__NI1136__)
1.73 +inline TCounter TIMER()
1.74 + { return *(volatile TUint*)(KHwCounterTimer1+KHoTimerValue)&0xffff;}
1.75 +#endif
1.76 +#if defined(__RVEMUBOARD__)
1.77 +inline TCounter TIMER()
1.78 + { return *(volatile TUint*)(KHwCounterTimer1+KHoTimerValue)&0xffff;}
1.79 +#endif
1.80 +#if defined(__NE1_TB__)
1.81 +inline TCounter TIMER()
1.82 + { return NETimer::Timer(2).iTimerCount; }
1.83 +#endif
1.84 +#if defined(__EPOC32__) && defined(__CPU_X86)
1.85 +TCounter TIMER();
1.86 +void SetUpTimerChannel2();
1.87 +#endif
1.88 +#ifdef __WINS__
1.89 +inline TCounter TIMER()
1.90 + {
1.91 + LARGE_INTEGER c;
1.92 + QueryPerformanceCounter(&c);
1.93 + return c.QuadPart;
1.94 + }
1.95 +#endif
1.96 +
1.97 +#if defined(__MISA__) || defined(__MCOT__)
1.98 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.99 + { return final-initial; } // SA1100 timer counts up
1.100 +inline TInt LongTimeDelta(TCounter initial, TCounter final, TUint, TUint)
1.101 + { return final-initial; } // SA1100 timer counts up
1.102 +#endif
1.103 +#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
1.104 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.105 + { return initial-final; } // OMAP timer counts down
1.106 +inline TInt LongTimeDelta(TCounter initial, TCounter final, TUint, TUint)
1.107 + { return initial-final; }
1.108 +#endif
1.109 +#if defined(__MI920__) || defined(__NI1136__)
1.110 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.111 + { return (initial-final)&0xffff; } // Integrator timer counts down
1.112 +TInt LongTimeDelta(TCounter initial, TCounter final, TUint init_ms, TUint final_ms)
1.113 + {
1.114 + TUint r=(initial-final)&0xffff; // Integrator timer counts down
1.115 + TUint ms=final_ms-init_ms;
1.116 + ms=2*ms-r;
1.117 + ms=(ms+32768)&~0xffff;
1.118 + return r+ms;
1.119 + }
1.120 +#endif
1.121 +#if defined(__RVEMUBOARD__)
1.122 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.123 + { return (initial-final)&0xffff; } // Timer counts down
1.124 +TInt LongTimeDelta(TCounter initial, TCounter final, TUint init_ms, TUint final_ms)
1.125 + {
1.126 + TUint r=(initial-final)&0xffff; // Timer counts down
1.127 + TUint ms=final_ms-init_ms;
1.128 + ms=2*ms-r;
1.129 + ms=(ms+32768)&~0xffff;
1.130 + return r+ms;
1.131 + }
1.132 +#endif
1.133 +#if defined(__NE1_TB__)
1.134 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.135 + { return final - initial; }
1.136 +inline TDelta LongTimeDelta(TCounter initial, TCounter final, TUint, TUint)
1.137 + { return final - initial; }
1.138 +#endif
1.139 +#if defined(__MAWD__) || defined(__MEIG__)
1.140 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.141 + { return (initial-final)&0xffff; } // Eiger/Windermere timer counts down
1.142 +TInt LongTimeDelta(TCounter initial, TCounter final, TUint init_ms, TUint final_ms)
1.143 + {
1.144 + TUint r=(initial-final)&0xffff; // Eiger/Windermere timer counts down
1.145 + TUint ms=final_ms-init_ms;
1.146 + ms=2*ms-r;
1.147 + ms=(ms+32768)&~0xffff;
1.148 + return r+ms;
1.149 + }
1.150 +#endif
1.151 +#if defined(__EPOC32__) && defined(__CPU_X86)
1.152 +TDelta TimeDelta(TUint initial, TUint final)
1.153 + {
1.154 + TUint tickdiff=(initial-final)&0xffff;
1.155 + TUint msdiff=((final>>16)-(initial>>16))&0xffff;
1.156 + msdiff=1193*msdiff-tickdiff;
1.157 + msdiff=(msdiff+32768)&~0xffff;
1.158 + return msdiff+tickdiff;
1.159 + }
1.160 +
1.161 +TInt LongTimeDelta(TUint initial, TUint final, TUint init_ms, TUint final_ms)
1.162 + {
1.163 + TUint r=(initial-final)&0xffff; // PC timer counts down
1.164 + TUint ms=final_ms-init_ms;
1.165 + ms=1193*ms-r;
1.166 + ms=(ms+32768)&~0xffff;
1.167 + return r+ms;
1.168 + }
1.169 +#endif
1.170 +#ifdef __WINS__
1.171 +inline TDelta TimeDelta(TCounter initial, TCounter final)
1.172 + { return final-initial; } // counts up
1.173 +inline TDelta LongTimeDelta(TCounter initial, TCounter final, TUint, TUint)
1.174 + { return final-initial; } // counts up
1.175 +#endif
1.176 +
1.177 +const TInt KMajorVersionNumber=0;
1.178 +const TInt KMinorVersionNumber=1;
1.179 +const TInt KBuildVersionNumber=1;
1.180 +
1.181 +const TInt KDaysFrom0ADTo2000AD=730497; // See US_TIME.CPP to verify this
1.182 +const TInt KSecondsPerDay=86400;
1.183 +
1.184 +TUint TicksToMicroseconds(TDelta aTicks)
1.185 + {
1.186 +#if defined(__MISA__) || defined(__MCOT__)
1.187 + Int64 ticks(aTicks);
1.188 + ticks*=(1000000);
1.189 + ticks+=KHwOscFreqHz/2; // 3.6864MHz tick
1.190 + ticks/=KHwOscFreqHz;
1.191 + return (TUint)ticks;
1.192 +#endif
1.193 +#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
1.194 + // Timer runs at 12Mhz/32 = 375kHz. Each tick is 2.66...us which is 16/6us
1.195 + aTicks<<=4; // * 16
1.196 + aTicks+=3; // rounding to the closest number of us
1.197 + return (TInt)(aTicks/6); // us = (ticks*16+3)/6
1.198 +#endif
1.199 +#if defined(__MI920__) || defined(__NI1136__)
1.200 + aTicks<<=14; // 1 tick = 32/3 us
1.201 + aTicks+=768; // round
1.202 + return (TInt)(aTicks/1536);
1.203 +#endif
1.204 +#if defined(__RVEMUBOARD__)
1.205 + return (TInt)(aTicks*256); // 1 tick = 256 us
1.206 +#endif
1.207 +#if defined(__NE1_TB__)
1.208 + NETimer& T2 = NETimer::Timer(2);
1.209 + TUint prescale = __e32_find_ms1_32(T2.iPrescaler & 0x3f);
1.210 + TUint f = 66666667 >> prescale;
1.211 + TUint64 x = I64LIT(1000000);
1.212 + x *= TUint64(aTicks);
1.213 + x += TUint64(f>>1);
1.214 + x /= TUint64(f);
1.215 + return (TUint)x;
1.216 +#endif
1.217 +#if defined(__MAWD__) || defined(__MEIG__)
1.218 + return aTicks*500; // 2kHz tick
1.219 +#endif
1.220 +#if defined(__EPOC32__) && defined(__CPU_X86)
1.221 + return (aTicks*8381+4190)/10000;
1.222 +#endif
1.223 +#ifdef __WINS__
1.224 + LARGE_INTEGER f;
1.225 + QueryPerformanceFrequency(&f);
1.226 + aTicks*=1000000;
1.227 + aTicks+=f.QuadPart/2;
1.228 + aTicks/=f.QuadPart;
1.229 + return (TUint)aTicks;
1.230 +#endif
1.231 + }
1.232 +
1.233 +class DTick;
1.234 +class TTickTimer
1.235 + {
1.236 +public:
1.237 + enum TMode
1.238 + {
1.239 + EOneShot,
1.240 + EPeriodic,
1.241 + EAbsolute,
1.242 + ETickDelay,
1.243 + };
1.244 +public:
1.245 + TTickTimer();
1.246 + TInt Start(TInt aMode, TUint aMin, TUint aRange, TInt aCount);
1.247 + void Cancel();
1.248 + void CompleteClient(TInt aValue);
1.249 + static void TickCallBack(TAny* aPtr);
1.250 + static void SecondCallBack(TAny* aPtr);
1.251 +public:
1.252 + TTickLink iTickLink;
1.253 + TSecondLink iSecondLink;
1.254 + TMode iMode;
1.255 + TInt iInterval;
1.256 + TTimeK iExpiryTime;
1.257 + TUint iMin;
1.258 + TUint iRange;
1.259 + TInt iParam;
1.260 + TCounter iStartTime0;
1.261 + TUint iStartTime1;
1.262 + TCounter iStartTime;
1.263 + TInt iMinErr;
1.264 + TInt iMaxErr;
1.265 + Int64 iTotalErr;
1.266 + TInt iCount;
1.267 + TInt iRequestedCount;
1.268 + TInt iIgnore;
1.269 + DTick* iLdd;
1.270 + TInt iId;
1.271 + TClientRequest* iRequest;
1.272 + };
1.273 +
1.274 +class DTickFactory : public DLogicalDevice
1.275 +//
1.276 +// Tick timer LDD factory
1.277 +//
1.278 + {
1.279 +public:
1.280 + DTickFactory();
1.281 + virtual TInt Install(); //overriding pure virtual
1.282 + virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual
1.283 + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual
1.284 + };
1.285 +
1.286 +class DTick : public DLogicalChannelBase
1.287 +//
1.288 +// Tick timer LDD channel
1.289 +//
1.290 + {
1.291 +public:
1.292 + DTick();
1.293 + ~DTick();
1.294 +protected:
1.295 + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.296 + virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
1.297 +public:
1.298 + void TimerExpired(TInt anId);
1.299 + inline DThread* Client() { return iThread; }
1.300 +public:
1.301 + DThread* iThread;
1.302 + TInt iTickPeriodUs;
1.303 + TTimeK iYear2000;
1.304 + TTickTimer iTickTimer[KMaxTimers];
1.305 + TUint iSeed[2];
1.306 + };
1.307 +
1.308 +TTickTimer::TTickTimer()
1.309 + : iMode(EOneShot),
1.310 + iInterval(0),
1.311 + iExpiryTime(0),
1.312 + iMin(0),
1.313 + iRange(1),
1.314 + iParam(0),
1.315 + iStartTime0(0),
1.316 + iStartTime1(0),
1.317 + iStartTime(0),
1.318 + iMinErr(KMaxTInt),
1.319 + iMaxErr(KMinTInt),
1.320 + iTotalErr(0),
1.321 + iCount(0),
1.322 + iRequestedCount(0),
1.323 + iIgnore(0),
1.324 + iLdd(NULL),
1.325 + iId(0),
1.326 + iRequest(NULL)
1.327 + {
1.328 + }
1.329 +
1.330 +void TTickTimer::TickCallBack(TAny* aPtr)
1.331 + {
1.332 + TCounter timer_val=TIMER();
1.333 + TTickTimer& m=*(TTickTimer*)aPtr;
1.334 + TDelta time=TimeDelta(m.iStartTime, timer_val);
1.335 + TInt time_us=TicksToMicroseconds(time);
1.336 + TInt rounded_interval=((m.iInterval+500)/1000)*1000;
1.337 + TInt error=time_us-rounded_interval;
1.338 + if (!m.iIgnore)
1.339 + {
1.340 + if (error<m.iMinErr)
1.341 + m.iMinErr=error;
1.342 + if (error>m.iMaxErr)
1.343 + m.iMaxErr=error;
1.344 + m.iTotalErr+=error;
1.345 + }
1.346 + if (m.iIgnore==1 && m.iMode==EPeriodic)
1.347 + {
1.348 + m.iStartTime0=timer_val;
1.349 + m.iStartTime1=NKern::TickCount();
1.350 + }
1.351 + if ((m.iIgnore && m.iIgnore--) || (++m.iCount<m.iRequestedCount))
1.352 + {
1.353 + if (m.iMode==EOneShot)
1.354 + {
1.355 + TUint rnd=Random(m.iLdd->iSeed);
1.356 + TUint ticks=(rnd%m.iRange)+m.iMin;
1.357 + m.iInterval=ticks*m.iLdd->iTickPeriodUs;
1.358 + m.iStartTime=TIMER();
1.359 + m.iTickLink.OneShot(m.iInterval, TickCallBack, &m);
1.360 + }
1.361 + else if (m.iMode==ETickDelay)
1.362 + {
1.363 + m.iStartTime=TIMER();
1.364 + m.iTickLink.OneShot(m.iInterval, TickCallBack, &m);
1.365 + NKern::Sleep(m.iRange);
1.366 + }
1.367 + else
1.368 + m.iStartTime=timer_val;
1.369 + return;
1.370 + }
1.371 + m.CompleteClient(KErrNone);
1.372 + if (m.iMode==EPeriodic)
1.373 + {
1.374 + m.iStartTime0=LongTimeDelta(m.iStartTime0, timer_val, m.iStartTime1, NKern::TickCount());
1.375 + m.iTickLink.Cancel();
1.376 + }
1.377 + }
1.378 +
1.379 +void TTickTimer::SecondCallBack(TAny* aPtr)
1.380 + {
1.381 + TTickTimer& m=*(TTickTimer*)aPtr;
1.382 + TTimeK now=Kern::SystemTime();
1.383 + Int64 error=now-m.iExpiryTime;
1.384 + if (error>KMaxTInt)
1.385 + error=KMaxTInt;
1.386 + if (error<KMinTInt)
1.387 + error=KMinTInt;
1.388 + if (error<m.iMinErr)
1.389 + m.iMinErr=(TInt)error;
1.390 + if (error>m.iMaxErr)
1.391 + m.iMaxErr=(TInt)error;
1.392 + m.iTotalErr+=error;
1.393 + if (++m.iCount<m.iRequestedCount)
1.394 + {
1.395 + TUint rnd=Random(m.iLdd->iSeed);
1.396 + TUint secs=(rnd%m.iRange)+m.iMin;
1.397 + m.iExpiryTime=now+secs*1000000+999999;
1.398 + m.iExpiryTime/=1000000;
1.399 + m.iExpiryTime*=1000000;
1.400 + m.iSecondLink.At(m.iExpiryTime, SecondCallBack, &m);
1.401 + return;
1.402 + }
1.403 + m.CompleteClient(KErrNone);
1.404 + }
1.405 +
1.406 +TInt TTickTimer::Start(TInt aMode, TUint a1, TUint a2, TInt aCount)
1.407 + {
1.408 + TInt r=KErrGeneral;
1.409 + iMode=(TMode)aMode;
1.410 + iMin=a1;
1.411 + iRange=a2;
1.412 + iMinErr=KMaxTInt;
1.413 + iMaxErr=KMinTInt;
1.414 + iTotalErr=0;
1.415 + iCount=0;
1.416 + iRequestedCount=aCount;
1.417 + switch (aMode)
1.418 + {
1.419 + case EOneShot:
1.420 + {
1.421 + TUint rnd=Random(iLdd->iSeed);
1.422 + TUint ticks=(rnd%iRange)+iMin;
1.423 + iInterval=ticks*iLdd->iTickPeriodUs;
1.424 + iStartTime=TIMER();
1.425 + iStartTime0=0;
1.426 + iStartTime1=0;
1.427 + iTickLink.OneShot(iInterval, TickCallBack, this);
1.428 + iIgnore=Min(aCount-1,1);
1.429 + r=KErrNone;
1.430 + break;
1.431 + }
1.432 + case EPeriodic:
1.433 + {
1.434 + iInterval=iMin*iLdd->iTickPeriodUs;
1.435 + iStartTime=TIMER();
1.436 + iStartTime0=iStartTime;
1.437 + iStartTime1=NKern::TickCount();
1.438 + iTickLink.Periodic(iInterval, TickCallBack, this);
1.439 + iIgnore=Min(aCount-1,1);
1.440 + r=KErrNone;
1.441 + break;
1.442 + }
1.443 + case EAbsolute:
1.444 + {
1.445 + TUint rnd=Random(iLdd->iSeed);
1.446 + TUint secs=(rnd%iRange)+iMin;
1.447 + TTimeK now=Kern::SystemTime();
1.448 + iExpiryTime=now+secs*1000000+999999;
1.449 + iExpiryTime/=1000000;
1.450 + iExpiryTime*=1000000;
1.451 + iSecondLink.At(iExpiryTime, SecondCallBack, this);
1.452 + iIgnore=0;
1.453 + iStartTime0=0;
1.454 + iStartTime1=0;
1.455 + r=KErrNone;
1.456 + break;
1.457 + }
1.458 + case ETickDelay:
1.459 + {
1.460 + iInterval=iMin*iLdd->iTickPeriodUs;
1.461 + iStartTime=TIMER();
1.462 + iStartTime0=0;
1.463 + iStartTime1=0;
1.464 + iTickLink.OneShot(iInterval, TickCallBack, this);
1.465 + iIgnore=Min(aCount-1,1);
1.466 + r=KErrNone;
1.467 + break;
1.468 + }
1.469 + default:
1.470 + break;
1.471 + }
1.472 + return r;
1.473 + }
1.474 +
1.475 +void TTickTimer::CompleteClient(TInt aValue)
1.476 + {
1.477 + Kern::QueueRequestComplete(iLdd->Client(),iRequest,aValue);
1.478 + }
1.479 +
1.480 +void TTickTimer::Cancel()
1.481 + {
1.482 + iTickLink.Cancel();
1.483 + iSecondLink.Cancel();
1.484 + CompleteClient(KErrCancel);
1.485 + }
1.486 +
1.487 +DECLARE_STANDARD_LDD()
1.488 + {
1.489 + return new DTickFactory;
1.490 + }
1.491 +
1.492 +DTickFactory::DTickFactory()
1.493 + {
1.494 + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.495 + //iParseMask=0;//No units, no info, no PDD
1.496 + //iUnitsMask=0;//Only one thing
1.497 + }
1.498 +
1.499 +TInt DTickFactory::Create(DLogicalChannelBase*& aChannel)
1.500 +//
1.501 +// Create a new DTick on this logical device
1.502 +//
1.503 + {
1.504 + aChannel=new DTick;
1.505 + return aChannel?KErrNone:KErrNoMemory;
1.506 + }
1.507 +
1.508 +TInt DTickFactory::Install()
1.509 +//
1.510 +// Install the LDD - overriding pure virtual
1.511 +//
1.512 + {
1.513 + return SetName(&KTickTestLddName);
1.514 + }
1.515 +
1.516 +void DTickFactory::GetCaps(TDes8& aDes) const
1.517 +//
1.518 +// Get capabilities - overriding pure virtual
1.519 +//
1.520 + {
1.521 + TCapsTickTestV01 b;
1.522 + b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.523 + Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
1.524 + }
1.525 +
1.526 +DTick::DTick()
1.527 +//
1.528 +// Constructor
1.529 +//
1.530 + {
1.531 + TInt i;
1.532 + for (i=0; i<KMaxTimers; i++)
1.533 + {
1.534 + iTickTimer[i].iLdd=this;
1.535 + iTickTimer[i].iId=i;
1.536 + }
1.537 + iSeed[0]=NKern::TickCount();
1.538 + iSeed[1]=0;
1.539 + iTickPeriodUs=Kern::TickPeriod();
1.540 +
1.541 + // Careful with the constants here or GCC will get it wrong
1.542 + iYear2000=Int64(KDaysFrom0ADTo2000AD)*Int64(KSecondsPerDay);
1.543 + iYear2000*=1000000;
1.544 +
1.545 + iThread=&Kern::CurrentThread();
1.546 + iThread->Open();
1.547 + }
1.548 +
1.549 +TInt DTick::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
1.550 +//
1.551 +// Create channel
1.552 +//
1.553 + {
1.554 +
1.555 + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
1.556 + return KErrNotSupported;
1.557 +
1.558 + for (TInt i=0; i<KMaxTimers; i++)
1.559 + {
1.560 + TInt r = Kern::CreateClientRequest(iTickTimer[i].iRequest);
1.561 + if (r != KErrNone)
1.562 + return r;
1.563 + }
1.564 +
1.565 +#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
1.566 + // Set up Timer3 as a free-running timer at 12Mhz/32 = 375kHz
1.567 + TOmapTimer::SetTimer3Ctrl( TOmapTimer::KHtOSTimer_Cntl_Ar
1.568 + | TOmapTimer::KHtOSTimer_Cntl_Free
1.569 + | TOmapTimer::KHtOSTimer_Cntl_ClkEnable );
1.570 + TOmapTimer::SetTimer3Prescale( TOmapTimer::EPrescaleBy32 );
1.571 + // Autoreload 0xFFFFFFFF to effectively wrap from zero back to 0xFFFFFFFF
1.572 + TOmapTimer::SetTimer3LoadTim( 0xFFFFFFFF );
1.573 + TOmapTimer::StartTimer3();
1.574 +#endif
1.575 +#if defined(__MI920__) || defined(__NI1136__)
1.576 + // Set up timer 1 as free running 93.75KHz clock
1.577 + TIntegratorAP::SetTimerLoad(TIntegratorAP::ECounterTimer1, 0); // start from 0xffff downwards
1.578 + TIntegratorAP::SetTimerMode(TIntegratorAP::ECounterTimer1, TIntegratorAP::ETimerModeFreeRunning);
1.579 + TIntegratorAP::SetTimerPreScale(TIntegratorAP::ECounterTimer1, TIntegratorAP::ETimerPreScaleDiv256); // 93.75kHz wrap 699ms
1.580 + TIntegratorAP::EnableTimer(TIntegratorAP::ECounterTimer1, TIntegratorAP::EEnable);
1.581 + TIntegratorAP::DisableIrq(TIntegratorAP::EIrqSet0,EIntIdTimer0); // make sure timer int is disabled
1.582 +#endif
1.583 +#if defined(__RVEMUBOARD__)
1.584 + // Switch timer 1 to a 1MHz clock in the system controller Ctrl register
1.585 + TRvEmuBoard::SetSCCtrl(KTimer1EnSel);
1.586 +
1.587 + // Set up timer 1 as free running 3.90625kHz clock
1.588 + TRvEmuBoard::SetTimerMode(KHwCounterTimer1, TRvEmuBoard::ETimerModeFreeRunning);
1.589 + TRvEmuBoard::SetTimerPreScale(KHwCounterTimer1, TRvEmuBoard::ETimerPreScaleDiv256);// 3.90625kHz wrap 16.777s
1.590 + TRvEmuBoard::EnableTimer(KHwCounterTimer1, TRvEmuBoard::EEnable);
1.591 +#endif
1.592 +#if defined(__NE1_TB__)
1.593 + // nothing to do since we use fast counter
1.594 +#endif
1.595 +#ifdef __MAWD__
1.596 + // Set up timer 1 as free running 2kHz clock
1.597 + TWind::SetBuzzerControl(0); // disable buzzer
1.598 + TWind::SetTimer1Control(KWindTimer1ControlTimerEnable);
1.599 + TWind::SetTimer1Load(0);
1.600 +#endif
1.601 +#ifdef __MEIG__
1.602 + // Set up timer 1 as free running 2kHz clock
1.603 + TEiger::ModifyControl21(KEigerControlTimer1PreOrFree|KEigerControlTimer1K512OrK2|
1.604 + KEigerControlBuzzerToggle|KEigerControlBuzzerTimer1OrToggle,0);
1.605 + TEiger::SetTimer1Data(0);
1.606 +#endif
1.607 +#if defined(__EPOC32__) && defined(__CPU_X86)
1.608 + // Set up timer channel 2 as free running counter at 14318180/12 Hz
1.609 + SetUpTimerChannel2();
1.610 +#endif
1.611 + return KErrNone;
1.612 + }
1.613 +
1.614 +DTick::~DTick()
1.615 +//
1.616 +// Destructor
1.617 +//
1.618 + {
1.619 + TInt i;
1.620 + for (i=0; i<KMaxTimers; i++)
1.621 + {
1.622 + iTickTimer[i].Cancel();
1.623 + Kern::DestroyClientRequest(iTickTimer[i].iRequest);
1.624 + }
1.625 + Kern::SafeClose((DObject*&)iThread, NULL);
1.626 + }
1.627 +
1.628 +TInt DTick::Request(TInt aFunction, TAny* a1, TAny* a2)
1.629 +//
1.630 +// Runs in context of client thread, system unlocked on entry and exit
1.631 +//
1.632 + {
1.633 + NKern::ThreadEnterCS(); // stop thread kills
1.634 + TInt r=KErrNone;
1.635 + TInt id=(TInt)a1;
1.636 + TTickTimer& m=iTickTimer[id];
1.637 + switch (aFunction)
1.638 + {
1.639 + case RTickTest::EControlStart:
1.640 + {
1.641 + STimerStartInfo info;
1.642 + kumemget(&info,a2,sizeof(info));
1.643 + r=m.iRequest->SetStatus(info.iStatus);
1.644 + if (r==KErrNone)
1.645 + r=m.Start(info.iMode, info.iMin, info.iRange, info.iCount);
1.646 + break;
1.647 + }
1.648 + case RTickTest::EControlStop:
1.649 + {
1.650 + m.Cancel();
1.651 + break;
1.652 + }
1.653 + case RTickTest::EControlGetInfo:
1.654 + {
1.655 + STickTestInfo info;
1.656 + info.iMinErr=m.iMinErr;
1.657 + info.iMaxErr=m.iMaxErr;
1.658 + info.iCount=m.iCount;
1.659 + info.iRequestedCount=m.iRequestedCount;
1.660 + Int64 avg=m.iTotalErr/m.iCount;
1.661 + info.iAvgErr=(TInt)avg;
1.662 + info.iTotalTime=TicksToMicroseconds(m.iStartTime0);
1.663 + kumemput(a2,&info,sizeof(info));
1.664 + break;
1.665 + }
1.666 + case RTickTest::EControlReadRtc:
1.667 + {
1.668 + TInt hwrtc;
1.669 + Arch::TheAsic()->SystemTimeInSecondsFrom2000(hwrtc);
1.670 + *(TTimeK*)a1=Kern::SystemTime();
1.671 + TTimeK hwtimeK=(TTimeK)hwrtc;
1.672 + hwtimeK*=1000000;
1.673 + hwtimeK+=iYear2000;
1.674 + kumemput(a2,&hwtimeK,sizeof(hwtimeK));
1.675 + break;
1.676 + }
1.677 + case RTickTest::EControlGetTickPeriod:
1.678 + {
1.679 + r=iTickPeriodUs;
1.680 + break;
1.681 + }
1.682 + default:
1.683 + r=KErrNotSupported;
1.684 + break;
1.685 + }
1.686 + NKern::ThreadLeaveCS();
1.687 + return r;
1.688 + }
1.689 +