sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test/iic/iic_psl/spi.cpp sl@0: // sl@0: #include "spi.h" sl@0: sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: #include sl@0: #endif sl@0: sl@0: #define NUM_CHANNELS 4 // Arbitrary sl@0: sl@0: // Macros to be updated(?) with interaction with Configuration Repository sl@0: const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMaster}; sl@0: #define CHANNEL_TYPE(n) (KChannelTypeArray[n]) sl@0: const DIicBusChannel::TChannelDuplex KChannelDuplexArray[NUM_CHANNELS] = {DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EFullDuplex}; sl@0: #define CHANNEL_DUPLEX(n) (KChannelDuplexArray[n]) sl@0: sl@0: #ifdef LOG_SPI sl@0: #define SPI_PRINT(str) Kern::Printf str sl@0: #else sl@0: #define SPI_PRINT(str) sl@0: #endif sl@0: sl@0: _LIT(KSpiThreadName,"SpiChannelThread"); sl@0: sl@0: const TInt KSpiThreadPriority = 5; // Arbitrary, can be 0-7, 7 highest sl@0: sl@0: #ifdef STANDALONE_CHANNEL sl@0: _LIT(KPddNameSpi,"spi_ctrless.pdd"); sl@0: #else sl@0: _LIT(KPddNameSpi,"spi.pdd"); sl@0: #endif sl@0: sl@0: #ifndef STANDALONE_CHANNEL sl@0: LOCAL_C TInt8 AssignChanNum() sl@0: { sl@0: static TInt8 iBaseChanNum = KSpiChannelNumBase; sl@0: SPI_PRINT(("SPI AssignChanNum - on entry, iBaseCanNum = 0x%x\n",iBaseChanNum)); sl@0: return iBaseChanNum++; // Arbitrary, for illustration sl@0: } sl@0: #endif sl@0: sl@0: NONSHARABLE_CLASS(DSimulatedSpiDevice) : public DPhysicalDevice sl@0: { sl@0: // Class to faciliate loading of the IIC classes sl@0: public: sl@0: class TCaps sl@0: { sl@0: public: sl@0: TVersion iVersion; sl@0: }; sl@0: public: sl@0: DSimulatedSpiDevice(); sl@0: virtual TInt Install(); sl@0: virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: inline static TVersion VersionRequired(); sl@0: }; sl@0: sl@0: TVersion DSimulatedSpiDevice::VersionRequired() sl@0: { sl@0: SPI_PRINT(("DSimulatedSpiDevice::VersionRequired\n")); sl@0: return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber); sl@0: } sl@0: sl@0: /** Factory class constructor */ sl@0: DSimulatedSpiDevice::DSimulatedSpiDevice() sl@0: { sl@0: SPI_PRINT(("DSimulatedSpiDevice::DSimulatedSpiDevice\n")); sl@0: iVersion = DSimulatedSpiDevice::VersionRequired(); sl@0: } sl@0: sl@0: TInt DSimulatedSpiDevice::Install() sl@0: { sl@0: SPI_PRINT(("DSimulatedSpiDevice::Install\n")); sl@0: return(SetName(&KPddNameSpi)); sl@0: } sl@0: sl@0: /** Called by the kernel's device driver framework to create a Physical Channel. */ sl@0: TInt DSimulatedSpiDevice::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/) sl@0: { sl@0: SPI_PRINT(("DSimulatedSpiDevice::Create\n")); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/ sl@0: TInt DSimulatedSpiDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) sl@0: { sl@0: SPI_PRINT(("DSimulatedSpiDevice::Validate\n")); sl@0: if (!Kern::QueryVersionSupported(DSimulatedSpiDevice::VersionRequired(),aVer)) sl@0: return(KErrNotSupported); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** Return the driver capabilities */ sl@0: void DSimulatedSpiDevice::GetCaps(TDes8& aDes) const sl@0: { sl@0: SPI_PRINT(("DSimulatedSpiDevice::GetCaps\n")); sl@0: // Create a capabilities object sl@0: TCaps caps; sl@0: caps.iVersion = iVersion; sl@0: // Zero the buffer sl@0: TInt maxLen = aDes.MaxLength(); sl@0: aDes.FillZ(maxLen); sl@0: // Copy capabilities sl@0: TInt size=sizeof(caps); sl@0: if(size>maxLen) sl@0: size=maxLen; sl@0: aDes.Copy((TUint8*)&caps,size); sl@0: } sl@0: sl@0: // supported channels for this implementation sl@0: static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS]; sl@0: sl@0: //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY) sl@0: DECLARE_STANDARD_PDD() // SPI test driver to be explicitly loaded as an LDD, not kernel extension sl@0: { sl@0: SPI_PRINT(("\n\nSPI PDD, channel creation loop follows ...\n")); sl@0: sl@0: #ifndef STANDALONE_CHANNEL sl@0: DIicBusChannel* chan=NULL; sl@0: for(TInt i=0; iCreate()!=KErrNone) sl@0: return NULL; sl@0: } sl@0: else if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave) sl@0: { sl@0: DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); sl@0: if(!chanM) sl@0: return NULL; sl@0: DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); sl@0: if(!chanS) sl@0: return NULL; sl@0: // For MasterSlave channel, the channel number for both the Master and Slave channels must be the same sl@0: TInt8 msChanNum = ((DSimulatedIicBusChannelMasterSpi*)chanM)->GetChanNum(); sl@0: ((DSimulatedIicBusChannelSlaveSpi*)chanS)->SetChanNum(msChanNum); sl@0: sl@0: chan=new DIicBusChannelMasterSlave(BUS_TYPE,CHANNEL_DUPLEX(i),(DIicBusChannelMaster*)chanM,(DIicBusChannelSlave*)chanS); // Generic implementation sl@0: if(!chan) sl@0: return NULL; sl@0: SPI_PRINT(("SPI chan created at 0x%x\n",chan)); sl@0: if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone) sl@0: return NULL; sl@0: } sl@0: else sl@0: { sl@0: chan=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); sl@0: if(!chan) sl@0: return NULL; sl@0: SPI_PRINT(("SPI chan created at 0x%x\n",chan)); sl@0: if(((DSimulatedIicBusChannelSlaveSpi*)chan)->Create()!=KErrNone) sl@0: return NULL; sl@0: } sl@0: ChannelPtrArray[i]=chan; sl@0: } sl@0: SPI_PRINT(("\nSPI PDD, channel creation loop done- about to invoke RegisterChannels\n\n")); sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_REGISTERCHANS_START_PSL_TRACE; sl@0: #endif sl@0: sl@0: TInt r = KErrNone; sl@0: r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS); sl@0: sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_REGISTERCHANS_END_PSL_TRACE; sl@0: #endif sl@0: SPI_PRINT(("\nSPI - returned from RegisterChannels with r=%d\n",r)); sl@0: if(r!=KErrNone) sl@0: { sl@0: delete chan; sl@0: return NULL; sl@0: } sl@0: #endif sl@0: return new DSimulatedSpiDevice; sl@0: } sl@0: sl@0: #ifdef STANDALONE_CHANNEL sl@0: EXPORT_C sl@0: #endif sl@0: DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi(const TBusType aBusType, const TChannelDuplex aChanDuplex) sl@0: : DIicBusChannelMaster(aBusType,aChanDuplex) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex)); sl@0: #ifndef STANDALONE_CHANNEL sl@0: iChannelNumber = AssignChanNum(); sl@0: #endif sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, iChannelNumber=%d\n",iChannelNumber)); sl@0: iTestState = ETestNone; sl@0: iChannelState = EIdle; sl@0: } sl@0: sl@0: // The time-out call back invoked when the Slave exeecds the allowed response time sl@0: TInt DSimulatedIicBusChannelMasterSpi::HandleSlaveTimeout() sl@0: { sl@0: SPI_PRINT(("HandleSlaveTimeout \n")); sl@0: return AsynchStateMachine(ETimeExpired); sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::DoCreate() sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoCreate\n")); sl@0: TInt r=Init(); // PIL Base class initialisation sl@0: r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KSpiThreadPriority,KSpiThreadName); sl@0: if(r == KErrNone) sl@0: SetDfcQ((TDfcQue*)iDynamicDfcQ); sl@0: DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(this,EFalse); sl@0: return r; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::CheckHdr(TDes8* aHdr) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr\n")); sl@0: sl@0: TConfigSpiBufV01* spiBuf = (TConfigSpiBufV01*)aHdr; sl@0: TConfigSpiV01* spiPtr = &((*spiBuf)()); sl@0: sl@0: // Valid values for the device ID will depend on the bus configuration sl@0: // sl@0: // Check that the values for word width, clock speed and clock mode are recognised sl@0: if((spiPtr->iWordWidth < 0) || (spiPtr->iWordWidth > ESpiWordWidth_16)) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised word width identifier %d\n",spiPtr->iWordWidth)); sl@0: return KErrArgument; sl@0: } sl@0: if(spiPtr->iClkSpeedHz < 0) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative clock speed specified %d\n",spiPtr->iClkSpeedHz)); sl@0: return KErrArgument; sl@0: } sl@0: if((spiPtr->iClkMode < 0) || (spiPtr->iClkMode > ESpiPolarityHighRisingEdge)) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised clock mode identifier %d\n",spiPtr->iClkMode)); sl@0: return KErrArgument; sl@0: } sl@0: // Values for the timeout period are arbitrary - can only check it is not a negative value sl@0: if(spiPtr->iTimeoutPeriod < 0) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative timeout period %d\n",spiPtr->iTimeoutPeriod)); sl@0: return KErrArgument; sl@0: } sl@0: if((spiPtr->iEndianness < 0) || (spiPtr->iEndianness > ELittleEndian)) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised endianness identifier %d\n",spiPtr->iEndianness)); sl@0: return KErrArgument; sl@0: } sl@0: if((spiPtr->iBitOrder < 0) || (spiPtr->iBitOrder > EMsbFirst)) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised bit order identifier %d\n",spiPtr->iBitOrder)); sl@0: return KErrArgument; sl@0: } sl@0: if((spiPtr->iSSPinActiveMode < 0) || (spiPtr->iSSPinActiveMode > ESpiCSPinActiveHigh)) sl@0: { sl@0: SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised Slave select pin mode identifier %d\n",spiPtr->iSSPinActiveMode)); sl@0: return KErrArgument; sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr word width = %d\n",spiPtr->iWordWidth)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock speed = %d\n",spiPtr->iClkSpeedHz)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock mode = %d\n",spiPtr->iClkMode)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr timeout period = %d\n",spiPtr->iTimeoutPeriod)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr endianness = %d\n",spiPtr->iEndianness)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr bit order = %d\n",spiPtr->iBitOrder)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr transaction wait cycles = %d\n",spiPtr->iTransactionWaitCycles)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr slave select pin mode = %d\n",spiPtr->iSSPinActiveMode)); sl@0: sl@0: // For the set of tests expecft the following values sl@0: // ESpiWordWidth_8, 100kHz, ESpiPolarityLowRisingEdge,aTimeoutPeriod=100 sl@0: // EBigEndian, EMsbFirst, 10 wait cycles, Slave select active low sl@0: if( (spiPtr->iWordWidth != ESpiWordWidth_8) || sl@0: (spiPtr->iClkSpeedHz != 100000) || sl@0: (spiPtr->iClkMode != ESpiPolarityLowRisingEdge) || sl@0: (spiPtr->iTimeoutPeriod != 100) || sl@0: (spiPtr->iEndianness != ELittleEndian) || sl@0: (spiPtr->iBitOrder != EMsbFirst) || sl@0: (spiPtr->iTransactionWaitCycles != 10) || sl@0: (spiPtr->iSSPinActiveMode != ESpiCSPinActiveLow) ) sl@0: return KErrCorrupt; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::CompareTransactionOne(TIicBusTransaction* aTransaction) sl@0: // Compares the indicated TIicBusTransaction with the expected content sl@0: // Returns KErrNone if there is a match, KErrCorrupt otherwise. sl@0: { sl@0: TInt i; sl@0: // Check the transaction header sl@0: // Should contain the default header for SPI sl@0: TDes8* bufPtr = GetTransactionHeader(aTransaction); sl@0: if(bufPtr == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL header\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr()); sl@0: if(buf->iWordWidth != ESpiWordWidth_8) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header wordwidth mis-match\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: if(buf->iClkSpeedHz !=100000) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header clockspeed mis-match\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: if(buf->iClkMode != ESpiPolarityLowRisingEdge) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header polarity mis-match\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: if(buf->iTimeoutPeriod != 100) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header timeout mis-match\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne header OK\n")); sl@0: sl@0: // Check the half-duplex transfer list sl@0: TIicBusTransfer* tfer = GetTransHalfDuplexTferPtr(aTransaction); sl@0: if(tfer == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL half-duplex transfer\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: // Process each transfer in the list sl@0: TInt8 dummy; sl@0: sl@0: // tfer1 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf1); sl@0: // buf1 contains copy of TUint8 KTransOneTferOne[21] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; sl@0: dummy=GetTferType(tfer); sl@0: if(dummy!=TIicBusTransfer::EMasterWrite) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 type=%d\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: dummy=GetTferBufGranularity(tfer); sl@0: if(dummy!=8) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 granularity=%d\n",dummy)); sl@0: return KErrCorrupt; sl@0: } sl@0: if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 buffer NULL\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: for(i=0;i<21;++i) sl@0: { sl@0: if((*bufPtr)[i]!=i) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer1 buffer element %d has 0x%x\n",i,(*bufPtr)[i])); sl@0: return KErrCorrupt; sl@0: } sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer1 OK\n")); sl@0: sl@0: sl@0: tfer=GetTferNextTfer(tfer); sl@0: // tfer2 = new TIicBusTransfer(TIicBusTransfer::EMasterRead,8,buf2); sl@0: // buf2 contains copy of TUint8 KTransOneTferTwo[8] = {17,18,19,20,21,22,23,24}; sl@0: dummy=GetTferType(tfer); sl@0: if(dummy!=TIicBusTransfer::EMasterRead) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 type=%d\n",dummy)); sl@0: return KErrCorrupt; sl@0: } sl@0: dummy=GetTferBufGranularity(tfer); sl@0: if(dummy!=8) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 granularity=%d\n",dummy)); sl@0: return KErrCorrupt; sl@0: } sl@0: if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 buffer NULL\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: for(i=0;i<8;++i) sl@0: { sl@0: if((*bufPtr)[i]!=(17+i)) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer2 buffer element %d has 0x%x\n",i,(*bufPtr)[i])); sl@0: return KErrCorrupt; sl@0: } sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer2 OK\n")); sl@0: sl@0: tfer=GetTferNextTfer(tfer); sl@0: // tfer3 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf3); sl@0: // buf2 contains copy of TUint8 KTransOneTferThree[6] = {87,85,83,81,79,77}; sl@0: dummy=GetTferType(tfer); sl@0: if(dummy!=TIicBusTransfer::EMasterWrite) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 type=%d\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: dummy=GetTferBufGranularity(tfer); sl@0: if(dummy!=8) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 granularity=%d\n",dummy)); sl@0: return KErrCorrupt; sl@0: } sl@0: if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 buffer NULL\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: for(i=0;i<6;++i) sl@0: { sl@0: if((*bufPtr)[i]!=(87-(2*i))) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer3 buffer element %d has 0x%x\n",i,(*bufPtr)[i])); sl@0: return KErrCorrupt; sl@0: } sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer3 OK\n")); sl@0: sl@0: // Shouldn't be any more transfers in the half duplex list sl@0: if((tfer=GetTferNextTfer(tfer))!=NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 iNext=0x%x\n",tfer)); sl@0: return KErrCorrupt; sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne half-duplex transfer OK\n")); sl@0: sl@0: // The full duplex transfer should be represented by a NULL pointer sl@0: if((tfer=GetTransFullDuplexTferPtr(aTransaction))!=NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - full duplex pointer=0x%x\n",tfer)); sl@0: return KErrCorrupt; sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne full duplex pointer is NULL (OK)\n")); sl@0: sl@0: // Synchronous transaction, so check the callback pointer is NULL sl@0: TIicBusCallback* dumCb = NULL; sl@0: dumCb=GetTransCallback(aTransaction); sl@0: if(dumCb!=NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - callback pointer=0x%x\n",dumCb)); sl@0: return KErrCorrupt; sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne callback pointer is NULL (OK)\n")); sl@0: sl@0: // Check the transaction flags are set to zero sl@0: TUint8 dumFlags; sl@0: dumFlags=GetTransFlags(aTransaction); sl@0: if(dumFlags!=0) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - flags=0x%x\n",dumFlags)); sl@0: return KErrCorrupt; sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne flags are zero (OK)\n")); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // The THwCallbackFunc gets called if the hardware preparation completes successfully. sl@0: void THwCallbackFunc(TAny* aPtr) sl@0: { sl@0: SPI_PRINT(("Hardware preparation completed, calling the callback function")); sl@0: DSimulatedIicBusChannelMasterSpi* aChanMasterSpi=(DSimulatedIicBusChannelMasterSpi* )aPtr; sl@0: TInt r = aChanMasterSpi->DoSimulatedTransaction(); sl@0: ((DSimulatedIicBusChannelMasterSpi*)aChanMasterSpi)->CompleteReq(r); sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::DoSimulatedTransaction() sl@0: { sl@0: TInt r = AsynchStateMachine(EHwTransferDone); sl@0: if(iTimeoutTimer.Cancel() == FALSE) sl@0: { sl@0: SPI_PRINT(("timer is not cancelled")); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::DoHwPreparation() sl@0: { sl@0: SPI_PRINT(("Preparing hardware for the transaction")); sl@0: sl@0: TInt r = KErrNone; sl@0: // The hardware preparation can either complete successfully or fail. sl@0: // If successful, invoke the callback function of THwDoneCallBack sl@0: // if not, execute the timeout machanism sl@0: // Currently DoHwPreparation is just a simple function. It should be more complicated sl@0: // for the real hardware. sl@0: switch(iTestState) sl@0: { sl@0: case (ETestSlaveTimeOut): sl@0: { sl@0: // In the timeout test, do nothing until the timeout callback function is invoked. sl@0: SPI_PRINT(("Simulating the timeout process.")); sl@0: break; sl@0: } sl@0: case (ETestNone): sl@0: { sl@0: // Pretend the hardware preparation's been done, and a callback function is invoked to call sl@0: // the Asynchronous State Machine sl@0: SPI_PRINT(("Hardware preparing work is executing normally.")); sl@0: iCb->Enque(); sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: SPI_PRINT(("Not a valid test.")); sl@0: r = KErrNotSupported; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: // Gateway function for PSL implementation, invoked for DFC processing sl@0: TInt DSimulatedIicBusChannelMasterSpi::DoRequest(TIicBusTransaction* aTransaction) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest invoked with aTransaction=0x%x\n",aTransaction)); sl@0: sl@0: TInt r = KErrNone; sl@0: iCurrTrans=aTransaction; sl@0: sl@0: // Check if the Asynchronous State Machine is available. If not, then return KErrInUse. sl@0: // This is used to stop the second transaction executing if the machine has already been holding sl@0: // by a transaction. However, this situation cannot be tested because of the malfunction in PIL sl@0: if(iChannelState!= EIdle) sl@0: return KErrInUse; sl@0: sl@0: iChannelState = EBusy; sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_MPROCESSTRANS_START_PSL_TRACE; sl@0: #endif sl@0: r = ProcessTrans(aTransaction); sl@0: sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - exiting\n")); sl@0: return r; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::ProcessTrans(TIicBusTransaction* aTransaction) sl@0: { sl@0: TInt r=KErrNone; sl@0: sl@0: switch(iTestState) sl@0: { sl@0: case(ETestWaitTransOne): sl@0: { sl@0: // The transaction received should exhibit the expected data sl@0: // Return KErrArgument if this is not the case sl@0: // The timer should be started at the beginning of every transaction sl@0: // For simplicity, we omit the timer here. sl@0: r=CompareTransactionOne(iCurrTrans); sl@0: iChannelState = EIdle; sl@0: CompleteRequest(KErrNone); sl@0: break; sl@0: } sl@0: case(ETestSlaveTimeOut): sl@0: { sl@0: // Test the timeout funciton sl@0: SPI_PRINT(("Test the slave timeout function\n")); sl@0: sl@0: // Simulate a timeout sl@0: // Start a timer and then wait for the Slave response to timeout sl@0: // A real bus would use its own means to identify a timeout sl@0: TInt aTime=1000000/NKern::TickPeriod(); sl@0: r = StartSlaveTimeOutTimer(aTime); sl@0: if(r != KErrNone) sl@0: return r; sl@0: r = DoHwPreparation(); sl@0: break; sl@0: } sl@0: case(ETestWaitPriorityTest): sl@0: { sl@0: static TInt TranCount = 0; sl@0: if(TranCount >= KPriorityTestNum) return KErrUnknown; sl@0: // block the channel sl@0: while(IsRequestDelayed(this)) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - starting Sleep...\n")); sl@0: NKern::Sleep(1000); // 1000 is arbitrary sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - completed Sleep, check if still delayed\n")); sl@0: }; sl@0: // get transaction header sl@0: TDes8* bufPtr = GetTransactionHeader(aTransaction); sl@0: if(bufPtr == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest ERROR - NULL header\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: sl@0: if(TranCount == 0) sl@0: { sl@0: // ignore the blocking transaction sl@0: TranCount++; sl@0: } sl@0: else sl@0: { sl@0: // store transaction header sl@0: iPriorityTestResult[TranCount++] = (*bufPtr)[0]; sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest Priority test transaction no.:%d Priority:%d", sl@0: (*bufPtr)[0], aTransaction->iKey)); sl@0: } sl@0: iChannelState = EIdle; sl@0: CompleteRequest(KErrNone); sl@0: if(TranCount == KPriorityTestNum) iPriorityTestDone = ETrue; sl@0: break; sl@0: } sl@0: sl@0: sl@0: sl@0: case(ETestNone): sl@0: { sl@0: SPI_PRINT(("Nothing to be tested, just do the usual transaction")); sl@0: sl@0: // Start the timer on the Slave response. sl@0: // Since no timeout, this timer will be cancelled in the THwCallbackFunc sl@0: r = StartSlaveTimeOutTimer(100000); sl@0: if(r != KErrNone) sl@0: return r; sl@0: // Use a class THwDoneCallBack derived from TDfc to trigger the asynchronous state machine sl@0: // when the hardware preparation completes successfully. sl@0: // The priority is set with an arbitrary number 5 sl@0: iCb = new THwDoneCallBack(THwCallbackFunc, this, iDynamicDfcQ, 5); sl@0: r = DoHwPreparation(); sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: SPI_PRINT(("Test status not matched")); sl@0: return KErrNotSupported; sl@0: } sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::AsynchStateMachine(TInt aReason) sl@0: { sl@0: TInt r=KErrNone; sl@0: sl@0: // The asynchronous state machine has two states, it could either be idle or busy. sl@0: // Initially, it's in idle state. When a user queues a transaction, the hardware preparation starts sl@0: // and the state changes to busy. After the hardware preparation completes, either successfully or not, sl@0: // the state machine will do the corresponding work for the transaction and then goes back to the idle state. sl@0: switch(iChannelState) sl@0: { sl@0: case(EIdle): sl@0: { sl@0: return KErrGeneral; sl@0: } sl@0: case (EBusy): sl@0: { sl@0: switch(aReason) sl@0: { sl@0: case(EHwTransferDone): sl@0: { sl@0: sl@0: // Simulate processing - for now, do nothing! sl@0: // sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHeader=0x%x\n",GetTransactionHeader(iCurrTrans))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(iCurrTrans))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(iCurrTrans))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iCallback=0x%x\n",GetTransCallback(iCurrTrans))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFlags=0x%x\n",GetTransFlags(iCurrTrans))); sl@0: sl@0: SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHeader info \n")); sl@0: TDes8* bufPtr = GetTransactionHeader(iCurrTrans); sl@0: if(bufPtr == NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine ERROR - NULL header\n")); sl@0: return KErrCorrupt; sl@0: } sl@0: TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr()); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header word width=0x%x\n",buf->iWordWidth)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock speed=0x%x\n",buf->iClkSpeedHz)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock mode=0x%x\n",buf->iClkMode)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header timeout period=0x%x\n",buf->iTimeoutPeriod)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header endianness=0x%x\n",buf->iEndianness)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header bit order=0x%x\n",buf->iBitOrder)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header wait cycles=0x%x\n",buf->iTransactionWaitCycles)); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header Slave select pin mode=0x%x\n",buf->iSSPinActiveMode)); sl@0: (void)buf; // Silence compiler when SPI_PRINT not used sl@0: sl@0: SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHalfDuplexTrans info \n")); sl@0: TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(iCurrTrans); sl@0: while(halfDuplexPtr != NULL) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer type=0x%x\n",GetTferType(halfDuplexPtr))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr))); sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr))); sl@0: halfDuplexPtr=GetTferNextTfer(halfDuplexPtr); sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - End of iHalfDuplexTrans info")); sl@0: sl@0: while(IsRequestDelayed(this)) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - starting Sleep...\n")); sl@0: NKern::Sleep(1000); // 1000 is arbitrary sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - completed Sleep, check if still delayed\n")); sl@0: }; sl@0: sl@0: iChannelState=EIdle; sl@0: delete iCb; sl@0: break; sl@0: } sl@0: case(ETimeExpired): sl@0: { sl@0: SPI_PRINT(("Time expired, the Asynchrnous State Machine will be Idle again, and wait for the next request.")); sl@0: iChannelState=EIdle; sl@0: r = KErrTimedOut; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: SPI_PRINT(("Request can not be handled, return error code.")); sl@0: return KErrNotSupported; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: SPI_PRINT(("No matched state")); sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TBool DSimulatedIicBusChannelMasterSpi::IsRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::IsRequestDelayed invoked for aChan=0x%x\n",aChan)); sl@0: return aChan->iReqDelayed; sl@0: } sl@0: sl@0: void DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan,TBool aDelay) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay)); sl@0: aChan->iReqDelayed=aDelay; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelMasterSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::StaticExtension\n")); sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_MSTATEXT_START_PSL_TRACE; sl@0: #endif sl@0: (void)aParam1; sl@0: (void)aParam2; sl@0: TInt r = KErrNone; sl@0: // Test values of aFunction were shifted left one place by the (test) client driver sl@0: // and for Slave values the two msb were cleared sl@0: // Return to its original value. sl@0: if(aFunction>KTestControlIoPilOffset) sl@0: aFunction >>= 1; sl@0: switch(aFunction) sl@0: { sl@0: case(RBusDevIicClient::ECtlIoDumpChan): sl@0: { sl@0: #ifdef _DEBUG sl@0: DumpChannel(); sl@0: #endif sl@0: break; sl@0: } sl@0: case(RBusDevIicClient::ECtlIoBlockReqCompletion): sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Blocking request completion\n")); sl@0: SetRequestDelayed(this, ETrue); sl@0: break; sl@0: } sl@0: case(RBusDevIicClient::ECtlIoUnblockReqCompletion): sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Unlocking request completion\n")); sl@0: SetRequestDelayed(this, EFalse); sl@0: break; sl@0: } sl@0: case(RBusDevIicClient::ECtlIoDeRegChan): sl@0: { sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_DEREGISTERCHAN_START_PSL_TRACE; sl@0: #endif sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: deregister channel\n")); sl@0: #ifndef STANDALONE_CHANNEL sl@0: r=DIicBusController::DeRegisterChannel(this); sl@0: #endif sl@0: sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_DEREGISTERCHAN_END_PSL_TRACE; sl@0: #endif sl@0: break; sl@0: } sl@0: sl@0: case(RBusDevIicClient::ECtlIoPriorityTest): sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect priority test\n")); sl@0: iPriorityTestDone = EFalse; sl@0: iTestState=ETestWaitPriorityTest; sl@0: break; sl@0: } sl@0: case(RBusDevIicClient::EGetTestResult): sl@0: { sl@0: if(!iPriorityTestDone) return KErrNotReady; sl@0: sl@0: SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: get priority test order\n")); sl@0: sl@0: //iPriorityTestResult[0] is the blocking transaction, ignore it. start from entry 1. sl@0: for(TInt i=1; iChanCaptureCb(r); sl@0: } sl@0: sl@0: #ifdef STANDALONE_CHANNEL sl@0: EXPORT_C sl@0: #endif sl@0: DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex) sl@0: : DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class sl@0: iSlaveTimer(SlaveAsyncSimCallback,this) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex)); sl@0: #ifndef STANDALONE_CHANNEL sl@0: iChannelNumber = AssignChanNum(); sl@0: #endif sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, iChannelNumber=%d\n",iChannelNumber)); sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl(TDes8* /*aConfigHdr*/, TBool aAsynch) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl, aAsynch=%d\n",aAsynch)); sl@0: TInt r = KErrNone; sl@0: if(aAsynch) sl@0: { sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_SCAPTCHANASYNC_START_PSL_TRACE; sl@0: #endif sl@0: // To simulate an asynchronous operation, just set a timer to expire sl@0: iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1 sl@0: } sl@0: else sl@0: { sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_SCAPTCHANSYNC_START_PSL_TRACE; sl@0: #endif sl@0: // PSL processing would happen here ... sl@0: // Expected to include implementation of the header configuration information sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_SCAPTCHANSYNC_END_PSL_TRACE; sl@0: #endif sl@0: } sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChanSync ... no real processing to do \n")); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelSlaveSpi::CheckHdr(TDes8* /*aHdr*/) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CheckHdr\n")); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelSlaveSpi::DoCreate() sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoCreate\n")); sl@0: TInt r=Init(); // PIL Base class initialisation sl@0: return r; sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelSlaveSpi::DoRequest(TInt /*aTrigger*/) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoRequest\n")); sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: void DSimulatedIicBusChannelSlaveSpi::ProcessData(TInt /*aTrigger*/, TIicBusSlaveCallback* /*aCb*/) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::ProcessData\n")); sl@0: } sl@0: sl@0: TInt DSimulatedIicBusChannelSlaveSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2) sl@0: { sl@0: SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::StaticExtension\n")); sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_SSTATEXT_START_PSL_TRACE; sl@0: #endif sl@0: (void)aParam1; sl@0: (void)aParam2; sl@0: // Test values of aFunction were shifted left one place by the (test) client driver sl@0: // and for Slave values the two msb were cleared sl@0: // Return to its original value. sl@0: if(aFunction>KTestControlIoPilOffset) sl@0: { sl@0: aFunction |= 0xC0000000; sl@0: aFunction >>= 1; sl@0: } sl@0: TInt r = KErrNone; sl@0: switch(aFunction) sl@0: { sl@0: case(RBusDevIicClient::ECtlIoDumpChan): sl@0: { sl@0: #ifdef _DEBUG sl@0: DumpChannel(); sl@0: #endif sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: Kern::Printf("aFunction %d is not recognised \n",aFunction); sl@0: r=KErrNotSupported; sl@0: } sl@0: } sl@0: sl@0: #ifdef IIC_INSTRUMENTATION_MACRO sl@0: IIC_SSTATEXT_START_PSL_TRACE; sl@0: #endif sl@0: (void)aFunction; sl@0: return r; sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: