kerneltest/e32test/iic/iic_psl/i2c.cpp
changeset 90 947f0dc9f7a8
parent 33 0173bcd7697c
child 199 189ece41fa29
equal deleted inserted replaced
52:2d65c2f76d7b 90:947f0dc9f7a8
    18 
    18 
    19 #ifdef IIC_INSTRUMENTATION_MACRO
    19 #ifdef IIC_INSTRUMENTATION_MACRO
    20 #include <drivers/iic_trace.h>
    20 #include <drivers/iic_trace.h>
    21 #endif
    21 #endif
    22 
    22 
    23 
    23 #ifndef STANDALONE_CHANNEL
    24 #if defined(MASTER_MODE) && !defined(SLAVE_MODE)
    24 #if defined(MASTER_MODE) && !defined(SLAVE_MODE)
    25 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::EMaster};
    25 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::EMaster};
    26 #elif defined(MASTER_MODE) && defined(SLAVE_MODE)
    26 #elif defined(MASTER_MODE) && defined(SLAVE_MODE)
    27 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMasterSlave};
    27 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMasterSlave};
    28 #else
    28 #else
    29 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::ESlave, DIicBusChannel::ESlave, DIicBusChannel::ESlave};
    29 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::ESlave, DIicBusChannel::ESlave, DIicBusChannel::ESlave};
    30 #endif
    30 #endif
    31 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
    31 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
    32 #define CHANNEL_DUPLEX(n) (DIicBusChannel::EHalfDuplex)
    32 #define CHANNEL_DUPLEX(n) (DIicBusChannel::EHalfDuplex)
       
    33 #endif/*STANDALONE_CHANNEL*/
    33 
    34 
    34 #ifdef STANDALONE_CHANNEL
    35 #ifdef STANDALONE_CHANNEL
    35 _LIT(KPddNameI2c,"i2c_ctrless.pdd");
    36 _LIT(KPddNameI2c,"i2c_ctrless.pdd");
    36 #else
    37 #else
    37 _LIT(KPddNameI2c,"i2c.pdd");
    38 _LIT(KPddNameI2c,"i2c.pdd");
   123 	if(size>maxLen)
   124 	if(size>maxLen)
   124 	   size=maxLen;
   125 	   size=maxLen;
   125 	aDes.Copy((TUint8*)&caps,size);
   126 	aDes.Copy((TUint8*)&caps,size);
   126     }
   127     }
   127 
   128 
       
   129 #ifndef STANDALONE_CHANNEL
   128 // supported channels for this implementation
   130 // supported channels for this implementation
   129 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
   131 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
   130 
   132 #endif
   131 
   133 
   132 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)	
   134 //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 DECLARE_STANDARD_PDD()		// I2c test driver to be explicitly loaded as an LDD, not kernel extension
   134 	{	
   136 	{	
   135 #ifndef STANDALONE_CHANNEL
   137 #ifndef STANDALONE_CHANNEL
   437 #ifdef SLAVE_MODE
   439 #ifdef SLAVE_MODE
   438 
   440 
   439 void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr)
   441 void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr)
   440 	{
   442 	{
   441 	// To support simulating an asynchronous capture operation
   443 	// To support simulating an asynchronous capture operation
   442 	// NOTE: this will be invoked in the context of DfcThread1
       
   443 	I2C_PRINT(("SlaveAsyncSimCallback\n"));
   444 	I2C_PRINT(("SlaveAsyncSimCallback\n"));
   444 	DSimulatedIicBusChannelSlaveI2c* channel = (DSimulatedIicBusChannelSlaveI2c*)aPtr;
   445 	DSimulatedIicBusChannelSlaveI2c* channel = (DSimulatedIicBusChannelSlaveI2c*)aPtr;
   445 	TInt r=KErrNone;// Just simulate successful capture
   446 
   446 #ifdef IIC_INSTRUMENTATION_MACRO
   447 	// This will be invoked in the context of DfcThread1, so require
   447 	IIC_SCAPTCHANASYNC_END_PSL_TRACE;
   448 	// synchronised access to iAsyncEvent and iRxTxTrigger
   448 #endif
   449 	// Use local variables to enable early release of the spin lock
   449 	channel->ChanCaptureCb(r);
   450 	//
       
   451 	// If DfcThread1 runs on a separate core to the simulated I2C bus, the other core
       
   452 	// will have updated values, and since this core may cached copies, memory access
       
   453 	// should be observed. The spin lock mechanism is expected to incorpoate this.
       
   454 	TInt intState=__SPIN_LOCK_IRQSAVE(channel->iEventSpinLock);
       
   455 	
       
   456 	TAsyncEvent asyncEvent = channel->iAsyncEvent;
       
   457 	TInt rxTxTrigger = channel->iRxTxTrigger;
       
   458 	channel->iAsyncEvent = ENoEvent;
       
   459 	channel->iRxTxTrigger =  0;
       
   460 	__SPIN_UNLOCK_IRQRESTORE(channel->iEventSpinLock,intState);
       
   461 
       
   462 	switch(asyncEvent)
       
   463 		{
       
   464 		case (EAsyncChanCapture):
       
   465 			{
       
   466 			TInt r=KErrNone;// Just simulate successful capture
       
   467 #ifdef IIC_INSTRUMENTATION_MACRO
       
   468 			IIC_SCAPTCHANASYNC_END_PSL_TRACE;
       
   469 #endif
       
   470 			channel->ChanCaptureCb(r);
       
   471 			break;
       
   472 			}
       
   473 		case (ERxWords):
       
   474 		case (ETxWords):
       
   475 		case (ERxTxWords):
       
   476 			{
       
   477 			channel->ChanNotifyClient(rxTxTrigger);
       
   478 			break;
       
   479 			}
       
   480 		default:
       
   481 			{
       
   482 			}
       
   483 		}
   450 	}
   484 	}
   451 
   485 
   452 #ifdef STANDALONE_CHANNEL
   486 #ifdef STANDALONE_CHANNEL
   453 EXPORT_C
   487 EXPORT_C
   454 #endif
   488 #endif
   455 DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
   489 DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
   456 	: DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
   490 	: DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
   457 	iBlockedTrigger(0),iBlockNotification(EFalse),
   491 	iBlockedTrigger(0),iBlockNotification(EFalse),iAsyncEvent(ENoEvent),iRxTxTrigger(0),
   458 	iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this)
   492 	iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this),
       
   493 	iEventSpinLock(TSpinLock::EOrderGenericIrqHigh2)  // Semi-arbitrary, high priority value (NTimer used)
   459 	{
   494 	{
   460 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
   495 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
   461 #ifndef STANDALONE_CHANNEL
   496 #ifndef STANDALONE_CHANNEL
   462 	iChannelNumber = AssignChanNum();
   497 	iChannelNumber = AssignChanNum();
   463 #endif
   498 #endif
   486 		{
   521 		{
   487 #ifdef IIC_INSTRUMENTATION_MACRO
   522 #ifdef IIC_INSTRUMENTATION_MACRO
   488 	IIC_SCAPTCHANASYNC_START_PSL_TRACE;
   523 	IIC_SCAPTCHANASYNC_START_PSL_TRACE;
   489 #endif
   524 #endif
   490 		// To simulate an asynchronous capture operation, just set a timer to expire
   525 		// 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
   526 		TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
       
   527 		iAsyncEvent = EAsyncChanCapture;
       
   528 		__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
       
   529 		iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
   492 		}
   530 		}
   493 	else
   531 	else
   494 		{
   532 		{
   495 #ifdef IIC_INSTRUMENTATION_MACRO
   533 #ifdef IIC_INSTRUMENTATION_MACRO
   496 	IIC_SCAPTCHANSYNC_START_PSL_TRACE;
   534 	IIC_SCAPTCHANSYNC_START_PSL_TRACE;
   598 	return r;
   636 	return r;
   599 	}
   637 	}
   600 
   638 
   601 void DSimulatedIicBusChannelSlaveI2c::ProcessData(TInt aTrigger, TIicBusSlaveCallback*  aCb)
   639 void DSimulatedIicBusChannelSlaveI2c::ProcessData(TInt aTrigger, TIicBusSlaveCallback*  aCb)
   602 	{
   640 	{
   603 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData\n"));
   641 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData trigger=0x%x\n",aTrigger));
   604 	// fills in iReturn, iRxWords and/or iTxWords
   642 	// fills in iReturn, iRxWords and/or iTxWords
   605 	//
   643 	//
   606 	if(aTrigger & ERxAllBytes)
   644 	if(aTrigger & ERxAllBytes)
   607 		{
   645 		{
   608 		aCb->SetRxWords(iNumWordsWereRx);
   646 		aCb->SetRxWords(iNumWordsWereRx);
   629 			{
   667 			{
   630 			aTrigger|=ETxOverrun;
   668 			aTrigger|=ETxOverrun;
   631 			iRxTxUnderOverRun&= ~ETxOverrun;
   669 			iRxTxUnderOverRun&= ~ETxOverrun;
   632 			}
   670 			}
   633 		}
   671 		}
   634 
       
   635 	aCb->SetTrigger(aTrigger);
   672 	aCb->SetTrigger(aTrigger);
   636 	}
   673 	}
   637 
   674 
   638 TInt DSimulatedIicBusChannelSlaveI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
   675 TInt DSimulatedIicBusChannelSlaveI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
   639 	{
   676 	{
   707 					}
   744 					}
   708 				}
   745 				}
   709 			if(iBlockNotification == EFalse)
   746 			if(iBlockNotification == EFalse)
   710 				{
   747 				{
   711 				//
   748 				//
   712 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
   749 				// Use a timer for asynchronous call to NotifyClient - this will invoke ProcessData and invoke the client callback
   713 				NotifyClient(trigger);
   750 				TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
       
   751 				// Tx may already have been requested, to add to the existing flags set in iRxTxTrigger
       
   752 				iRxTxTrigger |= trigger;
       
   753 				iAsyncEvent = ERxWords;
       
   754 				__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
       
   755 				iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
   714 				}
   756 				}
   715 			else
   757 			else
   716 				{
   758 				{
   717 				// Save the trigger value to notify when prompted.
   759 				// Save the trigger value to notify when prompted.
   718 				iBlockedTrigger=trigger;
   760 				iBlockedTrigger=trigger;
   782 					*dstPtr++=*srcPtr++;
   824 					*dstPtr++=*srcPtr++;
   783 				}
   825 				}
   784 			if(iBlockNotification == EFalse)
   826 			if(iBlockNotification == EFalse)
   785 				{
   827 				{
   786 				//
   828 				//
   787 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
   829 				// Use a timer for asynchronous call to NotifyClient - this will invoke ProcessData and invoke the client callback
   788 				NotifyClient(trigger);
   830 				TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
       
   831 				// Rx may already have been requested, to add to the existing flags set in iRxTxTrigger
       
   832 				iRxTxTrigger |= trigger;
       
   833 				iAsyncEvent = ETxWords;
       
   834 				__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
       
   835 				iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
       
   836 																	// No effect if OneShot already invoked
   789 				}
   837 				}
   790 			else
   838 			else
   791 				{
   839 				{
   792 				// Save the trigger value to notify when prompted.
   840 				// Save the trigger value to notify when prompted.
   793 				iBlockedTrigger=trigger;
   841 				iBlockedTrigger=trigger;
   866 				}		
   914 				}		
   867 			
   915 			
   868 			if(iBlockNotification == EFalse)
   916 			if(iBlockNotification == EFalse)
   869 				{
   917 				{
   870 				//
   918 				//
   871 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
   919 				// Use a timer for asynchronous call to NotifyClient - this will invoke ProcessData and invoke the client callback
   872 				NotifyClient(trigger);
   920 				TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
       
   921 				// Rx or Tx may already have been requested, to add to the existing flags set in iRxTxTrigger
       
   922 				iRxTxTrigger |= trigger;
       
   923 				iAsyncEvent = ERxTxWords;
       
   924 				__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
       
   925 				iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
   873 				}
   926 				}
   874 			else
   927 			else
   875 				{
   928 				{
   876 				// Save the trigger value to notify when prompted.
   929 				// Save the trigger value to notify when prompted.
   877 				iBlockedTrigger=trigger;
   930 				iBlockedTrigger=trigger;
  1033 			{
  1086 			{
  1034 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c: deregister channel\n"));
  1087 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c: deregister channel\n"));
  1035 #ifndef STANDALONE_CHANNEL
  1088 #ifndef STANDALONE_CHANNEL
  1036 			r=DIicBusController::DeRegisterChannel(this);
  1089 			r=DIicBusController::DeRegisterChannel(this);
  1037 #else
  1090 #else
  1038 			return KErrNotSupported;
  1091 			r = KErrNotSupported;
  1039 #endif
  1092 #endif
  1040 			break;
  1093 			break;
  1041 			}
  1094 			}
  1042 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
  1095 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
  1043 			{
  1096 			{