diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/driver1__pdd_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/driver1__pdd_8cpp-source.html Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,259 @@ + +
+00001 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +00002 // All rights reserved. +00003 // This component and the accompanying materials are made available +00004 // under the terms of "Eclipse Public License v1.0" +00005 // which accompanies this distribution, and is available +00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html". +00007 // +00008 // Initial Contributors: +00009 // Nokia Corporation - initial contribution. +00010 // +00011 // Contributors: +00012 // +00013 // Description: +00014 // Example Physical Device Driver +00015 // +00016 +00017 +00018 +00023 #include <kern_priv.h> +00024 #include "driver1.h" +00025 #include "driver1_dev.h" +00026 +00030 class DDevice1PddFactory : public DPhysicalDevice +00031 { +00032 public: +00033 DDevice1PddFactory(); +00034 +00035 // Inherited from DPhysicalDevice +00036 virtual TInt Install(); +00037 virtual void GetCaps(TDes8& aDes) const; +00038 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); +00039 virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); +00040 public: +00041 TInt iHardwareInUse; +00042 private: +00046 enum TMinimumLDDVersion +00047 { +00048 EMinimumLddMajorVersion=1, +00049 EMinimumLddMinorVersion=0, +00050 EMinimumLddBuild=0 //Not used +00051 }; +00052 }; +00053 +00054 // Name for PDD, must match LDD name with a '.' and distinguishing name appended +00055 _LIT(KDriver1PddName,"DRIVER1.template"); +00056 +00060 class DDriver1Device : public DDriver1 +00061 { +00062 public: +00063 DDriver1Device(DDevice1PddFactory* aFactory); +00064 ~DDriver1Device(); +00065 TInt DoCreate(); +00066 +00067 // Inherited from DDriver1. These functions are called by the LDD. +00068 virtual TInt BufferSize() const; +00069 virtual TInt Speed() const; +00070 virtual TInt SetSpeed(TInt aSpeed); +00071 virtual TInt SendData(const TDesC8& aData); +00072 virtual void SendDataCancel(); +00073 virtual TInt ReceiveData(TDes8& aBuffer); +00074 virtual void ReceiveDataCancel(); +00075 private: +00076 static void SendDataTimerCallback(TAny* aPtr); +00077 void SendDataCallback(); +00078 static void ReceiveDataTimerCallback(TAny* aPtr); +00079 void ReceiveDataCallback(); +00080 private: +00081 DDevice1PddFactory* iFactory; +00082 TInt iSpeed; +00083 NTimer iSendDataTimer; +00084 NTimer iReceiveDataTimer; +00085 TBuf8<256> iBuffer; +00086 TDes8* iReceiveBuffer; +00087 }; +00088 // +00089 // DDevice1PddFactory +00090 // +00091 +00096 DECLARE_STANDARD_PDD() +00097 { +00098 return new DDevice1PddFactory; +00099 } +00100 +00101 DDevice1PddFactory::DDevice1PddFactory() +00102 { +00103 // Sets version number for this device +00104 iVersion=RDriver1::VersionRequired(); +00105 } +00106 +00112 TInt DDevice1PddFactory::Install() +00113 { +00114 return SetName(&KDriver1PddName); +00115 } +00116 +00122 void DDevice1PddFactory::GetCaps(TDes8& aDes) const +00123 { +00124 // Create a capabilities object +00125 DDriver1::TCaps caps; +00126 caps.iVersion = iVersion; +00127 // Zero the buffer +00128 TInt maxLen = aDes.MaxLength(); +00129 aDes.FillZ(maxLen); +00130 // Copy capabilities +00131 TInt size=sizeof(caps); +00132 if(size>maxLen) +00133 size=maxLen; +00134 aDes.Copy((TUint8*)&caps,size); +00135 } +00136 +00148 TInt DDevice1PddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) +00149 { +00150 // Ignore the parameters we aren't interested in... +00151 (void)aUnit; +00152 (void)aInfo; +00153 (void)aVer; +00154 +00155 // Create a new physical channel +00156 DDriver1Device* device=new DDriver1Device(this); +00157 aChannel=device; +00158 if (!device) +00159 return KErrNoMemory; +00160 return device->DoCreate(); +00161 } +00162 +00173 TInt DDevice1PddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) +00174 { +00175 // Check version numbers +00176 if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(EMinimumLddMajorVersion,EMinimumLddMinorVersion,EMinimumLddBuild)))) +00177 return KErrNotSupported; +00178 +00179 // We don't support units +00180 if (aUnit != -1) +00181 return KErrNotSupported; +00182 +00183 // Ignore extra info, (this could be used for validation purposes). +00184 // Note, aInfo is a pointer to a descriptor in user memory, therefore safe methods should +00185 // be used for reading its contents e.g. using Kern::KUDesGet() +00186 (void)aInfo; +00187 +00188 // OK +00189 return KErrNone; +00190 } +00191 +00195 DDriver1Device::DDriver1Device(DDevice1PddFactory* aFactory) +00196 : iFactory(aFactory), +00197 iSpeed(100000), // 100000us (100ms) per byte +00198 iSendDataTimer(SendDataTimerCallback,this), +00199 iReceiveDataTimer(ReceiveDataTimerCallback,this) +00200 { +00201 } +00202 +00206 DDriver1Device::~DDriver1Device() +00207 { +00208 // Driver no longer using hardware resources +00209 NKern::LockedDec(iFactory->iHardwareInUse); +00210 } +00211 +00212 TInt DDriver1Device::DoCreate() +00213 { +00214 // Claim the hardware resources by incrementing iHardwareInUse. +00215 // Must do this before any other failure can happen in this function so that +00216 // the destructor can safely decrement iHardwareInUse. +00217 // +00218 // This method of ensuring hardware is only in use by one driver at a time +00219 // wouldn't be needed if the driver claimed real hardware resources which +00220 // could only be used once. E.g. binding to an interrupt. +00221 if(NKern::LockedInc(iFactory->iHardwareInUse)) +00222 return KErrInUse; +00223 +00224 // Other setup goes here +00225 return KErrNone; +00226 } +00230 TInt DDriver1Device::BufferSize() const +00231 { +00232 return iBuffer.MaxSize(); +00233 } +00234 +00238 TInt DDriver1Device::Speed() const +00239 { +00240 return iSpeed; +00241 } +00242 +00247 TInt DDriver1Device::SetSpeed(TInt aSpeed) +00248 { +00249 if(aSpeed<=0) +00250 return KErrArgument; +00251 iSpeed = aSpeed; +00252 return KErrNone; +00253 } +00254 +00255 // Methods for processing 'SendData' +00256 // +00260 TInt DDriver1Device::SendData(const TDesC8& aData) +00261 { +00262 // Save the last part of the data to 'send', we will pretend to 'receive' this later +00263 iBuffer=aData.Right(iBuffer.MaxSize()); +00264 // Pretend to send the data by waiting for iSpeed micro-seconds per byte... +00265 iSendDataTimer.OneShot(aData.Size()*iSpeed/NKern::TickPeriod()); +00266 return KErrNone; +00267 } +00268 +00272 void DDriver1Device::SendDataCancel() +00273 { +00274 // Stop the timer we were using to pretend we were processing the send. +00275 iSendDataTimer.Cancel(); +00276 } +00277 +00282 void DDriver1Device::SendDataTimerCallback(TAny* aPtr) +00283 { +00284 // Just forward callback to non-static callback function +00285 ((DDriver1Device*)aPtr)->SendDataCallback(); +00286 } +00287 +00291 void DDriver1Device::SendDataCallback() +00292 { +00293 // Tell LDD we've finished +00294 iLdd->SendDataComplete(KErrNone); +00295 } +00296 +00297 // +00298 // Methods for processing 'ReceiveData' +00299 // +00303 TInt DDriver1Device::ReceiveData(TDes8& aBuffer) +00304 { +00305 // Save a pointer to the buffer we need to put the 'received' data in +00306 iReceiveBuffer=&aBuffer; +00307 // Pretend to receive the data by waiting for iSpeed micro-seconds per byte... +00308 iReceiveDataTimer.OneShot(iBuffer.Size()*iSpeed/NKern::TickPeriod()); +00309 return KErrNone; +00310 } +00314 void DDriver1Device::ReceiveDataCancel() +00315 { +00316 // Stop the timer we were using to pretend we were processing the receive +00317 iReceiveDataTimer.Cancel(); +00318 } +00323 void DDriver1Device::ReceiveDataTimerCallback(TAny* aPtr) +00324 { +00325 // Just forward callback to non-static callback function +00326 ((DDriver1Device*)aPtr)->ReceiveDataCallback(); +00327 } +00331 void DDriver1Device::ReceiveDataCallback() +00332 { +00333 // Pretend the data we have received is that saved in iBuffer when we last did a send +00334 *iReceiveBuffer=iBuffer; +00335 // Tell LDD we've finished +00336 iLdd->ReceiveDataComplete(KErrNone); +00337 } +