os/kernelhwsrv/kernel/eka/drivers/adc/d_adc.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/adc/d_adc.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,219 @@
     1.4 +// Copyright (c) 1998-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 +// e32\drivers\adc\d_adc.cpp
    1.18 +// Generic ADC driver
    1.19 +// 
    1.20 +//
    1.21 +
    1.22 +
    1.23 +#include <adc.h>
    1.24 +
    1.25 +/******************************************************
    1.26 + * ADC Channel
    1.27 + ******************************************************/
    1.28 +EXPORT_C TAdcChannel::TAdcChannel(TInt anAdc)
    1.29 +	:	iChannelId(-1), iCommandCount(0), iCommandList(NULL),
    1.30 +		iReadings(NULL)
    1.31 +	{
    1.32 +	iNext=NULL;
    1.33 +//	iPriority=0;
    1.34 +	if (anAdc>=0 && anAdc<DAdc::NumberOfAdcs)
    1.35 +		iAdc=DAdc::TheAdcs[anAdc];
    1.36 +	else
    1.37 +		iAdc=NULL;
    1.38 +	}
    1.39 +
    1.40 +EXPORT_C void TAdcChannel::Read(TInt* aReadingBuffer)
    1.41 +//
    1.42 +// Initiate a reading of this channel
    1.43 +//
    1.44 +	{
    1.45 +	TInt irq=NKern::DisableAllInterrupts();
    1.46 +	if (!iNext)
    1.47 +		{
    1.48 +		iReadings=aReadingBuffer;
    1.49 +		iAdc->Add(this);
    1.50 +		}
    1.51 +	NKern::RestoreInterrupts(irq);
    1.52 +	}
    1.53 +
    1.54 +EXPORT_C void TAdcChannel::Preamble()
    1.55 +//
    1.56 +// Default preamble does nothing
    1.57 +//
    1.58 +	{
    1.59 +	}
    1.60 +
    1.61 +EXPORT_C void TAdcChannel::Postamble()
    1.62 +//
    1.63 +// Default postamble does nothing
    1.64 +//
    1.65 +	{
    1.66 +	}
    1.67 +
    1.68 +
    1.69 +/******************************************************
    1.70 + * ADC Controller
    1.71 + ******************************************************/
    1.72 +LOCAL_C void timerExpired(TAny* aPtr)
    1.73 +	{
    1.74 +	((DAdc*)aPtr)->TimerExpired();
    1.75 +	}
    1.76 +
    1.77 +DAdc::DAdc()
    1.78 +	:	iTimer(timerExpired,this)
    1.79 +	{
    1.80 +//	iCurrentChannel=NULL;
    1.81 +//	iCurrentCommand=0;
    1.82 +//	iCommandPtr=0;
    1.83 +//	iCommandCount=0;
    1.84 +//	iMinPriority=0;
    1.85 +	}
    1.86 +
    1.87 +DAdc::~DAdc()
    1.88 +	{
    1.89 +	}
    1.90 +
    1.91 +EXPORT_C TInt DAdc::SetMinPriority(TInt anAdc, TInt aPriority)
    1.92 +	{
    1.93 +	if (anAdc<0 || anAdc>=NumberOfAdcs)
    1.94 +		return KErrArgument;
    1.95 +	if (aPriority<0 || aPriority>KNumAdcChannelPriorities)
    1.96 +		return KErrArgument;
    1.97 +	return TheAdcs[anAdc]->DoSetMinPriority(aPriority);
    1.98 +	}
    1.99 +
   1.100 +TInt DAdc::DoSetMinPriority(TInt aPriority)
   1.101 +	{
   1.102 +	TInt irq=NKern::DisableAllInterrupts();
   1.103 +	if (aPriority<iMinPriority)
   1.104 +		{
   1.105 +		if (iList.iPresent[0])
   1.106 +			{
   1.107 +			TAdcChannel* pN=iList.First();
   1.108 +			if (pN->iPriority>=aPriority)
   1.109 +				{
   1.110 +				iList.Remove(pN);
   1.111 +				Execute(pN);
   1.112 +				}
   1.113 +			}
   1.114 +		}
   1.115 +	iMinPriority=aPriority;
   1.116 +	NKern::RestoreInterrupts(irq);
   1.117 +	return KErrNone;
   1.118 +	}
   1.119 +
   1.120 +void DAdc::Add(TAdcChannel* aChannel)
   1.121 +//
   1.122 +// Queue another ADC reading request
   1.123 +//
   1.124 +	{
   1.125 +	if (iCurrentChannel || (aChannel->iPriority<iMinPriority))
   1.126 +		iList.Add(aChannel);
   1.127 +	else
   1.128 +		Execute(aChannel);
   1.129 +	}
   1.130 +
   1.131 +void DAdc::Execute(TAdcChannel* aChannel)
   1.132 +//
   1.133 +// Begin execution of an ADC request
   1.134 +// This runs in an ISR or with interrupts disabled
   1.135 +//
   1.136 +	{
   1.137 +	aChannel->iNext=(TPriListLink*)1;	// so channel will not be queued again
   1.138 +	iCurrentChannel=aChannel;
   1.139 +	iCommandPtr=aChannel->iCommandList;
   1.140 +	iCommandCount=aChannel->iCommandCount;
   1.141 +	NextCommand();
   1.142 +	}
   1.143 +
   1.144 +void DAdc::NextCommand()
   1.145 +//
   1.146 +// Perform the next command in the command list
   1.147 +// This runs in an ISR or with interrupts disabled
   1.148 +//
   1.149 +	{
   1.150 +	TBool wait=EFalse;
   1.151 +	TAdcChannel* pC=iCurrentChannel;
   1.152 +	if (iCommandCount)
   1.153 +		{
   1.154 +		TInt c=*iCommandPtr++;
   1.155 +		iCurrentCommand=c;
   1.156 +		iCommandCount--;
   1.157 +		if (c & EAdcCmdPreamble)
   1.158 +			pC->Preamble();
   1.159 +		if (c & EAdcCmdPostamble)
   1.160 +			pC->Postamble();
   1.161 +		if (c & EAdcCmdWait)
   1.162 +			{
   1.163 +			iTimer.OneShot(c & 0xffff);
   1.164 +			wait=ETrue;
   1.165 +			}
   1.166 +		else if (c & EAdcCmdReading)
   1.167 +			{
   1.168 +			StartConversion(pC->iChannelId);
   1.169 +			wait=ETrue;
   1.170 +			}
   1.171 +		}
   1.172 +	if (iCommandCount==0 && !wait)
   1.173 +		{
   1.174 +		iCurrentChannel=NULL;
   1.175 +		pC->iNext=NULL;
   1.176 +		if (iList.iPresent[0])
   1.177 +			{
   1.178 +			TAdcChannel* pN=iList.First();
   1.179 +			if (pN->iPriority>=iMinPriority)
   1.180 +				{
   1.181 +				iList.Remove(pN);
   1.182 +				Execute(pN);
   1.183 +				}
   1.184 +			}
   1.185 +		pC->Complete();
   1.186 +		}
   1.187 +	}
   1.188 +
   1.189 +void DAdc::Start()
   1.190 +//
   1.191 +// Called on completion of initialisation to start processing requests
   1.192 +// This runs in an ISR
   1.193 +//
   1.194 +	{
   1.195 +	iCurrentChannel=NULL;
   1.196 +	if (iList.iPresent[0])
   1.197 +		{
   1.198 +		TAdcChannel* pN=iList.First();
   1.199 +		iList.Remove(pN);
   1.200 +		Execute(pN);
   1.201 +		}
   1.202 +	}
   1.203 +
   1.204 +void DAdc::ConversionComplete(TInt aValue)
   1.205 +//
   1.206 +// Called when a conversion has completed
   1.207 +// This runs in an ISR
   1.208 +//
   1.209 +	{
   1.210 +	if ((iCurrentCommand & EAdcCmdDiscard)==0)
   1.211 +		*(iCurrentChannel->iReadings)++=aValue;
   1.212 +	NextCommand();
   1.213 +	}
   1.214 +
   1.215 +void DAdc::TimerExpired()
   1.216 +//
   1.217 +// Called in ISR when timer expires
   1.218 +//
   1.219 +	{
   1.220 +	NextCommand();
   1.221 +	}
   1.222 +