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 +