kerneltest/e32test/iic/iic_psl/i2c.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/I2c.cpp
       
    15 //
       
    16 
       
    17 #include "i2c.h"
       
    18 
       
    19 #ifdef IIC_INSTRUMENTATION_MACRO
       
    20 #include <drivers/iic_trace.h>
       
    21 #endif
       
    22 
       
    23 
       
    24 #if defined(MASTER_MODE) && !defined(SLAVE_MODE)
       
    25 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::EMaster};
       
    26 #elif defined(MASTER_MODE) && defined(SLAVE_MODE)
       
    27 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMasterSlave};
       
    28 #else
       
    29 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::ESlave, DIicBusChannel::ESlave, DIicBusChannel::ESlave};
       
    30 #endif
       
    31 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
       
    32 #define CHANNEL_DUPLEX(n) (DIicBusChannel::EHalfDuplex)
       
    33 
       
    34 #ifdef STANDALONE_CHANNEL
       
    35 _LIT(KPddNameI2c,"i2c_ctrless.pdd");
       
    36 #else
       
    37 _LIT(KPddNameI2c,"i2c.pdd");
       
    38 #endif
       
    39 
       
    40 #ifndef STANDALONE_CHANNEL
       
    41 LOCAL_C TInt8 AssignChanNum()
       
    42 	{
       
    43 	static TInt8 iBaseChanNum = KI2cChannelNumBase;
       
    44 	I2C_PRINT(("I2C AssignChanNum - on entry, iBaseChanNum = 0x%x\n",iBaseChanNum));
       
    45 	return iBaseChanNum++; // Arbitrary, for illustration
       
    46 	}
       
    47 #endif/*STANDALONE_CHANNEL*/
       
    48 
       
    49 #ifdef SLAVE_MODE
       
    50 LOCAL_C TInt16 AssignSlaveChanId()
       
    51 	{
       
    52 	static TInt16 iBaseSlaveChanId = KI2cSlaveChannelIdBase;
       
    53 	I2C_PRINT(("I2C AssignSlaveChanId - on entry, iBaseSlaveChanId = 0x%x\n",iBaseSlaveChanId));
       
    54 	return iBaseSlaveChanId++; // Arbitrary, for illustration
       
    55 	}
       
    56 #endif/*SLAVE_MODE*/
       
    57 
       
    58 NONSHARABLE_CLASS(DSimulatedI2cDevice) : public DPhysicalDevice
       
    59 	{
       
    60 // Class to faciliate loading of the IIC classes
       
    61 public:
       
    62 	class TCaps
       
    63 		{
       
    64 	public:
       
    65 		TVersion iVersion;
       
    66 		};
       
    67 public:
       
    68 	DSimulatedI2cDevice();
       
    69 	virtual TInt Install();
       
    70 	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
    71 	virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
    72 	virtual void GetCaps(TDes8& aDes) const;
       
    73 	inline static TVersion VersionRequired();
       
    74 	};
       
    75 
       
    76 TVersion DSimulatedI2cDevice::VersionRequired()
       
    77 	{
       
    78 	I2C_PRINT(("DSimulatedI2cDevice::VersionRequired\n"));
       
    79 	return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber);
       
    80 	}
       
    81 
       
    82 /** Factory class constructor */
       
    83 DSimulatedI2cDevice::DSimulatedI2cDevice()
       
    84 	{
       
    85 	I2C_PRINT(("DSimulatedI2cDevice::DSimulatedI2cDevice\n"));
       
    86     iVersion = DSimulatedI2cDevice::VersionRequired();
       
    87 	}
       
    88 
       
    89 TInt DSimulatedI2cDevice::Install()
       
    90     {
       
    91 	I2C_PRINT(("DSimulatedI2cDevice::Install\n"));
       
    92     return(SetName(&KPddNameI2c));
       
    93     }
       
    94 
       
    95 /**  Called by the kernel's device driver framework to create a Physical Channel. */
       
    96 TInt DSimulatedI2cDevice::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
       
    97     {
       
    98 	I2C_PRINT(("DSimulatedI2cDevice::Create\n"));
       
    99     return KErrNone;
       
   100     }
       
   101 
       
   102 /**  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/
       
   103 TInt DSimulatedI2cDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
       
   104     {
       
   105 	I2C_PRINT(("DSimulatedI2cDevice::Validate\n"));
       
   106    	if (!Kern::QueryVersionSupported(DSimulatedI2cDevice::VersionRequired(),aVer))
       
   107 		return(KErrNotSupported);
       
   108     return KErrNone;
       
   109     }
       
   110 
       
   111 /** Return the driver capabilities */
       
   112 void DSimulatedI2cDevice::GetCaps(TDes8& aDes) const
       
   113     {
       
   114 	I2C_PRINT(("DSimulatedI2cDevice::GetCaps\n"));
       
   115 	// Create a capabilities object
       
   116 	TCaps caps;
       
   117 	caps.iVersion = iVersion;
       
   118 	// Zero the buffer
       
   119 	TInt maxLen = aDes.MaxLength();
       
   120 	aDes.FillZ(maxLen);
       
   121 	// Copy capabilities
       
   122 	TInt size=sizeof(caps);
       
   123 	if(size>maxLen)
       
   124 	   size=maxLen;
       
   125 	aDes.Copy((TUint8*)&caps,size);
       
   126     }
       
   127 
       
   128 
       
   129 DSimulatedI2cDevice* gDummyDevice;
       
   130 
       
   131 
       
   132 // supported channels for this implementation
       
   133 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
       
   134 
       
   135 
       
   136 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)	
       
   137 DECLARE_STANDARD_PDD()		// I2c test driver to be explicitly loaded as an LDD, not kernel extension
       
   138 	{	
       
   139 	if(gDummyDevice == NULL)
       
   140 		gDummyDevice = new DSimulatedI2cDevice;
       
   141 	if(gDummyDevice == NULL)
       
   142 		return NULL;
       
   143 	I2C_PRINT(("\n\nI2C PDD, channel creation loop follows ...\n"));
       
   144 
       
   145 #ifndef STANDALONE_CHANNEL
       
   146 	DIicBusChannel* chan=NULL;
       
   147 	for(TInt i=0; i<NUM_CHANNELS; i++)
       
   148 		{
       
   149 	I2C_PRINT(("\n"));
       
   150 #if defined(MASTER_MODE)
       
   151 		if(CHANNEL_TYPE(i) == (DIicBusChannel::EMaster))
       
   152 			{
       
   153 			chan=new DSimulatedIicBusChannelMasterI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
       
   154 			if(!chan)
       
   155 				return NULL;
       
   156 			I2C_PRINT(("I2C chan created at 0x%x\n",chan));
       
   157 			if(((DSimulatedIicBusChannelMasterI2c*)chan)->Create()!=KErrNone)
       
   158 			    {
       
   159 			    delete chan;
       
   160 				return NULL;
       
   161                 }
       
   162 			}
       
   163 #endif
       
   164 #if defined(MASTER_MODE) && defined(SLAVE_MODE)
       
   165 		if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave)
       
   166 			{
       
   167 			DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
       
   168 			if(!chanM)
       
   169 				return NULL;
       
   170 			DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
       
   171 			if(!chanS)
       
   172 			    {
       
   173 			    delete chanM;
       
   174 				return NULL;
       
   175 			    }
       
   176 			// For MasterSlave channel, the channel number for both the Master and Slave channels must be the same
       
   177 			TInt8 msChanNum = ((DSimulatedIicBusChannelMasterI2c*)chanM)->GetChanNum();
       
   178 			((DSimulatedIicBusChannelSlaveI2c*)chanS)->SetChanNum(msChanNum);
       
   179 
       
   180 			chan=new DSimulatedIicBusChannelMasterSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i),(DSimulatedIicBusChannelMasterI2c*)chanM,(DSimulatedIicBusChannelSlaveI2c*)chanS); // Generic implementation
       
   181 			if(!chan)
       
   182 			    {
       
   183 			    delete chanM;
       
   184 			    delete chanS;
       
   185 				return NULL;
       
   186 			    }
       
   187 			I2C_PRINT(("I2C chan created at 0x%x\n",chan));
       
   188 			if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone)
       
   189 			    {
       
   190 			    delete chanM;
       
   191 			    delete chanS;
       
   192 			    delete chan;
       
   193 				return NULL;
       
   194 			    }
       
   195 			}
       
   196 #endif
       
   197 #if defined(SLAVE_MODE)
       
   198 		if(CHANNEL_TYPE(i) == (DIicBusChannel::ESlave))
       
   199 			{
       
   200 			chan=new DSimulatedIicBusChannelSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
       
   201 			if(!chan)
       
   202 				return NULL;
       
   203 			I2C_PRINT(("I2C chan created at 0x%x\n",chan));
       
   204 			if(((DSimulatedIicBusChannelSlaveI2c*)chan)->Create()!=KErrNone)
       
   205 			    {
       
   206 			    delete chan;
       
   207 			    return NULL;
       
   208 			    }
       
   209 			}
       
   210 #endif
       
   211 #if !defined(MASTER_MODE) && !defined(SLAVE_MODE)
       
   212 #error I2C mode not defined as Master, Slave nor Master-Slave
       
   213 #endif
       
   214 		if(chan == NULL)
       
   215 			{
       
   216 			I2C_PRINT(("\n\nI2C: Channel of type (%d) not created for index %d\n\n",CHANNEL_TYPE(i),i));
       
   217 			return NULL;
       
   218 			}
       
   219 		ChannelPtrArray[i]=chan;
       
   220 		}
       
   221 	I2C_PRINT(("\nI2C PDD, channel creation loop done- about to invoke RegisterChannels\n\n"));
       
   222 #ifdef IIC_INSTRUMENTATION_MACRO
       
   223 	IIC_REGISTERCHANS_START_PSL_TRACE;
       
   224 #endif
       
   225 
       
   226 	TInt r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS);
       
   227 
       
   228 #ifdef IIC_INSTRUMENTATION_MACRO
       
   229 	IIC_REGISTERCHANS_END_PSL_TRACE;
       
   230 #endif
       
   231 	I2C_PRINT(("\nI2C - returned from RegisterChannels with r=%d\n",r));
       
   232 	if(r!=KErrNone)
       
   233 		{
       
   234 		delete chan;
       
   235 		return NULL;
       
   236 		}
       
   237 #endif
       
   238 	return gDummyDevice;
       
   239 	}
       
   240 
       
   241 
       
   242 #ifdef MASTER_MODE
       
   243 #ifdef STANDALONE_CHANNEL
       
   244 EXPORT_C
       
   245 #endif
       
   246 DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c(const TBusType aBusType, const TChannelDuplex aChanDuplex)
       
   247 	: DIicBusChannelMaster(aBusType,aChanDuplex)
       
   248 	{
       
   249 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
       
   250 #ifndef STANDALONE_CHANNEL
       
   251 	iChannelNumber = AssignChanNum();
       
   252 #endif
       
   253 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c, iChannelNumber=%d\n",iChannelNumber));
       
   254 	}
       
   255 
       
   256 TInt DSimulatedIicBusChannelMasterI2c::DoCreate()
       
   257 	{
       
   258 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoCreate\n"));
       
   259 	TInt r=Init();	// PIL Base class initialisation
       
   260 	r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KI2cThreadPriority,KI2cThreadName);
       
   261 	if(r == KErrNone)
       
   262 		SetDfcQ((TDfcQue*)iDynamicDfcQ);
       
   263 	DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(this,EFalse);
       
   264 	return r;
       
   265 	}
       
   266 
       
   267 TInt DSimulatedIicBusChannelMasterI2c::CheckHdr(TDes8* aHdr)
       
   268 	{
       
   269 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr\n"));
       
   270 
       
   271 	TConfigI2cBufV01* i2cBuf = (TConfigI2cBufV01*)aHdr;
       
   272 	TConfigI2cV01* i2cPtr = &((*i2cBuf)());
       
   273 
       
   274 	// Check that the values for address type, clock speed, user operation and endianness are recognised
       
   275 	if((i2cPtr->iAddrType < 0) || (i2cPtr->iAddrType > EI2cAddr10Bit))
       
   276 		{
       
   277 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr unrecognised address type identifier %d\n",i2cPtr->iAddrType));
       
   278 		return KErrArgument;
       
   279 		}
       
   280 	if(i2cPtr->iClkSpeedHz < 0)
       
   281 		{
       
   282 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr negative clock speed specified %d\n",i2cPtr->iClkSpeedHz));
       
   283 		return KErrArgument;
       
   284 		}
       
   285 	if((i2cPtr->iEndianness < 0) || (i2cPtr->iEndianness > ELittleEndian))
       
   286 		{
       
   287 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr unrecognised endianness identifier %d\n",i2cPtr->iEndianness));
       
   288 		return KErrArgument;
       
   289 		}
       
   290 	// Values for the timeout period are arbitrary - can only check it is not a negative value
       
   291 	if(i2cPtr->iTimeoutPeriod < 0)
       
   292 		{
       
   293 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr negative timeout period %d\n",i2cPtr->iTimeoutPeriod));
       
   294 		return KErrArgument;
       
   295 		}
       
   296 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr address type = %d\n",i2cPtr->iAddrType));
       
   297 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr clock speed ID = %d\n",i2cPtr->iClkSpeedHz));
       
   298 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr iEndianness ID = %d\n",i2cPtr->iEndianness));
       
   299 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr iTimeoutPeriod = %d\n",i2cPtr->iTimeoutPeriod));
       
   300 	return KErrNone;
       
   301 	}
       
   302 
       
   303 	// Gateway function for PSL implementation, invoked for DFC processing
       
   304 TInt DSimulatedIicBusChannelMasterI2c::DoRequest(TIicBusTransaction* aTransaction)
       
   305 	{
       
   306 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest invoked with aTransaction=0x%x\n",aTransaction));
       
   307 	TInt r = KErrNone;
       
   308 
       
   309 #ifdef IIC_INSTRUMENTATION_MACRO
       
   310 	IIC_MPROCESSTRANS_START_PSL_TRACE;
       
   311 #endif
       
   312 
       
   313 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iHeader=0x%x\n",GetTransactionHeader(aTransaction)));
       
   314 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(aTransaction)));
       
   315 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(aTransaction)));
       
   316 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iCallback=0x%x\n",GetTransCallback(aTransaction)));
       
   317 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iFlags=0x%x\n",GetTransFlags(aTransaction)));
       
   318 
       
   319 	I2C_PRINT(("\nDSimulatedIicBusChannelMasterI2c::DoRequest, iHeader info \n"));
       
   320 	TDes8* bufPtr = GetTransactionHeader(aTransaction);
       
   321 	if(bufPtr == NULL)
       
   322 		{
       
   323 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest ERROR - NULL header\n"));
       
   324 		return KErrCorrupt;
       
   325 		}
       
   326 	TConfigI2cV01 *buf = (TConfigI2cV01 *)(bufPtr->Ptr());
       
   327 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header address type=0x%x\n",buf->iAddrType));
       
   328 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header clock speed=0x%x\n",buf->iClkSpeedHz));
       
   329 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header endianness=0x%x\n",buf->iEndianness));
       
   330 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header timeout period=0x%x\n",buf->iTimeoutPeriod));
       
   331 	(void)buf;	// Silence compiler when I2C_PRINT not used
       
   332 
       
   333 	TInt aTime=1000000/NKern::TickPeriod();
       
   334 	r = StartSlaveTimeOutTimer(aTime);
       
   335 	I2C_PRINT(("\nDSimulatedIicBusChannelMasterI2c::ProcessTrans, iHalfDuplexTrans info \n"));
       
   336 	TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(aTransaction);
       
   337 	while(halfDuplexPtr != NULL)
       
   338 		{
       
   339 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans transfer type=0x%x\n",GetTferType(halfDuplexPtr)));
       
   340 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr)));
       
   341 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr)));
       
   342 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr)));
       
   343 		halfDuplexPtr=GetTferNextTfer(halfDuplexPtr);
       
   344 		}
       
   345 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - End of iHalfDuplexTrans info"));
       
   346 
       
   347 	while(IsRequestDelayed(this))
       
   348 		{
       
   349 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - starting Sleep...\n"));
       
   350 		NKern::Sleep(1000);	// 1000 is arbitrary
       
   351 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - completed Sleep, check if still delayed\n"));
       
   352 		}; 
       
   353 
       
   354 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - exiting\n"));
       
   355 
       
   356 	return r;
       
   357 	}
       
   358 
       
   359 
       
   360 TBool DSimulatedIicBusChannelMasterI2c::IsRequestDelayed(DSimulatedIicBusChannelMasterI2c* aChan)
       
   361 	{
       
   362 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::IsRequestDelayed invoked for aChan=0x%x\n",aChan));
       
   363 	return aChan->iReqDelayed;
       
   364 	}
       
   365 
       
   366 void DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(DSimulatedIicBusChannelMasterI2c* aChan,TBool aDelay) 
       
   367 	{
       
   368 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay));
       
   369 	aChan->iReqDelayed=aDelay;
       
   370 	}
       
   371 
       
   372 TInt DSimulatedIicBusChannelMasterI2c::HandleSlaveTimeout()
       
   373 	{
       
   374 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::HandleSlaveTimeout invoked for this=0x%x\n",this));
       
   375 	return KErrTimedOut;
       
   376 	}
       
   377 
       
   378 TInt DSimulatedIicBusChannelMasterI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
       
   379 	{
       
   380 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::StaticExtension\n"));
       
   381 	TInt r = KErrNone;
       
   382 #ifdef IIC_INSTRUMENTATION_MACRO
       
   383 	IIC_MSTATEXT_START_PSL_TRACE;
       
   384 #endif
       
   385 	(void)aParam1;
       
   386 	(void)aParam2;
       
   387 	
       
   388 	// Test values of aFunction were shifted left one place by the (test) client driver
       
   389 	// Return to its original value.
       
   390 	if(aFunction>KTestControlIoPilOffset)
       
   391 		aFunction >>= 1;
       
   392 	switch(aFunction)
       
   393 		{
       
   394 		case(RBusDevIicClient::ECtlIoDumpChan):
       
   395 			{
       
   396 #ifdef _DEBUG
       
   397 			DumpChannel();
       
   398 #endif
       
   399 			break;
       
   400 			}
       
   401 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
       
   402 			{
       
   403 			I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::Blocking request completion\n"));
       
   404 			SetRequestDelayed(this, ETrue);
       
   405 			break;
       
   406 			}
       
   407 		case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
       
   408 			{
       
   409 			I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::Unlocking request completion\n"));
       
   410 			SetRequestDelayed(this, EFalse);
       
   411 			break;
       
   412 			}
       
   413 		case(RBusDevIicClient::ECtlIoDeRegChan):
       
   414 			{
       
   415 #ifndef STANDALONE_CHANNEL
       
   416 #ifdef IIC_INSTRUMENTATION_MACRO
       
   417 	IIC_DEREGISTERCHAN_START_PSL_TRACE;
       
   418 #endif
       
   419 			I2C_PRINT(("DSimulatedIicBusChannelMasterI2c: deregister channel\n"));
       
   420 			r=DIicBusController::DeRegisterChannel(this);
       
   421 
       
   422 #ifdef IIC_INSTRUMENTATION_MACRO
       
   423 	IIC_DEREGISTERCHAN_END_PSL_TRACE;
       
   424 #endif/*IIC_INSTRUMENTATION_MACRO*/
       
   425 	
       
   426 #else/*STANDALONE_CHANNEL*/
       
   427 			r = KErrNotSupported;
       
   428 #endif/*STANDALONE_CHANNEL*/
       
   429 			break;
       
   430 			}
       
   431 		default:
       
   432 			{
       
   433 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
       
   434 			r=KErrNotSupported;
       
   435 			}
       
   436 		}
       
   437 		
       
   438 #ifdef IIC_INSTRUMENTATION_MACRO
       
   439 	IIC_MSTATEXT_END_PSL_TRACE;
       
   440 #endif		
       
   441 	return r;
       
   442 	}
       
   443 
       
   444 //#ifdef MASTER_MODE
       
   445 #endif
       
   446 
       
   447 #ifdef SLAVE_MODE
       
   448 
       
   449 void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr)
       
   450 	{
       
   451 	// To support simulating an asynchronous capture operation
       
   452 	// NOTE: this will be invoked in the context of DfcThread1
       
   453 	I2C_PRINT(("SlaveAsyncSimCallback\n"));
       
   454 	DSimulatedIicBusChannelSlaveI2c* channel = (DSimulatedIicBusChannelSlaveI2c*)aPtr;
       
   455 	TInt r=KErrNone;// Just simulate successful capture
       
   456 #ifdef IIC_INSTRUMENTATION_MACRO
       
   457 	IIC_SCAPTCHANASYNC_END_PSL_TRACE;
       
   458 #endif
       
   459 	channel->ChanCaptureCb(r);
       
   460 	}
       
   461 
       
   462 #ifdef STANDALONE_CHANNEL
       
   463 EXPORT_C
       
   464 #endif
       
   465 DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
       
   466 	: DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
       
   467 	iBlockedTrigger(0),iBlockNotification(EFalse),
       
   468 	iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this)
       
   469 	{
       
   470 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
       
   471 #ifndef STANDALONE_CHANNEL
       
   472 	iChannelNumber = AssignChanNum();
       
   473 #endif
       
   474 	iChannelId = AssignSlaveChanId();
       
   475 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, iChannelNumber=%d, iChannelId=0x%x\n",iChannelNumber,iChannelId));
       
   476 	}
       
   477 
       
   478 DSimulatedIicBusChannelSlaveI2c::~DSimulatedIicBusChannelSlaveI2c()
       
   479 	{
       
   480 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::~DSimulatedIicBusChannelSlaveI2c\n"));
       
   481 	}
       
   482 
       
   483 TInt DSimulatedIicBusChannelSlaveI2c::DoCreate()
       
   484 	{
       
   485 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DoCreate\n"));
       
   486 	TInt r=Init();	// PIL Base class initialisation
       
   487 	return r;
       
   488 	}
       
   489 
       
   490 
       
   491 TInt DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl(TBool aAsynch)
       
   492 	{
       
   493 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl\n"));
       
   494 	TInt r = KErrNone;
       
   495 	if(aAsynch)
       
   496 		{
       
   497 #ifdef IIC_INSTRUMENTATION_MACRO
       
   498 	IIC_SCAPTCHANASYNC_START_PSL_TRACE;
       
   499 #endif
       
   500 		// To simulate an asynchronous capture operation, just set a timer to expire
       
   501 		iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
       
   502 		}
       
   503 	else
       
   504 		{
       
   505 #ifdef IIC_INSTRUMENTATION_MACRO
       
   506 	IIC_SCAPTCHANSYNC_START_PSL_TRACE;
       
   507 #endif
       
   508 		// PSL processing would happen here ...
       
   509 		// Expected to include implementation of the header configuration information 
       
   510 
       
   511 		I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl (synchronous) ... no real processing to do \n"));
       
   512 
       
   513 #ifdef IIC_INSTRUMENTATION_MACRO
       
   514 	IIC_SCAPTCHANSYNC_END_PSL_TRACE;
       
   515 #endif
       
   516 		}
       
   517 
       
   518 	return r;
       
   519 	}
       
   520 
       
   521 TInt DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl()
       
   522 	{
       
   523 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl\n"));
       
   524 #ifdef IIC_INSTRUMENTATION_MACRO
       
   525 	IIC_SRELCHAN_START_PSL_TRACE;
       
   526 #endif
       
   527 	TInt r = KErrNone;
       
   528 
       
   529 	// PSL-specific processing would happen here ...
       
   530 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl ... no real processing to do \n"));
       
   531 
       
   532 #ifdef IIC_INSTRUMENTATION_MACRO
       
   533 	IIC_SRELCHAN_END_PSL_TRACE;
       
   534 #endif
       
   535 
       
   536 	return r;
       
   537 	}
       
   538 
       
   539 
       
   540 TInt DSimulatedIicBusChannelSlaveI2c::PrepareTrigger(TInt aTrigger)
       
   541 	{
       
   542 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger\n"));
       
   543 #ifdef IIC_INSTRUMENTATION_MACRO
       
   544 //	IIC_SNOTIFTRIG_START_PSL;
       
   545 #endif
       
   546 	TInt r=KErrNotSupported;
       
   547 	if(aTrigger&EReceive)
       
   548 		{
       
   549 		I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger - prepare hardware for Rx\n"));
       
   550 		r=KErrNone;
       
   551 		}
       
   552 	if(aTrigger&ETransmit)
       
   553 		{
       
   554 		I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger - prepare hardware for Tx\n"));
       
   555 		r=KErrNone;
       
   556 		}
       
   557 	// Check for any additional triggers and make the necessary preparation
       
   558 	// ... do nothing in simulated PSL
       
   559 	r=KErrNone;
       
   560 
       
   561 #ifdef IIC_INSTRUMENTATION_MACRO
       
   562 //	IIC_SNOTIFTRIG_END_PSL;
       
   563 #endif
       
   564 	return r;
       
   565 	}
       
   566 
       
   567 TInt DSimulatedIicBusChannelSlaveI2c::CheckHdr(TDes8* /*aHdr*/)
       
   568 	{
       
   569 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CheckHdr\n"));
       
   570 	return KErrNone;
       
   571 	}
       
   572 
       
   573 TInt DSimulatedIicBusChannelSlaveI2c::DoRequest(TInt aOperation)
       
   574 	{
       
   575 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DoRequest\n"));
       
   576 	TInt r = KErrNone;
       
   577 
       
   578 	switch(aOperation)
       
   579 		{
       
   580 		case(ESyncConfigPwrUp):
       
   581 			{
       
   582 			r=CaptureChannelPsl(EFalse);
       
   583 			break;
       
   584 			};
       
   585 		case(EAsyncConfigPwrUp):
       
   586 			{
       
   587 			r=CaptureChannelPsl(ETrue);
       
   588 			break;
       
   589 			};
       
   590 		case(EPowerDown):
       
   591 			{
       
   592 			r=ReleaseChannelPsl();
       
   593 			break;
       
   594 			};
       
   595 		case(EAbort):
       
   596 			{
       
   597 			break;
       
   598 			};
       
   599 		default:
       
   600 			{
       
   601 			// The remaining operations are to instigate an Rx, Tx or just prepare for
       
   602 			// overrun/underrun/bus error notifications.
       
   603 			// Handle all these, and any unsupported operation in the following function
       
   604 			r=PrepareTrigger(aOperation);
       
   605 			break;
       
   606 			};
       
   607 		}
       
   608 	return r;
       
   609 	}
       
   610 
       
   611 void DSimulatedIicBusChannelSlaveI2c::ProcessData(TInt aTrigger, TIicBusSlaveCallback*  aCb)
       
   612 	{
       
   613 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData\n"));
       
   614 	// fills in iReturn, iRxWords and/or iTxWords
       
   615 	//
       
   616 	if(aTrigger & ERxAllBytes)
       
   617 		{
       
   618 		aCb->SetRxWords(iNumWordsWereRx);
       
   619 		if(iRxTxUnderOverRun & ERxUnderrun)
       
   620 			{
       
   621 			aTrigger|=ERxUnderrun;
       
   622 			iRxTxUnderOverRun&= ~ERxUnderrun;
       
   623 			}
       
   624 		if(iRxTxUnderOverRun & ERxOverrun)
       
   625 			{
       
   626 			aTrigger|=ERxOverrun;
       
   627 			iRxTxUnderOverRun&= ~ERxOverrun;
       
   628 			}
       
   629 		}
       
   630 	if(aTrigger & ETxAllBytes)
       
   631 		{
       
   632 		aCb->SetTxWords(iNumWordsWereTx);
       
   633 		if(iRxTxUnderOverRun & ETxUnderrun)
       
   634 			{
       
   635 			aTrigger|=ETxUnderrun;
       
   636 			iRxTxUnderOverRun&= ~ETxUnderrun;
       
   637 			}
       
   638 		if(iRxTxUnderOverRun & ETxOverrun)
       
   639 			{
       
   640 			aTrigger|=ETxOverrun;
       
   641 			iRxTxUnderOverRun&= ~ETxOverrun;
       
   642 			}
       
   643 		}
       
   644 
       
   645 	aCb->SetTrigger(aTrigger);
       
   646 	}
       
   647 
       
   648 TInt DSimulatedIicBusChannelSlaveI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
       
   649 	{
       
   650 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::StaticExtension\n"));
       
   651 #ifdef IIC_INSTRUMENTATION_MACRO
       
   652 	IIC_SSTATEXT_START_PSL_TRACE;
       
   653 #endif
       
   654 	// Test values of aFunction were shifted left one place by the (test) client driver
       
   655 	// and for Slave values the two msb were cleared
       
   656 	// Return to its original value.
       
   657 	if(aFunction>KTestControlIoPilOffset)
       
   658 		{
       
   659 		aFunction |= 0xC0000000;
       
   660 		aFunction >>= 1;
       
   661 		}
       
   662 	TInt r = KErrNone;
       
   663 	switch(aFunction)
       
   664 		{
       
   665 		case(RBusDevIicClient::ECtlIoDumpChan):
       
   666 			{
       
   667 #ifdef _DEBUG
       
   668 			DumpChannel();
       
   669 #endif
       
   670 			break;
       
   671 			}
       
   672 		case(RBusDevIicClient::ECtlIoDeRegChan):
       
   673 			{
       
   674 #ifndef STANDALONE_CHANNEL
       
   675 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: deregister channel\n"));
       
   676 			// DIicBusController::DeRegisterChannel just removes the channel from the array of channels available 
       
   677 			r=DIicBusController::DeRegisterChannel(this);
       
   678 #else
       
   679 			r = KErrNotSupported;
       
   680 #endif
       
   681 			break;
       
   682 			}
       
   683 
       
   684 		case(RBusDevIicClient::ECtrlIoRxWords):
       
   685 			{
       
   686 			// Simulate receipt of a number of bytes
       
   687 			// aParam1 represents the ChannelId
       
   688 			// aParam2 specifies the number of bytes
       
   689 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxWords, channelId=0x%x, numBytes=0x%x\n",aParam1,aParam2));
       
   690 
       
   691 			// Load the buffer with simulated data
       
   692 			if(iRxBuf == NULL)
       
   693 				{
       
   694 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxWords, ERROR, iRxBuf == NULL\n"));
       
   695 				r=KErrGeneral;
       
   696 				break;
       
   697 				}
       
   698 			// Check for overrun-underrun conditions
       
   699 			TInt trigger=ERxAllBytes;
       
   700 			iNumWordsWereRx=(TInt8)((TInt)aParam2);
       
   701 			iDeltaWordsToRx = (TInt8)(iNumWordsWereRx - iNumRxWords);
       
   702 			if(iDeltaWordsToRx>0)
       
   703 				{
       
   704 				iNumWordsWereRx=iNumRxWords;
       
   705 				iRxTxUnderOverRun |= ERxOverrun;
       
   706 				}
       
   707 			if(iDeltaWordsToRx<0)
       
   708 				iRxTxUnderOverRun |= ERxUnderrun;
       
   709 
       
   710 			TInt8* ptr=(TInt8*)(iRxBuf+iRxOffset);
       
   711 			TInt8 startVal=0x10;
       
   712 			for(TInt8 numWords=0; numWords<iNumWordsWereRx; numWords++,startVal++)
       
   713 				{
       
   714 				for(TInt wordByte=0; wordByte<iRxGranularity; wordByte++,ptr++)
       
   715 					{
       
   716 					*ptr=startVal;
       
   717 					}
       
   718 				}
       
   719 			if(iBlockNotification == EFalse)
       
   720 				{
       
   721 				//
       
   722 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
       
   723 				NotifyClient(trigger);
       
   724 				}
       
   725 			else
       
   726 				{
       
   727 				// Save the trigger value to notify when prompted.
       
   728 				iBlockedTrigger=trigger;
       
   729 				}
       
   730 			break;
       
   731 
       
   732 			}
       
   733 
       
   734 		case(RBusDevIicClient::ECtrlIoUnblockNotification):
       
   735 			{
       
   736 			iBlockNotification=EFalse;
       
   737 			NotifyClient(iBlockedTrigger);
       
   738 			iBlockedTrigger=0;
       
   739 			break;
       
   740 			}
       
   741 
       
   742 		case(RBusDevIicClient::ECtrlIoBlockNotification):
       
   743 			{
       
   744 			iBlockNotification=ETrue;
       
   745 			break;
       
   746 			}
       
   747 
       
   748 		case(RBusDevIicClient::ECtrlIoTxWords):
       
   749 			{
       
   750 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxWords, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
       
   751 			// Simulate transmission of a number of bytes
       
   752 			// aParam1 represents the ChannelId
       
   753 			// aParam2 specifies the number of bytes
       
   754 			// Load the buffer with simulated data
       
   755 			if(iTxBuf == NULL)
       
   756 				{
       
   757 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxWords, ERROR, iTxBuf==NULL\n"));
       
   758 				r=KErrGeneral;
       
   759 				break;
       
   760 				}
       
   761 			// Check for overrun-underrun conditions
       
   762 			TInt trigger=ETxAllBytes;
       
   763 			iNumWordsWereTx=(TInt8)((TInt)aParam2);
       
   764 			iDeltaWordsToTx = (TInt8)(iNumWordsWereTx - iNumTxWords);
       
   765 			if(iDeltaWordsToTx>0)
       
   766 				{
       
   767 				iNumWordsWereTx=iNumTxWords;
       
   768 				iRxTxUnderOverRun |= ETxUnderrun;
       
   769 				}
       
   770 			if(iDeltaWordsToTx<0)
       
   771 				iRxTxUnderOverRun |= ETxOverrun;
       
   772 
       
   773 			// Initialise the check buffer
       
   774 			if(iTxCheckBuf!=NULL)
       
   775 				delete iTxCheckBuf;
       
   776 			// iTxCheckBuf is a member of class DSimulatedIicBusChannelSlaveI2c, which 
       
   777 			// is created here, and deleted not in ~DSimulatedIicBusChannelSlaveI2c()
       
   778 			// but from client side. This is because in t_iic, 
       
   779 			// we put a memory leak checking macro __KHEAP_MARKEND before
       
   780 			// the pdd gets unloaded which will call ~DSimulatedIicBusChannelSlaveI2c().  
       
   781 			// If we delete iTxCheckBuf in ~DSimulatedIicBusChannelSlaveI2c(),
       
   782 			// we will get a memory leak panic in __KHEAP_MARKEND.
       
   783 			// To support the test code, we moved iTxCheckBuf deletion to the client side. 
       
   784 			iTxCheckBuf = new TInt8[iNumTxWords*iTxGranularity];
       
   785 			memset(iTxCheckBuf,0,(iNumTxWords*iTxGranularity));
       
   786 
       
   787 			TInt8* srcPtr=(TInt8*)(iTxBuf+iTxOffset);
       
   788 			TInt8* dstPtr=iTxCheckBuf;
       
   789 			for(TInt8 numWords=0; numWords<iNumWordsWereTx; numWords++)
       
   790 				{
       
   791 				for(TInt wordByte=0; wordByte<iTxGranularity; wordByte++)
       
   792 					*dstPtr++=*srcPtr++;
       
   793 				}
       
   794 			if(iBlockNotification == EFalse)
       
   795 				{
       
   796 				//
       
   797 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
       
   798 				NotifyClient(trigger);
       
   799 				}
       
   800 			else
       
   801 				{
       
   802 				// Save the trigger value to notify when prompted.
       
   803 				iBlockedTrigger=trigger;
       
   804 				}
       
   805 			break;
       
   806 			}
       
   807 
       
   808 		case(RBusDevIicClient::ECtrlIoRxTxWords):
       
   809 			{
       
   810 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
       
   811 			// Simulate transmission of a number of bytes
       
   812 			// aParam1 represents the ChannelId
       
   813 			// aParam2 represents a pointer to the two numbers of bytes
       
   814 			// Check the buffers are available
       
   815 			if(iTxBuf == NULL)
       
   816 				{
       
   817 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, ERROR, iTxBuf==NULL\n"));
       
   818 				r=KErrGeneral;
       
   819 				break;
       
   820 				}
       
   821 			if(iRxBuf == NULL)
       
   822 				{
       
   823 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, ERROR, iRxBuf==NULL\n"));
       
   824 				r=KErrGeneral;
       
   825 				break;
       
   826 				}
       
   827 			// Check for overrun-underrun conditions
       
   828 			TInt trigger=ETxAllBytes|ERxAllBytes;
       
   829 			iNumWordsWereRx=(TInt8)(*(TInt*)aParam2);
       
   830 			TInt* tempPtr=((TInt*)(aParam2));
       
   831 			iNumWordsWereTx=(TInt8)(*(++tempPtr));
       
   832 
       
   833 			iDeltaWordsToTx = (TInt8)(iNumWordsWereTx - iNumTxWords);
       
   834 			if(iDeltaWordsToTx>0)
       
   835 				{
       
   836 				iNumWordsWereTx=iNumTxWords;
       
   837 				iRxTxUnderOverRun |= ETxUnderrun;
       
   838 				}
       
   839 			if(iDeltaWordsToTx<0)
       
   840 				iRxTxUnderOverRun |= ETxOverrun;
       
   841 
       
   842 
       
   843 			iDeltaWordsToRx = (TInt8)(iNumWordsWereRx - iNumRxWords);
       
   844 			if(iDeltaWordsToRx>0)
       
   845 				{
       
   846 				iNumWordsWereRx=iNumRxWords;
       
   847 				iRxTxUnderOverRun |= ERxOverrun;
       
   848 				}
       
   849 			if(iDeltaWordsToRx<0)
       
   850 				iRxTxUnderOverRun |= ERxUnderrun;
       
   851 
       
   852 
       
   853 			// Initialise the buffers
       
   854 			if(iTxCheckBuf!=NULL)
       
   855 				delete iTxCheckBuf;
       
   856 			iTxCheckBuf = new TInt8[iNumTxWords*iTxGranularity];
       
   857 			memset(iTxCheckBuf,0,(iNumTxWords*iTxGranularity));
       
   858 
       
   859 			TInt8* srcPtr=(TInt8*)(iTxBuf+iTxOffset);
       
   860 			TInt8* dstPtr=iTxCheckBuf;
       
   861 			TInt8 numWords=0;
       
   862 			for(numWords=0; numWords<iNumWordsWereTx; numWords++)
       
   863 				{
       
   864 				for(TInt wordByte=0; wordByte<iTxGranularity; wordByte++)
       
   865 					*dstPtr++=*srcPtr++;
       
   866 				}
       
   867 
       
   868 			TInt8* ptr=(TInt8*)(iRxBuf+iRxOffset);
       
   869 			TInt8 startVal=0x10;
       
   870 			for(numWords=0; numWords<iNumWordsWereRx; numWords++,startVal++)
       
   871 				{
       
   872 				for(TInt wordByte=0; wordByte<iRxGranularity; wordByte++,ptr++)
       
   873 					{
       
   874 					*ptr=startVal;
       
   875 					}
       
   876 				}		
       
   877 			
       
   878 			if(iBlockNotification == EFalse)
       
   879 				{
       
   880 				//
       
   881 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
       
   882 				NotifyClient(trigger);
       
   883 				}
       
   884 			else
       
   885 				{
       
   886 				// Save the trigger value to notify when prompted.
       
   887 				iBlockedTrigger=trigger;
       
   888 				}
       
   889 			break;
       
   890 			}
       
   891 
       
   892 		case(RBusDevIicClient::ECtrlIoTxChkBuf):
       
   893 			{
       
   894 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxChkBuf, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
       
   895 			// Return the address of iTxCheckBuf to the address pointed to by a1
       
   896 			// Both the simulated bus channel and the slave client are resident in the client process
       
   897 			// so the client can use the pointer value for direct access
       
   898 			TInt8** ptr = (TInt8**)aParam1;
       
   899 			*ptr=iTxCheckBuf;
       
   900 			break;
       
   901 			}
       
   902 
       
   903 		case(RBusDevIicClient::ECtlIoBusError):
       
   904 			{
       
   905 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtlIoBusError\n"));
       
   906 			NotifyClient(EGeneralBusError);
       
   907 			break;
       
   908 			}
       
   909 
       
   910 		case(RBusDevIicClient::ECtrlIoUpdTimeout):
       
   911 			{
       
   912 			// For this test, do the following for the Master and Client timeout values:
       
   913 			// (1) Read the current timeout value and check that it is set to the default
       
   914 			// (2) Check setting to a neagtive value fails
       
   915 			// (3) Set it to a new, different value
       
   916 			// (4) Read it back to check success
       
   917 			// (5) Return to the original value, and readback to confirm
       
   918 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c ECtrlIoUpdTimeout \n"));
       
   919 
       
   920 			TInt timeout = 0;
       
   921 			TInt r=KErrNone;
       
   922 			// Master timeout
       
   923 			timeout=GetMasterWaitTime();
       
   924 			if(timeout!=KSlaveDefMWaitTime)
       
   925 				{
       
   926 				I2C_PRINT(("ERROR: Initial Master Wait time != KSlaveDefMWaitTime (=%d) \n",timeout));
       
   927 				return KErrGeneral;
       
   928 				}
       
   929 			r=SetMasterWaitTime(-1);
       
   930 			if(r!=KErrArgument)
       
   931 				{
       
   932 				I2C_PRINT(("ERROR: Attempt to set negative Master wait time not rejected\n"));
       
   933 				return KErrGeneral;
       
   934 				}
       
   935 			r=SetMasterWaitTime(KSlaveDefCWaitTime);
       
   936 			if(r!=KErrNone)
       
   937 				{
       
   938 				I2C_PRINT(("ERROR: Attempt to set new valid Master wait time (%d) rejected\n",KSlaveDefCWaitTime));
       
   939 				return KErrGeneral;
       
   940 				}
       
   941 			timeout=GetMasterWaitTime();
       
   942 			if(timeout!=KSlaveDefCWaitTime)
       
   943 				{
       
   944 				I2C_PRINT(("ERROR: Master Wait time read back has unexpected value (=%d) \n",timeout));
       
   945 				return KErrGeneral;
       
   946 				}
       
   947 			r=SetMasterWaitTime(KSlaveDefMWaitTime);
       
   948 			if(r!=KErrNone)
       
   949 				{
       
   950 				I2C_PRINT(("ERROR: Attempt to set reset Master wait time (%d) rejected\n",KSlaveDefMWaitTime));
       
   951 				return KErrGeneral;
       
   952 				}
       
   953 			timeout=GetMasterWaitTime();
       
   954 			if(timeout!=KSlaveDefMWaitTime)
       
   955 				{
       
   956 				I2C_PRINT(("ERROR: Master Wait time read back of reset time has unexpected value (=%d) \n",timeout));
       
   957 				return KErrGeneral;
       
   958 				}
       
   959 			// Client timeout
       
   960 			timeout=GetClientWaitTime();
       
   961 			if(timeout!=KSlaveDefCWaitTime)
       
   962 				{
       
   963 				I2C_PRINT(("ERROR: Initial Client Wait time != KSlaveDefCWaitTime (=%d) \n",timeout));
       
   964 				return KErrGeneral;
       
   965 				}
       
   966 			r=SetClientWaitTime(-1);
       
   967 			if(r!=KErrArgument)
       
   968 				{
       
   969 				I2C_PRINT(("ERROR: Attempt to set negative Client wait time not rejected\n"));
       
   970 				return KErrGeneral;
       
   971 				}
       
   972 			r=SetClientWaitTime(KSlaveDefMWaitTime+1);
       
   973 			if(r!=KErrNone)
       
   974 				{
       
   975 				I2C_PRINT(("ERROR: Attempt to set new valid Client wait time (%d) rejected\n",KSlaveDefMWaitTime));
       
   976 				return KErrGeneral;
       
   977 				}
       
   978 			timeout=GetClientWaitTime();
       
   979 			if(timeout!=KSlaveDefMWaitTime+1)
       
   980 				{
       
   981 				I2C_PRINT(("ERROR: Client Wait time read back has unexpected value (=%d) \n",timeout));
       
   982 				return KErrGeneral;
       
   983 				}
       
   984 			r=SetClientWaitTime(KSlaveDefCWaitTime);
       
   985 			if(r!=KErrNone)
       
   986 				{
       
   987 				I2C_PRINT(("ERROR: Attempt to set reset Client wait time (%d) rejected\n",KSlaveDefCWaitTime));
       
   988 				return KErrGeneral;
       
   989 				}
       
   990 			timeout=GetClientWaitTime();
       
   991 			if(timeout!=KSlaveDefCWaitTime)
       
   992 				{
       
   993 				I2C_PRINT(("ERROR: Client Wait time read back of reset time has unexpected value (=%d) \n",timeout));
       
   994 				return KErrGeneral;
       
   995 				}
       
   996 			break;
       
   997 			}
       
   998 
       
   999 		default:
       
  1000 			{
       
  1001 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
       
  1002 			r=KErrNotSupported;
       
  1003 			}
       
  1004 		}
       
  1005 #ifdef IIC_INSTRUMENTATION_MACRO
       
  1006 	IIC_SSTATEXT_END_PSL_TRACE;
       
  1007 #endif
       
  1008 	return r;
       
  1009 	}
       
  1010 
       
  1011 
       
  1012 
       
  1013 //#ifdef MASTER_MODE
       
  1014 #endif
       
  1015 
       
  1016 #if defined(MASTER_MODE) && defined(SLAVE_MODE)
       
  1017 #ifdef STANDALONE_CHANNEL
       
  1018 EXPORT_C
       
  1019 #endif
       
  1020 DSimulatedIicBusChannelMasterSlaveI2c::DSimulatedIicBusChannelMasterSlaveI2c(TBusType /*aBusType*/, TChannelDuplex aChanDuplex, DSimulatedIicBusChannelMasterI2c* aMasterChan, DSimulatedIicBusChannelSlaveI2c* aSlaveChan)
       
  1021 	: DIicBusChannelMasterSlave(EI2c, aChanDuplex, aMasterChan, aSlaveChan)
       
  1022 	{}
       
  1023 
       
  1024 TInt DSimulatedIicBusChannelMasterSlaveI2c::StaticExtension(TUint aFunction, TAny* /*aParam1*/, TAny* /*aParam2*/)
       
  1025 	{
       
  1026 	I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::StaticExtension, aFunction=0x%x\n",aFunction));
       
  1027 	TInt r = KErrNone;
       
  1028 
       
  1029 	// Test values of aFunction were shifted left one place by the (test) client driver
       
  1030 	// Return to its original value.
       
  1031 	if(aFunction>KTestControlIoPilOffset)
       
  1032 		aFunction >>= 1;
       
  1033 	switch(aFunction)
       
  1034 		{
       
  1035 		case(RBusDevIicClient::ECtlIoDumpChan):
       
  1036 			{
       
  1037 #ifdef _DEBUG
       
  1038 			DumpChannel();
       
  1039 #endif
       
  1040 			break;
       
  1041 			}
       
  1042 		case(RBusDevIicClient::ECtlIoDeRegChan):
       
  1043 			{
       
  1044 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c: deregister channel\n"));
       
  1045 #ifndef STANDALONE_CHANNEL
       
  1046 			r=DIicBusController::DeRegisterChannel(this);
       
  1047 #else
       
  1048 			return KErrNotSupported;
       
  1049 #endif
       
  1050 			break;
       
  1051 			}
       
  1052 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
       
  1053 			{
       
  1054 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::Blocking request completion\n"));
       
  1055 			((DSimulatedIicBusChannelMasterI2c*)iMasterChannel)->SetRequestDelayed(((DSimulatedIicBusChannelMasterI2c*)iMasterChannel), ETrue);
       
  1056 			break;
       
  1057 			}
       
  1058 		case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
       
  1059 			{
       
  1060 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::Unlocking request completion\n"));
       
  1061 			((DSimulatedIicBusChannelMasterI2c*)iMasterChannel)->SetRequestDelayed(((DSimulatedIicBusChannelMasterI2c*)iMasterChannel), EFalse);
       
  1062 			break;
       
  1063 			}
       
  1064 		default:
       
  1065 			{
       
  1066 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
       
  1067 			r=KErrNotSupported;
       
  1068 			}
       
  1069 		}
       
  1070 	return r;
       
  1071 	}
       
  1072 
       
  1073 
       
  1074 //#if defined(MASTER_MODE) && defined(SLAVE_MODE)
       
  1075 #endif
       
  1076 
       
  1077 
       
  1078