Update contrib.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test/iic/iic_psl/I2c.cpp
19 #ifdef IIC_INSTRUMENTATION_MACRO
20 #include <drivers/iic_trace.h>
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};
29 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::ESlave, DIicBusChannel::ESlave, DIicBusChannel::ESlave};
31 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])
32 #define CHANNEL_DUPLEX(n) (DIicBusChannel::EHalfDuplex)
34 #ifdef STANDALONE_CHANNEL
35 _LIT(KPddNameI2c,"i2c_ctrless.pdd");
37 _LIT(KPddNameI2c,"i2c.pdd");
40 #ifndef STANDALONE_CHANNEL
41 LOCAL_C TInt8 AssignChanNum()
43 static TInt8 iBaseChanNum = KI2cChannelNumBase;
44 I2C_PRINT(("I2C AssignChanNum - on entry, iBaseChanNum = 0x%x\n",iBaseChanNum));
45 return iBaseChanNum++; // Arbitrary, for illustration
47 #endif/*STANDALONE_CHANNEL*/
50 LOCAL_C TInt16 AssignSlaveChanId()
52 static TInt16 iBaseSlaveChanId = KI2cSlaveChannelIdBase;
53 I2C_PRINT(("I2C AssignSlaveChanId - on entry, iBaseSlaveChanId = 0x%x\n",iBaseSlaveChanId));
54 return iBaseSlaveChanId++; // Arbitrary, for illustration
58 NONSHARABLE_CLASS(DSimulatedI2cDevice) : public DPhysicalDevice
60 // Class to faciliate loading of the IIC classes
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();
76 TVersion DSimulatedI2cDevice::VersionRequired()
78 I2C_PRINT(("DSimulatedI2cDevice::VersionRequired\n"));
79 return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber);
82 /** Factory class constructor */
83 DSimulatedI2cDevice::DSimulatedI2cDevice()
85 I2C_PRINT(("DSimulatedI2cDevice::DSimulatedI2cDevice\n"));
86 iVersion = DSimulatedI2cDevice::VersionRequired();
89 TInt DSimulatedI2cDevice::Install()
91 I2C_PRINT(("DSimulatedI2cDevice::Install\n"));
92 return(SetName(&KPddNameI2c));
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*/)
98 I2C_PRINT(("DSimulatedI2cDevice::Create\n"));
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)
105 I2C_PRINT(("DSimulatedI2cDevice::Validate\n"));
106 if (!Kern::QueryVersionSupported(DSimulatedI2cDevice::VersionRequired(),aVer))
107 return(KErrNotSupported);
111 /** Return the driver capabilities */
112 void DSimulatedI2cDevice::GetCaps(TDes8& aDes) const
114 I2C_PRINT(("DSimulatedI2cDevice::GetCaps\n"));
115 // Create a capabilities object
117 caps.iVersion = iVersion;
119 TInt maxLen = aDes.MaxLength();
122 TInt size=sizeof(caps);
125 aDes.Copy((TUint8*)&caps,size);
128 // supported channels for this implementation
129 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
132 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)
133 DECLARE_STANDARD_PDD() // I2c test driver to be explicitly loaded as an LDD, not kernel extension
135 #ifndef STANDALONE_CHANNEL
136 DIicBusChannel* chan=NULL;
137 for(TInt i=0; i<NUM_CHANNELS; i++)
140 #if defined(MASTER_MODE)
141 if(CHANNEL_TYPE(i) == (DIicBusChannel::EMaster))
143 chan=new DSimulatedIicBusChannelMasterI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
146 I2C_PRINT(("I2C chan created at 0x%x\n",chan));
147 if(((DSimulatedIicBusChannelMasterI2c*)chan)->Create()!=KErrNone)
154 #if defined(MASTER_MODE) && defined(SLAVE_MODE)
155 if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave)
157 DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
160 DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
166 // For MasterSlave channel, the channel number for both the Master and Slave channels must be the same
167 TInt8 msChanNum = ((DSimulatedIicBusChannelMasterI2c*)chanM)->GetChanNum();
168 ((DSimulatedIicBusChannelSlaveI2c*)chanS)->SetChanNum(msChanNum);
170 chan=new DSimulatedIicBusChannelMasterSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i),(DSimulatedIicBusChannelMasterI2c*)chanM,(DSimulatedIicBusChannelSlaveI2c*)chanS); // Generic implementation
177 I2C_PRINT(("I2C chan created at 0x%x\n",chan));
178 if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone)
187 #if defined(SLAVE_MODE)
188 if(CHANNEL_TYPE(i) == (DIicBusChannel::ESlave))
190 chan=new DSimulatedIicBusChannelSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
193 I2C_PRINT(("I2C chan created at 0x%x\n",chan));
194 if(((DSimulatedIicBusChannelSlaveI2c*)chan)->Create()!=KErrNone)
201 #if !defined(MASTER_MODE) && !defined(SLAVE_MODE)
202 #error I2C mode not defined as Master, Slave nor Master-Slave
206 I2C_PRINT(("\n\nI2C: Channel of type (%d) not created for index %d\n\n",CHANNEL_TYPE(i),i));
209 ChannelPtrArray[i]=chan;
211 I2C_PRINT(("\nI2C PDD, channel creation loop done- about to invoke RegisterChannels\n\n"));
212 #ifdef IIC_INSTRUMENTATION_MACRO
213 IIC_REGISTERCHANS_START_PSL_TRACE;
216 TInt r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS);
218 #ifdef IIC_INSTRUMENTATION_MACRO
219 IIC_REGISTERCHANS_END_PSL_TRACE;
221 I2C_PRINT(("\nI2C - returned from RegisterChannels with r=%d\n",r));
228 return new DSimulatedI2cDevice;
233 #ifdef STANDALONE_CHANNEL
236 DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c(const TBusType aBusType, const TChannelDuplex aChanDuplex)
237 : DIicBusChannelMaster(aBusType,aChanDuplex)
239 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
240 #ifndef STANDALONE_CHANNEL
241 iChannelNumber = AssignChanNum();
243 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c, iChannelNumber=%d\n",iChannelNumber));
246 TInt DSimulatedIicBusChannelMasterI2c::DoCreate()
248 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoCreate\n"));
249 TInt r=Init(); // PIL Base class initialisation
250 r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KI2cThreadPriority,KI2cThreadName);
252 SetDfcQ((TDfcQue*)iDynamicDfcQ);
253 DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(this,EFalse);
257 TInt DSimulatedIicBusChannelMasterI2c::CheckHdr(TDes8* aHdr)
259 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr\n"));
261 TConfigI2cBufV01* i2cBuf = (TConfigI2cBufV01*)aHdr;
262 TConfigI2cV01* i2cPtr = &((*i2cBuf)());
264 // Check that the values for address type, clock speed, user operation and endianness are recognised
265 if((i2cPtr->iAddrType < 0) || (i2cPtr->iAddrType > EI2cAddr10Bit))
267 I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr unrecognised address type identifier %d\n",i2cPtr->iAddrType));
270 if(i2cPtr->iClkSpeedHz < 0)
272 I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr negative clock speed specified %d\n",i2cPtr->iClkSpeedHz));
275 if((i2cPtr->iEndianness < 0) || (i2cPtr->iEndianness > ELittleEndian))
277 I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr unrecognised endianness identifier %d\n",i2cPtr->iEndianness));
280 // Values for the timeout period are arbitrary - can only check it is not a negative value
281 if(i2cPtr->iTimeoutPeriod < 0)
283 I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr negative timeout period %d\n",i2cPtr->iTimeoutPeriod));
286 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr address type = %d\n",i2cPtr->iAddrType));
287 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr clock speed ID = %d\n",i2cPtr->iClkSpeedHz));
288 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr iEndianness ID = %d\n",i2cPtr->iEndianness));
289 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr iTimeoutPeriod = %d\n",i2cPtr->iTimeoutPeriod));
293 // Gateway function for PSL implementation, invoked for DFC processing
294 TInt DSimulatedIicBusChannelMasterI2c::DoRequest(TIicBusTransaction* aTransaction)
296 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest invoked with aTransaction=0x%x\n",aTransaction));
299 #ifdef IIC_INSTRUMENTATION_MACRO
300 IIC_MPROCESSTRANS_START_PSL_TRACE;
303 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iHeader=0x%x\n",GetTransactionHeader(aTransaction)));
304 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(aTransaction)));
305 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(aTransaction)));
306 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iCallback=0x%x\n",GetTransCallback(aTransaction)));
307 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iFlags=0x%x\n",GetTransFlags(aTransaction)));
309 I2C_PRINT(("\nDSimulatedIicBusChannelMasterI2c::DoRequest, iHeader info \n"));
310 TDes8* bufPtr = GetTransactionHeader(aTransaction);
313 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest ERROR - NULL header\n"));
316 TConfigI2cV01 *buf = (TConfigI2cV01 *)(bufPtr->Ptr());
317 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header address type=0x%x\n",buf->iAddrType));
318 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header clock speed=0x%x\n",buf->iClkSpeedHz));
319 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header endianness=0x%x\n",buf->iEndianness));
320 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header timeout period=0x%x\n",buf->iTimeoutPeriod));
321 (void)buf; // Silence compiler when I2C_PRINT not used
323 TInt aTime=1000000/NKern::TickPeriod();
324 r = StartSlaveTimeOutTimer(aTime);
325 I2C_PRINT(("\nDSimulatedIicBusChannelMasterI2c::ProcessTrans, iHalfDuplexTrans info \n"));
326 TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(aTransaction);
327 while(halfDuplexPtr != NULL)
329 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans transfer type=0x%x\n",GetTferType(halfDuplexPtr)));
330 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr)));
331 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr)));
332 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr)));
333 halfDuplexPtr=GetTferNextTfer(halfDuplexPtr);
335 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - End of iHalfDuplexTrans info"));
337 while(IsRequestDelayed(this))
339 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - starting Sleep...\n"));
340 NKern::Sleep(1000); // 1000 is arbitrary
341 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - completed Sleep, check if still delayed\n"));
344 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - exiting\n"));
350 TBool DSimulatedIicBusChannelMasterI2c::IsRequestDelayed(DSimulatedIicBusChannelMasterI2c* aChan)
352 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::IsRequestDelayed invoked for aChan=0x%x\n",aChan));
353 return aChan->iReqDelayed;
356 void DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(DSimulatedIicBusChannelMasterI2c* aChan,TBool aDelay)
358 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay));
359 aChan->iReqDelayed=aDelay;
362 TInt DSimulatedIicBusChannelMasterI2c::HandleSlaveTimeout()
364 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::HandleSlaveTimeout invoked for this=0x%x\n",this));
368 TInt DSimulatedIicBusChannelMasterI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
370 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::StaticExtension\n"));
372 #ifdef IIC_INSTRUMENTATION_MACRO
373 IIC_MSTATEXT_START_PSL_TRACE;
378 // Test values of aFunction were shifted left one place by the (test) client driver
379 // Return to its original value.
380 if(aFunction>KTestControlIoPilOffset)
384 case(RBusDevIicClient::ECtlIoDumpChan):
391 case(RBusDevIicClient::ECtlIoBlockReqCompletion):
393 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::Blocking request completion\n"));
394 SetRequestDelayed(this, ETrue);
397 case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
399 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::Unlocking request completion\n"));
400 SetRequestDelayed(this, EFalse);
403 case(RBusDevIicClient::ECtlIoDeRegChan):
405 #ifndef STANDALONE_CHANNEL
406 #ifdef IIC_INSTRUMENTATION_MACRO
407 IIC_DEREGISTERCHAN_START_PSL_TRACE;
409 I2C_PRINT(("DSimulatedIicBusChannelMasterI2c: deregister channel\n"));
410 r=DIicBusController::DeRegisterChannel(this);
412 #ifdef IIC_INSTRUMENTATION_MACRO
413 IIC_DEREGISTERCHAN_END_PSL_TRACE;
414 #endif/*IIC_INSTRUMENTATION_MACRO*/
416 #else/*STANDALONE_CHANNEL*/
417 r = KErrNotSupported;
418 #endif/*STANDALONE_CHANNEL*/
423 Kern::Printf("aFunction %d is not recognised \n",aFunction);
428 #ifdef IIC_INSTRUMENTATION_MACRO
429 IIC_MSTATEXT_END_PSL_TRACE;
439 void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr)
441 // To support simulating an asynchronous capture operation
442 // NOTE: this will be invoked in the context of DfcThread1
443 I2C_PRINT(("SlaveAsyncSimCallback\n"));
444 DSimulatedIicBusChannelSlaveI2c* channel = (DSimulatedIicBusChannelSlaveI2c*)aPtr;
445 TInt r=KErrNone;// Just simulate successful capture
446 #ifdef IIC_INSTRUMENTATION_MACRO
447 IIC_SCAPTCHANASYNC_END_PSL_TRACE;
449 channel->ChanCaptureCb(r);
452 #ifdef STANDALONE_CHANNEL
455 DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
456 : DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
457 iBlockedTrigger(0),iBlockNotification(EFalse),
458 iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this)
460 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
461 #ifndef STANDALONE_CHANNEL
462 iChannelNumber = AssignChanNum();
464 iChannelId = AssignSlaveChanId();
465 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, iChannelNumber=%d, iChannelId=0x%x\n",iChannelNumber,iChannelId));
468 DSimulatedIicBusChannelSlaveI2c::~DSimulatedIicBusChannelSlaveI2c()
470 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::~DSimulatedIicBusChannelSlaveI2c\n"));
473 TInt DSimulatedIicBusChannelSlaveI2c::DoCreate()
475 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DoCreate\n"));
476 TInt r=Init(); // PIL Base class initialisation
481 TInt DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl(TBool aAsynch)
483 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl\n"));
487 #ifdef IIC_INSTRUMENTATION_MACRO
488 IIC_SCAPTCHANASYNC_START_PSL_TRACE;
490 // To simulate an asynchronous capture operation, just set a timer to expire
491 iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
495 #ifdef IIC_INSTRUMENTATION_MACRO
496 IIC_SCAPTCHANSYNC_START_PSL_TRACE;
498 // PSL processing would happen here ...
499 // Expected to include implementation of the header configuration information
501 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl (synchronous) ... no real processing to do \n"));
503 #ifdef IIC_INSTRUMENTATION_MACRO
504 IIC_SCAPTCHANSYNC_END_PSL_TRACE;
511 TInt DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl()
513 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl\n"));
514 #ifdef IIC_INSTRUMENTATION_MACRO
515 IIC_SRELCHAN_START_PSL_TRACE;
519 // PSL-specific processing would happen here ...
520 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl ... no real processing to do \n"));
522 #ifdef IIC_INSTRUMENTATION_MACRO
523 IIC_SRELCHAN_END_PSL_TRACE;
530 TInt DSimulatedIicBusChannelSlaveI2c::PrepareTrigger(TInt aTrigger)
532 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger\n"));
533 #ifdef IIC_INSTRUMENTATION_MACRO
534 // IIC_SNOTIFTRIG_START_PSL;
536 TInt r=KErrNotSupported;
537 if(aTrigger&EReceive)
539 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger - prepare hardware for Rx\n"));
542 if(aTrigger&ETransmit)
544 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger - prepare hardware for Tx\n"));
547 // Check for any additional triggers and make the necessary preparation
548 // ... do nothing in simulated PSL
551 #ifdef IIC_INSTRUMENTATION_MACRO
552 // IIC_SNOTIFTRIG_END_PSL;
557 TInt DSimulatedIicBusChannelSlaveI2c::CheckHdr(TDes8* /*aHdr*/)
559 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CheckHdr\n"));
563 TInt DSimulatedIicBusChannelSlaveI2c::DoRequest(TInt aOperation)
565 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DoRequest\n"));
570 case(ESyncConfigPwrUp):
572 r=CaptureChannelPsl(EFalse);
575 case(EAsyncConfigPwrUp):
577 r=CaptureChannelPsl(ETrue);
582 r=ReleaseChannelPsl();
591 // The remaining operations are to instigate an Rx, Tx or just prepare for
592 // overrun/underrun/bus error notifications.
593 // Handle all these, and any unsupported operation in the following function
594 r=PrepareTrigger(aOperation);
601 void DSimulatedIicBusChannelSlaveI2c::ProcessData(TInt aTrigger, TIicBusSlaveCallback* aCb)
603 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData\n"));
604 // fills in iReturn, iRxWords and/or iTxWords
606 if(aTrigger & ERxAllBytes)
608 aCb->SetRxWords(iNumWordsWereRx);
609 if(iRxTxUnderOverRun & ERxUnderrun)
611 aTrigger|=ERxUnderrun;
612 iRxTxUnderOverRun&= ~ERxUnderrun;
614 if(iRxTxUnderOverRun & ERxOverrun)
616 aTrigger|=ERxOverrun;
617 iRxTxUnderOverRun&= ~ERxOverrun;
620 if(aTrigger & ETxAllBytes)
622 aCb->SetTxWords(iNumWordsWereTx);
623 if(iRxTxUnderOverRun & ETxUnderrun)
625 aTrigger|=ETxUnderrun;
626 iRxTxUnderOverRun&= ~ETxUnderrun;
628 if(iRxTxUnderOverRun & ETxOverrun)
630 aTrigger|=ETxOverrun;
631 iRxTxUnderOverRun&= ~ETxOverrun;
635 aCb->SetTrigger(aTrigger);
638 TInt DSimulatedIicBusChannelSlaveI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
640 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::StaticExtension\n"));
641 #ifdef IIC_INSTRUMENTATION_MACRO
642 IIC_SSTATEXT_START_PSL_TRACE;
644 // Test values of aFunction were shifted left one place by the (test) client driver
645 // and for Slave values the two msb were cleared
646 // Return to its original value.
647 if(aFunction>KTestControlIoPilOffset)
649 aFunction |= 0xC0000000;
655 case(RBusDevIicClient::ECtlIoDumpChan):
662 case(RBusDevIicClient::ECtlIoDeRegChan):
664 #ifndef STANDALONE_CHANNEL
665 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: deregister channel\n"));
666 // DIicBusController::DeRegisterChannel just removes the channel from the array of channels available
667 r=DIicBusController::DeRegisterChannel(this);
669 r = KErrNotSupported;
674 case(RBusDevIicClient::ECtrlIoRxWords):
676 // Simulate receipt of a number of bytes
677 // aParam1 represents the ChannelId
678 // aParam2 specifies the number of bytes
679 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxWords, channelId=0x%x, numBytes=0x%x\n",aParam1,aParam2));
681 // Load the buffer with simulated data
684 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxWords, ERROR, iRxBuf == NULL\n"));
688 // Check for overrun-underrun conditions
689 TInt trigger=ERxAllBytes;
690 iNumWordsWereRx=(TInt8)((TInt)aParam2);
691 iDeltaWordsToRx = (TInt8)(iNumWordsWereRx - iNumRxWords);
692 if(iDeltaWordsToRx>0)
694 iNumWordsWereRx=iNumRxWords;
695 iRxTxUnderOverRun |= ERxOverrun;
697 if(iDeltaWordsToRx<0)
698 iRxTxUnderOverRun |= ERxUnderrun;
700 TInt8* ptr=(TInt8*)(iRxBuf+iRxOffset);
702 for(TInt8 numWords=0; numWords<iNumWordsWereRx; numWords++,startVal++)
704 for(TInt wordByte=0; wordByte<iRxGranularity; wordByte++,ptr++)
709 if(iBlockNotification == EFalse)
712 // Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
713 NotifyClient(trigger);
717 // Save the trigger value to notify when prompted.
718 iBlockedTrigger=trigger;
724 case(RBusDevIicClient::ECtrlIoUnblockNotification):
726 iBlockNotification=EFalse;
727 NotifyClient(iBlockedTrigger);
732 case(RBusDevIicClient::ECtrlIoBlockNotification):
734 iBlockNotification=ETrue;
738 case(RBusDevIicClient::ECtrlIoTxWords):
740 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxWords, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
741 // Simulate transmission of a number of bytes
742 // aParam1 represents the ChannelId
743 // aParam2 specifies the number of bytes
744 // Load the buffer with simulated data
747 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxWords, ERROR, iTxBuf==NULL\n"));
751 // Check for overrun-underrun conditions
752 TInt trigger=ETxAllBytes;
753 iNumWordsWereTx=(TInt8)((TInt)aParam2);
754 iDeltaWordsToTx = (TInt8)(iNumWordsWereTx - iNumTxWords);
755 if(iDeltaWordsToTx>0)
757 iNumWordsWereTx=iNumTxWords;
758 iRxTxUnderOverRun |= ETxUnderrun;
760 if(iDeltaWordsToTx<0)
761 iRxTxUnderOverRun |= ETxOverrun;
763 // Initialise the check buffer
764 if(iTxCheckBuf!=NULL)
766 // iTxCheckBuf is a member of class DSimulatedIicBusChannelSlaveI2c, which
767 // is created here, and deleted not in ~DSimulatedIicBusChannelSlaveI2c()
768 // but from client side. This is because in t_iic,
769 // we put a memory leak checking macro __KHEAP_MARKEND before
770 // the pdd gets unloaded which will call ~DSimulatedIicBusChannelSlaveI2c().
771 // If we delete iTxCheckBuf in ~DSimulatedIicBusChannelSlaveI2c(),
772 // we will get a memory leak panic in __KHEAP_MARKEND.
773 // To support the test code, we moved iTxCheckBuf deletion to the client side.
774 iTxCheckBuf = new TInt8[iNumTxWords*iTxGranularity];
775 memset(iTxCheckBuf,0,(iNumTxWords*iTxGranularity));
777 TInt8* srcPtr=(TInt8*)(iTxBuf+iTxOffset);
778 TInt8* dstPtr=iTxCheckBuf;
779 for(TInt8 numWords=0; numWords<iNumWordsWereTx; numWords++)
781 for(TInt wordByte=0; wordByte<iTxGranularity; wordByte++)
784 if(iBlockNotification == EFalse)
787 // Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
788 NotifyClient(trigger);
792 // Save the trigger value to notify when prompted.
793 iBlockedTrigger=trigger;
798 case(RBusDevIicClient::ECtrlIoRxTxWords):
800 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
801 // Simulate transmission of a number of bytes
802 // aParam1 represents the ChannelId
803 // aParam2 represents a pointer to the two numbers of bytes
804 // Check the buffers are available
807 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, ERROR, iTxBuf==NULL\n"));
813 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, ERROR, iRxBuf==NULL\n"));
817 // Check for overrun-underrun conditions
818 TInt trigger=ETxAllBytes|ERxAllBytes;
819 iNumWordsWereRx=(TInt8)(*(TInt*)aParam2);
820 TInt* tempPtr=((TInt*)(aParam2));
821 iNumWordsWereTx=(TInt8)(*(++tempPtr));
823 iDeltaWordsToTx = (TInt8)(iNumWordsWereTx - iNumTxWords);
824 if(iDeltaWordsToTx>0)
826 iNumWordsWereTx=iNumTxWords;
827 iRxTxUnderOverRun |= ETxUnderrun;
829 if(iDeltaWordsToTx<0)
830 iRxTxUnderOverRun |= ETxOverrun;
833 iDeltaWordsToRx = (TInt8)(iNumWordsWereRx - iNumRxWords);
834 if(iDeltaWordsToRx>0)
836 iNumWordsWereRx=iNumRxWords;
837 iRxTxUnderOverRun |= ERxOverrun;
839 if(iDeltaWordsToRx<0)
840 iRxTxUnderOverRun |= ERxUnderrun;
843 // Initialise the buffers
844 if(iTxCheckBuf!=NULL)
846 iTxCheckBuf = new TInt8[iNumTxWords*iTxGranularity];
847 memset(iTxCheckBuf,0,(iNumTxWords*iTxGranularity));
849 TInt8* srcPtr=(TInt8*)(iTxBuf+iTxOffset);
850 TInt8* dstPtr=iTxCheckBuf;
852 for(numWords=0; numWords<iNumWordsWereTx; numWords++)
854 for(TInt wordByte=0; wordByte<iTxGranularity; wordByte++)
858 TInt8* ptr=(TInt8*)(iRxBuf+iRxOffset);
860 for(numWords=0; numWords<iNumWordsWereRx; numWords++,startVal++)
862 for(TInt wordByte=0; wordByte<iRxGranularity; wordByte++,ptr++)
868 if(iBlockNotification == EFalse)
871 // Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
872 NotifyClient(trigger);
876 // Save the trigger value to notify when prompted.
877 iBlockedTrigger=trigger;
882 case(RBusDevIicClient::ECtrlIoTxChkBuf):
884 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxChkBuf, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
885 // Return the address of iTxCheckBuf to the address pointed to by a1
886 // Both the simulated bus channel and the slave client are resident in the client process
887 // so the client can use the pointer value for direct access
888 TInt8** ptr = (TInt8**)aParam1;
893 case(RBusDevIicClient::ECtlIoBusError):
895 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtlIoBusError\n"));
896 NotifyClient(EGeneralBusError);
900 case(RBusDevIicClient::ECtrlIoUpdTimeout):
902 // For this test, do the following for the Master and Client timeout values:
903 // (1) Read the current timeout value and check that it is set to the default
904 // (2) Check setting to a neagtive value fails
905 // (3) Set it to a new, different value
906 // (4) Read it back to check success
907 // (5) Return to the original value, and readback to confirm
908 I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c ECtrlIoUpdTimeout \n"));
913 timeout=GetMasterWaitTime();
914 if(timeout!=KSlaveDefMWaitTime)
916 I2C_PRINT(("ERROR: Initial Master Wait time != KSlaveDefMWaitTime (=%d) \n",timeout));
919 r=SetMasterWaitTime(-1);
922 I2C_PRINT(("ERROR: Attempt to set negative Master wait time not rejected\n"));
925 r=SetMasterWaitTime(KSlaveDefCWaitTime);
928 I2C_PRINT(("ERROR: Attempt to set new valid Master wait time (%d) rejected\n",KSlaveDefCWaitTime));
931 timeout=GetMasterWaitTime();
932 if(timeout!=KSlaveDefCWaitTime)
934 I2C_PRINT(("ERROR: Master Wait time read back has unexpected value (=%d) \n",timeout));
937 r=SetMasterWaitTime(KSlaveDefMWaitTime);
940 I2C_PRINT(("ERROR: Attempt to set reset Master wait time (%d) rejected\n",KSlaveDefMWaitTime));
943 timeout=GetMasterWaitTime();
944 if(timeout!=KSlaveDefMWaitTime)
946 I2C_PRINT(("ERROR: Master Wait time read back of reset time has unexpected value (=%d) \n",timeout));
950 timeout=GetClientWaitTime();
951 if(timeout!=KSlaveDefCWaitTime)
953 I2C_PRINT(("ERROR: Initial Client Wait time != KSlaveDefCWaitTime (=%d) \n",timeout));
956 r=SetClientWaitTime(-1);
959 I2C_PRINT(("ERROR: Attempt to set negative Client wait time not rejected\n"));
962 r=SetClientWaitTime(KSlaveDefMWaitTime+1);
965 I2C_PRINT(("ERROR: Attempt to set new valid Client wait time (%d) rejected\n",KSlaveDefMWaitTime));
968 timeout=GetClientWaitTime();
969 if(timeout!=KSlaveDefMWaitTime+1)
971 I2C_PRINT(("ERROR: Client Wait time read back has unexpected value (=%d) \n",timeout));
974 r=SetClientWaitTime(KSlaveDefCWaitTime);
977 I2C_PRINT(("ERROR: Attempt to set reset Client wait time (%d) rejected\n",KSlaveDefCWaitTime));
980 timeout=GetClientWaitTime();
981 if(timeout!=KSlaveDefCWaitTime)
983 I2C_PRINT(("ERROR: Client Wait time read back of reset time has unexpected value (=%d) \n",timeout));
991 Kern::Printf("aFunction %d is not recognised \n",aFunction);
995 #ifdef IIC_INSTRUMENTATION_MACRO
996 IIC_SSTATEXT_END_PSL_TRACE;
1003 //#ifdef MASTER_MODE
1006 #if defined(MASTER_MODE) && defined(SLAVE_MODE)
1007 #ifdef STANDALONE_CHANNEL
1010 DSimulatedIicBusChannelMasterSlaveI2c::DSimulatedIicBusChannelMasterSlaveI2c(TBusType /*aBusType*/, TChannelDuplex aChanDuplex, DSimulatedIicBusChannelMasterI2c* aMasterChan, DSimulatedIicBusChannelSlaveI2c* aSlaveChan)
1011 : DIicBusChannelMasterSlave(EI2c, aChanDuplex, aMasterChan, aSlaveChan)
1014 TInt DSimulatedIicBusChannelMasterSlaveI2c::StaticExtension(TUint aFunction, TAny* /*aParam1*/, TAny* /*aParam2*/)
1016 I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::StaticExtension, aFunction=0x%x\n",aFunction));
1019 // Test values of aFunction were shifted left one place by the (test) client driver
1020 // Return to its original value.
1021 if(aFunction>KTestControlIoPilOffset)
1025 case(RBusDevIicClient::ECtlIoDumpChan):
1032 case(RBusDevIicClient::ECtlIoDeRegChan):
1034 I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c: deregister channel\n"));
1035 #ifndef STANDALONE_CHANNEL
1036 r=DIicBusController::DeRegisterChannel(this);
1038 return KErrNotSupported;
1042 case(RBusDevIicClient::ECtlIoBlockReqCompletion):
1044 I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::Blocking request completion\n"));
1045 ((DSimulatedIicBusChannelMasterI2c*)iMasterChannel)->SetRequestDelayed(((DSimulatedIicBusChannelMasterI2c*)iMasterChannel), ETrue);
1048 case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
1050 I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::Unlocking request completion\n"));
1051 ((DSimulatedIicBusChannelMasterI2c*)iMasterChannel)->SetRequestDelayed(((DSimulatedIicBusChannelMasterI2c*)iMasterChannel), EFalse);
1056 Kern::Printf("aFunction %d is not recognised \n",aFunction);
1064 //#if defined(MASTER_MODE) && defined(SLAVE_MODE)