os/kernelhwsrv/kerneltest/e32test/iic/iic_psl/spi.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test/iic/iic_psl/spi.cpp
    15 //
    16 #include "spi.h"
    17 
    18 #ifdef IIC_INSTRUMENTATION_MACRO
    19 #include <drivers/iic_trace.h>
    20 #endif
    21 
    22 #define NUM_CHANNELS 4 // Arbitrary
    23 
    24 // Macros to be updated(?) with interaction with Configuration Repository
    25 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMaster};
    26 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
    27 const DIicBusChannel::TChannelDuplex KChannelDuplexArray[NUM_CHANNELS] = {DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EFullDuplex};
    28 #define CHANNEL_DUPLEX(n) (KChannelDuplexArray[n]) 
    29 
    30 #ifdef LOG_SPI
    31 #define SPI_PRINT(str) Kern::Printf str
    32 #else
    33 #define SPI_PRINT(str)
    34 #endif
    35 
    36 _LIT(KSpiThreadName,"SpiChannelThread");
    37 
    38 const TInt KSpiThreadPriority = 5; // Arbitrary, can be 0-7, 7 highest
    39 
    40 #ifdef STANDALONE_CHANNEL
    41 _LIT(KPddNameSpi,"spi_ctrless.pdd");
    42 #else
    43 _LIT(KPddNameSpi,"spi.pdd");
    44 #endif
    45 
    46 #ifndef STANDALONE_CHANNEL
    47 LOCAL_C TInt8 AssignChanNum()
    48 	{
    49 	static TInt8 iBaseChanNum = KSpiChannelNumBase;
    50 	SPI_PRINT(("SPI AssignChanNum - on entry, iBaseCanNum = 0x%x\n",iBaseChanNum));
    51 	return iBaseChanNum++; // Arbitrary, for illustration
    52 	}
    53 #endif
    54 
    55 NONSHARABLE_CLASS(DSimulatedSpiDevice) : public DPhysicalDevice
    56 	{
    57 // Class to faciliate loading of the IIC classes
    58 public:
    59 	class TCaps
    60 		{
    61 	public:
    62 		TVersion iVersion;
    63 		};
    64 public:
    65 	DSimulatedSpiDevice();
    66 	virtual TInt Install();
    67 	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    68 	virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    69 	virtual void GetCaps(TDes8& aDes) const;
    70 	inline static TVersion VersionRequired();
    71 	};
    72 
    73 TVersion DSimulatedSpiDevice::VersionRequired()
    74 	{
    75 	SPI_PRINT(("DSimulatedSpiDevice::VersionRequired\n"));
    76 	return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber);
    77 	}
    78 
    79 /** Factory class constructor */
    80 DSimulatedSpiDevice::DSimulatedSpiDevice()
    81 	{
    82 	SPI_PRINT(("DSimulatedSpiDevice::DSimulatedSpiDevice\n"));
    83     iVersion = DSimulatedSpiDevice::VersionRequired();
    84 	}
    85 
    86 TInt DSimulatedSpiDevice::Install()
    87     {
    88 	SPI_PRINT(("DSimulatedSpiDevice::Install\n"));
    89     return(SetName(&KPddNameSpi));
    90     }
    91 
    92 /**  Called by the kernel's device driver framework to create a Physical Channel. */
    93 TInt DSimulatedSpiDevice::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
    94     {
    95 	SPI_PRINT(("DSimulatedSpiDevice::Create\n"));
    96     return KErrNone;
    97     }
    98 
    99 /**  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/
   100 TInt DSimulatedSpiDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
   101     {
   102 	SPI_PRINT(("DSimulatedSpiDevice::Validate\n"));
   103    	if (!Kern::QueryVersionSupported(DSimulatedSpiDevice::VersionRequired(),aVer))
   104 		return(KErrNotSupported);
   105     return KErrNone;
   106     }
   107 
   108 /** Return the driver capabilities */
   109 void DSimulatedSpiDevice::GetCaps(TDes8& aDes) const
   110     {
   111 	SPI_PRINT(("DSimulatedSpiDevice::GetCaps\n"));
   112 	// Create a capabilities object
   113 	TCaps caps;
   114 	caps.iVersion = iVersion;
   115 	// Zero the buffer
   116 	TInt maxLen = aDes.MaxLength();
   117 	aDes.FillZ(maxLen);
   118 	// Copy capabilities
   119 	TInt size=sizeof(caps);
   120 	if(size>maxLen)
   121 	   size=maxLen;
   122 	aDes.Copy((TUint8*)&caps,size);
   123     }
   124 
   125 // supported channels for this implementation
   126 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
   127 
   128 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)	
   129 DECLARE_STANDARD_PDD()		// SPI test driver to be explicitly loaded as an LDD, not kernel extension
   130 	{
   131 	SPI_PRINT(("\n\nSPI PDD, channel creation loop follows ...\n"));
   132 
   133 #ifndef STANDALONE_CHANNEL
   134 	DIicBusChannel* chan=NULL;
   135 	for(TInt i=0; i<NUM_CHANNELS; i++)
   136 		{
   137 	SPI_PRINT(("\n"));
   138 		if(CHANNEL_TYPE(i) == (DIicBusChannel::EMaster))
   139 			{
   140 			chan=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
   141 			if(!chan)
   142 				return NULL;
   143 			SPI_PRINT(("SPI chan created at 0x%x\n",chan));
   144 			if(((DSimulatedIicBusChannelMasterSpi*)chan)->Create()!=KErrNone)
   145 				return NULL;
   146 			}
   147 		else if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave)
   148 			{
   149 			DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
   150 			if(!chanM)
   151 				return NULL;
   152 			DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
   153 			if(!chanS)
   154 				return NULL;
   155 			// For MasterSlave channel, the channel number for both the Master and Slave channels must be the same
   156 			TInt8 msChanNum = ((DSimulatedIicBusChannelMasterSpi*)chanM)->GetChanNum();
   157 			((DSimulatedIicBusChannelSlaveSpi*)chanS)->SetChanNum(msChanNum);
   158 
   159 			chan=new DIicBusChannelMasterSlave(BUS_TYPE,CHANNEL_DUPLEX(i),(DIicBusChannelMaster*)chanM,(DIicBusChannelSlave*)chanS); // Generic implementation
   160 			if(!chan)
   161 				return NULL;
   162 			SPI_PRINT(("SPI chan created at 0x%x\n",chan));
   163 			if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone)
   164 				return NULL;
   165 			}
   166 		else
   167 			{
   168 			chan=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i));
   169 			if(!chan)
   170 				return NULL;
   171 			SPI_PRINT(("SPI chan created at 0x%x\n",chan));
   172 			if(((DSimulatedIicBusChannelSlaveSpi*)chan)->Create()!=KErrNone)
   173 				return NULL;
   174 			}
   175 		ChannelPtrArray[i]=chan;
   176 		}
   177 	SPI_PRINT(("\nSPI PDD, channel creation loop done- about to invoke RegisterChannels\n\n"));
   178 #ifdef IIC_INSTRUMENTATION_MACRO
   179 	IIC_REGISTERCHANS_START_PSL_TRACE;
   180 #endif
   181 
   182 	TInt r = KErrNone;
   183 	r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS);
   184 
   185 #ifdef IIC_INSTRUMENTATION_MACRO
   186 	IIC_REGISTERCHANS_END_PSL_TRACE;
   187 #endif
   188 	SPI_PRINT(("\nSPI - returned from RegisterChannels with r=%d\n",r));
   189 	if(r!=KErrNone)
   190 		{
   191 		delete chan;
   192 		return NULL;
   193 		}
   194 #endif
   195 	return new DSimulatedSpiDevice;
   196 	}
   197 
   198 #ifdef STANDALONE_CHANNEL
   199 EXPORT_C
   200 #endif
   201 	DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi(const TBusType aBusType, const TChannelDuplex aChanDuplex)
   202 	: DIicBusChannelMaster(aBusType,aChanDuplex)
   203 	{
   204 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
   205 #ifndef STANDALONE_CHANNEL
   206 	iChannelNumber = AssignChanNum();
   207 #endif
   208 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, iChannelNumber=%d\n",iChannelNumber));
   209 	iTestState = ETestNone;
   210 	iChannelState = EIdle;
   211 	}
   212 
   213 // The time-out call back invoked when the Slave exeecds the allowed response time
   214 TInt DSimulatedIicBusChannelMasterSpi::HandleSlaveTimeout()
   215 	{
   216 	SPI_PRINT(("HandleSlaveTimeout \n"));
   217 	return AsynchStateMachine(ETimeExpired); 
   218 	}
   219 
   220 TInt DSimulatedIicBusChannelMasterSpi::DoCreate()
   221 	{
   222 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoCreate\n"));
   223 	TInt r=Init();	// PIL Base class initialisation
   224 	r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KSpiThreadPriority,KSpiThreadName);
   225 	if(r == KErrNone)
   226 		SetDfcQ((TDfcQue*)iDynamicDfcQ);
   227 	DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(this,EFalse);
   228 	return r;
   229 	}
   230 
   231 TInt DSimulatedIicBusChannelMasterSpi::CheckHdr(TDes8* aHdr)
   232 	{
   233 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr\n"));
   234 
   235 	TConfigSpiBufV01* spiBuf = (TConfigSpiBufV01*)aHdr;
   236 	TConfigSpiV01* spiPtr = &((*spiBuf)());
   237 
   238 	// Valid values for the device ID will depend on the bus configuration
   239 	//
   240 	// Check that the values for word width, clock speed and clock mode are recognised
   241 	if((spiPtr->iWordWidth < 0) || (spiPtr->iWordWidth > ESpiWordWidth_16))
   242 		{
   243 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised word width identifier %d\n",spiPtr->iWordWidth));
   244 		return KErrArgument;
   245 		}
   246 	if(spiPtr->iClkSpeedHz < 0)
   247 		{
   248 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative clock speed specified %d\n",spiPtr->iClkSpeedHz));
   249 		return KErrArgument;
   250 		}
   251 	if((spiPtr->iClkMode < 0) || (spiPtr->iClkMode > ESpiPolarityHighRisingEdge))
   252 		{
   253 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised clock mode identifier %d\n",spiPtr->iClkMode));
   254 		return KErrArgument;
   255 		}
   256 	// Values for the timeout period are arbitrary - can only check it is not a negative value
   257 	if(spiPtr->iTimeoutPeriod < 0)
   258 		{
   259 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative timeout period %d\n",spiPtr->iTimeoutPeriod));
   260 		return KErrArgument;
   261 		}
   262 	if((spiPtr->iEndianness < 0) || (spiPtr->iEndianness > ELittleEndian))
   263 		{
   264 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised endianness identifier %d\n",spiPtr->iEndianness));
   265 		return KErrArgument;
   266 		}
   267 	if((spiPtr->iBitOrder < 0) || (spiPtr->iBitOrder > EMsbFirst))
   268 		{
   269 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised bit order identifier %d\n",spiPtr->iBitOrder));
   270 		return KErrArgument;
   271 		}
   272 	if((spiPtr->iSSPinActiveMode < 0) || (spiPtr->iSSPinActiveMode > ESpiCSPinActiveHigh))
   273 		{
   274 		SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised Slave select pin mode identifier %d\n",spiPtr->iSSPinActiveMode));
   275 		return KErrArgument;
   276 		}
   277 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr word width = %d\n",spiPtr->iWordWidth));
   278 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock speed = %d\n",spiPtr->iClkSpeedHz));
   279 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock mode = %d\n",spiPtr->iClkMode));
   280 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr timeout period = %d\n",spiPtr->iTimeoutPeriod));
   281 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr endianness = %d\n",spiPtr->iEndianness));
   282 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr bit order = %d\n",spiPtr->iBitOrder));
   283 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr transaction wait cycles = %d\n",spiPtr->iTransactionWaitCycles));
   284 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr slave select pin mode = %d\n",spiPtr->iSSPinActiveMode));
   285 
   286 	// For the set of tests expecft the following values
   287 	// ESpiWordWidth_8, 100kHz, ESpiPolarityLowRisingEdge,aTimeoutPeriod=100
   288 	// EBigEndian, EMsbFirst, 10 wait cycles, Slave select active low
   289 	if(	(spiPtr->iWordWidth != ESpiWordWidth_8)	||
   290 		(spiPtr->iClkSpeedHz != 100000)	||
   291 		(spiPtr->iClkMode != ESpiPolarityLowRisingEdge)	||
   292 		(spiPtr->iTimeoutPeriod != 100) ||
   293 		(spiPtr->iEndianness != ELittleEndian) ||
   294 		(spiPtr->iBitOrder != EMsbFirst) ||
   295 		(spiPtr->iTransactionWaitCycles != 10) ||
   296 		(spiPtr->iSSPinActiveMode != ESpiCSPinActiveLow) )
   297 		return KErrCorrupt;
   298 	return KErrNone;
   299 	}
   300 
   301 TInt DSimulatedIicBusChannelMasterSpi::CompareTransactionOne(TIicBusTransaction* aTransaction)
   302 // Compares the indicated TIicBusTransaction with the expected content
   303 // Returns KErrNone if there is a match, KErrCorrupt otherwise.
   304 	{
   305 	TInt i;
   306 	// Check the transaction header
   307 	// Should contain the default header for SPI
   308 	TDes8* bufPtr = GetTransactionHeader(aTransaction);
   309 	if(bufPtr == NULL)
   310 		{
   311 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL header\n"));
   312 		return KErrCorrupt;
   313 		}
   314 	TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr());
   315 	if(buf->iWordWidth != ESpiWordWidth_8)
   316 		{
   317 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header wordwidth mis-match\n"));
   318 		return KErrCorrupt;
   319 		}
   320 	if(buf->iClkSpeedHz !=100000)
   321 		{
   322 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header clockspeed mis-match\n"));
   323 		return KErrCorrupt;
   324 		}
   325 	if(buf->iClkMode != ESpiPolarityLowRisingEdge)
   326 		{
   327 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header polarity mis-match\n"));
   328 		return KErrCorrupt;
   329 		}
   330 	if(buf->iTimeoutPeriod != 100)
   331 		{
   332 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header timeout mis-match\n"));
   333 		return KErrCorrupt;
   334 		}
   335 
   336 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne header OK\n"));
   337 	
   338 	// Check the half-duplex transfer list
   339 	TIicBusTransfer* tfer = GetTransHalfDuplexTferPtr(aTransaction);
   340 	if(tfer == NULL)
   341 		{
   342 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL half-duplex transfer\n"));
   343 		return KErrCorrupt;
   344 		}
   345 	// Process each transfer in the list
   346 	TInt8 dummy;
   347 
   348 	// tfer1 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf1);
   349 	// 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};
   350 	dummy=GetTferType(tfer);
   351 	if(dummy!=TIicBusTransfer::EMasterWrite)
   352 		{
   353 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 type=%d\n"));
   354 		return KErrCorrupt;
   355 		}
   356 	dummy=GetTferBufGranularity(tfer);
   357 	if(dummy!=8)
   358 		{
   359 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 granularity=%d\n",dummy));
   360 		return KErrCorrupt;
   361 		}
   362 	if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL)
   363 		{
   364 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 buffer NULL\n"));
   365 		return KErrCorrupt;
   366 		}
   367 	for(i=0;i<21;++i)
   368 		{
   369 		if((*bufPtr)[i]!=i)
   370 			{
   371 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer1 buffer element %d has 0x%x\n",i,(*bufPtr)[i]));
   372 			return KErrCorrupt;
   373 			}
   374 		}
   375 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer1 OK\n"));
   376 
   377 
   378 	tfer=GetTferNextTfer(tfer);
   379 	// tfer2 = new TIicBusTransfer(TIicBusTransfer::EMasterRead,8,buf2);
   380 	// buf2 contains copy of TUint8 KTransOneTferTwo[8] = {17,18,19,20,21,22,23,24};
   381 	dummy=GetTferType(tfer);
   382 	if(dummy!=TIicBusTransfer::EMasterRead)
   383 		{
   384 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 type=%d\n",dummy));
   385 		return KErrCorrupt;
   386 		}
   387 	dummy=GetTferBufGranularity(tfer);
   388 	if(dummy!=8)
   389 		{
   390 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 granularity=%d\n",dummy));
   391 		return KErrCorrupt;
   392 		}
   393 	if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL)
   394 		{
   395 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 buffer NULL\n"));
   396 		return KErrCorrupt;
   397 		}
   398 	for(i=0;i<8;++i)
   399 		{
   400 		if((*bufPtr)[i]!=(17+i))
   401 			{
   402 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer2 buffer element %d has 0x%x\n",i,(*bufPtr)[i]));
   403 			return KErrCorrupt;
   404 			}
   405 		}
   406 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer2 OK\n"));
   407 
   408 	tfer=GetTferNextTfer(tfer);
   409 	// tfer3 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf3);
   410 	// buf2 contains copy of TUint8 KTransOneTferThree[6] = {87,85,83,81,79,77};
   411 	dummy=GetTferType(tfer);
   412 	if(dummy!=TIicBusTransfer::EMasterWrite)
   413 		{
   414 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 type=%d\n"));
   415 		return KErrCorrupt;
   416 		}
   417 	dummy=GetTferBufGranularity(tfer);
   418 	if(dummy!=8)
   419 		{
   420 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 granularity=%d\n",dummy));
   421 		return KErrCorrupt;
   422 		}
   423 	if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL)
   424 		{
   425 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 buffer NULL\n"));
   426 		return KErrCorrupt;
   427 		}
   428 	for(i=0;i<6;++i)
   429 		{
   430 		if((*bufPtr)[i]!=(87-(2*i)))
   431 			{
   432 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer3 buffer element %d has 0x%x\n",i,(*bufPtr)[i]));
   433 			return KErrCorrupt;
   434 			}
   435 		}
   436 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer3 OK\n"));
   437 
   438 	// Shouldn't be any more transfers in the half duplex list
   439 	if((tfer=GetTferNextTfer(tfer))!=NULL)
   440 		{
   441 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 iNext=0x%x\n",tfer));
   442 		return KErrCorrupt;
   443 		}
   444 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne half-duplex transfer OK\n"));
   445 
   446 	// The full duplex transfer should be represented by a NULL pointer
   447 	if((tfer=GetTransFullDuplexTferPtr(aTransaction))!=NULL)
   448 		{
   449 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - full duplex pointer=0x%x\n",tfer));
   450 		return KErrCorrupt;
   451 		}
   452 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne full duplex pointer is NULL (OK)\n"));
   453 
   454 	// Synchronous transaction, so check the callback pointer is NULL
   455 	TIicBusCallback* dumCb = NULL;
   456 	dumCb=GetTransCallback(aTransaction);
   457 	if(dumCb!=NULL)
   458 		{
   459 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - callback pointer=0x%x\n",dumCb));
   460 		return KErrCorrupt;
   461 		}
   462 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne callback pointer is NULL (OK)\n"));
   463 
   464 	// Check the transaction flags are set to zero
   465 	TUint8 dumFlags;
   466 	dumFlags=GetTransFlags(aTransaction);
   467 	if(dumFlags!=0)
   468 		{
   469 		SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - flags=0x%x\n",dumFlags));
   470 		return KErrCorrupt;
   471 		}
   472 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne flags are zero (OK)\n"));
   473 
   474 	return KErrNone;
   475 	}
   476 
   477 
   478 // The THwCallbackFunc gets called if the hardware preparation completes successfully.
   479 void THwCallbackFunc(TAny* aPtr)
   480 	{
   481 	SPI_PRINT(("Hardware preparation completed, calling the callback function"));
   482 	DSimulatedIicBusChannelMasterSpi* aChanMasterSpi=(DSimulatedIicBusChannelMasterSpi* )aPtr;
   483 	TInt r = aChanMasterSpi->DoSimulatedTransaction();
   484 	((DSimulatedIicBusChannelMasterSpi*)aChanMasterSpi)->CompleteReq(r);
   485 	}
   486 
   487 TInt DSimulatedIicBusChannelMasterSpi::DoSimulatedTransaction()
   488 	{
   489 	TInt r = AsynchStateMachine(EHwTransferDone);
   490 	if(iTimeoutTimer.Cancel() == FALSE)
   491 		{
   492 		SPI_PRINT(("timer is not cancelled"));
   493 		}
   494 	return r;
   495 	}
   496 
   497 TInt DSimulatedIicBusChannelMasterSpi::DoHwPreparation()
   498 	{
   499 	SPI_PRINT(("Preparing hardware for the transaction"));
   500 	
   501 	TInt r = KErrNone;
   502 	// The hardware preparation can either complete successfully or fail. 
   503 	// If successful, invoke the callback function of THwDoneCallBack
   504 	// if not, execute the timeout machanism
   505 	// Currently DoHwPreparation is just a simple function. It should be more complicated 
   506 	// for the real hardware.
   507 	switch(iTestState)
   508 		{
   509 		case (ETestSlaveTimeOut):
   510 			{
   511 			// In the timeout test, do nothing until the timeout callback function is invoked.
   512 			SPI_PRINT(("Simulating the timeout process."));
   513 			break;
   514 			}
   515 		case (ETestNone):
   516 			{
   517 			// Pretend the hardware preparation's been done, and a callback function is invoked to call 
   518 			// the Asynchronous State Machine
   519 			SPI_PRINT(("Hardware preparing work is executing normally."));
   520 			iCb->Enque();
   521 			break;
   522 			}
   523 		default:
   524 			{
   525 			SPI_PRINT(("Not a valid test."));
   526 			r = KErrNotSupported;
   527 			break;
   528 			}	
   529 		}
   530 	
   531 	return r; 
   532 	}
   533 
   534 // Gateway function for PSL implementation, invoked for DFC processing
   535 TInt DSimulatedIicBusChannelMasterSpi::DoRequest(TIicBusTransaction* aTransaction)
   536 	{
   537 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest invoked with aTransaction=0x%x\n",aTransaction));
   538 	
   539 	TInt r = KErrNone;
   540 	iCurrTrans=aTransaction;
   541 	
   542 	// Check if the Asynchronous State Machine is available. If not, then return KErrInUse. 
   543 	// This is used to stop the second transaction executing if the machine has already been holding 
   544 	// by a transaction. However, this situation cannot be tested because of the malfunction in PIL
   545 	if(iChannelState!= EIdle)
   546 		return KErrInUse;
   547 	
   548 	iChannelState = EBusy;
   549 #ifdef IIC_INSTRUMENTATION_MACRO
   550 	IIC_MPROCESSTRANS_START_PSL_TRACE;
   551 #endif
   552 	r = ProcessTrans(aTransaction);
   553 
   554 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - exiting\n"));
   555 	return r;
   556 	}
   557 
   558 TInt DSimulatedIicBusChannelMasterSpi::ProcessTrans(TIicBusTransaction* aTransaction)
   559 		{
   560 		TInt r=KErrNone;
   561 		
   562 		switch(iTestState)
   563 			{
   564 			case(ETestWaitTransOne):
   565 				{
   566 				// The transaction received should exhibit the expected data
   567 				// Return KErrArgument if this is not the case
   568 				// The timer should be started at the beginning of every transaction
   569 				// For simplicity, we omit the timer here. 
   570 				r=CompareTransactionOne(iCurrTrans);
   571 				iChannelState = EIdle;
   572 				CompleteRequest(KErrNone);
   573 				break;
   574 				}
   575 			case(ETestSlaveTimeOut):
   576 				{
   577 				// Test the timeout funciton
   578 				SPI_PRINT(("Test the slave timeout function\n"));
   579 				
   580 				// Simulate a timeout 
   581 				// Start a timer and then wait for the Slave response to timeout
   582 				// A real bus would use its own means to identify a timeout
   583 				TInt aTime=1000000/NKern::TickPeriod();
   584 				r = StartSlaveTimeOutTimer(aTime);
   585 				if(r != KErrNone)
   586 					return r;
   587 				r = DoHwPreparation();
   588 				break;
   589 				}
   590 			case(ETestWaitPriorityTest):
   591 				{	
   592 				static TInt TranCount = 0;
   593 				if(TranCount >= KPriorityTestNum) return KErrUnknown;
   594 				// block the channel
   595 				while(IsRequestDelayed(this))
   596 					{
   597 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - starting Sleep...\n"));
   598 					NKern::Sleep(1000);	// 1000 is arbitrary
   599 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - completed Sleep, check if still delayed\n"));
   600 					}; 
   601 				// get transaction header			
   602 				TDes8* bufPtr = GetTransactionHeader(aTransaction);
   603 				if(bufPtr == NULL)
   604 				{
   605 				SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest ERROR - NULL header\n"));
   606 				return KErrCorrupt;
   607 				}
   608 
   609 				if(TranCount == 0)
   610 					{			
   611 					// ignore the blocking transaction
   612 					TranCount++;
   613 					}
   614 				else
   615 					{
   616 					// store transaction header
   617 					iPriorityTestResult[TranCount++] = (*bufPtr)[0];
   618 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest Priority test transaction no.:%d Priority:%d", 
   619 						(*bufPtr)[0], aTransaction->iKey));
   620 					}
   621 				iChannelState = EIdle;
   622 				CompleteRequest(KErrNone);
   623 				if(TranCount == KPriorityTestNum) iPriorityTestDone = ETrue;
   624 				break;
   625 				}
   626 
   627 
   628 
   629 			case(ETestNone):
   630 				{
   631 				SPI_PRINT(("Nothing to be tested, just do the usual transaction"));
   632 				
   633 				// Start the timer on the Slave response. 
   634 				// Since no timeout, this timer will be cancelled in the THwCallbackFunc
   635 				r = StartSlaveTimeOutTimer(100000);
   636 				if(r != KErrNone)
   637 					return r;
   638 				// Use a class THwDoneCallBack derived from TDfc to trigger the asynchronous state machine 
   639 				// when the hardware preparation completes successfully. 
   640 				// The priority is set with an arbitrary number 5
   641 				iCb = new THwDoneCallBack(THwCallbackFunc, this, iDynamicDfcQ, 5);
   642 				r = DoHwPreparation(); 
   643 				break;
   644 				}
   645 			default:
   646 				{
   647 				SPI_PRINT(("Test status not matched"));
   648 				return KErrNotSupported;
   649 				}
   650 			}
   651 
   652 		return r;
   653 		}
   654 	
   655 	
   656 TInt DSimulatedIicBusChannelMasterSpi::AsynchStateMachine(TInt aReason)
   657 	{
   658 	TInt r=KErrNone; 
   659 	
   660 	// The asynchronous state machine has two states, it could either be idle or busy.
   661 	// Initially, it's in idle state. When a user queues a transaction, the hardware preparation starts
   662 	// and the state changes to busy. After the hardware preparation completes, either successfully or not, 
   663 	// the state machine will do the corresponding work for the transaction and then goes back to the idle state.  
   664 	switch(iChannelState)
   665 		{
   666 		case(EIdle):
   667 			{
   668 			 return KErrGeneral;
   669 			}
   670 		case (EBusy):
   671 			{
   672 			switch(aReason)
   673 				{
   674 				case(EHwTransferDone):
   675 					{
   676 								
   677 					// Simulate processing - for now, do nothing!
   678 					//
   679 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHeader=0x%x\n",GetTransactionHeader(iCurrTrans)));
   680 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(iCurrTrans)));
   681 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(iCurrTrans)));
   682 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iCallback=0x%x\n",GetTransCallback(iCurrTrans)));
   683 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFlags=0x%x\n",GetTransFlags(iCurrTrans)));
   684 
   685 					SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHeader info \n"));
   686 					TDes8* bufPtr = GetTransactionHeader(iCurrTrans);
   687 					if(bufPtr == NULL)
   688 						{
   689 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine ERROR - NULL header\n"));
   690 						return KErrCorrupt;
   691 						}
   692 					TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr());
   693 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header word width=0x%x\n",buf->iWordWidth));
   694 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock speed=0x%x\n",buf->iClkSpeedHz));
   695 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock mode=0x%x\n",buf->iClkMode));
   696 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header timeout period=0x%x\n",buf->iTimeoutPeriod));
   697 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header endianness=0x%x\n",buf->iEndianness));
   698 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header bit order=0x%x\n",buf->iBitOrder));
   699 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header wait cycles=0x%x\n",buf->iTransactionWaitCycles));
   700 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header Slave select pin mode=0x%x\n",buf->iSSPinActiveMode));
   701 					(void)buf;	// Silence compiler when SPI_PRINT not used
   702 							
   703 					SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHalfDuplexTrans info \n"));
   704 					TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(iCurrTrans);
   705 					while(halfDuplexPtr != NULL)
   706 						{
   707 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer type=0x%x\n",GetTferType(halfDuplexPtr)));
   708 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr)));
   709 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr)));
   710 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr)));
   711 						halfDuplexPtr=GetTferNextTfer(halfDuplexPtr);
   712 						}
   713 					SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - End of iHalfDuplexTrans info"));
   714 					
   715 					while(IsRequestDelayed(this))
   716 						{
   717 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - starting Sleep...\n"));
   718 						NKern::Sleep(1000);	// 1000 is arbitrary
   719 						SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - completed Sleep, check if still delayed\n"));
   720 						}; 
   721 				
   722 					iChannelState=EIdle; 
   723 					delete iCb;
   724 					break;
   725 					}
   726 				case(ETimeExpired):
   727 					{
   728 					SPI_PRINT(("Time expired, the Asynchrnous State Machine will be Idle again, and wait for the next request."));
   729 					iChannelState=EIdle;
   730 					r = KErrTimedOut; 
   731 					break;
   732 					}
   733 				default:
   734 					{
   735 					SPI_PRINT(("Request can not be handled, return error code."));
   736 					return KErrNotSupported;
   737 					}
   738 				}
   739 			break;
   740 			}
   741 		default:
   742 			{
   743 			SPI_PRINT(("No matched state"));
   744 			return KErrGeneral;
   745 			}
   746 		}
   747 	return r; 
   748 	}
   749 
   750 
   751 TBool DSimulatedIicBusChannelMasterSpi::IsRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan)
   752 	{
   753 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::IsRequestDelayed invoked for aChan=0x%x\n",aChan));
   754 	return aChan->iReqDelayed;
   755 	}
   756 
   757 void DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan,TBool aDelay) 
   758 	{
   759 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay));
   760 	aChan->iReqDelayed=aDelay;
   761 	}
   762 
   763 TInt DSimulatedIicBusChannelMasterSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
   764 	{
   765 	SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::StaticExtension\n"));
   766 #ifdef IIC_INSTRUMENTATION_MACRO
   767 	IIC_MSTATEXT_START_PSL_TRACE;
   768 #endif
   769 	(void)aParam1;
   770 	(void)aParam2;
   771 	TInt r = KErrNone;
   772 	// Test values of aFunction were shifted left one place by the (test) client driver
   773 	// and for Slave values the two msb were cleared
   774 	// Return to its original value.
   775 	if(aFunction>KTestControlIoPilOffset)
   776 		aFunction >>= 1;
   777 	switch(aFunction)
   778 		{
   779 		case(RBusDevIicClient::ECtlIoDumpChan):
   780 			{
   781 #ifdef _DEBUG
   782 			DumpChannel();
   783 #endif
   784 			break;
   785 			}
   786 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
   787 			{
   788 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Blocking request completion\n"));
   789 			SetRequestDelayed(this, ETrue);
   790 			break;
   791 			}
   792 		case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
   793 			{
   794 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Unlocking request completion\n"));
   795 			SetRequestDelayed(this, EFalse);
   796 			break;
   797 			}
   798 		case(RBusDevIicClient::ECtlIoDeRegChan):
   799 			{
   800 #ifdef IIC_INSTRUMENTATION_MACRO
   801 	IIC_DEREGISTERCHAN_START_PSL_TRACE;
   802 #endif
   803 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: deregister channel\n"));
   804 #ifndef STANDALONE_CHANNEL
   805 			r=DIicBusController::DeRegisterChannel(this);
   806 #endif
   807 
   808 #ifdef IIC_INSTRUMENTATION_MACRO
   809 	IIC_DEREGISTERCHAN_END_PSL_TRACE;
   810 #endif
   811 			break;
   812 			}
   813 
   814 		case(RBusDevIicClient::ECtlIoPriorityTest):
   815 			{
   816 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect priority test\n"));
   817 			iPriorityTestDone = EFalse;
   818 			iTestState=ETestWaitPriorityTest;
   819 			break;
   820 			}
   821 		case(RBusDevIicClient::EGetTestResult):
   822 			{
   823 			if(!iPriorityTestDone) return KErrNotReady;
   824 			
   825 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: get priority test order\n"));
   826 
   827 			//iPriorityTestResult[0] is the blocking transaction, ignore it. start from entry 1.
   828 			for(TInt i=1; i<KPriorityTestNum; i++)
   829 				{
   830 				if(iPriorityTestResult[i]!=(KPriorityTestNum-i-1))
   831 					{
   832 					r = KErrGeneral;
   833 					break;
   834 					}
   835 				}
   836 				r = KErrNone;
   837 			break;
   838 			}
   839 
   840 		case(RBusDevIicClient::ECtlIoTracnOne):
   841 			{
   842 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect Transaction One\n"));
   843 			iTestState=ETestWaitTransOne;
   844 			break;
   845 			}
   846 		case(RBusDevIicClient::ECtlIoNone):
   847 			{
   848 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: terminate ControlIO state\n"));
   849 			iTestState=ETestNone;
   850 			break;
   851 			}
   852 		case(RBusDevIicClient::ECtlIoSetTimeOutFlag):
   853 			{
   854 			SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: test slave time out\n"));
   855 			iTestState=ETestSlaveTimeOut;
   856 			break;
   857 			}
   858 		default:
   859 			{
   860 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
   861 			r=KErrNotSupported;
   862 			}
   863 		}
   864 #ifdef IIC_INSTRUMENTATION_MACRO
   865 	IIC_MSTATEXT_END_PSL_TRACE;
   866 #endif		
   867 	return r;
   868 	}
   869 
   870 void DSimulatedIicBusChannelMasterSpi::CompleteReq(TInt aResult)
   871 	{
   872 #ifdef IIC_INSTRUMENTATION_MACRO
   873 	IIC_MPROCESSTRANS_END_PSL_TRACE;
   874 #endif
   875 	CompleteRequest(aResult);
   876 	}
   877 
   878 
   879 void DSimulatedIicBusChannelSlaveSpi::SlaveAsyncSimCallback(TAny* aPtr)
   880 	{
   881 	SPI_PRINT(("SlaveAsyncSimCallback\n"));
   882 	DSimulatedIicBusChannelSlaveSpi* channel = (DSimulatedIicBusChannelSlaveSpi*)aPtr;
   883 	TInt r=KErrNone;	// Just simulate successfull capture
   884 #ifdef IIC_INSTRUMENTATION_MACRO
   885 	IIC_SCAPTCHANASYNC_END_PSL_TRACE;
   886 #endif
   887 	channel->ChanCaptureCb(r);
   888 	}
   889 
   890 #ifdef STANDALONE_CHANNEL
   891 EXPORT_C
   892 #endif
   893 	DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
   894 	: DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
   895 	iSlaveTimer(SlaveAsyncSimCallback,this)
   896 	{
   897 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
   898 #ifndef STANDALONE_CHANNEL
   899 	iChannelNumber = AssignChanNum();
   900 #endif
   901 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, iChannelNumber=%d\n",iChannelNumber));
   902 	}
   903 
   904 TInt DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl(TDes8* /*aConfigHdr*/, TBool aAsynch)
   905 	{
   906 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl, aAsynch=%d\n",aAsynch));
   907 	TInt r = KErrNone;
   908 	if(aAsynch)
   909 		{
   910 #ifdef IIC_INSTRUMENTATION_MACRO
   911 	IIC_SCAPTCHANASYNC_START_PSL_TRACE;
   912 #endif
   913 		// To simulate an asynchronous operation, just set a timer to expire
   914 		iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
   915 		}
   916 	else
   917 		{
   918 #ifdef IIC_INSTRUMENTATION_MACRO
   919 	IIC_SCAPTCHANSYNC_START_PSL_TRACE;
   920 #endif
   921 		// PSL processing would happen here ...
   922 		// Expected to include implementation of the header configuration information 
   923 #ifdef IIC_INSTRUMENTATION_MACRO
   924 	IIC_SCAPTCHANSYNC_END_PSL_TRACE;
   925 #endif
   926 		}
   927 	SPI_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChanSync ... no real processing to do \n"));
   928 
   929 	return r;
   930 	}
   931 
   932 TInt DSimulatedIicBusChannelSlaveSpi::CheckHdr(TDes8* /*aHdr*/)
   933 	{
   934 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CheckHdr\n"));
   935 	return KErrNone;
   936 	}
   937 
   938 TInt DSimulatedIicBusChannelSlaveSpi::DoCreate()
   939 	{
   940 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoCreate\n"));
   941 	TInt r=Init();	// PIL Base class initialisation
   942 	return r;
   943 	}
   944 
   945 TInt DSimulatedIicBusChannelSlaveSpi::DoRequest(TInt /*aTrigger*/)
   946 	{
   947 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoRequest\n"));
   948 	return KErrNotSupported; 
   949 	}
   950 
   951 void DSimulatedIicBusChannelSlaveSpi::ProcessData(TInt /*aTrigger*/, TIicBusSlaveCallback*  /*aCb*/)
   952 	{
   953 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::ProcessData\n"));
   954 	}
   955 
   956 TInt DSimulatedIicBusChannelSlaveSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
   957 	{
   958 	SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::StaticExtension\n"));
   959 #ifdef IIC_INSTRUMENTATION_MACRO
   960 	IIC_SSTATEXT_START_PSL_TRACE;
   961 #endif
   962 	(void)aParam1;
   963 	(void)aParam2;
   964 	// Test values of aFunction were shifted left one place by the (test) client driver
   965 	// and for Slave values the two msb were cleared
   966 	// Return to its original value.
   967 	if(aFunction>KTestControlIoPilOffset)
   968 		{
   969 		aFunction |= 0xC0000000;
   970 		aFunction >>= 1;
   971 		}
   972 	TInt r = KErrNone;
   973 	switch(aFunction)
   974 		{
   975 		case(RBusDevIicClient::ECtlIoDumpChan):
   976 			{
   977 #ifdef _DEBUG
   978 			DumpChannel();
   979 #endif
   980 			break;
   981 			}
   982 		default:
   983 			{
   984 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
   985 			r=KErrNotSupported;
   986 			}
   987 		}
   988 
   989 #ifdef IIC_INSTRUMENTATION_MACRO
   990 	IIC_SSTATEXT_START_PSL_TRACE;
   991 #endif
   992 	(void)aFunction;
   993 	return r;
   994 	}
   995 
   996 
   997 
   998 
   999 
  1000