sl@0: // Copyright (c) 2002-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: // sl@0: sl@0: #include sl@0: #include sl@0: sl@0: #include "k32bm.h" sl@0: sl@0: class DBMNE1Device : public DPhysicalDevice sl@0: { sl@0: public: sl@0: DBMNE1Device(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: }; sl@0: sl@0: class DBMNE1Channel : public DBMPChannel sl@0: { sl@0: public: sl@0: DBMNE1Channel(); sl@0: ~DBMNE1Channel(); sl@0: virtual TBMTicks TimerPeriod(); sl@0: virtual TBMTicks TimerStamp(); sl@0: virtual TBMNs TimerTicksToNs(TBMTicks); sl@0: virtual TBMTicks TimerNsToTicks(TBMNs); sl@0: virtual TInt BindInterrupt(MBMIsr*); sl@0: virtual TInt BindInterrupt(MBMInterruptLatencyIsr*); sl@0: virtual void RequestInterrupt(); sl@0: virtual void CancelInterrupt(); sl@0: sl@0: private: sl@0: static const TBMTicks KBMNE1Period = (((TBMTicks) 1) << 32); sl@0: sl@0: static void Isr(TAny*); sl@0: sl@0: MBMIsr* iIsr; sl@0: MBMInterruptLatencyIsr* iInterruptLatencyIsr; sl@0: TUint iPrescale; sl@0: TUint iNsPerTick; sl@0: NTimer iTimer; sl@0: volatile TUint iStartCount; sl@0: volatile TUint iRunCount; sl@0: volatile TUint iCancelCount; sl@0: }; sl@0: sl@0: sl@0: DECLARE_STANDARD_PDD() sl@0: // sl@0: // Create a new device sl@0: // sl@0: { sl@0: __ASSERT_CRITICAL; sl@0: return new DBMNE1Device; sl@0: } sl@0: sl@0: DBMNE1Device::DBMNE1Device() sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: //iUnitsMask=0; sl@0: iVersion = TVersion(1,0,1); sl@0: } sl@0: sl@0: TInt DBMNE1Device::Install() sl@0: // sl@0: // Install the device driver. sl@0: // sl@0: { sl@0: TInt r = SetName(&KBMPdName); sl@0: return r; sl@0: } sl@0: sl@0: void DBMNE1Device::GetCaps(TDes8& aDes) const sl@0: // sl@0: // Return the Comm capabilities. sl@0: // sl@0: { sl@0: } sl@0: sl@0: TInt DBMNE1Device::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) sl@0: // sl@0: // Create a channel on the device. sl@0: // sl@0: { sl@0: __ASSERT_CRITICAL; sl@0: aChannel = new DBMNE1Channel; sl@0: return aChannel?KErrNone:KErrNoMemory; sl@0: } sl@0: sl@0: TInt DBMNE1Device::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) sl@0: { sl@0: if (!Kern::QueryVersionSupported(iVersion,aVer)) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: DBMNE1Channel::DBMNE1Channel() sl@0: : iTimer(&Isr, this) sl@0: { sl@0: // iIsr = NULL; sl@0: // iInterruptLatencyIsr = NULL; sl@0: NETimer& T2 = NETimer::Timer(2); sl@0: iPrescale = __e32_find_ms1_32(T2.iPrescaler & 0x3f); sl@0: iNsPerTick = 15u << iPrescale; sl@0: } sl@0: sl@0: DBMNE1Channel::~DBMNE1Channel() sl@0: { sl@0: CancelInterrupt(); sl@0: } sl@0: sl@0: TBMTicks DBMNE1Channel::TimerPeriod() sl@0: { sl@0: return KBMNE1Period; sl@0: } sl@0: sl@0: TBMTicks DBMNE1Channel::TimerStamp() sl@0: { sl@0: return NETimer::Timer(2).iTimerCount; sl@0: } sl@0: sl@0: TBMNs DBMNE1Channel::TimerTicksToNs(TBMTicks ticks) sl@0: { sl@0: return ticks * (TBMTicks)iNsPerTick; sl@0: } sl@0: sl@0: TBMTicks DBMNE1Channel::TimerNsToTicks(TBMNs ns) sl@0: { sl@0: return ns / (TBMTicks)iNsPerTick; sl@0: } sl@0: sl@0: void DBMNE1Channel::Isr(TAny* ptr) sl@0: { sl@0: DBMNE1Channel* mCh = (DBMNE1Channel*) ptr; sl@0: BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr); sl@0: if (mCh->iIsr) sl@0: { sl@0: mCh->iIsr->Isr(NETimer::Timer(2).iTimerCount); sl@0: } sl@0: else sl@0: { sl@0: TUint x = NETimer::Timer(0).iTimerCount; sl@0: x = (x + (1u<iPrescale) - 1) >> mCh->iPrescale; sl@0: mCh->iInterruptLatencyIsr->InterruptLatencyIsr(x); sl@0: } sl@0: __e32_atomic_add_ord32(&mCh->iRunCount, 1); sl@0: } sl@0: sl@0: TInt DBMNE1Channel::BindInterrupt(MBMIsr* aIsr) sl@0: { sl@0: BM_ASSERT(!iIsr); sl@0: BM_ASSERT(!iInterruptLatencyIsr); sl@0: iIsr = aIsr; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DBMNE1Channel::BindInterrupt(MBMInterruptLatencyIsr* aIsr) sl@0: { sl@0: BM_ASSERT(!iIsr); sl@0: BM_ASSERT(!iInterruptLatencyIsr); sl@0: iInterruptLatencyIsr = aIsr; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: void DBMNE1Channel::RequestInterrupt() sl@0: { sl@0: BM_ASSERT(iIsr || iInterruptLatencyIsr); sl@0: if (iTimer.OneShot(1)==KErrNone) sl@0: __e32_atomic_add_ord32(&iStartCount, 1); sl@0: } sl@0: sl@0: void DBMNE1Channel::CancelInterrupt() sl@0: { sl@0: if (iTimer.Cancel()) sl@0: __e32_atomic_add_ord32(&iCancelCount, 1); sl@0: while (iStartCount != iCancelCount + iRunCount) sl@0: {} sl@0: } sl@0: