1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/iic/iic_psl/spi.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1000 @@
1.4 +// Copyright (c) 2008-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 +// e32test/iic/iic_psl/spi.cpp
1.18 +//
1.19 +#include "spi.h"
1.20 +
1.21 +#ifdef IIC_INSTRUMENTATION_MACRO
1.22 +#include <drivers/iic_trace.h>
1.23 +#endif
1.24 +
1.25 +#define NUM_CHANNELS 4 // Arbitrary
1.26 +
1.27 +// Macros to be updated(?) with interaction with Configuration Repository
1.28 +const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMaster};
1.29 +#define CHANNEL_TYPE(n) (KChannelTypeArray[n])
1.30 +const DIicBusChannel::TChannelDuplex KChannelDuplexArray[NUM_CHANNELS] = {DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EFullDuplex};
1.31 +#define CHANNEL_DUPLEX(n) (KChannelDuplexArray[n])
1.32 +
1.33 +#ifdef LOG_SPI
1.34 +#define SPI_PRINT(str) Kern::Printf str
1.35 +#else
1.36 +#define SPI_PRINT(str)
1.37 +#endif
1.38 +
1.39 +_LIT(KSpiThreadName,"SpiChannelThread");
1.40 +
1.41 +const TInt KSpiThreadPriority = 5; // Arbitrary, can be 0-7, 7 highest
1.42 +
1.43 +#ifdef STANDALONE_CHANNEL
1.44 +_LIT(KPddNameSpi,"spi_ctrless.pdd");
1.45 +#else
1.46 +_LIT(KPddNameSpi,"spi.pdd");
1.47 +#endif
1.48 +
1.49 +#ifndef STANDALONE_CHANNEL
1.50 +LOCAL_C TInt8 AssignChanNum()
1.51 + {
1.52 + static TInt8 iBaseChanNum = KSpiChannelNumBase;
1.53 + SPI_PRINT(("SPI AssignChanNum - on entry, iBaseCanNum = 0x%x\n",iBaseChanNum));
1.54 + return iBaseChanNum++; // Arbitrary, for illustration
1.55 + }
1.56 +#endif
1.57 +
1.58 +NONSHARABLE_CLASS(DSimulatedSpiDevice) : public DPhysicalDevice
1.59 + {
1.60 +// Class to faciliate loading of the IIC classes
1.61 +public:
1.62 + class TCaps
1.63 + {
1.64 + public:
1.65 + TVersion iVersion;
1.66 + };
1.67 +public:
1.68 + DSimulatedSpiDevice();
1.69 + virtual TInt Install();
1.70 + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.71 + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.72 + virtual void GetCaps(TDes8& aDes) const;
1.73 + inline static TVersion VersionRequired();
1.74 + };
1.75 +
1.76 +TVersion DSimulatedSpiDevice::VersionRequired()
1.77 + {
1.78 + SPI_PRINT(("DSimulatedSpiDevice::VersionRequired\n"));
1.79 + return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber);
1.80 + }
1.81 +
1.82 +/** Factory class constructor */
1.83 +DSimulatedSpiDevice::DSimulatedSpiDevice()
1.84 + {
1.85 + SPI_PRINT(("DSimulatedSpiDevice::DSimulatedSpiDevice\n"));
1.86 + iVersion = DSimulatedSpiDevice::VersionRequired();
1.87 + }
1.88 +
1.89 +TInt DSimulatedSpiDevice::Install()
1.90 + {
1.91 + SPI_PRINT(("DSimulatedSpiDevice::Install\n"));
1.92 + return(SetName(&KPddNameSpi));
1.93 + }
1.94 +
1.95 +/** Called by the kernel's device driver framework to create a Physical Channel. */
1.96 +TInt DSimulatedSpiDevice::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
1.97 + {
1.98 + SPI_PRINT(("DSimulatedSpiDevice::Create\n"));
1.99 + return KErrNone;
1.100 + }
1.101 +
1.102 +/** Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/
1.103 +TInt DSimulatedSpiDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
1.104 + {
1.105 + SPI_PRINT(("DSimulatedSpiDevice::Validate\n"));
1.106 + if (!Kern::QueryVersionSupported(DSimulatedSpiDevice::VersionRequired(),aVer))
1.107 + return(KErrNotSupported);
1.108 + return KErrNone;
1.109 + }
1.110 +
1.111 +/** Return the driver capabilities */
1.112 +void DSimulatedSpiDevice::GetCaps(TDes8& aDes) const
1.113 + {
1.114 + SPI_PRINT(("DSimulatedSpiDevice::GetCaps\n"));
1.115 + // Create a capabilities object
1.116 + TCaps caps;
1.117 + caps.iVersion = iVersion;
1.118 + // Zero the buffer
1.119 + TInt maxLen = aDes.MaxLength();
1.120 + aDes.FillZ(maxLen);
1.121 + // Copy capabilities
1.122 + TInt size=sizeof(caps);
1.123 + if(size>maxLen)
1.124 + size=maxLen;
1.125 + aDes.Copy((TUint8*)&caps,size);
1.126 + }
1.127 +
1.128 +// supported channels for this implementation
1.129 +static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
1.130 +
1.131 +//DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)
1.132 +DECLARE_STANDARD_PDD() // SPI test driver to be explicitly loaded as an LDD, not kernel extension
1.133 + {
1.134 + SPI_PRINT(("\n\nSPI PDD, channel creation loop follows ...\n"));
1.135 +
1.136 +#ifndef STANDALONE_CHANNEL
1.137 + DIicBusChannel* chan=NULL;
1.138 + for(TInt i=0; i<NUM_CHANNELS; i++)
1.139 + {
1.140 + SPI_PRINT(("\n"));
1.141 + if(CHANNEL_TYPE(i) == (DIicBusChannel::EMaster))
1.142 + {
1.143 + chan=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
1.144 + if(!chan)
1.145 + return NULL;
1.146 + SPI_PRINT(("SPI chan created at 0x%x\n",chan));
1.147 + if(((DSimulatedIicBusChannelMasterSpi*)chan)->Create()!=KErrNone)
1.148 + return NULL;
1.149 + }
1.150 + else if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave)
1.151 + {
1.152 + DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
1.153 + if(!chanM)
1.154 + return NULL;
1.155 + DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
1.156 + if(!chanS)
1.157 + return NULL;
1.158 + // For MasterSlave channel, the channel number for both the Master and Slave channels must be the same
1.159 + TInt8 msChanNum = ((DSimulatedIicBusChannelMasterSpi*)chanM)->GetChanNum();
1.160 + ((DSimulatedIicBusChannelSlaveSpi*)chanS)->SetChanNum(msChanNum);
1.161 +
1.162 + chan=new DIicBusChannelMasterSlave(BUS_TYPE,CHANNEL_DUPLEX(i),(DIicBusChannelMaster*)chanM,(DIicBusChannelSlave*)chanS); // Generic implementation
1.163 + if(!chan)
1.164 + return NULL;
1.165 + SPI_PRINT(("SPI chan created at 0x%x\n",chan));
1.166 + if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone)
1.167 + return NULL;
1.168 + }
1.169 + else
1.170 + {
1.171 + chan=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
1.172 + if(!chan)
1.173 + return NULL;
1.174 + SPI_PRINT(("SPI chan created at 0x%x\n",chan));
1.175 + if(((DSimulatedIicBusChannelSlaveSpi*)chan)->Create()!=KErrNone)
1.176 + return NULL;
1.177 + }
1.178 + ChannelPtrArray[i]=chan;
1.179 + }
1.180 + SPI_PRINT(("\nSPI PDD, channel creation loop done- about to invoke RegisterChannels\n\n"));
1.181 +#ifdef IIC_INSTRUMENTATION_MACRO
1.182 + IIC_REGISTERCHANS_START_PSL_TRACE;
1.183 +#endif
1.184 +
1.185 + TInt r = KErrNone;
1.186 + r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS);
1.187 +
1.188 +#ifdef IIC_INSTRUMENTATION_MACRO
1.189 + IIC_REGISTERCHANS_END_PSL_TRACE;
1.190 +#endif
1.191 + SPI_PRINT(("\nSPI - returned from RegisterChannels with r=%d\n",r));
1.192 + if(r!=KErrNone)
1.193 + {
1.194 + delete chan;
1.195 + return NULL;
1.196 + }
1.197 +#endif
1.198 + return new DSimulatedSpiDevice;
1.199 + }
1.200 +
1.201 +#ifdef STANDALONE_CHANNEL
1.202 +EXPORT_C
1.203 +#endif
1.204 + DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi(const TBusType aBusType, const TChannelDuplex aChanDuplex)
1.205 + : DIicBusChannelMaster(aBusType,aChanDuplex)
1.206 + {
1.207 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
1.208 +#ifndef STANDALONE_CHANNEL
1.209 + iChannelNumber = AssignChanNum();
1.210 +#endif
1.211 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, iChannelNumber=%d\n",iChannelNumber));
1.212 + iTestState = ETestNone;
1.213 + iChannelState = EIdle;
1.214 + }
1.215 +
1.216 +// The time-out call back invoked when the Slave exeecds the allowed response time
1.217 +TInt DSimulatedIicBusChannelMasterSpi::HandleSlaveTimeout()
1.218 + {
1.219 + SPI_PRINT(("HandleSlaveTimeout \n"));
1.220 + return AsynchStateMachine(ETimeExpired);
1.221 + }
1.222 +
1.223 +TInt DSimulatedIicBusChannelMasterSpi::DoCreate()
1.224 + {
1.225 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoCreate\n"));
1.226 + TInt r=Init(); // PIL Base class initialisation
1.227 + r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KSpiThreadPriority,KSpiThreadName);
1.228 + if(r == KErrNone)
1.229 + SetDfcQ((TDfcQue*)iDynamicDfcQ);
1.230 + DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(this,EFalse);
1.231 + return r;
1.232 + }
1.233 +
1.234 +TInt DSimulatedIicBusChannelMasterSpi::CheckHdr(TDes8* aHdr)
1.235 + {
1.236 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr\n"));
1.237 +
1.238 + TConfigSpiBufV01* spiBuf = (TConfigSpiBufV01*)aHdr;
1.239 + TConfigSpiV01* spiPtr = &((*spiBuf)());
1.240 +
1.241 + // Valid values for the device ID will depend on the bus configuration
1.242 + //
1.243 + // Check that the values for word width, clock speed and clock mode are recognised
1.244 + if((spiPtr->iWordWidth < 0) || (spiPtr->iWordWidth > ESpiWordWidth_16))
1.245 + {
1.246 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised word width identifier %d\n",spiPtr->iWordWidth));
1.247 + return KErrArgument;
1.248 + }
1.249 + if(spiPtr->iClkSpeedHz < 0)
1.250 + {
1.251 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative clock speed specified %d\n",spiPtr->iClkSpeedHz));
1.252 + return KErrArgument;
1.253 + }
1.254 + if((spiPtr->iClkMode < 0) || (spiPtr->iClkMode > ESpiPolarityHighRisingEdge))
1.255 + {
1.256 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised clock mode identifier %d\n",spiPtr->iClkMode));
1.257 + return KErrArgument;
1.258 + }
1.259 + // Values for the timeout period are arbitrary - can only check it is not a negative value
1.260 + if(spiPtr->iTimeoutPeriod < 0)
1.261 + {
1.262 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative timeout period %d\n",spiPtr->iTimeoutPeriod));
1.263 + return KErrArgument;
1.264 + }
1.265 + if((spiPtr->iEndianness < 0) || (spiPtr->iEndianness > ELittleEndian))
1.266 + {
1.267 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised endianness identifier %d\n",spiPtr->iEndianness));
1.268 + return KErrArgument;
1.269 + }
1.270 + if((spiPtr->iBitOrder < 0) || (spiPtr->iBitOrder > EMsbFirst))
1.271 + {
1.272 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised bit order identifier %d\n",spiPtr->iBitOrder));
1.273 + return KErrArgument;
1.274 + }
1.275 + if((spiPtr->iSSPinActiveMode < 0) || (spiPtr->iSSPinActiveMode > ESpiCSPinActiveHigh))
1.276 + {
1.277 + SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised Slave select pin mode identifier %d\n",spiPtr->iSSPinActiveMode));
1.278 + return KErrArgument;
1.279 + }
1.280 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr word width = %d\n",spiPtr->iWordWidth));
1.281 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock speed = %d\n",spiPtr->iClkSpeedHz));
1.282 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock mode = %d\n",spiPtr->iClkMode));
1.283 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr timeout period = %d\n",spiPtr->iTimeoutPeriod));
1.284 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr endianness = %d\n",spiPtr->iEndianness));
1.285 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr bit order = %d\n",spiPtr->iBitOrder));
1.286 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr transaction wait cycles = %d\n",spiPtr->iTransactionWaitCycles));
1.287 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr slave select pin mode = %d\n",spiPtr->iSSPinActiveMode));
1.288 +
1.289 + // For the set of tests expecft the following values
1.290 + // ESpiWordWidth_8, 100kHz, ESpiPolarityLowRisingEdge,aTimeoutPeriod=100
1.291 + // EBigEndian, EMsbFirst, 10 wait cycles, Slave select active low
1.292 + if( (spiPtr->iWordWidth != ESpiWordWidth_8) ||
1.293 + (spiPtr->iClkSpeedHz != 100000) ||
1.294 + (spiPtr->iClkMode != ESpiPolarityLowRisingEdge) ||
1.295 + (spiPtr->iTimeoutPeriod != 100) ||
1.296 + (spiPtr->iEndianness != ELittleEndian) ||
1.297 + (spiPtr->iBitOrder != EMsbFirst) ||
1.298 + (spiPtr->iTransactionWaitCycles != 10) ||
1.299 + (spiPtr->iSSPinActiveMode != ESpiCSPinActiveLow) )
1.300 + return KErrCorrupt;
1.301 + return KErrNone;
1.302 + }
1.303 +
1.304 +TInt DSimulatedIicBusChannelMasterSpi::CompareTransactionOne(TIicBusTransaction* aTransaction)
1.305 +// Compares the indicated TIicBusTransaction with the expected content
1.306 +// Returns KErrNone if there is a match, KErrCorrupt otherwise.
1.307 + {
1.308 + TInt i;
1.309 + // Check the transaction header
1.310 + // Should contain the default header for SPI
1.311 + TDes8* bufPtr = GetTransactionHeader(aTransaction);
1.312 + if(bufPtr == NULL)
1.313 + {
1.314 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL header\n"));
1.315 + return KErrCorrupt;
1.316 + }
1.317 + TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr());
1.318 + if(buf->iWordWidth != ESpiWordWidth_8)
1.319 + {
1.320 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header wordwidth mis-match\n"));
1.321 + return KErrCorrupt;
1.322 + }
1.323 + if(buf->iClkSpeedHz !=100000)
1.324 + {
1.325 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header clockspeed mis-match\n"));
1.326 + return KErrCorrupt;
1.327 + }
1.328 + if(buf->iClkMode != ESpiPolarityLowRisingEdge)
1.329 + {
1.330 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header polarity mis-match\n"));
1.331 + return KErrCorrupt;
1.332 + }
1.333 + if(buf->iTimeoutPeriod != 100)
1.334 + {
1.335 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header timeout mis-match\n"));
1.336 + return KErrCorrupt;
1.337 + }
1.338 +
1.339 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne header OK\n"));
1.340 +
1.341 + // Check the half-duplex transfer list
1.342 + TIicBusTransfer* tfer = GetTransHalfDuplexTferPtr(aTransaction);
1.343 + if(tfer == NULL)
1.344 + {
1.345 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL half-duplex transfer\n"));
1.346 + return KErrCorrupt;
1.347 + }
1.348 + // Process each transfer in the list
1.349 + TInt8 dummy;
1.350 +
1.351 + // tfer1 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf1);
1.352 + // buf1 contains copy of TUint8 KTransOneTferOne[21] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
1.353 + dummy=GetTferType(tfer);
1.354 + if(dummy!=TIicBusTransfer::EMasterWrite)
1.355 + {
1.356 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 type=%d\n"));
1.357 + return KErrCorrupt;
1.358 + }
1.359 + dummy=GetTferBufGranularity(tfer);
1.360 + if(dummy!=8)
1.361 + {
1.362 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 granularity=%d\n",dummy));
1.363 + return KErrCorrupt;
1.364 + }
1.365 + if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL)
1.366 + {
1.367 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 buffer NULL\n"));
1.368 + return KErrCorrupt;
1.369 + }
1.370 + for(i=0;i<21;++i)
1.371 + {
1.372 + if((*bufPtr)[i]!=i)
1.373 + {
1.374 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer1 buffer element %d has 0x%x\n",i,(*bufPtr)[i]));
1.375 + return KErrCorrupt;
1.376 + }
1.377 + }
1.378 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer1 OK\n"));
1.379 +
1.380 +
1.381 + tfer=GetTferNextTfer(tfer);
1.382 + // tfer2 = new TIicBusTransfer(TIicBusTransfer::EMasterRead,8,buf2);
1.383 + // buf2 contains copy of TUint8 KTransOneTferTwo[8] = {17,18,19,20,21,22,23,24};
1.384 + dummy=GetTferType(tfer);
1.385 + if(dummy!=TIicBusTransfer::EMasterRead)
1.386 + {
1.387 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 type=%d\n",dummy));
1.388 + return KErrCorrupt;
1.389 + }
1.390 + dummy=GetTferBufGranularity(tfer);
1.391 + if(dummy!=8)
1.392 + {
1.393 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 granularity=%d\n",dummy));
1.394 + return KErrCorrupt;
1.395 + }
1.396 + if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL)
1.397 + {
1.398 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 buffer NULL\n"));
1.399 + return KErrCorrupt;
1.400 + }
1.401 + for(i=0;i<8;++i)
1.402 + {
1.403 + if((*bufPtr)[i]!=(17+i))
1.404 + {
1.405 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer2 buffer element %d has 0x%x\n",i,(*bufPtr)[i]));
1.406 + return KErrCorrupt;
1.407 + }
1.408 + }
1.409 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer2 OK\n"));
1.410 +
1.411 + tfer=GetTferNextTfer(tfer);
1.412 + // tfer3 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf3);
1.413 + // buf2 contains copy of TUint8 KTransOneTferThree[6] = {87,85,83,81,79,77};
1.414 + dummy=GetTferType(tfer);
1.415 + if(dummy!=TIicBusTransfer::EMasterWrite)
1.416 + {
1.417 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 type=%d\n"));
1.418 + return KErrCorrupt;
1.419 + }
1.420 + dummy=GetTferBufGranularity(tfer);
1.421 + if(dummy!=8)
1.422 + {
1.423 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 granularity=%d\n",dummy));
1.424 + return KErrCorrupt;
1.425 + }
1.426 + if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL)
1.427 + {
1.428 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 buffer NULL\n"));
1.429 + return KErrCorrupt;
1.430 + }
1.431 + for(i=0;i<6;++i)
1.432 + {
1.433 + if((*bufPtr)[i]!=(87-(2*i)))
1.434 + {
1.435 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer3 buffer element %d has 0x%x\n",i,(*bufPtr)[i]));
1.436 + return KErrCorrupt;
1.437 + }
1.438 + }
1.439 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer3 OK\n"));
1.440 +
1.441 + // Shouldn't be any more transfers in the half duplex list
1.442 + if((tfer=GetTferNextTfer(tfer))!=NULL)
1.443 + {
1.444 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 iNext=0x%x\n",tfer));
1.445 + return KErrCorrupt;
1.446 + }
1.447 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne half-duplex transfer OK\n"));
1.448 +
1.449 + // The full duplex transfer should be represented by a NULL pointer
1.450 + if((tfer=GetTransFullDuplexTferPtr(aTransaction))!=NULL)
1.451 + {
1.452 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - full duplex pointer=0x%x\n",tfer));
1.453 + return KErrCorrupt;
1.454 + }
1.455 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne full duplex pointer is NULL (OK)\n"));
1.456 +
1.457 + // Synchronous transaction, so check the callback pointer is NULL
1.458 + TIicBusCallback* dumCb = NULL;
1.459 + dumCb=GetTransCallback(aTransaction);
1.460 + if(dumCb!=NULL)
1.461 + {
1.462 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - callback pointer=0x%x\n",dumCb));
1.463 + return KErrCorrupt;
1.464 + }
1.465 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne callback pointer is NULL (OK)\n"));
1.466 +
1.467 + // Check the transaction flags are set to zero
1.468 + TUint8 dumFlags;
1.469 + dumFlags=GetTransFlags(aTransaction);
1.470 + if(dumFlags!=0)
1.471 + {
1.472 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - flags=0x%x\n",dumFlags));
1.473 + return KErrCorrupt;
1.474 + }
1.475 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne flags are zero (OK)\n"));
1.476 +
1.477 + return KErrNone;
1.478 + }
1.479 +
1.480 +
1.481 +// The THwCallbackFunc gets called if the hardware preparation completes successfully.
1.482 +void THwCallbackFunc(TAny* aPtr)
1.483 + {
1.484 + SPI_PRINT(("Hardware preparation completed, calling the callback function"));
1.485 + DSimulatedIicBusChannelMasterSpi* aChanMasterSpi=(DSimulatedIicBusChannelMasterSpi* )aPtr;
1.486 + TInt r = aChanMasterSpi->DoSimulatedTransaction();
1.487 + ((DSimulatedIicBusChannelMasterSpi*)aChanMasterSpi)->CompleteReq(r);
1.488 + }
1.489 +
1.490 +TInt DSimulatedIicBusChannelMasterSpi::DoSimulatedTransaction()
1.491 + {
1.492 + TInt r = AsynchStateMachine(EHwTransferDone);
1.493 + if(iTimeoutTimer.Cancel() == FALSE)
1.494 + {
1.495 + SPI_PRINT(("timer is not cancelled"));
1.496 + }
1.497 + return r;
1.498 + }
1.499 +
1.500 +TInt DSimulatedIicBusChannelMasterSpi::DoHwPreparation()
1.501 + {
1.502 + SPI_PRINT(("Preparing hardware for the transaction"));
1.503 +
1.504 + TInt r = KErrNone;
1.505 + // The hardware preparation can either complete successfully or fail.
1.506 + // If successful, invoke the callback function of THwDoneCallBack
1.507 + // if not, execute the timeout machanism
1.508 + // Currently DoHwPreparation is just a simple function. It should be more complicated
1.509 + // for the real hardware.
1.510 + switch(iTestState)
1.511 + {
1.512 + case (ETestSlaveTimeOut):
1.513 + {
1.514 + // In the timeout test, do nothing until the timeout callback function is invoked.
1.515 + SPI_PRINT(("Simulating the timeout process."));
1.516 + break;
1.517 + }
1.518 + case (ETestNone):
1.519 + {
1.520 + // Pretend the hardware preparation's been done, and a callback function is invoked to call
1.521 + // the Asynchronous State Machine
1.522 + SPI_PRINT(("Hardware preparing work is executing normally."));
1.523 + iCb->Enque();
1.524 + break;
1.525 + }
1.526 + default:
1.527 + {
1.528 + SPI_PRINT(("Not a valid test."));
1.529 + r = KErrNotSupported;
1.530 + break;
1.531 + }
1.532 + }
1.533 +
1.534 + return r;
1.535 + }
1.536 +
1.537 +// Gateway function for PSL implementation, invoked for DFC processing
1.538 +TInt DSimulatedIicBusChannelMasterSpi::DoRequest(TIicBusTransaction* aTransaction)
1.539 + {
1.540 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest invoked with aTransaction=0x%x\n",aTransaction));
1.541 +
1.542 + TInt r = KErrNone;
1.543 + iCurrTrans=aTransaction;
1.544 +
1.545 + // Check if the Asynchronous State Machine is available. If not, then return KErrInUse.
1.546 + // This is used to stop the second transaction executing if the machine has already been holding
1.547 + // by a transaction. However, this situation cannot be tested because of the malfunction in PIL
1.548 + if(iChannelState!= EIdle)
1.549 + return KErrInUse;
1.550 +
1.551 + iChannelState = EBusy;
1.552 +#ifdef IIC_INSTRUMENTATION_MACRO
1.553 + IIC_MPROCESSTRANS_START_PSL_TRACE;
1.554 +#endif
1.555 + r = ProcessTrans(aTransaction);
1.556 +
1.557 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - exiting\n"));
1.558 + return r;
1.559 + }
1.560 +
1.561 +TInt DSimulatedIicBusChannelMasterSpi::ProcessTrans(TIicBusTransaction* aTransaction)
1.562 + {
1.563 + TInt r=KErrNone;
1.564 +
1.565 + switch(iTestState)
1.566 + {
1.567 + case(ETestWaitTransOne):
1.568 + {
1.569 + // The transaction received should exhibit the expected data
1.570 + // Return KErrArgument if this is not the case
1.571 + // The timer should be started at the beginning of every transaction
1.572 + // For simplicity, we omit the timer here.
1.573 + r=CompareTransactionOne(iCurrTrans);
1.574 + iChannelState = EIdle;
1.575 + CompleteRequest(KErrNone);
1.576 + break;
1.577 + }
1.578 + case(ETestSlaveTimeOut):
1.579 + {
1.580 + // Test the timeout funciton
1.581 + SPI_PRINT(("Test the slave timeout function\n"));
1.582 +
1.583 + // Simulate a timeout
1.584 + // Start a timer and then wait for the Slave response to timeout
1.585 + // A real bus would use its own means to identify a timeout
1.586 + TInt aTime=1000000/NKern::TickPeriod();
1.587 + r = StartSlaveTimeOutTimer(aTime);
1.588 + if(r != KErrNone)
1.589 + return r;
1.590 + r = DoHwPreparation();
1.591 + break;
1.592 + }
1.593 + case(ETestWaitPriorityTest):
1.594 + {
1.595 + static TInt TranCount = 0;
1.596 + if(TranCount >= KPriorityTestNum) return KErrUnknown;
1.597 + // block the channel
1.598 + while(IsRequestDelayed(this))
1.599 + {
1.600 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - starting Sleep...\n"));
1.601 + NKern::Sleep(1000); // 1000 is arbitrary
1.602 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - completed Sleep, check if still delayed\n"));
1.603 + };
1.604 + // get transaction header
1.605 + TDes8* bufPtr = GetTransactionHeader(aTransaction);
1.606 + if(bufPtr == NULL)
1.607 + {
1.608 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest ERROR - NULL header\n"));
1.609 + return KErrCorrupt;
1.610 + }
1.611 +
1.612 + if(TranCount == 0)
1.613 + {
1.614 + // ignore the blocking transaction
1.615 + TranCount++;
1.616 + }
1.617 + else
1.618 + {
1.619 + // store transaction header
1.620 + iPriorityTestResult[TranCount++] = (*bufPtr)[0];
1.621 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest Priority test transaction no.:%d Priority:%d",
1.622 + (*bufPtr)[0], aTransaction->iKey));
1.623 + }
1.624 + iChannelState = EIdle;
1.625 + CompleteRequest(KErrNone);
1.626 + if(TranCount == KPriorityTestNum) iPriorityTestDone = ETrue;
1.627 + break;
1.628 + }
1.629 +
1.630 +
1.631 +
1.632 + case(ETestNone):
1.633 + {
1.634 + SPI_PRINT(("Nothing to be tested, just do the usual transaction"));
1.635 +
1.636 + // Start the timer on the Slave response.
1.637 + // Since no timeout, this timer will be cancelled in the THwCallbackFunc
1.638 + r = StartSlaveTimeOutTimer(100000);
1.639 + if(r != KErrNone)
1.640 + return r;
1.641 + // Use a class THwDoneCallBack derived from TDfc to trigger the asynchronous state machine
1.642 + // when the hardware preparation completes successfully.
1.643 + // The priority is set with an arbitrary number 5
1.644 + iCb = new THwDoneCallBack(THwCallbackFunc, this, iDynamicDfcQ, 5);
1.645 + r = DoHwPreparation();
1.646 + break;
1.647 + }
1.648 + default:
1.649 + {
1.650 + SPI_PRINT(("Test status not matched"));
1.651 + return KErrNotSupported;
1.652 + }
1.653 + }
1.654 +
1.655 + return r;
1.656 + }
1.657 +
1.658 +
1.659 +TInt DSimulatedIicBusChannelMasterSpi::AsynchStateMachine(TInt aReason)
1.660 + {
1.661 + TInt r=KErrNone;
1.662 +
1.663 + // The asynchronous state machine has two states, it could either be idle or busy.
1.664 + // Initially, it's in idle state. When a user queues a transaction, the hardware preparation starts
1.665 + // and the state changes to busy. After the hardware preparation completes, either successfully or not,
1.666 + // the state machine will do the corresponding work for the transaction and then goes back to the idle state.
1.667 + switch(iChannelState)
1.668 + {
1.669 + case(EIdle):
1.670 + {
1.671 + return KErrGeneral;
1.672 + }
1.673 + case (EBusy):
1.674 + {
1.675 + switch(aReason)
1.676 + {
1.677 + case(EHwTransferDone):
1.678 + {
1.679 +
1.680 + // Simulate processing - for now, do nothing!
1.681 + //
1.682 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHeader=0x%x\n",GetTransactionHeader(iCurrTrans)));
1.683 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(iCurrTrans)));
1.684 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(iCurrTrans)));
1.685 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iCallback=0x%x\n",GetTransCallback(iCurrTrans)));
1.686 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFlags=0x%x\n",GetTransFlags(iCurrTrans)));
1.687 +
1.688 + SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHeader info \n"));
1.689 + TDes8* bufPtr = GetTransactionHeader(iCurrTrans);
1.690 + if(bufPtr == NULL)
1.691 + {
1.692 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine ERROR - NULL header\n"));
1.693 + return KErrCorrupt;
1.694 + }
1.695 + TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr());
1.696 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header word width=0x%x\n",buf->iWordWidth));
1.697 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock speed=0x%x\n",buf->iClkSpeedHz));
1.698 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock mode=0x%x\n",buf->iClkMode));
1.699 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header timeout period=0x%x\n",buf->iTimeoutPeriod));
1.700 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header endianness=0x%x\n",buf->iEndianness));
1.701 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header bit order=0x%x\n",buf->iBitOrder));
1.702 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header wait cycles=0x%x\n",buf->iTransactionWaitCycles));
1.703 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header Slave select pin mode=0x%x\n",buf->iSSPinActiveMode));
1.704 + (void)buf; // Silence compiler when SPI_PRINT not used
1.705 +
1.706 + SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHalfDuplexTrans info \n"));
1.707 + TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(iCurrTrans);
1.708 + while(halfDuplexPtr != NULL)
1.709 + {
1.710 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer type=0x%x\n",GetTferType(halfDuplexPtr)));
1.711 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr)));
1.712 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr)));
1.713 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr)));
1.714 + halfDuplexPtr=GetTferNextTfer(halfDuplexPtr);
1.715 + }
1.716 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - End of iHalfDuplexTrans info"));
1.717 +
1.718 + while(IsRequestDelayed(this))
1.719 + {
1.720 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - starting Sleep...\n"));
1.721 + NKern::Sleep(1000); // 1000 is arbitrary
1.722 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - completed Sleep, check if still delayed\n"));
1.723 + };
1.724 +
1.725 + iChannelState=EIdle;
1.726 + delete iCb;
1.727 + break;
1.728 + }
1.729 + case(ETimeExpired):
1.730 + {
1.731 + SPI_PRINT(("Time expired, the Asynchrnous State Machine will be Idle again, and wait for the next request."));
1.732 + iChannelState=EIdle;
1.733 + r = KErrTimedOut;
1.734 + break;
1.735 + }
1.736 + default:
1.737 + {
1.738 + SPI_PRINT(("Request can not be handled, return error code."));
1.739 + return KErrNotSupported;
1.740 + }
1.741 + }
1.742 + break;
1.743 + }
1.744 + default:
1.745 + {
1.746 + SPI_PRINT(("No matched state"));
1.747 + return KErrGeneral;
1.748 + }
1.749 + }
1.750 + return r;
1.751 + }
1.752 +
1.753 +
1.754 +TBool DSimulatedIicBusChannelMasterSpi::IsRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan)
1.755 + {
1.756 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::IsRequestDelayed invoked for aChan=0x%x\n",aChan));
1.757 + return aChan->iReqDelayed;
1.758 + }
1.759 +
1.760 +void DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan,TBool aDelay)
1.761 + {
1.762 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay));
1.763 + aChan->iReqDelayed=aDelay;
1.764 + }
1.765 +
1.766 +TInt DSimulatedIicBusChannelMasterSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
1.767 + {
1.768 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::StaticExtension\n"));
1.769 +#ifdef IIC_INSTRUMENTATION_MACRO
1.770 + IIC_MSTATEXT_START_PSL_TRACE;
1.771 +#endif
1.772 + (void)aParam1;
1.773 + (void)aParam2;
1.774 + TInt r = KErrNone;
1.775 + // Test values of aFunction were shifted left one place by the (test) client driver
1.776 + // and for Slave values the two msb were cleared
1.777 + // Return to its original value.
1.778 + if(aFunction>KTestControlIoPilOffset)
1.779 + aFunction >>= 1;
1.780 + switch(aFunction)
1.781 + {
1.782 + case(RBusDevIicClient::ECtlIoDumpChan):
1.783 + {
1.784 +#ifdef _DEBUG
1.785 + DumpChannel();
1.786 +#endif
1.787 + break;
1.788 + }
1.789 + case(RBusDevIicClient::ECtlIoBlockReqCompletion):
1.790 + {
1.791 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Blocking request completion\n"));
1.792 + SetRequestDelayed(this, ETrue);
1.793 + break;
1.794 + }
1.795 + case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
1.796 + {
1.797 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Unlocking request completion\n"));
1.798 + SetRequestDelayed(this, EFalse);
1.799 + break;
1.800 + }
1.801 + case(RBusDevIicClient::ECtlIoDeRegChan):
1.802 + {
1.803 +#ifdef IIC_INSTRUMENTATION_MACRO
1.804 + IIC_DEREGISTERCHAN_START_PSL_TRACE;
1.805 +#endif
1.806 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: deregister channel\n"));
1.807 +#ifndef STANDALONE_CHANNEL
1.808 + r=DIicBusController::DeRegisterChannel(this);
1.809 +#endif
1.810 +
1.811 +#ifdef IIC_INSTRUMENTATION_MACRO
1.812 + IIC_DEREGISTERCHAN_END_PSL_TRACE;
1.813 +#endif
1.814 + break;
1.815 + }
1.816 +
1.817 + case(RBusDevIicClient::ECtlIoPriorityTest):
1.818 + {
1.819 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect priority test\n"));
1.820 + iPriorityTestDone = EFalse;
1.821 + iTestState=ETestWaitPriorityTest;
1.822 + break;
1.823 + }
1.824 + case(RBusDevIicClient::EGetTestResult):
1.825 + {
1.826 + if(!iPriorityTestDone) return KErrNotReady;
1.827 +
1.828 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: get priority test order\n"));
1.829 +
1.830 + //iPriorityTestResult[0] is the blocking transaction, ignore it. start from entry 1.
1.831 + for(TInt i=1; i<KPriorityTestNum; i++)
1.832 + {
1.833 + if(iPriorityTestResult[i]!=(KPriorityTestNum-i-1))
1.834 + {
1.835 + r = KErrGeneral;
1.836 + break;
1.837 + }
1.838 + }
1.839 + r = KErrNone;
1.840 + break;
1.841 + }
1.842 +
1.843 + case(RBusDevIicClient::ECtlIoTracnOne):
1.844 + {
1.845 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect Transaction One\n"));
1.846 + iTestState=ETestWaitTransOne;
1.847 + break;
1.848 + }
1.849 + case(RBusDevIicClient::ECtlIoNone):
1.850 + {
1.851 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: terminate ControlIO state\n"));
1.852 + iTestState=ETestNone;
1.853 + break;
1.854 + }
1.855 + case(RBusDevIicClient::ECtlIoSetTimeOutFlag):
1.856 + {
1.857 + SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: test slave time out\n"));
1.858 + iTestState=ETestSlaveTimeOut;
1.859 + break;
1.860 + }
1.861 + default:
1.862 + {
1.863 + Kern::Printf("aFunction %d is not recognised \n",aFunction);
1.864 + r=KErrNotSupported;
1.865 + }
1.866 + }
1.867 +#ifdef IIC_INSTRUMENTATION_MACRO
1.868 + IIC_MSTATEXT_END_PSL_TRACE;
1.869 +#endif
1.870 + return r;
1.871 + }
1.872 +
1.873 +void DSimulatedIicBusChannelMasterSpi::CompleteReq(TInt aResult)
1.874 + {
1.875 +#ifdef IIC_INSTRUMENTATION_MACRO
1.876 + IIC_MPROCESSTRANS_END_PSL_TRACE;
1.877 +#endif
1.878 + CompleteRequest(aResult);
1.879 + }
1.880 +
1.881 +
1.882 +void DSimulatedIicBusChannelSlaveSpi::SlaveAsyncSimCallback(TAny* aPtr)
1.883 + {
1.884 + SPI_PRINT(("SlaveAsyncSimCallback\n"));
1.885 + DSimulatedIicBusChannelSlaveSpi* channel = (DSimulatedIicBusChannelSlaveSpi*)aPtr;
1.886 + TInt r=KErrNone; // Just simulate successfull capture
1.887 +#ifdef IIC_INSTRUMENTATION_MACRO
1.888 + IIC_SCAPTCHANASYNC_END_PSL_TRACE;
1.889 +#endif
1.890 + channel->ChanCaptureCb(r);
1.891 + }
1.892 +
1.893 +#ifdef STANDALONE_CHANNEL
1.894 +EXPORT_C
1.895 +#endif
1.896 + DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
1.897 + : DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
1.898 + iSlaveTimer(SlaveAsyncSimCallback,this)
1.899 + {
1.900 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
1.901 +#ifndef STANDALONE_CHANNEL
1.902 + iChannelNumber = AssignChanNum();
1.903 +#endif
1.904 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, iChannelNumber=%d\n",iChannelNumber));
1.905 + }
1.906 +
1.907 +TInt DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl(TDes8* /*aConfigHdr*/, TBool aAsynch)
1.908 + {
1.909 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl, aAsynch=%d\n",aAsynch));
1.910 + TInt r = KErrNone;
1.911 + if(aAsynch)
1.912 + {
1.913 +#ifdef IIC_INSTRUMENTATION_MACRO
1.914 + IIC_SCAPTCHANASYNC_START_PSL_TRACE;
1.915 +#endif
1.916 + // To simulate an asynchronous operation, just set a timer to expire
1.917 + iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
1.918 + }
1.919 + else
1.920 + {
1.921 +#ifdef IIC_INSTRUMENTATION_MACRO
1.922 + IIC_SCAPTCHANSYNC_START_PSL_TRACE;
1.923 +#endif
1.924 + // PSL processing would happen here ...
1.925 + // Expected to include implementation of the header configuration information
1.926 +#ifdef IIC_INSTRUMENTATION_MACRO
1.927 + IIC_SCAPTCHANSYNC_END_PSL_TRACE;
1.928 +#endif
1.929 + }
1.930 + SPI_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChanSync ... no real processing to do \n"));
1.931 +
1.932 + return r;
1.933 + }
1.934 +
1.935 +TInt DSimulatedIicBusChannelSlaveSpi::CheckHdr(TDes8* /*aHdr*/)
1.936 + {
1.937 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CheckHdr\n"));
1.938 + return KErrNone;
1.939 + }
1.940 +
1.941 +TInt DSimulatedIicBusChannelSlaveSpi::DoCreate()
1.942 + {
1.943 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoCreate\n"));
1.944 + TInt r=Init(); // PIL Base class initialisation
1.945 + return r;
1.946 + }
1.947 +
1.948 +TInt DSimulatedIicBusChannelSlaveSpi::DoRequest(TInt /*aTrigger*/)
1.949 + {
1.950 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoRequest\n"));
1.951 + return KErrNotSupported;
1.952 + }
1.953 +
1.954 +void DSimulatedIicBusChannelSlaveSpi::ProcessData(TInt /*aTrigger*/, TIicBusSlaveCallback* /*aCb*/)
1.955 + {
1.956 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::ProcessData\n"));
1.957 + }
1.958 +
1.959 +TInt DSimulatedIicBusChannelSlaveSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
1.960 + {
1.961 + SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::StaticExtension\n"));
1.962 +#ifdef IIC_INSTRUMENTATION_MACRO
1.963 + IIC_SSTATEXT_START_PSL_TRACE;
1.964 +#endif
1.965 + (void)aParam1;
1.966 + (void)aParam2;
1.967 + // Test values of aFunction were shifted left one place by the (test) client driver
1.968 + // and for Slave values the two msb were cleared
1.969 + // Return to its original value.
1.970 + if(aFunction>KTestControlIoPilOffset)
1.971 + {
1.972 + aFunction |= 0xC0000000;
1.973 + aFunction >>= 1;
1.974 + }
1.975 + TInt r = KErrNone;
1.976 + switch(aFunction)
1.977 + {
1.978 + case(RBusDevIicClient::ECtlIoDumpChan):
1.979 + {
1.980 +#ifdef _DEBUG
1.981 + DumpChannel();
1.982 +#endif
1.983 + break;
1.984 + }
1.985 + default:
1.986 + {
1.987 + Kern::Printf("aFunction %d is not recognised \n",aFunction);
1.988 + r=KErrNotSupported;
1.989 + }
1.990 + }
1.991 +
1.992 +#ifdef IIC_INSTRUMENTATION_MACRO
1.993 + IIC_SSTATEXT_START_PSL_TRACE;
1.994 +#endif
1.995 + (void)aFunction;
1.996 + return r;
1.997 + }
1.998 +
1.999 +
1.1000 +
1.1001 +
1.1002 +
1.1003 +