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