os/kernelhwsrv/kerneltest/e32test/misc/d_rndtim.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\misc\d_rndtim.cpp
sl@0
    15
// LDD for generating random interrupts
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include "platform.h"
sl@0
    20
#include <kernel/kern_priv.h>
sl@0
    21
#include "d_rndtim.h"
sl@0
    22
#include "../misc/prbs.h"
sl@0
    23
sl@0
    24
#if defined(__MAWD__)
sl@0
    25
#include <windermere.h>
sl@0
    26
#elif defined(__MISA__)
sl@0
    27
#define INT_ID KIntIdOstMatchGeneral
sl@0
    28
#include <sa1100.h>
sl@0
    29
#elif defined(__MCOT__)
sl@0
    30
#define INT_ID KIntIdOstMatchGeneral
sl@0
    31
#include <cotulla.h>
sl@0
    32
#elif defined(__MI920__) || defined(__NI1136__)
sl@0
    33
#include <integratorap.h>
sl@0
    34
#elif defined(__EPOC32__) && defined(__CPU_X86)
sl@0
    35
#include <x86.h>
sl@0
    36
#endif
sl@0
    37
sl@0
    38
#ifndef INT_ID
sl@0
    39
#error Random timer ISR not supported on this platform
sl@0
    40
#endif
sl@0
    41
sl@0
    42
sl@0
    43
const TInt KMajorVersionNumber=0;
sl@0
    44
const TInt KMinorVersionNumber=1;
sl@0
    45
const TInt KBuildVersionNumber=1;
sl@0
    46
sl@0
    47
class DRndTimFactory : public DLogicalDevice
sl@0
    48
//
sl@0
    49
// IPC copy LDD factory
sl@0
    50
//
sl@0
    51
	{
sl@0
    52
public:
sl@0
    53
	DRndTimFactory();
sl@0
    54
	virtual TInt Install();						//overriding pure virtual
sl@0
    55
	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
sl@0
    56
	virtual TInt Create(DLogicalChannelBase*& aChannel);	//overriding pure virtual
sl@0
    57
	};
sl@0
    58
sl@0
    59
class DRndTim : public DLogicalChannelBase
sl@0
    60
//
sl@0
    61
// Millisecond timer LDD channel
sl@0
    62
//
sl@0
    63
	{
sl@0
    64
public:
sl@0
    65
	DRndTim();
sl@0
    66
	virtual ~DRndTim();
sl@0
    67
protected:
sl@0
    68
	virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
sl@0
    69
	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
sl@0
    70
public:
sl@0
    71
	static void TimerIsr(TAny* aPtr);
sl@0
    72
	static void IDfcFn(TAny* aPtr);
sl@0
    73
	void StartTimer();
sl@0
    74
	void StopTimer();
sl@0
    75
	TInt SetPriority(TInt aHandle, TInt aPriority);
sl@0
    76
	TInt Calibrate(TInt aMilliseconds);
sl@0
    77
public:
sl@0
    78
	TInt iIntId;
sl@0
    79
	NFastSemaphore iSem;
sl@0
    80
	volatile TUint32 iSeed[2];
sl@0
    81
	volatile TUint32 iIsrCount;
sl@0
    82
	DThread* iThread;
sl@0
    83
	TDfc iIDfc;
sl@0
    84
	};
sl@0
    85
sl@0
    86
DECLARE_STANDARD_LDD()
sl@0
    87
	{
sl@0
    88
    return new DRndTimFactory;
sl@0
    89
    }
sl@0
    90
sl@0
    91
DRndTimFactory::DRndTimFactory()
sl@0
    92
//
sl@0
    93
// Constructor
sl@0
    94
//
sl@0
    95
    {
sl@0
    96
    iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
    97
    //iParseMask=0;//No units, no info, no PDD
sl@0
    98
    //iUnitsMask=0;//Only one thing
sl@0
    99
    }
sl@0
   100
sl@0
   101
TInt DRndTimFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
   102
//
sl@0
   103
// Create a new DRndTim on this logical device
sl@0
   104
//
sl@0
   105
    {
sl@0
   106
	aChannel=new DRndTim;
sl@0
   107
    return aChannel?KErrNone:KErrNoMemory;
sl@0
   108
    }
sl@0
   109
sl@0
   110
TInt DRndTimFactory::Install()
sl@0
   111
//
sl@0
   112
// Install the LDD - overriding pure virtual
sl@0
   113
//
sl@0
   114
    {
sl@0
   115
    return SetName(&KRndTimLddName);
sl@0
   116
    }
sl@0
   117
sl@0
   118
void DRndTimFactory::GetCaps(TDes8& aDes) const
sl@0
   119
//
sl@0
   120
// Get capabilities - overriding pure virtual
sl@0
   121
//
sl@0
   122
    {
sl@0
   123
    TCapsRndTimV01 b;
sl@0
   124
    b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
   125
    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
sl@0
   126
    }
sl@0
   127
sl@0
   128
DRndTim::DRndTim()
sl@0
   129
//
sl@0
   130
// Constructor
sl@0
   131
//
sl@0
   132
	:	iIntId(-1),
sl@0
   133
		iIDfc(&IDfcFn, this)
sl@0
   134
    {
sl@0
   135
	iThread=&Kern::CurrentThread();
sl@0
   136
	iThread->Open();
sl@0
   137
	iSem.iOwningThread = &iThread->iNThread;
sl@0
   138
	iSeed[0] = 0xb504f333u;
sl@0
   139
	iSeed[1] = 0xf9de6484u;
sl@0
   140
    }
sl@0
   141
sl@0
   142
DRndTim::~DRndTim()
sl@0
   143
	{
sl@0
   144
	StopTimer();
sl@0
   145
	if (iIntId >= 0)
sl@0
   146
		Interrupt::Unbind(iIntId);
sl@0
   147
	Kern::SafeClose((DObject*&)iThread, NULL);
sl@0
   148
	}
sl@0
   149
sl@0
   150
TInt DRndTim::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
sl@0
   151
//
sl@0
   152
// Create channel
sl@0
   153
//
sl@0
   154
    {
sl@0
   155
sl@0
   156
    if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
sl@0
   157
    	return KErrNotSupported;
sl@0
   158
	StopTimer();
sl@0
   159
	TInt r = Interrupt::Bind(INT_ID, &TimerIsr, this);
sl@0
   160
	if (r == KErrNone)
sl@0
   161
		iIntId = INT_ID;
sl@0
   162
	return r;
sl@0
   163
	}
sl@0
   164
sl@0
   165
TInt DRndTim::Request(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   166
	{
sl@0
   167
	TInt r = KErrNotSupported;
sl@0
   168
	switch (aFunction)
sl@0
   169
		{
sl@0
   170
		case RRndTim::EControlWait:
sl@0
   171
			NKern::FSWait(&iSem);
sl@0
   172
			r = KErrNone;
sl@0
   173
			break;
sl@0
   174
		case RRndTim::EControlSetPriority:
sl@0
   175
			r = SetPriority(TInt(a1), TInt(a2));
sl@0
   176
			break;
sl@0
   177
		case RRndTim::EControlStartTimer:
sl@0
   178
			NKern::ThreadEnterCS();
sl@0
   179
			StartTimer();
sl@0
   180
			NKern::ThreadLeaveCS();
sl@0
   181
			break;
sl@0
   182
		case RRndTim::EControlStopTimer:
sl@0
   183
			NKern::ThreadEnterCS();
sl@0
   184
			StopTimer();
sl@0
   185
			NKern::ThreadLeaveCS();
sl@0
   186
			break;
sl@0
   187
		case RRndTim::EControlCalibrate:
sl@0
   188
			NKern::ThreadEnterCS();
sl@0
   189
			r = Calibrate(TInt(a1));
sl@0
   190
			NKern::ThreadLeaveCS();
sl@0
   191
			break;
sl@0
   192
		default:
sl@0
   193
			break;
sl@0
   194
		}
sl@0
   195
	return r;
sl@0
   196
	}
sl@0
   197
sl@0
   198
TInt DRndTim::SetPriority(TInt aHandle, TInt aPriority)
sl@0
   199
	{
sl@0
   200
	TInt r = KErrBadHandle;
sl@0
   201
	DThread& c = Kern::CurrentThread();
sl@0
   202
	NKern::ThreadEnterCS();
sl@0
   203
	NKern::LockSystem();
sl@0
   204
	DThread* t = (DThread*)Kern::ObjectFromHandle(&c, aHandle, EThread);
sl@0
   205
	if (t && !t->Open())
sl@0
   206
		{
sl@0
   207
		NKern::UnlockSystem();
sl@0
   208
		r = Kern::SetThreadPriority(aPriority, t);
sl@0
   209
		t->Close(NULL);
sl@0
   210
		}
sl@0
   211
	else
sl@0
   212
		NKern::UnlockSystem();
sl@0
   213
	NKern::ThreadLeaveCS();
sl@0
   214
	return r;
sl@0
   215
	}
sl@0
   216
sl@0
   217
TInt DRndTim::Calibrate(TInt aMilliseconds)
sl@0
   218
	{
sl@0
   219
	TUint32 n1, n2;
sl@0
   220
	TInt ticks = NKern::TimerTicks(aMilliseconds);
sl@0
   221
	n1 = iIsrCount;
sl@0
   222
	NKern::Sleep(ticks);
sl@0
   223
	n2 = iIsrCount;
sl@0
   224
	return (TInt)(n2-n1);
sl@0
   225
	}
sl@0
   226
sl@0
   227
void DRndTim::StartTimer()
sl@0
   228
	{
sl@0
   229
#if defined(__MISA__) 
sl@0
   230
	// for SA11x0 use OST match 0
sl@0
   231
	TSa1100::ModifyIntLevels(0,KHtIntsOstMatchGeneral);	// route new timer interrupt to FIQ
sl@0
   232
	TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   233
	TUint oscr=TSa1100::OstData();
sl@0
   234
	TSa1100::SetOstMatch(KHwOstMatchGeneral, oscr + 5000);
sl@0
   235
	TSa1100::EnableOstInterrupt(KHwOstMatchGeneral);
sl@0
   236
#elif defined(__MCOT__)
sl@0
   237
	// for SA11x0 use OST match 0
sl@0
   238
	TCotulla::ModifyIntLevels(0,KHtIntsOstMatchGeneral);	// route new timer interrupt to FIQ
sl@0
   239
	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   240
	TUint oscr=TCotulla::OstData();
sl@0
   241
	TCotulla::SetOstMatch(KHwOstMatchGeneral, oscr + 5000);
sl@0
   242
	TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
sl@0
   243
#endif
sl@0
   244
	Interrupt::Enable(INT_ID);
sl@0
   245
	}
sl@0
   246
sl@0
   247
void DRndTim::StopTimer()
sl@0
   248
	{
sl@0
   249
#if defined(__MISA__) 
sl@0
   250
	Interrupt::Disable(KIntIdOstMatchGeneral);
sl@0
   251
	TSa1100::DisableOstInterrupt(KHwOstMatchGeneral);
sl@0
   252
	TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   253
#elif defined(__MCOT__)
sl@0
   254
	Interrupt::Disable(KIntIdOstMatchGeneral);
sl@0
   255
	TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
sl@0
   256
	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   257
#endif
sl@0
   258
	}
sl@0
   259
sl@0
   260
void DRndTim::TimerIsr(TAny* aPtr)
sl@0
   261
	{
sl@0
   262
	DRndTim* d = (DRndTim*)aPtr;
sl@0
   263
	++d->iIsrCount;
sl@0
   264
#if defined(__MISA__) 
sl@0
   265
	TUint interval = Random((TUint*)d->iSeed);
sl@0
   266
	interval &= 0x3ff;
sl@0
   267
	interval += 256;	// 256-1279 ticks = approx 69 to 347 microseconds
sl@0
   268
	TUint oscr=TSa1100::OstData();
sl@0
   269
	TSa1100::SetOstMatch(KHwOstMatchGeneral, oscr + interval);
sl@0
   270
	TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   271
#elif defined(__MCOT__)
sl@0
   272
	TUint interval = Random((TUint*)d->iSeed);
sl@0
   273
	interval &= 0x3ff;
sl@0
   274
	interval += 256;	// 256-1279 ticks = approx 69 to 347 microseconds
sl@0
   275
	TUint oscr=TCotulla::OstData();
sl@0
   276
	TCotulla::SetOstMatch(KHwOstMatchGeneral, oscr + interval);
sl@0
   277
	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   278
#endif
sl@0
   279
	d->iIDfc.Add();
sl@0
   280
	}
sl@0
   281
sl@0
   282
void DRndTim::IDfcFn(TAny* aPtr)
sl@0
   283
	{
sl@0
   284
	DRndTim* d = (DRndTim*)aPtr;
sl@0
   285
	d->iSem.Signal();
sl@0
   286
	}
sl@0
   287
sl@0
   288