--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/d_rndtim.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,288 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// e32test\misc\d_rndtim.cpp
+// LDD for generating random interrupts
+//
+//
+
+#include "platform.h"
+#include <kernel/kern_priv.h>
+#include "d_rndtim.h"
+#include "../misc/prbs.h"
+
+#if defined(__MAWD__)
+#include <windermere.h>
+#elif defined(__MISA__)
+#define INT_ID KIntIdOstMatchGeneral
+#include <sa1100.h>
+#elif defined(__MCOT__)
+#define INT_ID KIntIdOstMatchGeneral
+#include <cotulla.h>
+#elif defined(__MI920__) || defined(__NI1136__)
+#include <integratorap.h>
+#elif defined(__EPOC32__) && defined(__CPU_X86)
+#include <x86.h>
+#endif
+
+#ifndef INT_ID
+#error Random timer ISR not supported on this platform
+#endif
+
+
+const TInt KMajorVersionNumber=0;
+const TInt KMinorVersionNumber=1;
+const TInt KBuildVersionNumber=1;
+
+class DRndTimFactory : public DLogicalDevice
+//
+// IPC copy LDD factory
+//
+ {
+public:
+ DRndTimFactory();
+ virtual TInt Install(); //overriding pure virtual
+ virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual
+ virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual
+ };
+
+class DRndTim : public DLogicalChannelBase
+//
+// Millisecond timer LDD channel
+//
+ {
+public:
+ DRndTim();
+ virtual ~DRndTim();
+protected:
+ virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+ virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
+public:
+ static void TimerIsr(TAny* aPtr);
+ static void IDfcFn(TAny* aPtr);
+ void StartTimer();
+ void StopTimer();
+ TInt SetPriority(TInt aHandle, TInt aPriority);
+ TInt Calibrate(TInt aMilliseconds);
+public:
+ TInt iIntId;
+ NFastSemaphore iSem;
+ volatile TUint32 iSeed[2];
+ volatile TUint32 iIsrCount;
+ DThread* iThread;
+ TDfc iIDfc;
+ };
+
+DECLARE_STANDARD_LDD()
+ {
+ return new DRndTimFactory;
+ }
+
+DRndTimFactory::DRndTimFactory()
+//
+// Constructor
+//
+ {
+ iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+ //iParseMask=0;//No units, no info, no PDD
+ //iUnitsMask=0;//Only one thing
+ }
+
+TInt DRndTimFactory::Create(DLogicalChannelBase*& aChannel)
+//
+// Create a new DRndTim on this logical device
+//
+ {
+ aChannel=new DRndTim;
+ return aChannel?KErrNone:KErrNoMemory;
+ }
+
+TInt DRndTimFactory::Install()
+//
+// Install the LDD - overriding pure virtual
+//
+ {
+ return SetName(&KRndTimLddName);
+ }
+
+void DRndTimFactory::GetCaps(TDes8& aDes) const
+//
+// Get capabilities - overriding pure virtual
+//
+ {
+ TCapsRndTimV01 b;
+ b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+ Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
+ }
+
+DRndTim::DRndTim()
+//
+// Constructor
+//
+ : iIntId(-1),
+ iIDfc(&IDfcFn, this)
+ {
+ iThread=&Kern::CurrentThread();
+ iThread->Open();
+ iSem.iOwningThread = &iThread->iNThread;
+ iSeed[0] = 0xb504f333u;
+ iSeed[1] = 0xf9de6484u;
+ }
+
+DRndTim::~DRndTim()
+ {
+ StopTimer();
+ if (iIntId >= 0)
+ Interrupt::Unbind(iIntId);
+ Kern::SafeClose((DObject*&)iThread, NULL);
+ }
+
+TInt DRndTim::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
+//
+// Create channel
+//
+ {
+
+ if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
+ return KErrNotSupported;
+ StopTimer();
+ TInt r = Interrupt::Bind(INT_ID, &TimerIsr, this);
+ if (r == KErrNone)
+ iIntId = INT_ID;
+ return r;
+ }
+
+TInt DRndTim::Request(TInt aFunction, TAny* a1, TAny* a2)
+ {
+ TInt r = KErrNotSupported;
+ switch (aFunction)
+ {
+ case RRndTim::EControlWait:
+ NKern::FSWait(&iSem);
+ r = KErrNone;
+ break;
+ case RRndTim::EControlSetPriority:
+ r = SetPriority(TInt(a1), TInt(a2));
+ break;
+ case RRndTim::EControlStartTimer:
+ NKern::ThreadEnterCS();
+ StartTimer();
+ NKern::ThreadLeaveCS();
+ break;
+ case RRndTim::EControlStopTimer:
+ NKern::ThreadEnterCS();
+ StopTimer();
+ NKern::ThreadLeaveCS();
+ break;
+ case RRndTim::EControlCalibrate:
+ NKern::ThreadEnterCS();
+ r = Calibrate(TInt(a1));
+ NKern::ThreadLeaveCS();
+ break;
+ default:
+ break;
+ }
+ return r;
+ }
+
+TInt DRndTim::SetPriority(TInt aHandle, TInt aPriority)
+ {
+ TInt r = KErrBadHandle;
+ DThread& c = Kern::CurrentThread();
+ NKern::ThreadEnterCS();
+ NKern::LockSystem();
+ DThread* t = (DThread*)Kern::ObjectFromHandle(&c, aHandle, EThread);
+ if (t && !t->Open())
+ {
+ NKern::UnlockSystem();
+ r = Kern::SetThreadPriority(aPriority, t);
+ t->Close(NULL);
+ }
+ else
+ NKern::UnlockSystem();
+ NKern::ThreadLeaveCS();
+ return r;
+ }
+
+TInt DRndTim::Calibrate(TInt aMilliseconds)
+ {
+ TUint32 n1, n2;
+ TInt ticks = NKern::TimerTicks(aMilliseconds);
+ n1 = iIsrCount;
+ NKern::Sleep(ticks);
+ n2 = iIsrCount;
+ return (TInt)(n2-n1);
+ }
+
+void DRndTim::StartTimer()
+ {
+#if defined(__MISA__)
+ // for SA11x0 use OST match 0
+ TSa1100::ModifyIntLevels(0,KHtIntsOstMatchGeneral); // route new timer interrupt to FIQ
+ TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
+ TUint oscr=TSa1100::OstData();
+ TSa1100::SetOstMatch(KHwOstMatchGeneral, oscr + 5000);
+ TSa1100::EnableOstInterrupt(KHwOstMatchGeneral);
+#elif defined(__MCOT__)
+ // for SA11x0 use OST match 0
+ TCotulla::ModifyIntLevels(0,KHtIntsOstMatchGeneral); // route new timer interrupt to FIQ
+ TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
+ TUint oscr=TCotulla::OstData();
+ TCotulla::SetOstMatch(KHwOstMatchGeneral, oscr + 5000);
+ TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
+#endif
+ Interrupt::Enable(INT_ID);
+ }
+
+void DRndTim::StopTimer()
+ {
+#if defined(__MISA__)
+ Interrupt::Disable(KIntIdOstMatchGeneral);
+ TSa1100::DisableOstInterrupt(KHwOstMatchGeneral);
+ TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
+#elif defined(__MCOT__)
+ Interrupt::Disable(KIntIdOstMatchGeneral);
+ TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
+ TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
+#endif
+ }
+
+void DRndTim::TimerIsr(TAny* aPtr)
+ {
+ DRndTim* d = (DRndTim*)aPtr;
+ ++d->iIsrCount;
+#if defined(__MISA__)
+ TUint interval = Random((TUint*)d->iSeed);
+ interval &= 0x3ff;
+ interval += 256; // 256-1279 ticks = approx 69 to 347 microseconds
+ TUint oscr=TSa1100::OstData();
+ TSa1100::SetOstMatch(KHwOstMatchGeneral, oscr + interval);
+ TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
+#elif defined(__MCOT__)
+ TUint interval = Random((TUint*)d->iSeed);
+ interval &= 0x3ff;
+ interval += 256; // 256-1279 ticks = approx 69 to 347 microseconds
+ TUint oscr=TCotulla::OstData();
+ TCotulla::SetOstMatch(KHwOstMatchGeneral, oscr + interval);
+ TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
+#endif
+ d->iIDfc.Add();
+ }
+
+void DRndTim::IDfcFn(TAny* aPtr)
+ {
+ DRndTim* d = (DRndTim*)aPtr;
+ d->iSem.Signal();
+ }
+
+