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