navienginebsp/ne1_tb/test/csi/d_csi.cpp
changeset 0 5de814552237
equal deleted inserted replaced
-1:000000000000 0:5de814552237
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #ifdef STANDALONE_CHANNEL
       
    20 #include <drivers/iic_transaction.h>
       
    21 #include "csi_master.h"
       
    22 #include "csi_slave.h"
       
    23 #else
       
    24 #include <drivers/iic.h>
       
    25 #endif
       
    26 #include <drivers/iic_channel.h>
       
    27 #include <drivers/gpio.h>
       
    28 #include "cs42l51.h"
       
    29 
       
    30 #include "d_csi.h"
       
    31 
       
    32 #define __KTRACE(s)
       
    33 //#define __KTRACE(s) __KTRACE_OPT(KIIC, s)
       
    34 
       
    35 const TInt KMaxNumChannels = 1; // we only support one client at the time
       
    36 
       
    37 // generic check-error macro - to not put this manually on each operation.
       
    38 #define CHECK_ERR(r) \
       
    39           if(r != KErrNone){ \
       
    40           __KTRACE(Kern::Printf("d_csi.cpp, line: %d returned r=%d", __LINE__, r)); \
       
    41           return r;}
       
    42 
       
    43 // Default Test Header
       
    44 const TConfigSpiV01 DefaultHeader =
       
    45 	{
       
    46 	ESpiWordWidth_8, //iWordWidth
       
    47 	260000, //iClkSpeed
       
    48 	ESpiPolarityLowRisingEdge, //iClkMode
       
    49 	500, // iTimeoutPeriod
       
    50 	EBigEndian, // iEndianness
       
    51 	EMsbFirst, //iBitOrder
       
    52 	0, //iTransactionWaitCycles
       
    53 	ESpiCSPinActiveLow //iCsPinActiveMode
       
    54 	};
       
    55 
       
    56 _LIT(KLddRootName,"d_csi");
       
    57 _LIT(KIicClientThreadName,"IicClientLddThread");
       
    58 
       
    59 // Constructor
       
    60 DDeviceIicClient::DDeviceIicClient()
       
    61 	{
       
    62 	 __KTRACE(Kern::Printf("DDeviceIicClient::DDeviceIicClient()"));
       
    63 	iParseMask = 0; // No info, no PDD, no Units
       
    64 	iUnitsMask = 0;
       
    65 	iVersion = TVersion(KIicClientMajorVersionNumber,
       
    66 	        KIicClientMinorVersionNumber, KIicClientBuildVersionNumber);
       
    67 	}
       
    68 
       
    69 // Destructor
       
    70 DDeviceIicClient::~DDeviceIicClient()
       
    71 	{
       
    72 	__KTRACE(Kern::Printf("DDeviceIicClient::~DDeviceIicClient()"));
       
    73 	}
       
    74 
       
    75 // Install the device driver.
       
    76 TInt DDeviceIicClient::Install()
       
    77 	{
       
    78 	__KTRACE(Kern::Printf("DDeviceIicClient::Install()"));
       
    79 	return (SetName(&KLddRootName));
       
    80 	}
       
    81 
       
    82 void DDeviceIicClient::GetCaps(TDes8& aDes) const
       
    83 // Return the IicClient capabilities.
       
    84 	{
       
    85 	TPckgBuf<TCapsIicClient> b;
       
    86 	b().version = TVersion(KIicClientMajorVersionNumber, KIicClientMinorVersionNumber, KIicClientBuildVersionNumber);
       
    87 	Kern::InfoCopy(aDes, b);
       
    88 	}
       
    89 
       
    90 // Create a channel on the device.
       
    91 TInt DDeviceIicClient::Create(DLogicalChannelBase*& aChannel)
       
    92 	{
       
    93 	__KTRACE(Kern::Printf("DDeviceIicClient::Create(DLogicalChannelBase*& aChannel)"));
       
    94 
       
    95 	if (iOpenChannels >= KMaxNumChannels)
       
    96 		{
       
    97 		return KErrOverflow;
       
    98 		}
       
    99 	aChannel = new DChannelIicClient;
       
   100 	return aChannel ? KErrNone : KErrNoMemory;
       
   101 	}
       
   102 
       
   103 DChannelIicClient::DChannelIicClient()
       
   104 	{
       
   105 	iClient = &Kern::CurrentThread();
       
   106 	iSlaveCallback = NULL;
       
   107 	// Increase the DThread's ref count so that it does not close without us
       
   108 	iClient->Open();
       
   109 	}
       
   110 
       
   111 DChannelIicClient::~DChannelIicClient()
       
   112 	{
       
   113 	__KTRACE(Kern::Printf("DChannelIicClient::~DChannelIicClient()"));
       
   114 	iDfcQue->Destroy();
       
   115 	
       
   116 	//free memory:
       
   117 	delete iSpiHeader;
       
   118 #ifdef STANDALONE_CHANNEL
       
   119 #ifdef MASTER_MODE
       
   120 	if(iMasterChannel)
       
   121 		delete iMasterChannel;
       
   122 #endif/*MASTER_MODE*/
       
   123 	
       
   124 #ifdef SLAVE_MODE
       
   125 	if(iSlaveChannel)
       
   126 		delete iSlaveChannel;
       
   127 #endif/*SLAVE_MODE*/
       
   128 #endif
       
   129 	
       
   130 	// decrement the DThread's reference count
       
   131     Kern::SafeClose((DObject*&) iClient, NULL);
       
   132 	}
       
   133 
       
   134 TInt DChannelIicClient::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/,
       
   135         const TVersion& /*aVer*/)
       
   136 	{
       
   137 	__KTRACE(Kern::Printf("DChannelIicClient::DoCreate(), UNIT %d", aUnit));
       
   138 	TInt r = KErrNone;
       
   139 
       
   140 	// Bus Realisation Config iCsiBusId;
       
   141 	iCsiBusId = 0;
       
   142 	SET_BUS_TYPE(iCsiBusId,DIicBusChannel::ESpi);
       
   143 	SET_CHAN_NUM(iCsiBusId,KCodecChannelNumber);
       
   144 	SET_SLAVE_ADDR(iCsiBusId,14);
       
   145 	
       
   146 #ifdef STANDALONE_CHANNEL
       
   147 #ifdef MASTER_MODE
       
   148 	// create channel 0 - as master..
       
   149 	iMasterChannel = DCsiChannelMaster::New(0, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex);
       
   150 	if (!iMasterChannel)
       
   151 		{
       
   152 		__KTRACE_OPT(KIIC, Kern::Printf("Error no memory"));
       
   153 		return KErrNoMemory;
       
   154 		}
       
   155 #endif /*MASTER_MODE*/
       
   156 	
       
   157 #ifdef SLAVE_MODE
       
   158 	// and created channel 1 - as slave..
       
   159 	iSlaveChannel = DCsiChannelSlave::New(1, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex);
       
   160 	if (!iSlaveChannel)
       
   161 		{
       
   162 		__KTRACE_OPT(KIIC, Kern::Printf("Error no memory"));
       
   163 		#ifdef MASTER_MODE
       
   164 		delete iMasterChannel; //Free memory
       
   165 		#endif
       
   166 		return KErrNoMemory;
       
   167 		}
       
   168 #endif  /*SLAVE_MODE*/
       
   169 
       
   170 
       
   171 #endif/*STANDALONE_CHANNEL*/
       
   172 	
       
   173 	r = Kern::DynamicDfcQCreate(iDfcQue, KIicClientThreadPriority, KIicClientThreadName);
       
   174 	if(r == KErrNone)
       
   175 		{
       
   176 		iSpiHeader = new TConfigSpiBufV01(DefaultHeader);
       
   177 		if(iSpiHeader)
       
   178 			{
       
   179 			SetDfcQ(iDfcQue);
       
   180 			iMsgQ.Receive();
       
   181 			}
       
   182 		else
       
   183 			{
       
   184 			r = KErrNoMemory;
       
   185 			}
       
   186 		}
       
   187 	return r;
       
   188 	}
       
   189 
       
   190 void DChannelIicClient::HandleMsg(TMessageBase* aMsg)
       
   191 	{
       
   192 	TThreadMessage& m = *(TThreadMessage*) aMsg;
       
   193 	TInt id = m.iValue;
       
   194 
       
   195 	if (id == ECloseMsg)
       
   196 		{
       
   197 		// make sure, we've released the SlaveChannel on closure..
       
   198 		DoControl(RBusCsiTestClient::EReleaseSlaveChannel, NULL, NULL);
       
   199 
       
   200 		iMsgQ.iMessage->Complete(KErrNone, EFalse);
       
   201 		return;
       
   202 		}
       
   203 	else if (id == KMaxTInt)
       
   204 		{
       
   205 		DoCancel(m.Int0());
       
   206 		m.Complete(KErrNone, ETrue);
       
   207 		return;
       
   208 		}
       
   209 
       
   210 	if (id < 0)
       
   211 		{
       
   212 		TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
       
   213 		TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
       
   214 		if (r != KErrNone)
       
   215 			{
       
   216 			Kern::RequestComplete(iClient, pS, r);
       
   217 			}
       
   218 		m.Complete(KErrNone, ETrue);
       
   219 		}
       
   220 	else
       
   221 		{
       
   222 		TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
       
   223 		m.Complete(r, ETrue);
       
   224 		}
       
   225 	}
       
   226 
       
   227 void DChannelIicClient::DoCancel(TInt aMask)
       
   228 	{
       
   229 	// Cancel an outstanding request.
       
   230 	// Not implemented.
       
   231 	return;
       
   232 	}
       
   233 
       
   234 #ifdef MASTER_MODE
       
   235 TInt DChannelIicClient::QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback *aCallback/*=NULL*/)
       
   236 	{
       
   237 #ifndef STANDALONE_CHANNEL
       
   238 	if(!aCallback)
       
   239 		return IicBus::QueueTransaction(aBusId, aTransaction);
       
   240 	else
       
   241 		return IicBus::QueueTransaction(aBusId, aTransaction, aCallback);
       
   242 #else
       
   243 	if(iMasterChannel)
       
   244 		{
       
   245 		aTransaction->iBusId = aBusId;
       
   246 		if(!aCallback)
       
   247 			return iMasterChannel->QueueTransaction(aTransaction);
       
   248 		else
       
   249 			return iMasterChannel->QueueTransaction(aTransaction, aCallback);
       
   250 		}
       
   251 	else 
       
   252 		return KErrGeneral; //iMaster not initialised? - channels not created?
       
   253 #endif
       
   254 	}
       
   255 #endif /*MASTER_MODE*/
       
   256 
       
   257 #ifdef SLAVE_MODE
       
   258 TInt DChannelIicClient::RegisterRxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset)
       
   259 	{
       
   260 #ifdef STANDALONE_CHANNEL
       
   261 	if(iSlaveChannel)
       
   262 		return iSlaveChannel->RegisterTxBuffer(aRxBuffer, aBufGranularity, aNumWords, aOffset);
       
   263 	else 
       
   264 		return KErrGeneral;
       
   265 #else
       
   266 	return IicBus::RegisterRxBuffer(aChannelId, aRxBuffer, aBufGranularity, aNumWords, aOffset);
       
   267 #endif
       
   268 	}
       
   269 
       
   270 TInt DChannelIicClient::RegisterTxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset)
       
   271 	{
       
   272 #ifdef STANDALONE_CHANNEL
       
   273 	if(iSlaveChannel)
       
   274 		return iSlaveChannel->RegisterTxBuffer(aRxBuffer, aBufGranularity, aNumWords, aOffset);
       
   275 	else 
       
   276 		return KErrGeneral;
       
   277 #else
       
   278 	return IicBus::RegisterTxBuffer(aChannelId, aRxBuffer, aBufGranularity, aNumWords, aOffset);
       
   279 #endif
       
   280 	}
       
   281 
       
   282 TInt DChannelIicClient::CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch)
       
   283 	{
       
   284 #ifdef STANDALONE_CHANNEL
       
   285 	if(iSlaveChannel)
       
   286 		return iSlaveChannel->CaptureChannel(aConfigHdr, aCallback, aChannelId, aAsynch);
       
   287 	else 
       
   288 		return KErrGeneral;
       
   289 #else
       
   290 	return IicBus::CaptureChannel(aBusId, aConfigHdr, aCallback, aChannelId, aAsynch);
       
   291 #endif
       
   292 	}
       
   293 
       
   294 
       
   295 TInt DChannelIicClient::ReleaseChannel(TInt aChannelId)
       
   296 	{
       
   297 #ifdef STANDALONE_CHANNEL
       
   298 	if(iSlaveChannel)
       
   299 		return iSlaveChannel->ReleaseChannel();
       
   300 	else 
       
   301 		return KErrGeneral;
       
   302 #else
       
   303 		return IicBus::ReleaseChannel(aChannelId);
       
   304 #endif
       
   305 	}
       
   306 
       
   307 TInt DChannelIicClient::SetNotificationTrigger(TInt aChannelId, TInt aTrigger)
       
   308 	{
       
   309 #ifdef STANDALONE_CHANNEL
       
   310 	if(iSlaveChannel)
       
   311 		return iSlaveChannel->SetNotificationTrigger(aTrigger);
       
   312 	else
       
   313 		return KErrGeneral;
       
   314 #else
       
   315 		return IicBus::SetNotificationTrigger(aChannelId, aTrigger);
       
   316 #endif
       
   317 	}
       
   318 #endif /*SLAVE_MODE*/
       
   319 
       
   320 // This test tests the timeout for the half-duplex Write requests.
       
   321 // it creates a transaction with one transfer.
       
   322 // Clk 200kHz actually sets the clock to  260000 kHz. With 8bit granularity - gives 25kB/s
       
   323 // 32,5 bytes should be transferred in 1ms
       
   324 // so e.g. setting the timeout to 1ms and the transfer size to more than that 32 bytes should
       
   325 // cause a transfer timeout for transmission.
       
   326 // test case:
       
   327 // 1. setting timeout to 1ms with buffer 128 bytes - should result in KErrTImeout return value.
       
   328 // 2. setting timeout to 5ms (~160 bytes transfer) - should result in KErrNone return value.
       
   329 #ifdef MASTER_MODE
       
   330 TInt DChannelIicClient::TestTransferTimeout()
       
   331 	{
       
   332 	__KTRACE(Kern::Printf("DChannelIicClient::TestTransferTimeout()"));
       
   333 	TInt r = KErrNone;
       
   334 
       
   335 	TUint32 busId = 0;
       
   336 	SET_BUS_TYPE(busId,DIicBusChannel::ESpi);
       
   337 	SET_CHAN_NUM(busId,0);
       
   338 	SET_SLAVE_ADDR(busId,13); // test it with any number between 1-32
       
   339 
       
   340 	// Create a transaction header
       
   341 	const TConfigSpiV01 TestHeader =
       
   342 		{
       
   343 		ESpiWordWidth_8, //iWordWidth
       
   344 		260000, //iClkSpeed
       
   345 		ESpiPolarityLowRisingEdge, //iClkMode
       
   346 		1, // iTimeoutPeriod
       
   347 		EBigEndian, // iEndianness
       
   348 		EMsbFirst, //iBitOrder
       
   349 		0, //iTransactionWaitCycles
       
   350 		ESpiCSPinActiveLow //iCsPinActiveMode
       
   351 		};
       
   352 
       
   353 	TPckgBuf<TConfigSpiV01> header(TestHeader);
       
   354 
       
   355 	// create transfer object
       
   356 	TBuf8<128> transfer_buf; // buffer..
       
   357 	transfer_buf.SetLength(transfer_buf.MaxLength());
       
   358 
       
   359 	TIicBusTransfer transfer(TIicBusTransfer::EMasterWrite, 8, &transfer_buf);
       
   360 
       
   361 	// Create a transaction using header and transfer..
       
   362 	TIicBusTransaction transaction1(&header, &transfer);
       
   363 
       
   364 	// this transaction should return KErrTimeout
       
   365 	r = QueueTransaction(busId, &transaction1);
       
   366 
       
   367 	if (r != KErrTimedOut)
       
   368 		{
       
   369 		__KTRACE(Kern::Printf("no timeout??, r= %d", r));
       
   370 		return r;
       
   371 		}
       
   372 
       
   373 	// change the timeout to  and create another transaction..
       
   374 	header().iTimeoutPeriod = 6; // it works for 4 too (~130Bytes)
       
   375 	transfer_buf.SetLength(transfer_buf.MaxLength());
       
   376 	TIicBusTransfer transfer2(TIicBusTransfer::EMasterWrite, 8, &transfer_buf);
       
   377 
       
   378 	TIicBusTransaction transaction2(&header, &transfer2);
       
   379 
       
   380 	// this transaction should return KErrNone
       
   381 	r = QueueTransaction(busId, &transaction2);
       
   382 
       
   383 	if (r != KErrNone)
       
   384 		{
       
   385 		__KTRACE(Kern::Printf("Transaction failed, r= %d", r));
       
   386 		}
       
   387 
       
   388 	return r;
       
   389 	}
       
   390 
       
   391 TInt DChannelIicClient::TestHalfDuplexTransaction()
       
   392 	{
       
   393 	__KTRACE(Kern::Printf("DChannelIicClient::TestHalfDuplexTransaction()"));
       
   394 	TInt r = KErrNone;
       
   395 
       
   396 	TUint32 busId = 0;
       
   397 	SET_BUS_TYPE(busId,DIicBusChannel::ESpi);
       
   398 	SET_CHAN_NUM(busId,0);
       
   399 	SET_SLAVE_ADDR(busId,13); // test it with any number between 1-32
       
   400 
       
   401 	// create header
       
   402 	const TConfigSpiV01 TestHeader =
       
   403 		{
       
   404 		ESpiWordWidth_8, //iWordWidth
       
   405 		260000, //iClkSpeed
       
   406 		ESpiPolarityLowRisingEdge, //iClkMode
       
   407 		500, // iTimeoutPeriod
       
   408 		EBigEndian, // iEndianness
       
   409 		EMsbFirst, //iBitOrder
       
   410 		0, //iTransactionWaitCycles
       
   411 		ESpiCSPinActiveLow //iCsPinActiveMode
       
   412 		};
       
   413 
       
   414 	TPckgBuf<TConfigSpiV01> header(TestHeader);
       
   415 
       
   416 	// create transfer object
       
   417 	TBuf8<32> txTransferBuf; // buffer..
       
   418 	TBuf8<32> rxTransferBuf; // buffer..
       
   419 	for (TInt i = 0; i < txTransferBuf.MaxLength(); ++i)
       
   420 		{
       
   421 		txTransferBuf.Append(i);
       
   422 		}
       
   423 	txTransferBuf.SetLength(txTransferBuf.MaxLength());
       
   424 	rxTransferBuf.SetLength(rxTransferBuf.MaxLength());
       
   425 
       
   426 	// combine some transfers -in one transaction.
       
   427 	TIicBusTransfer txTransfer(TIicBusTransfer::EMasterWrite, 8, &txTransferBuf);
       
   428 	TIicBusTransfer rxTransfer(TIicBusTransfer::EMasterRead, 8, &rxTransferBuf);
       
   429 	txTransfer.LinkAfter(&rxTransfer);
       
   430 
       
   431 	TIicBusTransfer txTransfer2(TIicBusTransfer::EMasterWrite, 8, &txTransferBuf);
       
   432 	rxTransfer.LinkAfter(&txTransfer2);
       
   433 
       
   434 	TIicBusTransfer  rxTransfer2(TIicBusTransfer::EMasterRead, 8, &rxTransferBuf);
       
   435 	txTransfer2.LinkAfter(&rxTransfer2);
       
   436 
       
   437 	// Create a transaction using header and list of transfers..
       
   438 	TIicBusTransaction transaction(&header, &txTransfer);
       
   439 
       
   440 	// queue the transaction - it should complete successful
       
   441 	r = QueueTransaction(busId, &transaction);
       
   442 
       
   443 	return r;
       
   444 	}
       
   445 
       
   446 TInt DChannelIicClient::TestBulkTransfer()
       
   447 	{
       
   448 	//Create a Transaction object which  contains 2 Transfers. of buffer sizes say 256 and 64
       
   449 	const TUint8 KTrBuf1Length = 128;
       
   450 	const TUint8 KTrBuf2Length = 64;
       
   451 
       
   452 	TUint32 busId = 0;
       
   453 	SET_BUS_TYPE(busId,DIicBusChannel::ESpi);
       
   454 	SET_CHAN_NUM(busId,0);
       
   455 	SET_SLAVE_ADDR(busId,5);
       
   456 
       
   457 	// create header
       
   458 	const TConfigSpiV01 TestHeader =
       
   459 		{
       
   460 		ESpiWordWidth_16, //iWordWidth
       
   461 		260000, //iClkSpeed
       
   462 		ESpiPolarityLowRisingEdge, //iClkMode
       
   463 		3000, // iTimeoutPeriod
       
   464 		EBigEndian, // iEndianness
       
   465 		EMsbFirst, //iBitOrder
       
   466 		0, //iTransactionWaitCycles
       
   467 		ESpiCSPinActiveLow //iCsPinActiveMode
       
   468 		};
       
   469 
       
   470 	TPckgBuf<TConfigSpiV01> header(TestHeader);
       
   471 
       
   472 	TBuf8<KTrBuf1Length> transBuf1;
       
   473 	TBuf8<KTrBuf2Length> transBuf2;
       
   474 	TInt r = KErrNone;
       
   475 
       
   476 	for (TInt i = 0; i < KTrBuf1Length; ++i)
       
   477 		{
       
   478 		transBuf1.Append(i + '0');
       
   479 		}
       
   480 
       
   481 	for (TInt i = 0; i < KTrBuf2Length; ++i)
       
   482 		{
       
   483 		transBuf2.Append(i + 'a');
       
   484 		}
       
   485 
       
   486 	transBuf1.SetLength(KTrBuf1Length);
       
   487 	transBuf2.SetLength(KTrBuf2Length);
       
   488 
       
   489 	//TIicBusTransfer  trans1;
       
   490 	TIicBusTransfer trans1(TIicBusTransfer::TIicBusTransfer::EMasterWrite, 8, &transBuf2);
       
   491 	TIicBusTransfer trans2(TIicBusTransfer::TIicBusTransfer::EMasterRead, 8, &transBuf1);
       
   492 	trans1.LinkAfter(&trans2);
       
   493 
       
   494 	// for the other direction - re-use buffers..(they will be interleaved)
       
   495 	TIicBusTransfer trans3(TIicBusTransfer::TIicBusTransfer::EMasterRead, 8, &transBuf1);
       
   496 	TIicBusTransfer trans4(TIicBusTransfer::TIicBusTransfer::EMasterWrite, 8, &transBuf2);
       
   497 	trans3.LinkAfter(&trans4);
       
   498 
       
   499 	// transaction
       
   500 	TIicBusTransaction trans(&header, &trans1); // this will set the transaction with trans1 and trans2
       
   501 	trans.SetFullDuplexTrans(&trans3); // and this will add trans3 and trans4 for the other direction
       
   502 
       
   503 	r = QueueTransaction(busId, &trans);
       
   504 
       
   505 	return r;
       
   506 	}
       
   507 
       
   508 // Testing CSI interface with AudioCodec:
       
   509 // this involves several CSI write transactions to set-up the AudioCodec
       
   510 // and configure it to generate the sound (of a particular frequency)
       
   511 
       
   512 // CSI configuration parameters needed to transmit data to the Codec
       
   513 // these are used as the transaction header object.
       
   514 const TConfigSpiV01 KCodecSpiV01Config =
       
   515 	{
       
   516 	ESpiWordWidth_8, //iWordWidth
       
   517 	260000, //iClkSpeed
       
   518 	ESpiPolarityHighFallingEdge, //iClkMode
       
   519 	100, // iTimeoutPeriod
       
   520 	EBigEndian, // iEndianness
       
   521 	EMsbFirst, //iBitOrder
       
   522 	0, //iTransactionWaitCycles
       
   523 	ESpiCSPinActiveLow //iCsPinActiveMode
       
   524 	};
       
   525 
       
   526 // helper function - to update buffer data and queue the transaction with the updated data
       
   527 TInt DChannelIicClient::QueueRegisterWriteTransaction(TInt16 aRegister,
       
   528         TInt16 aValue, TIicBusTransaction* aTrans, TInt aConfig)
       
   529 	{
       
   530 	iTransBuff().iRegister = aRegister;
       
   531 	iTransBuff().iData = aValue;
       
   532 	TInt r = QueueTransaction(aConfig, aTrans);
       
   533 	return r;
       
   534 	}
       
   535 
       
   536 // this method configures the codec and sets its registers to create a sound of
       
   537 // requested frequency, duration time, volume and the time..etc..
       
   538 // to set these params we will be using single transactions - reusing all objects created on the stack:
       
   539 // - transaction (TIicBusTransaction),
       
   540 // - header object (TConfigSpiV01 - embedded in  TPckgBuf<TConfigSpiV01> headerBuff)
       
   541 // - TIicBusRealisationConfig - busId / config
       
   542 
       
   543 TInt DChannelIicClient::TestAudioCodecBeep(TUint8 aFreq, TUint8 aTime,
       
   544         TUint8 aOffTime, TUint8 aVolume, TBool aRepeat /*=0*/)
       
   545 	{
       
   546 	__KTRACE(Kern::Printf("DChannelIicClient::TestAudioCodecBeep()"));
       
   547 
       
   548 	// enable and configure pin 25 - it is connected to the chip's reset line
       
   549 	GPIO::SetPinMode(KCodecResetPin, GPIO::EEnabled);
       
   550 	GPIO::SetPinDirection(KCodecResetPin, GPIO::EOutput);
       
   551 	GPIO::SetDebounceTime(KCodecResetPin, 0);
       
   552 
       
   553 	// Bus Realisation Config
       
   554 	TUint32 iCsiBusId = 0;
       
   555 	SET_BUS_TYPE(iCsiBusId,DIicBusChannel::ESpi);
       
   556 	SET_CHAN_NUM(iCsiBusId,KCodecChannelNumber);
       
   557 	SET_SLAVE_ADDR(iCsiBusId,KCodecCSPin); // use codec's CS pin number as a Slave address
       
   558 
       
   559 	TInt config = iCsiBusId;
       
   560 
       
   561 	// create header
       
   562 	TPckgBuf<TConfigSpiV01> header(KCodecSpiV01Config);
       
   563 
       
   564 	// create transfer object - use iTransBuff member, which contains RCS42AudioCodec::TCodecConfigData
       
   565 	TIicBusTransfer transfer(TIicBusTransfer::EMasterWrite, 8, &iTransBuff);
       
   566 	TIicBusTransaction transaction(&header, &transfer);
       
   567 
       
   568 	// setup the transaction - to use this header and transfer object
       
   569 	transaction.SetHalfDuplexTrans(&header, &transfer);
       
   570 
       
   571 	// fill the TCodecConfigData.Address only once, it won't change..
       
   572 	iTransBuff().iAddress = KCodecWriteCommand;
       
   573 
       
   574 	// power-up sequence..
       
   575 	// put !reset line high to start the power-up sequence..
       
   576 	//    GPIO::SetOutputState(KCodecResetPin, GPIO::ELow);
       
   577 	GPIO::SetOutputState(KCodecResetPin, GPIO::EHigh);
       
   578 
       
   579 	TInt r = KErrNone;
       
   580 
       
   581 	r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN, &transaction, config);
       
   582 	CHECK_ERR(r);
       
   583 
       
   584 	r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN_ALL, &transaction, config);
       
   585 	CHECK_ERR(r);
       
   586 
       
   587 	// freeze all registers.. until are set-up.
       
   588 	r = QueueRegisterWriteTransaction(KHwCS42L51DACControl, KHtCS42L51DACControl_FREEZE, &transaction, config);
       
   589 	CHECK_ERR(r);
       
   590 
       
   591 	//Set Mic power control and speed control register(0x03)
       
   592 	r = QueueRegisterWriteTransaction(KHwCS42L51MicPwrSpeed, KHtCS42L51MicPwrSpeed_AUTO, &transaction, config);
       
   593 	CHECK_ERR(r);
       
   594 
       
   595 	// interface control (0x04) // serial port settings..
       
   596 	// I2s, Slave, SDOUT->SDIN internally connected.. Digimix->ON?
       
   597 	// use I2S format, Slave, Digital & Mic mix
       
   598 	TUint16 val = (KHCS42L51CtrlI2sUpto24bit << KHsCS42L51CtrlFormat)
       
   599 	        | KHtCS42L51Ctrl_DIGMIX | KHtCS42L51Ctrl_MICMIX;
       
   600 	r = QueueRegisterWriteTransaction(KHwCS42L51Ctrl, val, &transaction, config);
       
   601 	CHECK_ERR(r);
       
   602 
       
   603 	// DAC output select (0x08)
       
   604 	//      7      6        5        4          3        2         1        0
       
   605 	// HP_GAIN2 HP_GAIN1 HP_GAIN0 DAC_SNGVOL INV_PCMB INV_PCMA DACB_MUTE DACA_MUTE
       
   606 	r = QueueRegisterWriteTransaction(KHwCS42L51DACOutputControl, KHtCS42L51DACOutputControl_DAC_SNGVOL, &transaction, config);
       
   607 	CHECK_ERR(r);
       
   608 
       
   609 	// ALCX & PGAX ctrl, A(0x0A), B (0x0B)
       
   610 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PGA_A_Control, 0, &transaction, config);
       
   611 	CHECK_ERR(r);
       
   612 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PGA_B_Control, 0, &transaction, config);
       
   613 	CHECK_ERR(r);
       
   614 
       
   615 	// ADCx Mixer Volume Ctrl A(0x0E), B (0x0F)
       
   616 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_ADC_A_MixVolume, 0x10, &transaction, config);
       
   617 	CHECK_ERR(r);
       
   618 
       
   619 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_ADC_B_MixVolume, 0x10, &transaction, config);
       
   620 	CHECK_ERR(r);
       
   621 
       
   622 	// PCMx Volume Ctrl A(0x10), B (0x11)
       
   623 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PCM_A_MixVolume, 0x10, &transaction, config);
       
   624 	CHECK_ERR(r);
       
   625 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PCM_B_MixVolume, 0x10, &transaction, config);
       
   626 	CHECK_ERR(r);
       
   627 
       
   628 	// Volume Control: AOUTA (Address 16h) & AOUTB (Address 17h)
       
   629 	//send next one..
       
   630 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Out_A_Volume, 0x10, &transaction, config);
       
   631 	CHECK_ERR(r);
       
   632 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Out_B_Volume, 0x10, &transaction, config);
       
   633 	CHECK_ERR(r);
       
   634 
       
   635 	// DAC Control (Address 09h)
       
   636 	//      7        6       5       4       3      2      1        0
       
   637 	// DATA_SEL1 DATA_SEL0 FREEZE Reserved DEEMPH AMUTE DAC_SZC1 DAC_SZC0
       
   638 	// DATA_SEL1 DATA_SEL0:
       
   639 	// 00 - PCM Serial Port to DAC
       
   640 	// 01 - Signal Processing Engine to DAC
       
   641 	// 10 - ADC Serial Port to DAC    (11 - Reserved)
       
   642 	r = QueueRegisterWriteTransaction(KHwCS42L51DACControl, (1 << KHsCS42L51DACControl_DATA_SEL), &transaction, config);
       
   643 	CHECK_ERR(r);
       
   644 
       
   645 	// power-up sequence..end - clear PDN ..after loading register settings..
       
   646 	r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, 0, &transaction, config);
       
   647 	CHECK_ERR(r);
       
   648 
       
   649 	// now - the codec is ready to generate the beep of requested frequency..
       
   650 	// Set the beep frequency and time..
       
   651 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Beep_FQ_Time, (aFreq
       
   652 	    << KHsCS42L51ALC_Beep_FQ) | (aTime & KHmCS42L51ALC_Beep_Time_Mask), &transaction, config);
       
   653 	CHECK_ERR(r);
       
   654 
       
   655 	// Set the Volume and off time
       
   656 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Beep_Off_Volume,
       
   657 	    (aOffTime << KHsCS42L51ALC_Beep_Off) | (aVolume & KHmCS42L51ALC_Beep_Volume_Mask),
       
   658 	    &transaction, config);
       
   659 	CHECK_ERR(r);
       
   660 
       
   661 	// set the 'repeat' bit and enable the beep..
       
   662 	r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Beep_Conf_Tone,
       
   663 	    (aRepeat ? KHtCS42L51ALC_Beep_Conf_Tone_REPEAT : 0) |
       
   664 	    KHtCS42L51ALC_Beep_Conf_Tone_BEEP, &transaction, config);
       
   665 	CHECK_ERR(r);
       
   666 
       
   667 	NKern::Sleep(500); // give it some time to play ;)
       
   668 
       
   669 	// power down the codec:
       
   670 	r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN, &transaction, config);
       
   671 	CHECK_ERR(r);
       
   672 
       
   673 	GPIO::SetOutputState(KCodecResetPin, GPIO::ELow);
       
   674 	return KErrNone;
       
   675 	}
       
   676 
       
   677 
       
   678 // Test Transaction with different configuration settings
       
   679 // 1) Different Header settinngs (TConfigSpiBufV01))
       
   680 // 2) Different Bus Config settings (Bus Realisation Config)
       
   681 TInt DChannelIicClient::TestConfigParams(TInt aBusId)
       
   682 	{
       
   683 	TInt r = KErrNone;
       
   684 
       
   685 	const TUint8 KTrasferBufferLength = 120;
       
   686 
       
   687 	//First Create a Half Duplex Transfer List of 3 Transfers of Type W,R,W
       
   688 	TBuf8<KTrasferBufferLength> trBuf1;
       
   689 	TBuf8<KTrasferBufferLength> trBuf2;
       
   690 
       
   691 	TIicBusTransfer hdTrasfer1(TIicBusTransfer::EMasterWrite, 8, &trBuf1);
       
   692 	TIicBusTransfer hdTrasfer2(TIicBusTransfer::EMasterRead, 8, &trBuf2);
       
   693 
       
   694 	//Link the Half Duplex Transfers 1->2
       
   695 	hdTrasfer1.LinkAfter(&hdTrasfer2);
       
   696 
       
   697 	//Create A Ful Duplex Transfer of 3 Transfers of type ,R,W,R
       
   698 	TBuf8<KTrasferBufferLength> trBuf3;
       
   699 	TBuf8<KTrasferBufferLength> trBuf4;
       
   700 
       
   701 	TIicBusTransfer fdTrasfer1(TIicBusTransfer::EMasterRead, 8, &trBuf3);
       
   702 	TIicBusTransfer fdTrasfer2(TIicBusTransfer::EMasterWrite, 8, &trBuf4);
       
   703 
       
   704 	//Link the Full Duplex Transfers 1->2
       
   705 	fdTrasfer1.LinkAfter(&fdTrasfer2);
       
   706 
       
   707 	for (TUint i = 0; i < KTrasferBufferLength; i++)
       
   708 		{
       
   709 		//Fill the Buffers  associated with Write Transfer with some data
       
   710 		trBuf1.Append(i + '0');
       
   711 		trBuf4.Append(i + 'A');
       
   712 		}
       
   713 
       
   714 	trBuf1.SetLength(KTrasferBufferLength);
       
   715 	trBuf2.SetLength(KTrasferBufferLength);
       
   716 	trBuf3.SetLength(KTrasferBufferLength);
       
   717 	trBuf4.SetLength(KTrasferBufferLength);
       
   718 
       
   719 	// Create a transaction using header and transfer..
       
   720 	TIicBusTransaction fdTransaction(iSpiHeader, &hdTrasfer1);
       
   721 
       
   722 	fdTransaction.SetFullDuplexTrans(&fdTrasfer1);
       
   723 
       
   724 	// Queue Transaction
       
   725 	r = QueueTransaction(aBusId, &fdTransaction);
       
   726 
       
   727 	return r;
       
   728 	}
       
   729 
       
   730 
       
   731 // Test Duplex Transaction
       
   732 // Construct two chain of combined transfers for the transaction:
       
   733 // 1) A Half Duplex Transfer with a Read , Write and Read  operation
       
   734 // 2) A Full Duplex Transfer with a Write, Read and Write Operation.
       
   735 TInt DChannelIicClient::TestDuplexTransaction()
       
   736 	{
       
   737 	__KTRACE(Kern::Printf("DChannelIicClient::TestDuplexTransaction\n"));
       
   738 
       
   739 	TInt r = KErrNone;
       
   740 
       
   741 	TUint32 busId = 0;
       
   742 	SET_BUS_TYPE(busId,DIicBusChannel::ESpi);
       
   743 	SET_CHAN_NUM(busId,0);
       
   744 	SET_SLAVE_ADDR(busId,1);
       
   745 
       
   746 	// create header
       
   747 	const TConfigSpiV01 DefaultHeader =
       
   748 		{
       
   749 		ESpiWordWidth_8, //iWordWidth
       
   750 		260000, //iClkSpeed
       
   751 		ESpiPolarityLowRisingEdge, //iClkMode
       
   752 		1000, // iTimeoutPeriod
       
   753 		EBigEndian, // iEndianness
       
   754 		EMsbFirst, //iBitOrder
       
   755 		0, //iTransactionWaitCycles
       
   756 		ESpiCSPinActiveLow//iCsPinActiveMode
       
   757 		};
       
   758 
       
   759 	const TUint8 KTrasferBufferLength = 120;
       
   760 
       
   761 	TConfigSpiBufV01 header(DefaultHeader);
       
   762 
       
   763 	//First Create a Half Duplex Transfer List of 3 Transfers of Type W,R,W
       
   764 	TBuf8<KTrasferBufferLength> trBuf1;
       
   765 	TBuf8<KTrasferBufferLength> trBuf2;
       
   766 	TBuf8<KTrasferBufferLength> trBuf3;
       
   767 
       
   768 	TIicBusTransfer hdTrasfer1(TIicBusTransfer::EMasterWrite, 8, &trBuf1);
       
   769 	TIicBusTransfer hdTrasfer2(TIicBusTransfer::EMasterRead, 8, &trBuf2);
       
   770 	TIicBusTransfer hdTrasfer3(TIicBusTransfer::EMasterWrite, 8, &trBuf3);
       
   771 
       
   772 	//Link the Half Duples Transfers 1->2->3
       
   773 	hdTrasfer1.LinkAfter(&hdTrasfer2);
       
   774 	hdTrasfer2.LinkAfter(&hdTrasfer3);
       
   775 
       
   776 	//Create A Ful Duples Transfer of 3 Transfers of type ,R,W,R
       
   777 	TBuf8<KTrasferBufferLength> trBuf4;
       
   778 	TBuf8<KTrasferBufferLength> trBuf5;
       
   779 	TBuf8<KTrasferBufferLength> trBuf6;
       
   780 
       
   781 	TIicBusTransfer fdTrasfer1(TIicBusTransfer::EMasterRead, 8, &trBuf4);
       
   782 	TIicBusTransfer fdTrasfer2(TIicBusTransfer::EMasterWrite, 8, &trBuf5);
       
   783 	TIicBusTransfer fdTrasfer3(TIicBusTransfer::EMasterRead, 8, &trBuf6);
       
   784 
       
   785 	//Link the Full Duples Transfers 1->2->3
       
   786 	fdTrasfer1.LinkAfter(&fdTrasfer2);
       
   787 	fdTrasfer2.LinkAfter(&fdTrasfer3);
       
   788 
       
   789 	for (TUint i = 0; i < KTrasferBufferLength; i++)
       
   790 		{
       
   791 		//Fill the Buffers  associated with Write Transfer with some data
       
   792 		trBuf1.Append(i + '0');
       
   793 		trBuf3.Append(i + 'A');
       
   794 		trBuf5.Append(i + 'a');
       
   795 		//Read Buffers
       
   796 		trBuf2.Append('$');
       
   797 		trBuf4.Append('?');
       
   798 		trBuf6.Append('*');
       
   799 		}
       
   800 
       
   801 	trBuf1.SetLength(KTrasferBufferLength);
       
   802 	trBuf2.SetLength(KTrasferBufferLength);
       
   803 	trBuf3.SetLength(KTrasferBufferLength);
       
   804 	trBuf4.SetLength(KTrasferBufferLength);
       
   805 	trBuf5.SetLength(KTrasferBufferLength);
       
   806 	trBuf6.SetLength(KTrasferBufferLength);
       
   807 
       
   808 	// Create a transaction using header and transfer..
       
   809 	TIicBusTransaction fdTransaction(&header, &hdTrasfer1);
       
   810 	fdTransaction.SetFullDuplexTrans(&fdTrasfer1);
       
   811 
       
   812 	//Queue Transaction
       
   813 	r = QueueTransaction(busId, &fdTransaction);
       
   814 
       
   815 	return r;
       
   816 	}
       
   817 
       
   818 // Callback for Master's asynchronous transactions
       
   819 // this is called whenever the transaction has been finished.
       
   820 void DChannelIicClient::AsyncTransCallbackFunc(TIicBusTransaction* aTransaction, TInt /*aBusId*/, TInt aResult, TAny* aParam)
       
   821 	{
       
   822 	__KTRACE(Kern::Printf("DChannelIicClient::AsyncTransCallbackFunc  aResult  =%d\n",aResult));
       
   823 	TCallBckRequest<3> *cr = (TCallBckRequest<3>*)aParam;
       
   824 
       
   825 	// complete request..
       
   826 	Kern::RequestComplete(cr->iClient, cr->iReqStatus, aResult);
       
   827 
       
   828 	// now can finally delete cr object = wchich will delete 1-6 (i don't like that..TIicBusTransaction has all this info..)
       
   829 	delete cr;
       
   830 	if(aTransaction)
       
   831 	    delete aTransaction;
       
   832 	}
       
   833 
       
   834 /*
       
   835 Test Asynchronous Transaction
       
   836 with a chain of HD(HalfDuplex) transfers:  Read -> Write -> Read
       
   837 
       
   838  Memory management for asynchronous transactions: we create the following on the heap:
       
   839   1. transaction header (in DoRequest),
       
   840   2. transaction
       
   841   3. transfers for transaction (chained in linked-list)
       
   842   4. buffers for transfers
       
   843   5. IIC callback object (TIicBusCallback)
       
   844   6. callback request - which stores pointers to callback object(TIicBusCallback),
       
   845      and pointers to the client and the request status object (used by RequestComplete)
       
   846 
       
   847   All of these need to be deleted in the AsyncTransCallbackFunc
       
   848   (at the end of transaction)
       
   849 */
       
   850 const TUint8 KTrasferBufferLength = 120;
       
   851 
       
   852 TInt DChannelIicClient::TestAsynTransaction(TRequestStatus* aStatus, TConfigSpiBufV01* aSpiHeader, TInt aBusId)
       
   853 	{
       
   854 	__KTRACE(Kern::Printf("DChannelIicClient::TestAsynTransaction\n"));
       
   855 	TInt r = KErrNone;
       
   856 
       
   857 	// Store required RequestComplete pointers in our TCbRequest (6.)
       
   858 	TCallBckRequest<3> *cbRequest = new TCallBckRequest<3>(iClient, aStatus, aSpiHeader);
       
   859 
       
   860 	//Create the CallBack Function (5.)
       
   861 	TIicBusCallback *callback = new TIicBusCallback(AsyncTransCallbackFunc, (TAny*)cbRequest, iDfcQue, 5); // 5 arbitrary
       
   862 	cbRequest->iCallback = callback;
       
   863 
       
   864 	// create buffers (4.)
       
   865 	HBuf8* trBuf1 = HBuf8::New(KTrasferBufferLength);
       
   866 	cbRequest->iBuffers[0] = trBuf1;
       
   867 	HBuf8* trBuf2 = HBuf8::New(KTrasferBufferLength);
       
   868 	cbRequest->iBuffers[1] = trBuf2;
       
   869 	HBuf8* trBuf3 = HBuf8::New(KTrasferBufferLength);
       
   870 	cbRequest->iBuffers[2] = trBuf3;
       
   871 
       
   872 	// create transfers..(3.)
       
   873 	TIicBusTransfer* hdTrasfer1 = new TIicBusTransfer(TIicBusTransfer::EMasterRead, 8, trBuf1);
       
   874 	cbRequest->iTransfers[0] = hdTrasfer1;
       
   875 	TIicBusTransfer* hdTrasfer2 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite, 8, trBuf2);
       
   876 	cbRequest->iTransfers[1] = hdTrasfer2;
       
   877 	TIicBusTransfer* hdTrasfer3 = new TIicBusTransfer(TIicBusTransfer::EMasterRead, 8, trBuf3);
       
   878 	cbRequest->iTransfers[2] = hdTrasfer3;
       
   879 
       
   880 	// Create a transaction using header and transfer..(2.)
       
   881 	TIicBusTransaction* transaction = new TIicBusTransaction(aSpiHeader, hdTrasfer1);
       
   882 
       
   883 	if(!trBuf1 || !trBuf2 || !trBuf2 ||
       
   884 	   !hdTrasfer1 || !hdTrasfer2 || !hdTrasfer3 ||
       
   885 	   !transaction || ! cbRequest || !callback)
       
   886 		{
       
   887 		delete cbRequest;
       
   888 		__KTRACE(Kern::Printf("No memory for allocating transfer buffers"));
       
   889 		return KErrNoMemory;
       
   890 		}
       
   891 
       
   892 
       
   893 	// put some dummy data in buffers..
       
   894 	for (TUint i = 0; i < KTrasferBufferLength; ++i)
       
   895 		{
       
   896 		//Fill the Buffers  associated with Write Transfer with some data
       
   897 		trBuf1->Append(i + '0');
       
   898 		trBuf2->Append(i + 'a');
       
   899 		trBuf3->Append(i + 'A');
       
   900 		}
       
   901 
       
   902 	//Link the transfers 1->2->3
       
   903 	hdTrasfer1->LinkAfter(hdTrasfer2);
       
   904 	hdTrasfer2->LinkAfter(hdTrasfer3);
       
   905 
       
   906 	// Queue Transaction
       
   907 	r = QueueTransaction(aBusId, transaction, callback);
       
   908 	return r;
       
   909 	}
       
   910 #endif/*MASTER_MODE*/
       
   911 
       
   912 // =======================
       
   913 //  Slave channel tests
       
   914 //
       
   915 // callbackForOneduplex asynchronous transaction..
       
   916 void DChannelIicClient::MasterCallbackFunc(TIicBusTransaction* aTransction,
       
   917                                            TInt aBusId,
       
   918                                            TInt aResult,
       
   919                                            TAny* aParam)
       
   920 	{
       
   921 //	DChannelIicClient* a = (DChannelIicClient*) aParam;
       
   922 	__KTRACE(Kern::Printf("MasterCallbackFunc, aResult = %d", aResult));
       
   923 	}
       
   924 
       
   925 #ifdef MASTER_MODE
       
   926 // this method asynchronously queues one duplex transaction using
       
   927 // the buffers, which are part of the DChannelIicClient().
       
   928 TInt DChannelIicClient::QueueOneDuplexTransaction(TInt aSize)
       
   929 	{
       
   930 	__KTRACE(Kern::Printf("QueueOneDuplexTransaction, aSize = %d", aSize));
       
   931 
       
   932 	TInt r = KErrNone;
       
   933 	if(aSize > KMaxSlaveTestBufferSize)
       
   934 		{
       
   935 		return KErrArgument;
       
   936 		}
       
   937 
       
   938 	TUint32 busId = 0;
       
   939 	SET_BUS_TYPE(busId,DIicBusChannel::ESpi);
       
   940 	SET_CHAN_NUM(busId,0);
       
   941 	SET_SLAVE_ADDR(busId,13); // test it with any number between 1-32
       
   942 
       
   943 	// create header
       
   944 	const TConfigSpiV01 TestHeader =
       
   945 		{
       
   946 		ESpiWordWidth_8, //iWordWidth
       
   947 		260000, //iClkSpeed
       
   948 		ESpiPolarityLowRisingEdge, //iClkMode
       
   949 		500, // iTimeoutPeriod
       
   950 		EBigEndian, // iEndianness
       
   951 		EMsbFirst, //iBitOrder
       
   952 		0, //iTransactionWaitCycles
       
   953 		ESpiCSPinActiveLow //iCsPinActiveMode
       
   954 		};
       
   955 	TPckgBuf<TConfigSpiV01> header(TestHeader);
       
   956 
       
   957 	TBuf8<KMaxSlaveTestBufferSize> txBuf; // buffer..
       
   958 	TBuf8<KMaxSlaveTestBufferSize> rxBuf; // buffer..
       
   959 
       
   960 	// create transfer object
       
   961 	for (TInt i = 0; i < aSize; ++i)
       
   962 		{
       
   963 		txBuf.Append(i);
       
   964 		}
       
   965 	rxBuf.SetLength(aSize);
       
   966 
       
   967 	// combine some transfers -in one transaction.
       
   968 	TIicBusTransfer txTransfer(TIicBusTransfer::EMasterWrite, 8, &txBuf);
       
   969 	TIicBusTransfer rxTransfer(TIicBusTransfer::EMasterRead, 8, &rxBuf);
       
   970 
       
   971 	// Create a transaction using header and list of transfers..
       
   972 	iMasterTransaction.SetHalfDuplexTrans(&header, &txTransfer);
       
   973 	iMasterTransaction.SetFullDuplexTrans(&rxTransfer);
       
   974 
       
   975 	// queue the transaction
       
   976 	r = QueueTransaction(busId, &iMasterTransaction);
       
   977 
       
   978 	return r;
       
   979 	}
       
   980 #endif /*MASTER_MODE*/
       
   981 
       
   982 #ifdef SLAVE_MODE
       
   983 TInt DChannelIicClient::RegisterSlaveBuffers()
       
   984 	{
       
   985 	__KTRACE(Kern::Printf("RegisterSlaveBuffers(), size %d", iSlaveBufSize));
       
   986 	TInt r = KErrNone;
       
   987 	// put some data in the buffer - so we could see-if this is actually beeing transfered...
       
   988 	for(TInt i = 0; i < iSlaveBufSize; ++i)
       
   989 		{
       
   990 		iTxBuf.Append(i);
       
   991 		}
       
   992 
       
   993 	TPtr8 rxBuf(0, 0);
       
   994 	TPtr8 txBuf(0, 0);
       
   995 
       
   996 	rxBuf.Set((TUint8*) iRxBuf.Ptr(), iSlaveBufSize, iRxBuf.MaxLength());
       
   997 	txBuf.Set((TUint8*) iTxBuf.Ptr(), iSlaveBufSize, iTxBuf.MaxLength());
       
   998 
       
   999 	r = RegisterRxBuffer(iChannelId, rxBuf, 8, iSlaveBufSize, 0);
       
  1000 
       
  1001 	if(r != KErrNone)
       
  1002 		{
       
  1003 		__KTRACE(Kern::Printf("Error Register Rx Buffer, r %d", r));
       
  1004 		}
       
  1005 	else
       
  1006 		{
       
  1007 		r = RegisterTxBuffer(iChannelId, txBuf, 8, iSlaveBufSize, 0);	
       
  1008 		}
       
  1009 
       
  1010 	return r;
       
  1011 	}
       
  1012 
       
  1013 TInt DChannelIicClient::CaptureSlaveChannel(TInt aBufSize, TBool aAsynch /* = EFalse*/)
       
  1014 	{
       
  1015 	if(aBufSize > KMaxSlaveTestBufferSize)
       
  1016 		{
       
  1017 		return KErrArgument;
       
  1018 		}
       
  1019 
       
  1020 	TInt r = KErrNone;
       
  1021 	TUint32 slaveBusId = 0;
       
  1022 	SET_BUS_TYPE(slaveBusId,DIicBusChannel::ESpi);
       
  1023 	SET_CHAN_NUM(slaveBusId,1);
       
  1024 	
       
  1025 	// create header
       
  1026 	const TConfigSpiV01 TestHeader =
       
  1027 		{
       
  1028 		ESpiWordWidth_8, //iWordWidth
       
  1029 		260000, //iClkSpeed
       
  1030 		ESpiPolarityLowRisingEdge, //iClkMode
       
  1031 		500, // iTimeoutPeriod
       
  1032 		EBigEndian, // iEndianness
       
  1033 		EMsbFirst, //iBitOrder
       
  1034 		0, //iTransactionWaitCycles
       
  1035 		ESpiCSPinActiveLow //iCsPinActiveMode
       
  1036 		};
       
  1037 
       
  1038 	TPckgBuf<TConfigSpiV01> header(TestHeader);
       
  1039 
       
  1040 	// create callback objects for slave tests..
       
  1041 	if (!iSlaveCallback)
       
  1042 		{
       
  1043 		iSlaveCallback = new TIicBusSlaveCallback(SlaveCallbackFunc, (TAny*) this, iDfcQue, 0);
       
  1044 		}
       
  1045 
       
  1046 	if (!iMasterCallback)
       
  1047 		{
       
  1048 		iMasterCallback = new TIicBusCallback(MasterCallbackFunc, (TAny*) this, iDfcQue, 0);
       
  1049 		}
       
  1050 
       
  1051 	if (!(iSlaveCallback && iMasterCallback))
       
  1052 		{
       
  1053 		if(iSlaveCallback)
       
  1054 			{
       
  1055 			delete iSlaveCallback;
       
  1056 			}
       
  1057 
       
  1058 		if(iMasterCallback)
       
  1059 			{
       
  1060 			delete iMasterCallback;
       
  1061 			}
       
  1062 		return KErrNoMemory;
       
  1063 		}
       
  1064 
       
  1065 	TInt channelId = 0;
       
  1066 	// capture channel..
       
  1067 	r = CaptureChannel(slaveBusId, &header, iSlaveCallback, channelId, aAsynch);
       
  1068 	if (r != KErrNone)
       
  1069 		{
       
  1070 		__KTRACE(Kern::Printf("Error capturing the channel, r %d", r));
       
  1071 		}
       
  1072 	else
       
  1073 		{
       
  1074 		iSlaveBufSize = aBufSize;
       
  1075 
       
  1076 		if(!aAsynch)
       
  1077 			{
       
  1078 			iChannelId = channelId;
       
  1079 			__KTRACE(Kern::Printf("channelId %d", iChannelId));
       
  1080 			r = RegisterSlaveBuffers();
       
  1081 			}
       
  1082 		}
       
  1083 
       
  1084 	return r;
       
  1085 	}
       
  1086 
       
  1087 TInt DChannelIicClient::ReleaseSlaveChannel()
       
  1088 	{
       
  1089 	TInt r = KErrNone;
       
  1090 	// release the channel
       
  1091 
       
  1092 	if (iChannelId)
       
  1093 		{
       
  1094 		r = ReleaseChannel(iChannelId);
       
  1095 		if (r == KErrNone)
       
  1096 			{
       
  1097 			iChannelId = 0;
       
  1098 			if(iSlaveCallback)
       
  1099 				{
       
  1100 				delete iSlaveCallback;
       
  1101 				iSlaveCallback = NULL;
       
  1102 				}
       
  1103 
       
  1104 			if(iMasterCallback)
       
  1105 				{
       
  1106 				delete iMasterCallback;
       
  1107 				iMasterCallback = NULL;
       
  1108 				}
       
  1109 			}
       
  1110 		else
       
  1111 			{
       
  1112 			__KTRACE(Kern::Printf("Error releasing the channel, r %d", r));
       
  1113 			}
       
  1114 		}
       
  1115 	//	else // if the channel was released already - silently return KErrNone..
       
  1116 
       
  1117 	return r;
       
  1118 	}
       
  1119 
       
  1120 #ifdef _DEBUG
       
  1121 void PrintTrigger(TInt aTrigger)
       
  1122 	{
       
  1123 	Kern::Printf("\naReturn:");
       
  1124 	if(aTrigger & ETxAllBytes){Kern::Printf("ETxAllBytes");}
       
  1125 	if(aTrigger & ETxOverrun){Kern::Printf("ETxOverrun");}
       
  1126 	if(aTrigger & ETxUnderrun){Kern::Printf("ETxUnderrun");}
       
  1127 
       
  1128 	if(aTrigger & ERxAllBytes){Kern::Printf("ERxAllBytes");}
       
  1129 	if(aTrigger & ERxOverrun){Kern::Printf("ERxOverrun");}
       
  1130 	if(aTrigger & ERxUnderrun){Kern::Printf("ERxUnderrun");}
       
  1131 
       
  1132 	if(aTrigger & EGeneralBusError){Kern::Printf("EGeneralBusError");}
       
  1133 	if(aTrigger & EAsyncCaptChan){Kern::Printf("EAsyncCaptChan");}
       
  1134 
       
  1135 	Kern::Printf("\n");
       
  1136 	}
       
  1137 #endif
       
  1138 
       
  1139 
       
  1140 void DChannelIicClient::SlaveCallbackFunc(TInt aChannelId, TInt aReturn,
       
  1141         TInt aTrigger, TInt16 aRxWords, TInt16 aTxWords, TAny* aParam)
       
  1142 	{
       
  1143 	__KTRACE(Kern::Printf("SlaveClientCallbackFunc(),aChannelId=0x%x,aReturn=%d,aTrigger=0x%x,aRxWords=0x%x,aTxWords=0x%x,aParam=0x%x\n",aChannelId,aReturn,aTrigger,aRxWords,aTxWords,aParam));
       
  1144 
       
  1145 	DChannelIicClient* aClient = (DChannelIicClient*) aParam;
       
  1146 	if(aClient)
       
  1147 		{
       
  1148 		if(aTrigger & (EAsyncCaptChan))
       
  1149 			{
       
  1150 			if(aReturn == KErrCompletion)
       
  1151 				{
       
  1152 				aClient->iChannelId = aChannelId;
       
  1153 				__KTRACE(Kern::Printf("channelId %d", aChannelId));
       
  1154 				TInt r = aClient->RegisterSlaveBuffers();
       
  1155 				//AsyncCaptChan expects a KErrCompletion returned. 
       
  1156 				//If RegisterSlaveBuffers fails, the error code will be assigned to aReturn,
       
  1157 				//then passed back to client. 
       
  1158 				if(r != KErrNone)
       
  1159 				    aReturn = r; 
       
  1160 				}
       
  1161 
       
  1162 			Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, aReturn);
       
  1163 			return;
       
  1164 			}
       
  1165 
       
  1166 		if(aTrigger & (EGeneralBusError))
       
  1167 			{
       
  1168 #ifdef _DEBUG
       
  1169 			Kern::Printf("\n\naRxWords %d", aRxWords);
       
  1170 			Kern::Printf("aTxWords %d", aTxWords);
       
  1171 			PrintTrigger(aReturn);
       
  1172 #endif
       
  1173 			Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrGeneral);
       
  1174 			return;
       
  1175 			}
       
  1176 
       
  1177 		TInt r = KErrNone;
       
  1178 		// if there was an underrun/overrun
       
  1179 		if(aTrigger & ETxUnderrun)
       
  1180 			{
       
  1181 			TPtr8 txBuf(0, 0);
       
  1182 
       
  1183 			txBuf.Set((TUint8*) aClient->iTxBuf.Ptr(), aClient->iTxBuf.MaxLength(), aClient->iTxBuf.MaxLength());
       
  1184 
       
  1185 			// use aTxWords as an offset..
       
  1186 			if(aTxWords + 32 <= KMaxSlaveTestBufferSize)
       
  1187 				{
       
  1188 				r = aClient->RegisterTxBuffer(aClient->iChannelId, txBuf, 8, 32, aTxWords);
       
  1189 				if (r != KErrNone)
       
  1190 					{
       
  1191 			         Kern::Printf("Error Register Tx Buffer, r %d", r);
       
  1192 					}
       
  1193 				else
       
  1194 					{
       
  1195 					r = aClient->SetNotificationTrigger(aClient->iChannelId, ETxAllBytes);
       
  1196 					if (r != KErrNone)
       
  1197 						{
       
  1198 						Kern::Printf("Error setting notification trigger, r %d", r);
       
  1199 						}
       
  1200 					}
       
  1201 
       
  1202 				// updated the buffer - so return..
       
  1203 				return;
       
  1204 				}
       
  1205 			}
       
  1206 
       
  1207 		// if we've finished..
       
  1208 		if(aReturn & (ETxAllBytes | ERxAllBytes))
       
  1209 			{
       
  1210 			//PrintTrigger(aReturn);
       
  1211 			Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrNone);
       
  1212 			}
       
  1213 
       
  1214 #if 0
       
  1215 		TInt8* ptr = (TInt8*)aClient->iRxBuf.Ptr();
       
  1216 		for(TInt i = 0; i < aRxWords; ++i)
       
  1217 			{
       
  1218 			Kern::Printf("Rx item %d: %x", i, (TInt8)*(ptr+i));
       
  1219 			}
       
  1220 #endif
       
  1221 
       
  1222 		if(aTrigger & (/*ERxAllBytes |*/ ETxAllBytes))
       
  1223 			{
       
  1224 			Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrNone);
       
  1225 			}
       
  1226 		}
       
  1227 	else
       
  1228 		{
       
  1229 		Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrGeneral);
       
  1230 		}
       
  1231 
       
  1232 	}
       
  1233 
       
  1234 TInt DChannelIicClient::SetSlaveNotificationTrigger(TUint32 aTrigger)
       
  1235 	{
       
  1236 	TInt r = KErrNone;
       
  1237 	__KTRACE(Kern::Printf("DChannelIicClient::SetSlaveNotificationTrigger() aTrigger=0x%x", aTrigger));
       
  1238 
       
  1239 	if (!iChannelId)
       
  1240 		{
       
  1241 		__KTRACE(Kern::Printf("Channel not captured..Call CaptureSlaveChannel() first.."));
       
  1242 		return KErrArgument;
       
  1243 		}
       
  1244 
       
  1245 	//    ERxAllBytes         = 0x01,
       
  1246 	//    ERxUnderrun         = 0x02,
       
  1247 	//    ERxOverrun          = 0x04,
       
  1248 	//    ETxAllBytes         = 0x08,
       
  1249 	//    ETxUnderrun         = 0x10,
       
  1250 	//    ETxOverrun          = 0x20,
       
  1251 	//    EGeneralBusError    = 0x40
       
  1252 
       
  1253 	r = SetNotificationTrigger(iChannelId, aTrigger);
       
  1254 
       
  1255 	if (r != KErrNone)
       
  1256 		{
       
  1257 		__KTRACE(Kern::Printf("Error setting notification trigger, r %d", r));
       
  1258 		}
       
  1259 
       
  1260 	return r;
       
  1261 	}
       
  1262 #endif /*SLAVE_MODE*/
       
  1263 
       
  1264 // to handle synchronous requests from the client
       
  1265 TInt DChannelIicClient::DoControl(TInt aId, TAny* a1, TAny* a2)
       
  1266 	{
       
  1267 	TInt r = KErrNone;
       
  1268 	switch (aId)
       
  1269 		{
       
  1270 		case RBusCsiTestClient::ETestAudioCodecBeep:
       
  1271 			{
       
  1272 #ifdef MASTER_MODE
       
  1273 			r = TestAudioCodecBeep(0, 7, 3, 5);
       
  1274 #else/* MASTER_MODE */
       
  1275 			r = KErrNotSupported; 
       
  1276 #endif/* MASTER_MODE */
       
  1277 			break;
       
  1278 			}
       
  1279 		case RBusCsiTestClient::ETestTransferTimeout:
       
  1280 			{
       
  1281 #ifdef MASTER_MODE			
       
  1282 			r = TestTransferTimeout();
       
  1283 #else/* MASTER_MODE */
       
  1284 			r = KErrNotSupported; 
       
  1285 #endif/* MASTER_MODE */
       
  1286 			break;
       
  1287 			}
       
  1288 		case RBusCsiTestClient::ETestTestHalfDuplex:
       
  1289 			{
       
  1290 #ifdef MASTER_MODE
       
  1291 			r = TestHalfDuplexTransaction();
       
  1292 #else /* MASTER_MODE */
       
  1293             r = KErrNotSupported; 
       
  1294 #endif /* MASTER_MODE */
       
  1295 			break;
       
  1296 			}
       
  1297 		case RBusCsiTestClient::ETestBulkTransfer:
       
  1298 			{
       
  1299 #ifdef MASTER_MODE
       
  1300 			r = TestBulkTransfer();
       
  1301 #else/* MASTER_MODE */
       
  1302             r = KErrNotSupported; 
       
  1303 #endif/* MASTER_MODE */
       
  1304 			break;
       
  1305 			}
       
  1306 		case RBusCsiTestClient::ETestDuplexTransaction:
       
  1307 			{
       
  1308 #ifdef MASTER_MODE
       
  1309 			r = TestDuplexTransaction();
       
  1310 #else/* MASTER_MODE */
       
  1311             r = KErrNotSupported; 
       
  1312 #endif/* MASTER_MODE */
       
  1313 			break;
       
  1314 			}
       
  1315 		case RBusCsiTestClient::ETestConfigParams:
       
  1316 			{
       
  1317 			// This is an asynchronous transaction - so we're using iSpiHeader member
       
  1318 			// to copy the data from the user.
       
  1319 #ifdef MASTER_MODE
       
  1320 			r = Kern::ThreadDesRead(iClient, (TDes8*) a1, *iSpiHeader, 0, KChunkShiftBy0);
       
  1321 			if(r == KErrNone)
       
  1322 				{
       
  1323 				// a2 is a BusConfig value
       
  1324 				r = TestConfigParams((TInt)a2);
       
  1325 				}
       
  1326 #else/* MASTER_MODE */
       
  1327 			r = KErrNotSupported;
       
  1328 #endif/* MASTER_MODE */
       
  1329 			break;
       
  1330 			}
       
  1331 		case RBusCsiTestClient::ECaptureSlaveChannel:
       
  1332 			{
       
  1333 #ifdef SLAVE_MODE
       
  1334 			r = CaptureSlaveChannel((TInt)a1);
       
  1335 #else/* SLAVE_MODE */
       
  1336 			r = KErrNotSupported;
       
  1337 #endif/* SLAVE_MODE */
       
  1338 			break;
       
  1339 			}
       
  1340 		case RBusCsiTestClient::EReleaseSlaveChannel:
       
  1341 			{
       
  1342 #ifdef SLAVE_MODE			
       
  1343 			r = ReleaseSlaveChannel();
       
  1344 #else/* SLAVE_MODE */
       
  1345             r = KErrNotSupported;
       
  1346 #endif/* SLAVE_MODE */
       
  1347 			break;
       
  1348 			}
       
  1349 		case RBusCsiTestClient::EQueueOneDuplexTransaction:
       
  1350 			{
       
  1351 #ifdef MASTER_MODE
       
  1352 			r = QueueOneDuplexTransaction((TInt)a1);
       
  1353 #else/* MASTER_MODE */
       
  1354             r = KErrNotSupported; 
       
  1355 #endif/* MASTER_MODE */
       
  1356 			break;
       
  1357 			}
       
  1358 		default:
       
  1359 			{
       
  1360 			__KTRACE(Kern::Printf("DChannelIicClient::DoControl():Unrecognized value for aId=0x%x\n", aId));
       
  1361 			r = KErrArgument;
       
  1362 			break;
       
  1363 			}
       
  1364 		}
       
  1365 	return r;
       
  1366 	}
       
  1367 
       
  1368 // to handle asynchronous requests from the client
       
  1369 TInt DChannelIicClient::DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2)
       
  1370 	{
       
  1371 	__KTRACE(Kern::Printf("DChannelIicClient::DoRequest(aId=0x%x, aStatus=0x%x, a1=0x%x, a2=0x%x\n",
       
  1372 					aId, aStatus, a1, a2));
       
  1373 
       
  1374 	TInt r = KErrNone;
       
  1375 	switch (aId)
       
  1376 		{
       
  1377 		case RBusCsiTestClient::ETestAsynTransaction:
       
  1378 			{
       
  1379 #ifdef MASTER_MODE
       
  1380 			// Create a header, and copy it's content from the User.
       
  1381 			// it will be deleted after the transaction is completed.
       
  1382 			TConfigSpiBufV01* spiHeader = new TConfigSpiBufV01;
       
  1383 			if(spiHeader)
       
  1384 				{
       
  1385 				r = Kern::ThreadDesRead(iClient, (TDes8*) a1, *spiHeader, 0, KChunkShiftBy0);
       
  1386 				if(r == KErrNone)
       
  1387 					{
       
  1388 					// a2 is a BusConfig value
       
  1389 					r = TestAsynTransaction(aStatus, spiHeader, (TInt) a2);
       
  1390 					}
       
  1391 				else
       
  1392 					{
       
  1393 					delete spiHeader;
       
  1394 					}
       
  1395 				}
       
  1396 			else
       
  1397 				{
       
  1398 				r = KErrNoMemory;
       
  1399 				}
       
  1400 #else
       
  1401 			r = KErrNotSupported;
       
  1402 #endif/*MASTER_MODE*/
       
  1403 			break;
       
  1404 			}
       
  1405 
       
  1406 		case (RBusCsiTestClient::ECaptureSlaveChannelAsync):
       
  1407 			{
       
  1408 #ifdef SLAVE_MODE
       
  1409 			// a1 - size
       
  1410 			iSlaveReqStatus = aStatus;
       
  1411 			r = CaptureSlaveChannel((TInt) a1, ETrue);
       
  1412 #else
       
  1413 			r = KErrNotSupported;
       
  1414 #endif/*SLAVE_MODE*/
       
  1415 			break;
       
  1416 			}
       
  1417 
       
  1418 		case (RBusCsiTestClient::ESetSlaveNotificationTrigger):
       
  1419 			{
       
  1420 #ifdef SLAVE_MODE
       
  1421 			// a1 = trigger
       
  1422 			iSlaveReqStatus = aStatus;
       
  1423 			r = SetSlaveNotificationTrigger((TUint32) a1);
       
  1424 #else
       
  1425 			r = KErrNotSupported;
       
  1426 #endif
       
  1427 			break;
       
  1428 			}
       
  1429 
       
  1430 		default:
       
  1431 			{
       
  1432 			__KTRACE(Kern::Printf("DChannelIicClient::DoRequest(): unrecognized value for aId=0x%x\n", aId));
       
  1433 			r = KErrArgument;
       
  1434 			break;
       
  1435 			}
       
  1436 		}
       
  1437 	return r;
       
  1438 	}
       
  1439 
       
  1440 // LDD entry point
       
  1441 DECLARE_STANDARD_LDD()
       
  1442 	{
       
  1443 	return new DDeviceIicClient;
       
  1444 	}
       
  1445