1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/iic/t_iic.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1624 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test/iic/t_iic.cpp
1.18 +//
1.19 +
1.20 +// This file interacts with test-specific LDD to instigate tests of functionality
1.21 +// that would normally be invoked by kernel-side device driver clients of the IIC.
1.22 +#include <e32test.h>
1.23 +#include <e32cmn.h>
1.24 +#include <e32cmn_private.h>
1.25 +#include <e32def.h>
1.26 +#include <e32def_private.h>
1.27 +#include "t_iic.h"
1.28 +
1.29 +//for memory leak checking
1.30 +#include <e32svr.h>
1.31 +#include <u32hal.h>
1.32 +
1.33 +_LIT(testName,"t_iic");
1.34 +
1.35 +_LIT(KIicProxyFileNameCtrlLess, "iic_client_ctrless.ldd"); // Kernel-side proxy LDD acting as a client of the IIC
1.36 +_LIT(KIicProxyFileNameRootCtrlLess, "iic_client_ctrless");
1.37 +_LIT(KIicProxySlaveFileNameCtrlLess, "iic_slaveclient_ctrless.ldd"); // Kernel-side proxy LDD acting as a slave client of the IIC
1.38 +_LIT(KIicProxySlaveFileNameRootCtrlLess, "iic_slaveclient_ctrless");
1.39 +_LIT(KIicProxyFileName, "iic_client.ldd"); // Kernel-side proxy LDD acting as a client of the IIC
1.40 +_LIT(KIicProxyFileNameRoot, "iic_client");
1.41 +_LIT(KIicProxySlaveFileName, "iic_slaveclient.ldd"); // Kernel-side proxy LDD acting as a slave client of the IIC
1.42 +_LIT(KIicProxySlaveFileNameRoot, "iic_slaveclient");
1.43 +
1.44 +#ifdef IIC_SIMULATED_PSL
1.45 +_LIT(KSpiFileNameCtrlLess, "spi_ctrless.pdd"); // Simulated PSL bus implementation
1.46 +_LIT(KI2cFileNameCtrlLess, "i2c_ctrless.pdd"); // Simulated PSL bus implementation
1.47 +_LIT(KIicPslFileName, "iic_testpsl.pdd"); // Simulated PSL implementation
1.48 +_LIT(KSpiFileName, "spi.pdd"); // Simulated PSL bus implementation
1.49 +_LIT(KI2cFileName, "i2c.pdd"); // Simulated PSL bus implementation
1.50 +#endif
1.51 +
1.52 +_LIT(KIicPslFileNameRoot, "iic.pdd");
1.53 +
1.54 +// Specify a stand-alone channel
1.55 +GLDEF_D TBool aStandAloneChan;
1.56 +
1.57 +GLDEF_D RTest gTest(testName);
1.58 +
1.59 +
1.60 +// SPI has Master channel numbers 1,2 and 4, Slave channel number 3
1.61 +GLDEF_D RBusDevIicClient gChanMasterSpi;
1.62 +GLDEF_D RBusDevIicClient gChanSlaveSpi;
1.63 +
1.64 +// I2C has Master channel numbers 10 and 11, if built with MASTER_MODE, only
1.65 +// I2C has Slave channel numbers 12 and 13, if built with SLAVE_MODE, only
1.66 +// I2C has Master channel number 10 and Slave channel number 11 if built with both MASTER_MODE and SLAVE_MODE
1.67 +GLDEF_D RBusDevIicClient gChanMasterI2c;
1.68 +GLDEF_D RBusDevIicClient gChanSlaveI2c;
1.69 +
1.70 +LOCAL_C TInt CreateSingleUserSideTransfer(TUsideTferDesc*& aTfer, TInt8 aType, TInt8 aBufGran, TDes8* aBuf, TUsideTferDesc* aNext)
1.71 +// Utility function to create a single transfer
1.72 + {
1.73 + aTfer = new TUsideTferDesc();
1.74 + if(aTfer==NULL)
1.75 + return KErrNoMemory;
1.76 + aTfer->iType=aType;
1.77 + aTfer->iBufGranularity=aBufGran;
1.78 + aTfer->iBuffer = aBuf;
1.79 + aTfer->iNext = aNext;
1.80 + return KErrNone;
1.81 + }
1.82 +
1.83 +LOCAL_C TInt CreateSingleUserSideTransaction(TUsideTracnDesc*& aTracn, TBusType aType, TDes8* aHdr, TUsideTferDesc* aHalfDupTrans, TUsideTferDesc* aFullDupTrans, TUint8 aFlags, TAny* aPreambleArg, TAny* aMultiTranscArg)
1.84 +// Utility function to create a single transaction
1.85 + {
1.86 + aTracn = new TUsideTracnDesc();
1.87 + if(aTracn==NULL)
1.88 + return KErrNoMemory;
1.89 + aTracn->iType=aType;
1.90 + aTracn->iHeader=aHdr;
1.91 + aTracn->iHalfDuplexTrans=aHalfDupTrans;
1.92 + aTracn->iFullDuplexTrans=aFullDupTrans;
1.93 + aTracn->iFlags=aFlags;
1.94 + aTracn->iPreambleArg = aPreambleArg;
1.95 + aTracn->iMultiTranscArg = aMultiTranscArg;
1.96 + return KErrNone;
1.97 + }
1.98 +
1.99 +
1.100 +//----------------------------------------------------------------------------------------------
1.101 +//! @SYMTestCaseID KBASE-T_IIC-2402
1.102 +//! @SYMTestType UT
1.103 +//! @SYMPREQ PREQ2128,2129
1.104 +//! @SYMTestCaseDesc This test case test the Master channel basic functionality
1.105 +//! @SYMTestActions 0) Create a transaction and invoke the synchronous Queue Transaction API
1.106 +//!
1.107 +//! 1) Re-use the transaction and invoke asynchronous Queue Transaction API. Wait for
1.108 +//| the TRequestStatus to be completed.
1.109 +//!
1.110 +//! 2) Instruct the Kernel-side proxy client to instigate testing of priority queuing.
1.111 +//! The proxy uses controlIO to block the transaction queue, then queues 5 transactions in reverse
1.112 +//! priority order. The proxy then uses controlIO to unblock the transaction queue and checks that
1.113 +//! the transactions complete in priority order.
1.114 +//!
1.115 +//! 3) Attempt to cancel a previously-completed asynchronous request for a queued transaction
1.116 +//!
1.117 +//! 4) Use controlio to block request completion. Issue two asynchronous Queue Transaction requests.
1.118 +//! Request cancellation of the second transaction. Wait for completion of the TRequestStatus for
1.119 +//! the second request. Attempt to de-register the channel. Use controlio to unblock request completion.
1.120 +//! Wait for completion of the TRequestStatus for the first request.
1.121 +//!
1.122 +//! 5) Attempt to de-register a channel that is not busy.
1.123 +//!
1.124 +//! 6) Attempt to queue a transaction on an invalid (de-registered) channel
1.125 +//!
1.126 +//! 7) Instruct the Kernel-side proxy client to instigate construction of a valid full duplex transaction.
1.127 +//!
1.128 +//! 8) Instruct the Kernel-side proxy client to instigate construction of a invalid full duplex transaction,
1.129 +//! where both transfer in same direction
1.130 +//!
1.131 +//! 9) Instruct the Kernel-side proxy client to instigate construction of a invalid full duplex transaction,
1.132 +//! where with different node length (not the number of node on opposite linklist ) at the same
1.133 +//! position on the opposite transfer linklist
1.134 +//!
1.135 +//! 10) Instruct the Kernel-side proxy client to instigate construction of a valid full duplex transaction,
1.136 +//! with different size for the last node
1.137 +//!
1.138 +//! 11) Instruct the Kernel-side proxy client to instigate construction of a valid full duplex transaction,
1.139 +//! with different number of transfer
1.140 +//!
1.141 +//!
1.142 +//! @SYMTestExpectedResults 0) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.143 +//! 1) Kernel-side proxy client should return with KErrNone, exits otherwise. TRequestStatus should
1.144 +//! be set to KErrNone, exits otherwise.
1.145 +//! 2) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.146 +//! 3) Kernel-side proxy client should return with KErrNone, exits otherwise.TRequestStatus should
1.147 +//! be set to KErrNone, exits otherwise.
1.148 +//! 4) The TRequestStatus for the cancelled request should be set to KErrCancel, exits otherwise.
1.149 +//! The attempt to de-register the channel should return KErrInUse, exits otherwise. The
1.150 +//! TRequestStatus for the first request should be set to KErrNone, exits otherwise.
1.151 +//! 5) Kernel-side proxy client should return with KErrNone or KErrArgument, exits otherwise.
1.152 +//! 6) Kernel-side proxy client should return with KErrArgument, exits otherwise.
1.153 +//! 7) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.154 +//! 8) Kernel-side proxy client should return with KErrNotSupported, exits otherwise.
1.155 +//! 9) Kernel-side proxy client should return with KErrNotSupported, exits otherwise.
1.156 +//! 10) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.157 +//! 11) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.158 +//!
1.159 +//! @SYMTestPriority High
1.160 +//! @SYMTestStatus Implemented
1.161 +//----------------------------------------------------------------------------------------------
1.162 +LOCAL_C TInt MasterBasicTests()
1.163 +//
1.164 +// Exercise the Master Channel API with trivial data
1.165 +//
1.166 + {
1.167 + gTest.Printf(_L("\n\nStarting MasterBasicTests\n"));
1.168 +
1.169 + TInt r=KErrNone;
1.170 +
1.171 + TUint32 busIdSpi = 0;
1.172 +
1.173 + // Use the SPI bus
1.174 + // SPI uses channel numbers 1,2,3 and 4
1.175 + SET_BUS_TYPE(busIdSpi,ESpi);
1.176 + SET_CHAN_NUM(busIdSpi,2);
1.177 + TConfigSpiBufV01* spiBuf = NULL;
1.178 + // aDeviceId=1 ... 100kHz ... aTimeoutPeriod=100 ... aTransactionWaitCycles=10 - arbitrary paarmeters.
1.179 + r = CreateSpiBuf(spiBuf, ESpiWordWidth_8, 100000, ESpiPolarityLowRisingEdge, 100 ,ELittleEndian, EMsbFirst, 10, ESpiCSPinActiveLow);
1.180 + gTest(r==KErrNone);
1.181 +
1.182 + // Use a single transfer
1.183 + _LIT(halfDuplexText,"Half Duplex Text");
1.184 + TBuf8<17> halfDuplexBuf_8;
1.185 + halfDuplexBuf_8.Copy(halfDuplexText);
1.186 + TUsideTferDesc* tfer = NULL;
1.187 + r = CreateSingleUserSideTransfer(tfer, EMasterWrite, 8, &halfDuplexBuf_8, NULL);
1.188 + gTest(r==KErrNone);
1.189 +
1.190 + // Create the transaction object
1.191 + TUsideTracnDesc* tracn = NULL;
1.192 + r = CreateSingleUserSideTransaction(tracn, ESpi, spiBuf, tfer, NULL, 0, NULL, NULL);
1.193 + gTest(r==KErrNone);
1.194 +
1.195 + // Test basic queueing operations
1.196 + // inline TInt QueueTransaction(TInt aBusId, TUsideTracnDesc* aTransaction)
1.197 + gTest.Printf(_L("\n\nStarting synchronous QueueTransaction \n"));
1.198 + r = gChanMasterSpi.QueueTransaction(busIdSpi, tracn);
1.199 + gTest.Printf(_L("Synchronous QueueTransaction returned = %d\n"),r);
1.200 + gTest(r==KErrNone);
1.201 + // inline void QueueTransaction(TRequestStatus& aStatus, TInt aBusId, TUsideTracnDesc* aTransaction)
1.202 + gTest.Printf(_L("\n\nStarting asynchronous QueueTransaction \n"));
1.203 + TRequestStatus status;
1.204 +
1.205 + gChanMasterSpi.QueueTransaction(status, busIdSpi, tracn);
1.206 + User::WaitForRequest(status);
1.207 + if(status != KErrNone)
1.208 + {
1.209 + gTest.Printf(_L("TRequestStatus value after queue = %d\n"), status.Int());
1.210 + gTest(EFalse);
1.211 + }
1.212 +
1.213 + // Test message with priorities
1.214 + gTest.Printf(_L("\n\nStarting test for message with priorities\n\n"),r);
1.215 + r = gChanMasterSpi.TestPriority(busIdSpi);
1.216 + gTest(r==KErrNone);
1.217 +
1.218 + // Test cancel operation (on previously completed request)
1.219 +
1.220 + // inline void CancelAsyncOperation(TRequestStatus* aStatus, TInt aBusId) {TInt* parms[2]; parms[0]=(TInt*)aStatus; parms[1]=(TInt*)aBusId;DoCancel((TInt)&parms[0]);}
1.221 + gTest.Printf(_L("\n\nStarting CancelAsyncOperation \n"));
1.222 + gChanMasterSpi.CancelAsyncOperation(&status, busIdSpi);
1.223 + if(status == KRequestPending)
1.224 + User::WaitForRequest(status);
1.225 + if(status != KErrNone)
1.226 + {
1.227 + gTest.Printf(_L("TRequestStatus value after (belated) cancel = %d\n"), status.Int());
1.228 + gTest(EFalse);
1.229 + }
1.230 +
1.231 + // Test cancel operation (on pending request)
1.232 + // Also test that a channel with a transaction queued can not be de-registered.
1.233 + // For this:
1.234 + // (1) create a second transaction object
1.235 + // (2) use controlio/StaticExtension to block request completion
1.236 + // (3) use asynchronous queue transaction for the two transaction objects
1.237 + // (4) request cancellation of the second request
1.238 + // (5) check that the TRequestStatus object associated with the second request is completed with KErrCancel
1.239 + // (6) check that attempt to de-register the channel fails with KErrInUse
1.240 + // (7) use controlio/StaticExtension to unblock request completion
1.241 + // (8) check that the TRequestStatus object associated with the first request is completed with KErrNone
1.242 + //
1.243 + gTest.Printf(_L("\n\nStarting (successful) cancellation test\n\n"),r);
1.244 + _LIT(halfDuplexText2,"2 Half Duplex Text 2");
1.245 + TBuf8<21> halfDuplexBuf2_8;
1.246 + halfDuplexBuf2_8.Copy(halfDuplexText2);
1.247 + TUsideTferDesc* tfer2 = NULL;
1.248 + r = CreateSingleUserSideTransfer(tfer2, EMasterRead, 16, &halfDuplexBuf2_8, NULL);
1.249 + gTest(r == KErrNone);
1.250 +
1.251 + TUsideTracnDesc* tracn2 = NULL;
1.252 + delete spiBuf;
1.253 + spiBuf = NULL;
1.254 +
1.255 + // aDeviceId=1 ... 100kHz ... aTimeoutPeriod=100 ... aTransactionWaitCycles=10 - arbitrary paarmeters.
1.256 + r = CreateSpiBuf(spiBuf, ESpiWordWidth_8, 100000, ESpiPolarityLowRisingEdge, 100 ,ELittleEndian, EMsbFirst, 10, ESpiCSPinActiveLow);
1.257 + gTest(r == KErrNone);
1.258 +
1.259 + r = CreateSingleUserSideTransaction(tracn2, ESpi, spiBuf, tfer2, NULL, 0, NULL, NULL);
1.260 + gTest(r == KErrNone);
1.261 +
1.262 + //
1.263 + gTest.Printf(_L("Invoking BlockReqCompletion\n"));
1.264 + r = gChanMasterSpi.BlockReqCompletion(busIdSpi);
1.265 + gTest.Printf(_L("BlockReqCompletion returned = %d\n"),r);
1.266 + gTest(r == KErrNone);
1.267 +
1.268 + //
1.269 + gTest.Printf(_L("Queueing first transaction \n"));
1.270 + gChanMasterSpi.QueueTransaction(status, busIdSpi, tracn);
1.271 + TRequestStatus status2;
1.272 +
1.273 + gTest.Printf(_L("Queueing second transaction \n"));
1.274 + gChanMasterSpi.QueueTransaction(status2, busIdSpi, tracn2);
1.275 + //
1.276 + User::After(50000);
1.277 + //
1.278 + gTest.Printf(_L("Issuing Cancel for second transaction\n"));
1.279 + gChanMasterSpi.CancelAsyncOperation(&status2, busIdSpi);
1.280 + gTest.Printf(_L("Returned from Cancel for second transaction\n"));
1.281 + if(status2 == KRequestPending)
1.282 + User::WaitForRequest(status2);
1.283 + if(status2 != KErrCancel)
1.284 + {
1.285 + gTest.Printf(_L("TRequestStatus (2) value after cancel = %d\n"), status2.Int());
1.286 + gTest(EFalse);
1.287 + }
1.288 +
1.289 + // If it is stand-alone channel, the client is reponsible for channel creation.
1.290 + // So the RegisterChan and DeRegisterChan are not needed.
1.291 + if (aStandAloneChan == 0)
1.292 + {
1.293 + gTest.Printf(_L("Invoking DeRegisterChan\n"));
1.294 + r = gChanMasterSpi.DeRegisterChan(busIdSpi);
1.295 +
1.296 + gTest.Printf(_L("DeRegisterChan returned = %d\n"),r);
1.297 + gTest(r==KErrInUse);
1.298 + }
1.299 + //
1.300 + gTest.Printf(_L("Invoking UnlockReqCompletion\n"));
1.301 + r = gChanMasterSpi.UnblockReqCompletion(busIdSpi);
1.302 + gTest.Printf(_L("UnblockReqCompletion returned = %d\n"),r);
1.303 + //
1.304 + User::After(50000);
1.305 + //
1.306 + User::WaitForRequest(status);
1.307 + if(status != KErrNone)
1.308 + {
1.309 + gTest.Printf(_L("TRequestStatus value after queue = %d\n"), status.Int());
1.310 + gTest(EFalse);
1.311 + }
1.312 +
1.313 + // Clean up
1.314 + delete spiBuf;
1.315 + delete tfer;
1.316 + delete tracn;
1.317 + delete tfer2;
1.318 + delete tracn2;
1.319 +
1.320 + gTest.Printf(_L("\n\nStarting full duplex transaction creation test\n\n"),r);
1.321 +
1.322 + TUint32 busIdSpiFd = 0;
1.323 +
1.324 + // Use the SPI bus
1.325 + // SPI uses channel numbers 1,2,3 and 4
1.326 + SET_BUS_TYPE(busIdSpi,ESpi);
1.327 + SET_CHAN_NUM(busIdSpi,4);
1.328 +
1.329 + // Test creating a valid full duplex transaction
1.330 + gTest.Printf(_L("\n\nStarting valid full duplex transaction test\n\n"),r);
1.331 + r = gChanMasterSpi.TestValidFullDuplexTrans(busIdSpiFd);
1.332 + gTest(r==KErrNone);
1.333 +
1.334 + // Test creating a full duplex transaction with both transfer in same direction (invalid)
1.335 + gTest.Printf(_L("\n\nStarting invalid direction full duplex transaction test\n\n"),r);
1.336 + r = gChanMasterSpi.TestInvalidFullDuplexTrans1(busIdSpiFd);
1.337 + gTest.Printf(_L("Full duplex transaction with invalid direction returned = %d\n"),r);
1.338 + gTest(r==KErrNotSupported);
1.339 +
1.340 + // Test creating a full duplex transaction with different node length (not the number of node on opposite linklist )
1.341 + // at the same position on the opposite transfer linklist
1.342 + gTest.Printf(_L("\n\nStarting invalid transfer length full duplex transaction test\n\n"),r);
1.343 + r = gChanMasterSpi.TestInvalidFullDuplexTrans2(busIdSpiFd);
1.344 + gTest(r==KErrNotSupported);
1.345 +
1.346 + // Test creating a valid full duplex transaction with different size for the last node
1.347 + gTest.Printf(_L("\n\nStarting valid full duplex transaction test with diff size last node\n\n"),r);
1.348 + r = gChanMasterSpi.TestLastNodeFullDuplexTrans(busIdSpiFd);
1.349 + gTest(r==KErrNone);
1.350 +
1.351 + // Test creating a valid full duplex transaction with different number of transfer
1.352 + gTest.Printf(_L("\n\nStarting valid full duplex transaction test with diff number of transfer\n\n"),r);
1.353 + r = gChanMasterSpi.TestDiffNodeNumFullDuplexTrans(busIdSpiFd);
1.354 + gTest(r==KErrNone);
1.355 +
1.356 + return KErrNone;
1.357 + }
1.358 +
1.359 +
1.360 +//----------------------------------------------------------------------------------------------
1.361 +//! @SYMTestCaseID KBASE-T_IIC-2403
1.362 +//! @SYMTestType UT
1.363 +//! @SYMPREQ PREQ2128,2129
1.364 +//! @SYMTestCaseDesc This test case tests the Master channel data handling for transactions
1.365 +//! @SYMTestActions 0) Instruct the kernel-side proxy to construct a transaction of pre-defined data
1.366 +//! and inform the simulated bus to expect to receive this data. Then the proxy invokes
1.367 +//! the synchronous Queue Transaction API. On receipt of the transaction, the simulated bus
1.368 +//! checks the header and transafer content of the transaction to confirm that it is correct.
1.369 +//!
1.370 +//! @SYMTestExpectedResults 0) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.371 +//!
1.372 +//! @SYMTestPriority High
1.373 +//! @SYMTestStatus Implemented
1.374 +//----------------------------------------------------------------------------------------------
1.375 +LOCAL_C TInt MasterTransactionTests()
1.376 +//
1.377 +// Exercise the Master Channel API with trivial data
1.378 +//
1.379 + {
1.380 + gTest.Printf(_L("\n\nStarting MasterTransactionTests\n"));
1.381 +
1.382 + TInt r = KErrNone;
1.383 +
1.384 + // Prove that the simulated bus can access the transfer data contained within a transaction
1.385 + // Do this by instructing the proxy client to:
1.386 + // (1) Inform the bus of the test about to be informed
1.387 + // (2) Send a transaction with a known number of transfers with known data
1.388 + // (3) Check the result announced by the bus.
1.389 + //
1.390 + // Use the SPI bus
1.391 + // SPI uses channel numbers 1,2,3 and 4
1.392 + TUint32 busIdSpi = 0;
1.393 + SET_BUS_TYPE(busIdSpi,ESpi);
1.394 + SET_CHAN_NUM(busIdSpi,4); // Master, Full-duplex - required by TestBufferReUse
1.395 + r = gChanMasterSpi.TestTracnOne(busIdSpi);
1.396 + gTest.Printf(_L("TestTracnOne returned = %d\n"),r);
1.397 + gTest(r==KErrNone);
1.398 +
1.399 + // Test that transfer and transaction buffers can be modifed for re-use
1.400 + // This test modifies the content of a full-duplex transaction - so a full-duplex channel must be used
1.401 + TRequestStatus status;
1.402 + gChanMasterSpi.TestBufferReUse(busIdSpi, status);
1.403 + User::WaitForRequest(status);
1.404 + r=status.Int();
1.405 + if(r != KErrNone)
1.406 + {
1.407 + gTest.Printf(_L("TRequestStatus value after CaptureChannel = %d\n"),r);
1.408 + gTest(r==KErrCompletion);
1.409 + }
1.410 +
1.411 + return KErrNone;
1.412 + }
1.413 +
1.414 +//----------------------------------------------------------------------------------------------
1.415 +//! @SYMTestCaseID KBASE-T_IIC-2401
1.416 +//! @SYMTestType UT
1.417 +//! @SYMPREQ PREQ2128,2129
1.418 +//! @SYMTestCaseDesc This test case test the Master channel preamble and multi-transaction functionality.
1.419 +//! @SYMTestActions 0) Create a transaction that requires preamble support, and queue it for processing
1.420 +//!
1.421 +//! 1) If the test has been invoked for preamble testing, wait for the preamble-specific
1.422 +//! TRequestStatus to be completed.
1.423 +//!
1.424 +//! 2) If the test has been invoked for multi-transaction testing, wait for the multi-transaction
1.425 +//! -specific TRequestStatus to be completed.
1.426 +//!
1.427 +//!
1.428 +//! @SYMTestExpectedResults 0) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.429 +//! 1) If waiting on the preamble-specific TRequestStatus, it should be set to KErrNone, exists otherwise.
1.430 +//! 2) If waiting on the multi-transaction-specific TRequestStatus, it should be set to KErrNone, exists otherwise.
1.431 +//!
1.432 +//! @SYMTestPriority High
1.433 +//! @SYMTestStatus Implemented
1.434 +//----------------------------------------------------------------------------------------------
1.435 +LOCAL_C TInt MasterExtTests(TUint8 aFlags)
1.436 +//
1.437 +// Exercise the Master Channel API for Preamble functionality
1.438 +//
1.439 +
1.440 +// For the multi-transaction test, a bus Master might not know
1.441 +// how much data to write to a Slave until it performs a single read on it.
1.442 +// However, specifying a read separately from the subsequent write
1.443 +// introduces the risk of allowing another transaction to go ahead of the
1.444 +// following write and thus invalidating it. The multi-transaction feature of IIC
1.445 +// allows a callback to be called(in the context of the bus channel) after
1.446 +// the transfers of a preliminary transaction have taken place
1.447 +// (could be a single read), without completing the overall transaction,
1.448 +// then extend the delayed transaction by inserting more transfers
1.449 +//
1.450 + {
1.451 + gTest.Printf(_L("\n\nStarting MasterExtTests\n"));
1.452 +
1.453 + TInt r = KErrNone;
1.454 +
1.455 + // Create a transaction that requires preamble support
1.456 + // To prove required operation has executed, make callback complete a TRequestStatus object
1.457 + TRequestStatus preamblestatus;
1.458 + TRequestStatus multitranscstatus;
1.459 +
1.460 + // Use the SPI bus
1.461 + // SPI uses channel numbers 1,2,3 and 4
1.462 + TUint32 busIdSpi = 0;
1.463 + SET_BUS_TYPE(busIdSpi, ESpi);
1.464 + SET_CHAN_NUM(busIdSpi, 1);
1.465 + TConfigSpiBufV01* spiBuf = NULL;
1.466 + // aDeviceId=1 ... 100kHz ... aTimeoutPeriod=100 ... aTransactionWaitCycles=10 - arbitrary paarmeters.
1.467 + r = CreateSpiBuf(spiBuf, ESpiWordWidth_8, 100000,
1.468 + ESpiPolarityLowRisingEdge, 100, ELittleEndian, EMsbFirst, 10,
1.469 + ESpiCSPinActiveLow);
1.470 + if (r != KErrNone)
1.471 + return r;
1.472 +
1.473 + // Use a single transfer
1.474 + _LIT(extText, "Ext Text");
1.475 + TBuf8<14> extBuf_8;
1.476 + extBuf_8.Copy(extText);
1.477 + TUsideTferDesc* tfer = NULL;
1.478 + r = CreateSingleUserSideTransfer(tfer, EMasterRead, 8, &extBuf_8, NULL);
1.479 + if (r != KErrNone)
1.480 + {
1.481 + delete spiBuf;
1.482 + return r;
1.483 + }
1.484 +
1.485 + // Create the transaction object
1.486 + TUsideTracnDesc* tracn = NULL;
1.487 + r = CreateSingleUserSideTransaction(tracn, ESpi, spiBuf, tfer, NULL,
1.488 + aFlags, (TAny*) &preamblestatus, (TAny*) &multitranscstatus);
1.489 +
1.490 + if (r != KErrNone)
1.491 + {
1.492 + delete spiBuf;
1.493 + delete tfer;
1.494 + return r;
1.495 + }
1.496 +
1.497 + // Send the transaction to the kernel-side proxy
1.498 + // inline TInt QueueTransaction(TInt aBusId, TUsideTracnDesc* aTransaction)
1.499 + gTest.Printf(_L("\nInvoke synchronous QueueTransaction for preamble test %x\n"), tracn);
1.500 +
1.501 + r = gChanMasterSpi.QueueTransaction(busIdSpi, tracn);
1.502 + gTest.Printf(_L("synchronous QueueTransaction returned = %d\n"), r);
1.503 +
1.504 + if (r == KErrNone)
1.505 + {
1.506 + // ... and wait for the TRequestStatus object to be completed
1.507 + if (aFlags & KTransactionWithPreamble)
1.508 + {
1.509 + User::WaitForRequest(preamblestatus);
1.510 + r = preamblestatus.Int();
1.511 + if (r != KErrNone)
1.512 + {
1.513 + gTest.Printf(_L("MasterPreambleTests: TRequestStatus completed with = %d\n"), r);
1.514 + }
1.515 + }
1.516 +
1.517 +
1.518 + if (aFlags & KTransactionWithMultiTransc)
1.519 + {
1.520 + User::WaitForRequest(multitranscstatus);
1.521 + if (r != KErrNone)
1.522 + {
1.523 + gTest.Printf(_L("MasterMultiTranscTests: TRequestStatus completed with = %d\n"), r);
1.524 + }
1.525 + }
1.526 + }
1.527 +
1.528 + delete spiBuf;
1.529 + delete tfer;
1.530 + delete tracn;
1.531 +
1.532 + return r;
1.533 + }
1.534 +
1.535 +#ifdef SLAVE_MODE
1.536 +LOCAL_C TInt CreateSlaveChanI2cConfig(TConfigI2cBufV01*& aI2cBuf, TUint32& aBusIdI2c, TUint8 aChanNum)
1.537 + {
1.538 + // Initialise TConfigI2cBufV01 and the Bus Realisation Config for gChanSlaveI2c.
1.539 + // Customised:
1.540 + // - token containing the bus realisation variability.
1.541 + // - pointer to a descriptor containing the device specific configuration option applicable to all transactions.
1.542 + // - reference to variable to hold a platform-specific cookie that uniquely identifies the channel instance to be
1.543 + // used by this client
1.544 + aBusIdI2c = 0;
1.545 + SET_BUS_TYPE(aBusIdI2c,EI2c);
1.546 + SET_CHAN_NUM(aBusIdI2c,aChanNum);
1.547 + //
1.548 + // clock speed=36Hz, aTimeoutPeriod=100 - arbitrary parameter
1.549 + TInt r=CreateI2cBuf(aI2cBuf, EI2cAddr7Bit, 36, ELittleEndian, 100);
1.550 + return r;
1.551 + }
1.552 +
1.553 +LOCAL_C TInt SyncCaptureGChanSlaveI2c(TInt& aChanId, TConfigI2cBufV01* aI2cBuf, TUint32 aBusIdI2c)
1.554 + {
1.555 + // Synchronous capture of a Slave channel. Need to provide:
1.556 + // - token containing the bus realisation variability.
1.557 + // - pointer to a descriptor containing the device specific configuration option applicable to all transactions.
1.558 + // - reference to variable to hold a platform-specific cookie that uniquely identifies the channel instance to be used by this client
1.559 + gTest.Printf(_L("\n\nStarting synchronous CaptureChannel \n"));
1.560 + TInt r = gChanSlaveI2c.CaptureChannel(aBusIdI2c, aI2cBuf, aChanId );
1.561 + gTest.Printf(_L("Synchronous CaptureChannel returned = %d, aChanId=0x%x\n"),r,aChanId);
1.562 + return r;
1.563 + }
1.564 +
1.565 +
1.566 +LOCAL_C TInt AsyncCaptureGChanSlaveI2c(TInt& aChanId, TConfigI2cBufV01* aI2cBuf, TUint32 aBusIdI2c)
1.567 + {
1.568 + // Asynchronous capture of a Slave channel. Need to provide:
1.569 + // - token containing the bus realisation variability.
1.570 + // - pointer to a descriptor containing the device specific configuration option applicable to all transactions.
1.571 + // - reference to variable to hold a platform-specific cookie that uniquely identifies the channel instance to be used by this client
1.572 + // - pointer to TRequestStatus used to indicate operation completion
1.573 + gTest.Printf(_L("\n\nStarting asynchronous CaptureChannel \n"));
1.574 + TRequestStatus status;
1.575 + TInt r = gChanSlaveI2c.CaptureChannel(aBusIdI2c, aI2cBuf, aChanId, status );
1.576 + gTest(r==KErrNone);
1.577 + User::WaitForRequest(status);
1.578 + r=status.Int();
1.579 + if(r != KErrCompletion)
1.580 + {
1.581 + gTest.Printf(_L("TRequestStatus value after CaptureChannel = %d\n"),r);
1.582 + gTest(r==KErrCompletion);
1.583 + }
1.584 + gTest.Printf(_L("Asynchronous CaptureChannel gave aChanId=0x%x\n"),aChanId);
1.585 + return KErrNone;
1.586 + }
1.587 +#endif
1.588 +//----------------------------------------------------------------------------------------------
1.589 +//! @SYMTestCaseID KBASE-T_IIC-2399
1.590 +//! @SYMTestType UT
1.591 +//! @SYMPREQ PREQ2128,2129
1.592 +//! @SYMTestCaseDesc This test case tests Slave channel capture and release APIs.
1.593 +//! @SYMTestActions 0) Perform synchronous capture of a channel
1.594 +//!
1.595 +//! 1) Release the channel
1.596 +//!
1.597 +//! 2) Perform asynchronous capture of a channel
1.598 +//!
1.599 +//! 3) Attempt synchronous capture of a channel that is already captured
1.600 +//!
1.601 +//! 4) Attempt asynchronous capture of a channel that is already captured
1.602 +//!
1.603 +//! 5) Release the channel
1.604 +//!
1.605 +//! @SYMTestExpectedResults 0) Kernel-side proxy client should return with KErrCompletion, exits otherwise.
1.606 +//! 1) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.607 +//! 2) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.608 +//! 3) Kernel-side proxy client should return with KErrInUse, exits otherwise.
1.609 +//! 4) Kernel-side proxy client should return with KErrNone, exits otherwise. The associated
1.610 +//! TRequestStatus should be set to KErrInUse, exits otherwise.
1.611 +//! 5) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.612 +//!
1.613 +//! @SYMTestPriority High
1.614 +//! @SYMTestStatus Implemented
1.615 +//----------------------------------------------------------------------------------------------
1.616 +LOCAL_C TInt SlaveChannelCaptureReleaseTests()
1.617 +//
1.618 +// Exercise the Slave Channel API for channel capture and release
1.619 +//
1.620 + {
1.621 + gTest.Printf(_L("\n\nStarting SlaveChannelCaptureReleaseTests\n"));
1.622 + TInt r=KErrNone;
1.623 +#ifdef SLAVE_MODE
1.624 +
1.625 + // Create a I2C configuration buffer and the configuration data for use in capturing gChanSlaveI2c
1.626 + TUint32 busIdI2c = 0;
1.627 + TConfigI2cBufV01* i2cBuf=NULL;
1.628 + r=CreateSlaveChanI2cConfig(i2cBuf, busIdI2c, 11); // 11 is the Slave channel number
1.629 + gTest(r==KErrNone);
1.630 +
1.631 + // Synchronous capture of a Slave channel.
1.632 + TInt chanId = 0; // Initialise to zero to silence compiler ...
1.633 + r=SyncCaptureGChanSlaveI2c(chanId, i2cBuf, busIdI2c);
1.634 + gTest(r==KErrNone);
1.635 + //
1.636 + // Release the channel
1.637 + gTest.Printf(_L("\n\nInvoke ReleaseChannel for chanId=0x%x \n"),chanId);
1.638 + r = gChanSlaveI2c.ReleaseChannel( chanId );
1.639 + gTest.Printf(_L("ReleaseChannel returned = %d\n"),r);
1.640 + gTest(r==KErrNone);
1.641 + //
1.642 + // Asynchronous capture of a Slave channel.
1.643 + chanId = 0; // Re-initialise to zero to silence compiler ...
1.644 + r=AsyncCaptureGChanSlaveI2c(chanId, i2cBuf, busIdI2c);
1.645 + gTest(r==KErrNone);
1.646 +
1.647 + // Try capturing a slave channel that is already captured
1.648 + //
1.649 + // Create another instance of a client, and use to attempt duplicated capture
1.650 + TInt dumChanId = 0; // Initialise to zero to silence compiler ...
1.651 + RBusDevIicClient tempChanSlaveI2c;
1.652 + TBufC<24> proxySlaveName;
1.653 + if(aStandAloneChan == 0)
1.654 + proxySlaveName = KIicProxySlaveFileNameRoot;
1.655 + else
1.656 + proxySlaveName = KIicProxySlaveFileNameRootCtrlLess;
1.657 + r = tempChanSlaveI2c.Open(proxySlaveName);
1.658 + gTest(r==KErrNone);
1.659 + r = tempChanSlaveI2c.InitSlaveClient();
1.660 + gTest(r==KErrNone);
1.661 + //
1.662 + // Synchronous capture
1.663 + gTest.Printf(_L("\n\nStarting attempted synchronous CaptureChannel of previously-captured channel\n"));
1.664 + r = tempChanSlaveI2c.CaptureChannel(busIdI2c, i2cBuf, dumChanId );
1.665 + gTest.Printf(_L("Synchronous CaptureChannel returned = %d, dumChanId=0x%x\n"),r,dumChanId);
1.666 + gTest(r==KErrInUse);
1.667 + //
1.668 + // Asynchronous capture
1.669 + dumChanId = 0;
1.670 + gTest.Printf(_L("\n\nStarting attempted asynchronous CaptureChannel of previously-captured channel\n"));
1.671 + TRequestStatus status;
1.672 + r = tempChanSlaveI2c.CaptureChannel(busIdI2c, i2cBuf, dumChanId, status );
1.673 + gTest(r==KErrNone);
1.674 + User::WaitForRequest(status);
1.675 + r=status.Int();
1.676 + if(r != KErrInUse)
1.677 + {
1.678 + gTest.Printf(_L("TRequestStatus value after attempted CaptureChannel of previously-captured channel = %d\n"),r);
1.679 + gTest(r==KErrInUse);
1.680 + }
1.681 + gTest.Printf(_L("Asynchronous CaptureChannel gave dumChanId=0x%x\n"),dumChanId);
1.682 +
1.683 + tempChanSlaveI2c.Close();
1.684 + //
1.685 + // Clean up, release the channel
1.686 + r = gChanSlaveI2c.ReleaseChannel( chanId );
1.687 + gTest.Printf(_L("ReleaseChannel returned = %d\n"),r);
1.688 + gTest(r==KErrNone);
1.689 +
1.690 + delete i2cBuf;
1.691 +#else
1.692 + gTest.Printf(_L("\nSlaveChannelCaptureReleaseTests only supported when SLAVE_MODE is defined\n"));
1.693 +#endif
1.694 + return r;
1.695 + }
1.696 +
1.697 +//----------------------------------------------------------------------------------------------
1.698 +//! @SYMTestCaseID KBASE-T_IIC-2400
1.699 +//! @SYMTestType UT
1.700 +//! @SYMPREQ PREQ2128,2129
1.701 +//! @SYMTestCaseDesc This test case tests Slave channel capture operation for receive and transmit of data
1.702 +//! @SYMTestActions 0) Check that the timeout threshold values can be updated
1.703 +//!
1.704 +//! 1) Check that an Rx Buffer can be registered, and that a replacement buffer can be registered in its place
1.705 +//! if a notification has not been requested.
1.706 +//!
1.707 +//! 2) Specify a notification trigger for Rx events
1.708 +//!
1.709 +//! 3) Attempt to register a replacement Rx buffer
1.710 +//!
1.711 +//! 4) Use controlIO to instruct the simulated bus to indicate that it has received the required number of words
1.712 +//! and wait for the TRequestStatus to be completed.
1.713 +//!
1.714 +//! 5) Specify a notification trigger for Rx events, use controlIO to instruct the simulated bus to indicate that
1.715 +//! it has received less than the required number of words and wait for the TRequestStatus to be completed.
1.716 +//!
1.717 +//! 6) Specify a notification trigger for Rx events, use controlIO to instruct the simulated bus to indicate that
1.718 +//! it has received more than the required number of words and wait for the TRequestStatus to be completed.
1.719 +//!
1.720 +//! 7) Repeat steps 1-6, but for Tx
1.721 +//!
1.722 +//! 8) Specify a notification trigger for Rx and Tx events. Use controlIO to instruct the simulated bus to indicate that
1.723 +//! it has received the required number of words, then that it has transmitted the required number of words, and wait
1.724 +//! for the TRequestStatus to be completed.
1.725 +//!
1.726 +//! 9) Repeat step 8, but simulate Tx, then Rx.
1.727 +//!
1.728 +//! 10) Specify a notification trigger for bus error events. Use controlIO to instruct the simulated bus to indicate that
1.729 +//! it has encountered a bus error, and wait for the TRequestStatus to be completed.
1.730 +//!
1.731 +//! 11) Use controlIO to instruct the simulated bus to block Master response. Specify a notification trigger for bus error
1.732 +//! events. Use controlIO to instruct the simulated bus to indicate that it has received more than the required number
1.733 +//! of words. Wait for the TRequestStatus to be completed (with KErrNone). Specify a notification trigger for Tx and
1.734 +//! Tx Overrun, then use controlIO to instruct the simulated bus to unblock Master responses.Wait for the TRequestStatus
1.735 +//! to be completed.
1.736 +//!
1.737 +//! @SYMTestExpectedResults 0) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.738 +//! 1) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.739 +//! 2) Kernel-side proxy client should return with KErrNone, exits otherwise.
1.740 +//! 3) Kernel-side proxy client should return with KErrAlreadyExists, exits otherwise.
1.741 +//! 4) Kernel-side proxy client should return with KErrNone, exits otherwise. The associated
1.742 +//! TRequestStatus should be set to KErrNone, exits otherwise.
1.743 +//! 5) Kernel-side proxy client should return with KErrNone for both API calls, exits otherwise. The associated
1.744 +//! TRequestStatus should be set to KErrNone, exits otherwise.
1.745 +//! 6) Kernel-side proxy client should return with KErrNone for both API calls, exits otherwise. The associated
1.746 +//! TRequestStatus should be set to KErrNone, exits otherwise.
1.747 +//! 7) Results should be the same as for steps 1-6.
1.748 +//! 8) Kernel-side proxy client should return with KErrNone for each API call, exits otherwise. The associated
1.749 +//! TRequestStatus should be set to KErrNone, exits otherwise.
1.750 +//! 9) Kernel-side proxy client should return with KErrNone for each API call, exits otherwise. The associated
1.751 +//! TRequestStatus should be set to KErrNone, exits otherwise.
1.752 +//! 10) Kernel-side proxy client should return with KErrNone for each API call, exits otherwise. The associated
1.753 +//! TRequestStatus should be set to KErrNone, exits otherwise.
1.754 +//! 11) Kernel-side proxy client should return with KErrNone for each API call, exits otherwise. The associated
1.755 +//! TRequestStatus should be set to KErrNone in both cases, exits otherwise.
1.756 +//!
1.757 +//! @SYMTestPriority High
1.758 +//! @SYMTestStatus Implemented
1.759 +//----------------------------------------------------------------------------------------------
1.760 +
1.761 +LOCAL_C TInt SlaveRxTxNotificationTests()
1.762 +//
1.763 +// Exercise the Slave channel operation for receive and transmit of data
1.764 +//
1.765 +
1.766 +// The means to supply a buffer to be filled with data received from the Master, and the number of words expected.
1.767 +// It is only after the reception of the number of words specified that the notification should be issued
1.768 +// (or on under-run/overrun/timeout/bus specific error).
1.769 +//
1.770 +// The means to supply a buffer with data to be transmitted to the Master, and the number of words to transmit.
1.771 +// It is only after the transmission of the number of words specified that the notification should be issued
1.772 +// (or under-run/overrun/timeout/bus specific error).
1.773 +//
1.774 +// The means to enable and disable the events which will trigger the notification callback. These events are:
1.775 +// 1) the complete reception of the number of words specified,
1.776 +// 2) the complete transmission of the number of words specified,
1.777 +// 3) errors: receive buffer under-run (the Master terminates the transaction or reverts the direction of
1.778 +// transfer before all expected data has been received), receive buffer overrun
1.779 +// (Master attempts to write more data than this channel expected to receive), transmit buffer overrun
1.780 +// (Master attempts to read more data than supplied by client), transmit buffer under-run
1.781 +// (the Master terminates the transaction or reverts the direction of transfer before all expected data
1.782 +// has been transmitted to it), access timeout(1) error, or bus specific error (e.g. collision, framing).
1.783 + {
1.784 + gTest.Printf(_L("\n\nStarting SlaveRxTxNotificationTests\n"));
1.785 + TInt r=KErrNone;
1.786 +#ifdef SLAVE_MODE
1.787 +
1.788 + //Configure and capture a channel
1.789 + gTest.Printf(_L("Create and capture channel\n"));
1.790 + TUint32 busIdI2c;
1.791 + TConfigI2cBufV01* i2cBuf=NULL;
1.792 + r=CreateSlaveChanI2cConfig(i2cBuf, busIdI2c, 11); // 11 is the Slave channel number
1.793 + gTest(r==KErrNone);
1.794 +
1.795 + TInt chanId = 0; // Initialise to zero to silence compiler ...
1.796 + r=SyncCaptureGChanSlaveI2c(chanId, i2cBuf, busIdI2c);
1.797 + gTest(r==KErrNone);
1.798 +
1.799 + // Update wait times for Master and Client
1.800 + // Delegate the operation of this test to the proxy client (iic_client). The proxy will read, modify, and reinstate
1.801 + // the timeout values.
1.802 + gTest.Printf(_L("Starting UpdateTimeoutValues\n"));
1.803 + r=gChanSlaveI2c.UpdateTimeoutValues(busIdI2c, chanId);
1.804 + gTest(r==KErrNone);
1.805 +
1.806 +
1.807 + // Receive and transmit buffers must be created by the client in Kernel heap and remain in their ownership throughout.
1.808 + // Therefore, the kernel-side proxy will provide the buffer
1.809 + // The buffers are of size KRxBufSizeInBytes and KRxBufSizeInBytes (currently 64)
1.810 +
1.811 + //
1.812 + // Rx tests
1.813 + //
1.814 +
1.815 + // For Rx, specify buffer granularity=4 (32-bit words), 8 words to receive, offset of 16 bytes
1.816 + // 64 bytes as 16 words: words 0-3 offset, words 4-11 data, words 12-15 unused
1.817 + gTest.Printf(_L("Starting RegisterRxBuffer\n"));
1.818 + r=gChanSlaveI2c.RegisterRxBuffer(chanId, 4, 8, 16);
1.819 + gTest(r==KErrNone);
1.820 + //
1.821 + // If a buffer is already registered but a notification has not yet been requested the API should return KErrNone
1.822 + gTest.Printf(_L("Starting (repeated) RegisterRxBuffer\n"));
1.823 + r=gChanSlaveI2c.RegisterRxBuffer(chanId, 4, 8, 16);
1.824 + gTest(r==KErrNone);
1.825 + //
1.826 + // Now set the notification trigger
1.827 + TRequestStatus status;
1.828 + TInt triggerMask=ERxAllBytes;
1.829 + gTest.Printf(_L("Starting SetNotificationTrigger with ERxAllBytes\n"));
1.830 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.831 + gTest(r==KErrNone);
1.832 + //
1.833 + // If a buffer is registered and a notification has been requested the API should return KErrAlreadyExists
1.834 + gTest.Printf(_L("Starting RegisterRxBuffer (to be rejected)\n"));
1.835 + r=gChanSlaveI2c.RegisterRxBuffer(chanId, 4, 8, 16);
1.836 + gTest(r==KErrAlreadyExists);
1.837 + //
1.838 + // Now instruct the bus implementation to represent receipt of the required number of words from the bus master.
1.839 + gTest.Printf(_L("Starting SimulateRxNWords\n"));
1.840 + r=gChanSlaveI2c.SimulateRxNWords(busIdI2c, chanId, 8);
1.841 + gTest(r==KErrNone);
1.842 + //
1.843 + // Wait for the notification
1.844 + User::WaitForRequest(status);
1.845 + r=status.Int();
1.846 + if(r != KErrNone)
1.847 + {
1.848 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.849 + gTest(r==KErrNone);
1.850 + }
1.851 + gTest.Printf(_L("Starting Rx test completed OK\n"));
1.852 + //
1.853 + // Repeat for each error condition. Re-use the buffer previously registered.
1.854 + //
1.855 + //
1.856 + triggerMask=ERxAllBytes|ERxUnderrun;
1.857 + gTest.Printf(_L("Starting SetNotificationTrigger with ERxAllBytes\n"));
1.858 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.859 + gTest(r==KErrNone);
1.860 + // Now instruct the bus implementation to represent the bus master transmitting less words than anticipated (Rx Underrun)
1.861 + gTest.Printf(_L("Starting SimulateRxNWords for Underrun\n"));
1.862 + r=gChanSlaveI2c.SimulateRxNWords(busIdI2c, chanId, 6);
1.863 + gTest(r==KErrNone);
1.864 + //
1.865 + // Wait for the notification
1.866 + User::WaitForRequest(status);
1.867 + r=status.Int();
1.868 + if(r != KErrNone)
1.869 + {
1.870 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.871 + gTest(r==KErrNone);
1.872 + }
1.873 + gTest.Printf(_L("Rx Underrun test completed OK\n"));
1.874 + // Re-set the notification trigger
1.875 + triggerMask=ERxAllBytes|ERxOverrun;
1.876 + gTest.Printf(_L("Starting SetNotificationTrigger\n"));
1.877 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.878 + gTest(r==KErrNone);
1.879 + // Now instruct the bus implementation to represent the bus master attempting to transmit more words than
1.880 + // anticipated (Rx Overrun)
1.881 + gTest.Printf(_L("Starting SimulateRxNWords for Overrun\n"));
1.882 + r=gChanSlaveI2c.SimulateRxNWords(busIdI2c, chanId, 10);
1.883 + gTest(r==KErrNone);
1.884 + //
1.885 + // Wait for the notification
1.886 + User::WaitForRequest(status);
1.887 + r=status.Int();
1.888 + if(r != KErrNone)
1.889 + {
1.890 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.891 + gTest(r==KErrNone);
1.892 + }
1.893 + gTest.Printf(_L("Rx Overrun test completed OK\n"));
1.894 +
1.895 + //
1.896 + // Tx tests
1.897 + //
1.898 +
1.899 + // For Tx, specify buffer granularity=4 (32-bit words), 12 words to transmit, offset of 8 bytes
1.900 + // 64 bytes as 16 words: words 0-1 offset, words 2-13 data, words 14-15 unused
1.901 + gTest.Printf(_L("\nStarting RegisterTxBuffer\n"));
1.902 + r=gChanSlaveI2c.RegisterTxBuffer(chanId, 4, 12, 8);
1.903 + gTest(r==KErrNone);
1.904 + //
1.905 + // If a buffer is already registered but a notification has not yet been requested the API should return KErrNone
1.906 + gTest.Printf(_L("Starting (repeated) RegisterTxBuffer\n"));
1.907 + r=gChanSlaveI2c.RegisterTxBuffer(chanId, 4, 12, 8);
1.908 + gTest(r==KErrNone);
1.909 + //
1.910 +
1.911 + // Re-set the notification trigger
1.912 + // Now set the notification trigger
1.913 + gTest.Printf(_L("Starting SetNotificationTrigger\n"));
1.914 + triggerMask=ETxAllBytes;
1.915 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.916 + gTest(r==KErrNone);
1.917 + //
1.918 + // If a buffer is already registered, a subsequent request to do the same should return KErrAlreadyExists
1.919 + gTest.Printf(_L("Starting RegisterTxBuffer (to be rejected)\n"));
1.920 + r=gChanSlaveI2c.RegisterTxBuffer(chanId, 4, 12, 8);
1.921 + gTest(r==KErrAlreadyExists);
1.922 + //
1.923 + // Now instruct the bus implementation to represent transmission of the required number of words to the bus master.
1.924 + gTest.Printf(_L("Starting SimulateTxNWords (to be rejected)\n"));
1.925 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
1.926 + gTest(r==KErrNone);
1.927 + //
1.928 + // Wait for the notification
1.929 + User::WaitForRequest(status);
1.930 + r=status.Int();
1.931 + if(r != KErrNone)
1.932 + {
1.933 + gTest.Printf(_L("TRequestStatus value after transmitting data = %d\n"),r);
1.934 + gTest(r==KErrNone);
1.935 + }
1.936 + gTest.Printf(_L("Tx test completed OK\n"));
1.937 + //
1.938 + // Repeat for each error condition. Re-use the buffer previously registered
1.939 + //
1.940 + // Re-set the notification trigger
1.941 + gTest.Printf(_L("Starting SetNotificationTrigger\n"));
1.942 + triggerMask=ETxAllBytes|ETxOverrun;
1.943 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.944 + gTest(r==KErrNone);
1.945 + // Now instruct the bus implementation to represent transmission of less than the required number of words
1.946 + // to the bus master (Tx Overrun)
1.947 + gTest.Printf(_L("Starting SimulateTxNWords for Tx Overrun\n"));
1.948 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 10);
1.949 + gTest(r==KErrNone);
1.950 + //
1.951 + // Wait for the notification
1.952 + User::WaitForRequest(status);
1.953 + r=status.Int();
1.954 + if(r != KErrNone)
1.955 + {
1.956 + gTest.Printf(_L("TRequestStatus value after transmitting data = %d\n"),r);
1.957 + gTest(r==KErrNone);
1.958 + }
1.959 + gTest.Printf(_L("Tx Overrun test completed OK\n"));
1.960 + // Re-set the notification trigger
1.961 + triggerMask=ETxAllBytes|ETxUnderrun;
1.962 + gTest.Printf(_L("Starting SetNotificationTrigger\n"));
1.963 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.964 + gTest(r==KErrNone);
1.965 + // Now instruct the bus implementation to represent the bus master attempting to read more words than
1.966 + // anticipated (Tx Underrun)
1.967 + gTest.Printf(_L("Starting SimulateTxNWords for Tx Underrun\n"));
1.968 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 14);
1.969 + gTest(r==KErrNone);
1.970 + //
1.971 + // Wait for the notification
1.972 + User::WaitForRequest(status);
1.973 + r=status.Int();
1.974 + if(r != KErrNone)
1.975 + {
1.976 + gTest.Printf(_L("TRequestStatus value after transmitting data = %d\n"),r);
1.977 + gTest(r==KErrNone);
1.978 + }
1.979 + gTest.Printf(_L("Tx Underrun test completed OK\n"));
1.980 +
1.981 + //
1.982 + // Simultaneous Rx,Tx tests
1.983 + //
1.984 + // For these tests, the proxy client (iic_slaveclient) will check that the expected results are witnessed
1.985 + // in the required order, and will complete the TRequestStatus when the sequence is complete (or error occurs).
1.986 + //
1.987 + // Set the notification trigger for both Rx and Tx
1.988 + triggerMask=ERxAllBytes|ETxAllBytes;
1.989 + gTest.Printf(_L("\nStarting SetNotificationTrigger with ERxAllBytes|ETxAllBytes\n"));
1.990 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.991 + gTest(r==KErrNone);
1.992 + // Now instruct the bus implementation to represent receipt of the required number of words from the bus master.
1.993 + gTest.Printf(_L("Starting SimulateRxNWords\n"));
1.994 + r=gChanSlaveI2c.SimulateRxNWords(busIdI2c, chanId, 8);
1.995 + gTest(r==KErrNone);
1.996 + // Now instruct the bus implementation to represent transmission of the required number of words to the bus master.
1.997 + gTest.Printf(_L("Starting SimulateTxNWords\n"));
1.998 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
1.999 + gTest(r==KErrNone);
1.1000 + //
1.1001 + // Wait for the notification
1.1002 + User::WaitForRequest(status);
1.1003 + r=status.Int();
1.1004 + if(r != KErrNone)
1.1005 + {
1.1006 + gTest.Printf(_L("TRequestStatus value after receiving and transmitting data = %d\n"),r);
1.1007 + gTest(r==KErrNone);
1.1008 + }
1.1009 + gTest.Printf(_L("Rx, Tx test completed OK\n"));
1.1010 + //
1.1011 + // Set the notification trigger for both Rx and Tx
1.1012 + gTest.Printf(_L("Starting SetNotificationTrigger with ERxAllBytes|ETxAllBytes\n"));
1.1013 + triggerMask=ERxAllBytes|ETxAllBytes;
1.1014 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1015 + gTest(r==KErrNone);
1.1016 + // Now instruct the bus implementation to represent transmission of the required number of words to the bus master.
1.1017 + gTest.Printf(_L("Starting SimulateTxNWords\n"));
1.1018 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
1.1019 + gTest(r==KErrNone);
1.1020 + // Now instruct the bus implementation to represent receipt of the required number of words from the bus master.
1.1021 + gTest.Printf(_L("Starting SimulateRxNWords\n"));
1.1022 + r=gChanSlaveI2c.SimulateRxNWords(busIdI2c, chanId, 8);
1.1023 + gTest(r==KErrNone);
1.1024 + //
1.1025 + // Wait for the notification
1.1026 + User::WaitForRequest(status);
1.1027 + r=status.Int();
1.1028 + if(r != KErrNone)
1.1029 + {
1.1030 + gTest.Printf(_L("TRequestStatus value after receiving and transmitting data = %d\n"),r);
1.1031 + gTest(r==KErrNone);
1.1032 + }
1.1033 + gTest.Printf(_L("Tx, Rx test completed OK\n"));
1.1034 + //
1.1035 + // Set the notification trigger for both Rx and Tx
1.1036 + gTest.Printf(_L("Starting SetNotificationTrigger with ERxAllBytes|ETxAllBytes\n"));
1.1037 + triggerMask=ERxAllBytes|ETxAllBytes;
1.1038 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1039 + gTest(r==KErrNone);
1.1040 + // Now instruct the bus implementation to represent simultaneous transmission of the required number of words (12)
1.1041 + // to the bus master and receipt of the required number of words (8) from the bus master
1.1042 + gTest.Printf(_L("Starting SimulateRxTxNWords\n"));
1.1043 + r=gChanSlaveI2c.SimulateRxTxNWords(busIdI2c, chanId, 8, 12);
1.1044 + gTest(r==KErrNone);
1.1045 + //
1.1046 + // Wait for the notification
1.1047 + User::WaitForRequest(status);
1.1048 + r=status.Int();
1.1049 + if(r != KErrNone)
1.1050 + {
1.1051 + gTest.Printf(_L("TRequestStatus value after receiving and transmitting data = %d\n"),r);
1.1052 + gTest(r==KErrNone);
1.1053 + }
1.1054 + gTest.Printf(_L("Tx with Rx test completed OK\n"));
1.1055 +
1.1056 + // Clear the trigger mask - this is just invoking SetNotificationTrigger with a zero trigger
1.1057 + // so that no subsequent triggers are expected (and so no TRequestStatus is provided)
1.1058 + gTest.Printf(_L("Starting SetNotificationTrigger with 0\n"));
1.1059 + triggerMask=0;
1.1060 + r=gChanSlaveI2c.SetNotifNoTrigger(chanId,triggerMask);
1.1061 + gTest(r==KErrNone);
1.1062 +
1.1063 + //
1.1064 + // Rx Overrun and Tx Underrun when both Rx and Tx notifications are requested
1.1065 + //
1.1066 + gTest.Printf(_L("Starting RxOverrun-TxUnderrun with simultaneous Rx,Tx notification requests\n"));
1.1067 + gChanSlaveI2c.TestOverrunUnderrun(busIdI2c,chanId,status);
1.1068 + //
1.1069 + // Wait for the notification
1.1070 + User::WaitForRequest(status);
1.1071 + r=status.Int();
1.1072 + if(r != KErrNone)
1.1073 + {
1.1074 + gTest.Printf(_L("TRequestStatus value after RxOverrun-TxUnderrun with simultaneous Rx,Tx notification requests= %d\n"),r);
1.1075 + gTest(r==KErrNone);
1.1076 + }
1.1077 + gTest.Printf(_L("RxOverrun-TxUnderrun with simultaneous Rx,Tx notification requests test completed OK\n"));
1.1078 +
1.1079 +
1.1080 + //
1.1081 + // Bus Error tests
1.1082 + //
1.1083 +
1.1084 + // Simulate a bus error
1.1085 + // A bus error will cause all pending bus activity to be aborted.
1.1086 + // Request a notification, then simulate a bus error
1.1087 + triggerMask=ERxAllBytes|ETxAllBytes;
1.1088 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1089 + gTest(r==KErrNone);
1.1090 + gTest.Printf(_L("Starting SimulateBusErr\n"));
1.1091 + r = gChanSlaveI2c.SimulateBusErr(busIdI2c,chanId);
1.1092 + gTest(r==KErrNone);
1.1093 + //
1.1094 + // Wait for the notification
1.1095 + User::WaitForRequest(status);
1.1096 + r=status.Int();
1.1097 + if(r != KErrNone)
1.1098 + {
1.1099 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.1100 + gTest(r==KErrNone);
1.1101 + }
1.1102 + gTest.Printf(_L("Bus error test completed OK\n"));
1.1103 +
1.1104 + // Clear the trigger mask and prepare for the next test
1.1105 + // This is unnecessary if the SetNotificationTrigger for the following test
1.1106 + // is called within the timeout period applied for Client responses ...
1.1107 + // but it represents a Client ending a transaction cleanly, and so is
1.1108 + // left here as an example
1.1109 + gTest.Printf(_L("\nStarting SetNotificationTrigger with 0\n"));
1.1110 + triggerMask=0;
1.1111 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1112 + gTest(r==KErrNone);
1.1113 +
1.1114 + // Simulate Master timeout
1.1115 + // Do this by:
1.1116 + // - Requesting a trigger for Tx
1.1117 + // - simulating the Master performing a read (ie the PSL indicates a Tx event) to start the transaction
1.1118 + // - provide a buffer for Tx, and request notification of Tx events, ie wait for Master response
1.1119 + // - block the PSL Tx notification to the PIL, so that the PIL timeout timer expires when a simulated Tx event
1.1120 + // is next requested
1.1121 + //
1.1122 + // Indicate the test to be performed
1.1123 + gTest.Printf(_L("\nStarting BlockNotification\n"));
1.1124 + // Register a buffer for Tx, then set the notification trigger
1.1125 + gTest.Printf(_L("RegisterTxBuffer - for Master to start the transaction\n"));
1.1126 + r=gChanSlaveI2c.RegisterTxBuffer(chanId, 4, 12, 8);
1.1127 + gTest(r==KErrNone);
1.1128 + gTest.Printf(_L("SetNotificationTrigger - for Master to start the transaction\n"));
1.1129 + triggerMask=ETxAllBytes;
1.1130 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1131 + gTest(r==KErrNone);
1.1132 + // Now instruct the bus implementation to simulate the Master reading the expected number of words
1.1133 + gTest.Printf(_L("Starting SimulateTxNWords\n"));
1.1134 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
1.1135 + gTest(r==KErrNone);
1.1136 + // Wait for the notification
1.1137 + User::WaitForRequest(status);
1.1138 + gTest.Printf(_L("Status request completed\n"));
1.1139 + r=status.Int();
1.1140 + if(r != KErrNone)
1.1141 + {
1.1142 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.1143 + gTest(r==KErrNone);
1.1144 + }
1.1145 + // Client is now expected to perform its part of the transaction - so pretend we need another Tx
1.1146 + // - but block completion of the Tx so that we generate a bus error
1.1147 + gTest.Printf(_L("SetNotificationTrigger - for second part of the transaction\n"));
1.1148 + triggerMask=ETxAllBytes;
1.1149 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1150 + gTest(r==KErrNone);
1.1151 + gTest.Printf(_L("BlockNotification\n"));
1.1152 + r=gChanSlaveI2c.BlockNotification(busIdI2c, chanId);
1.1153 + gTest(r==KErrNone);
1.1154 + // Now instruct the bus implementation to represent the bus master attempting to read the required number of words
1.1155 + gTest.Printf(_L("\nStarting SimulateTxNWords\n"));
1.1156 + r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
1.1157 + gTest(r==KErrNone);
1.1158 + //
1.1159 + // Wait for the notification
1.1160 + User::WaitForRequest(status);
1.1161 + r=status.Int();
1.1162 + if(r != KErrNone)
1.1163 + {
1.1164 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.1165 + gTest(r==KErrNone);
1.1166 + }
1.1167 + gTest.Printf(_L("Blocked notification test completed OK\n"));
1.1168 + // Re-set the notification trigger - for the 'blocked' Tx
1.1169 + // This is required because, in the event of a bus error, the set of requested Rx,Tx
1.1170 + // flags are cleared
1.1171 + gTest.Printf(_L("Starting SetNotificationTrigger with ETxAllBytes\n"));
1.1172 + triggerMask=ETxAllBytes;
1.1173 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1174 + gTest(r==KErrNone);
1.1175 + // Remove the block
1.1176 + gTest.Printf(_L("Starting UnblockNotification\n"));
1.1177 + r=gChanSlaveI2c.UnblockNotification(busIdI2c, chanId);
1.1178 + gTest(r==KErrNone);
1.1179 + //
1.1180 + // Wait for the notification
1.1181 + User::WaitForRequest(status);
1.1182 + r=status.Int();
1.1183 + if(r != KErrNone)
1.1184 + {
1.1185 + gTest.Printf(_L("TRequestStatus value after receiving data = %d\n"),r);
1.1186 + gTest(r==KErrNone);
1.1187 + }
1.1188 + gTest.Printf(_L("UnBlocked notification test completed OK\n"));
1.1189 + // Clear the trigger mask
1.1190 + gTest.Printf(_L("Starting SetNotificationTrigger with 0\n"));
1.1191 + triggerMask=0;
1.1192 + r=gChanSlaveI2c.SetNotificationTrigger(chanId,triggerMask,&status);
1.1193 + gTest(r==KErrNone);
1.1194 +
1.1195 + // Release the channel
1.1196 + r = gChanSlaveI2c.ReleaseChannel( chanId );
1.1197 + gTest(r==KErrNone);
1.1198 +
1.1199 + delete i2cBuf;
1.1200 +#else
1.1201 + gTest.Printf(_L("\nSlaveRxTxNotificationTests only supported when SLAVE_MODE is defined\n"));
1.1202 +#endif
1.1203 +
1.1204 + return r;
1.1205 + }
1.1206 +
1.1207 +//----------------------------------------------------------------------------------------------
1.1208 +//! @SYMTestCaseID KBASE-T_IIC-2404
1.1209 +//! @SYMTestType UT
1.1210 +//! @SYMPREQ PREQ2128,2129
1.1211 +//! @SYMTestCaseDesc This test case tests that MasterSlave channels can only be used in one mode at a time, and that
1.1212 +//! if captured for Slave operation or with transactions queued for Master operation the channel can
1.1213 +//! not be de-registered.
1.1214 +//! @SYMTestActions 0) Capture the channel for Slave operation. Attempt to synchronously queue a transaction
1.1215 +//! on the channel. Attempt to asynchronously queue a transaction on the channel. Attempt
1.1216 +//! to de-register the channel.Release the Slave channel
1.1217 +//!
1.1218 +//! 1) Use controlio to block completion of queued transactions. Request asynchronous queue
1.1219 +//! transaction. Attempt to capture the channel for Slave operation. Attempt to de-register
1.1220 +//! the channel. Unblock completion of transactions and wait for the TRequestStatus for the
1.1221 +//! transaction to be completed.
1.1222 +//!
1.1223 +//! @SYMTestExpectedResults 0) Once captured for Slave operation, attempts to queue a transaction or de-register the channel
1.1224 +//! return KErrInUse, exits otherwise.
1.1225 +//! 1) With a transaction queued, attempt to capture the channel returns KErrInUse, exits otherwise.
1.1226 +//! Attempt to de-register channel returns KErrInUse, exits otherwise. The TRequestStatus should
1.1227 +//! be set to KErrTimedOut, exits otherwise.
1.1228 +//!
1.1229 +//!
1.1230 +//! @SYMTestPriority High
1.1231 +//! @SYMTestStatus Implemented
1.1232 +//----------------------------------------------------------------------------------------------
1.1233 +LOCAL_C TInt MasterSlaveAcquisitionTests()
1.1234 +//
1.1235 +// Test to check that:
1.1236 +// (1) A Master-Slave channel that has been captured for use in Slave mode will not allow requests for
1.1237 +// queing transactions to be accepted
1.1238 +// (2) A Master-Slave channel that has been captured for use in Slave mode can not be de-registered
1.1239 +// (3) A Master-Slave channel that has one or more transactions queued in its Master channel transaction queue
1.1240 +// can not be captured for use in Slave Made
1.1241 +// (4) A Master-Slave channel that has one or more transactions queued in its Master channel transaction queue
1.1242 +// can not be de-registered
1.1243 +//
1.1244 + {
1.1245 + gTest.Printf(_L("\n\nStarting MasterSlaveAcquisitionTests\n"));
1.1246 + TInt r=KErrNone;
1.1247 +
1.1248 +#if defined(MASTER_MODE) && defined(SLAVE_MODE)
1.1249 + // Create a Master-Slave channel
1.1250 + RBusDevIicClient chanMasterSlaveI2c;
1.1251 + TBufC<18> proxyName;
1.1252 + if(!aStandAloneChan)
1.1253 + proxyName = KIicProxyFileNameRoot;
1.1254 + else
1.1255 + proxyName = KIicProxyFileNameRootCtrlLess;
1.1256 + r = chanMasterSlaveI2c.Open(proxyName);
1.1257 + gTest(r==KErrNone);
1.1258 + r = chanMasterSlaveI2c.InitSlaveClient(); // Initialise callback used for Slave processing
1.1259 + gTest(r==KErrNone);
1.1260 + //
1.1261 + // Capture the channel for Slave operation
1.1262 + // Attempt to synchronously queue a transaction on the channel - expect KErrInUse as a response
1.1263 + // Attempt to asynchronously queue a transaction on the channel - expect KErrInUse as a response
1.1264 + // Attempt to de-register the channel - expect KErrInUse as a response
1.1265 + // Release the Slave channel
1.1266 + //
1.1267 + // Create a I2C configuration buffer and the configuration data for use in capturing gChanSlaveI2c
1.1268 + TUint32 busIdI2c = 0;
1.1269 + TConfigI2cBufV01* i2cBuf=NULL;
1.1270 + r=CreateSlaveChanI2cConfig(i2cBuf, busIdI2c, 12); // 12 is the MasterSlave channel number
1.1271 + gTest(r==KErrNone);
1.1272 + TInt chanId;
1.1273 +
1.1274 + gTest.Printf(_L("\nStarting synchronous CaptureChannel \n"));
1.1275 + r = chanMasterSlaveI2c.CaptureChannel(busIdI2c, i2cBuf, chanId );
1.1276 + gTest.Printf(_L("Synchronous CaptureChannel returned = %d, chanId=0x%x\n"),r,chanId);
1.1277 + gTest(r==KErrNone);
1.1278 + //
1.1279 + _LIT(halfDuplexText,"Half Duplex Text");
1.1280 + TBuf8<17> halfDuplexBuf_8;
1.1281 + halfDuplexBuf_8.Copy(halfDuplexText);
1.1282 + TUsideTferDesc* tfer = NULL;
1.1283 + r=CreateSingleUserSideTransfer(tfer, EMasterWrite, 8, &halfDuplexBuf_8, NULL);
1.1284 + if(r!=KErrNone)
1.1285 + return r;
1.1286 + if(tfer==NULL)
1.1287 + return KErrGeneral;
1.1288 + //
1.1289 + TUsideTracnDesc* tracn = NULL;
1.1290 + r = CreateSingleUserSideTransaction(tracn, EI2c, i2cBuf, tfer, NULL, 0, NULL, NULL);
1.1291 + if(r!=KErrNone)
1.1292 + return r;
1.1293 + if(tracn==NULL)
1.1294 + return KErrGeneral;
1.1295 +
1.1296 +
1.1297 + gTest.Printf(_L("\nStarting synchronous QueueTransaction \n"));
1.1298 + r = chanMasterSlaveI2c.QueueTransaction(busIdI2c, tracn);
1.1299 + gTest.Printf(_L("Synchronous QueueTransaction returned = %d\n"),r);
1.1300 + gTest(r==KErrInUse);
1.1301 + gTest.Printf(_L("\nStarting asynchronous QueueTransaction \n"));
1.1302 + TRequestStatus status;
1.1303 + chanMasterSlaveI2c.QueueTransaction(status, busIdI2c, tracn);
1.1304 + User::WaitForRequest(status);
1.1305 + if(status != KErrInUse)
1.1306 + {
1.1307 + gTest.Printf(_L("TRequestStatus value after queue = %d\n"),status.Int());
1.1308 + gTest(r==KErrInUse);
1.1309 + }
1.1310 +//
1.1311 +// // If it is stand-alone channel, the client is responsible for channel creation.
1.1312 +// // So the RegisterChan and DeRegisterChan are not needed.
1.1313 + if(aStandAloneChan == 0)
1.1314 + {
1.1315 + gTest.Printf(_L("\nStarting deregistration of captured channel\n"));
1.1316 + r = chanMasterSlaveI2c.DeRegisterChan(busIdI2c);
1.1317 + gTest.Printf(_L("DeRegisterChan returned = %d\n"),r);
1.1318 + gTest(r==KErrInUse);
1.1319 + }
1.1320 +
1.1321 + gTest.Printf(_L("\nInvoke ReleaseChannel for chanId=0x%x \n"),chanId);
1.1322 + r = chanMasterSlaveI2c.ReleaseChannel( chanId );
1.1323 + gTest.Printf(_L("ReleaseChannel returned = %d\n"),r);
1.1324 + gTest(r==KErrNone);
1.1325 +
1.1326 + //
1.1327 + // Use ControlIO/StaticExtension to block transactions on the Master Channel
1.1328 + // Queue an asynchronous transaction on the channel
1.1329 + // Attempt to capture the channel for Slave operation - expect KErrInUse as a response
1.1330 + // Attempt to de-register the channel - expect KErrInUse as a response
1.1331 + // Unblock the channel
1.1332 + // Check for (timed out) completion of the transaction
1.1333 + //
1.1334 + gTest.Printf(_L("Invoking BlockReqCompletion\n"));
1.1335 + r = chanMasterSlaveI2c.BlockReqCompletion(busIdI2c);
1.1336 + gTest.Printf(_L("BlockReqCompletion returned = %d\n"),r);
1.1337 + //
1.1338 + gTest.Printf(_L("Queueing first transaction \n"));
1.1339 + chanMasterSlaveI2c.QueueTransaction(status, busIdI2c, tracn);
1.1340 + //
1.1341 + User::After(50000);
1.1342 + //
1.1343 + gTest.Printf(_L("\nStarting synchronous CaptureChannel \n"));
1.1344 + r = chanMasterSlaveI2c.CaptureChannel(busIdI2c, i2cBuf, chanId );
1.1345 + gTest.Printf(_L("Synchronous CaptureChannel returned = %d, chanId=0x%x\n"),r,chanId);
1.1346 + gTest(r==KErrInUse);
1.1347 +
1.1348 + // If it is stand-alone channel, the client is responsible for channel creation.
1.1349 + // So the RegisterChan and DeRegisterChan are not needed.
1.1350 + if(aStandAloneChan == 0)
1.1351 + {
1.1352 + gTest.Printf(_L("\nStarting deregistration of channel\n"));
1.1353 + r = chanMasterSlaveI2c.DeRegisterChan(busIdI2c);
1.1354 + gTest.Printf(_L("DeRegisterChan returned = %d\n"),r);
1.1355 + gTest(r==KErrInUse);
1.1356 + }
1.1357 + gTest.Printf(_L("Invoking UnlockReqCompletion\n"));
1.1358 + r = chanMasterSlaveI2c.UnblockReqCompletion(busIdI2c);
1.1359 + gTest.Printf(_L("UnblockReqCompletion returned = %d\n"),r);
1.1360 + //
1.1361 + User::After(50000);
1.1362 + //
1.1363 + User::WaitForRequest(status);
1.1364 + r=status.Int();
1.1365 + if(r != KErrTimedOut)
1.1366 + {
1.1367 + gTest.Printf(_L("TRequestStatus value after queue = %d\n"),r);
1.1368 + gTest(r==KErrTimedOut);
1.1369 + }
1.1370 + r=KErrNone; // Ensure error code is not propagated
1.1371 +
1.1372 + delete i2cBuf;
1.1373 + delete tfer;
1.1374 + delete tracn;
1.1375 + chanMasterSlaveI2c.Close();
1.1376 +#else
1.1377 + gTest.Printf(_L("\nMasterSlaveAcquisitionTests only supported when both MASTER_MODE and SLAVE_MODE are defined\n"));
1.1378 +#endif
1.1379 +
1.1380 + return r;
1.1381 + }
1.1382 +
1.1383 +//----------------------------------------------------------------------------------------------
1.1384 +//! @SYMTestCaseID KBASE-T_IIC-2404
1.1385 +//! @SYMTestType UT
1.1386 +//! @SYMDEF DEF141732
1.1387 +//! @SYMTestCaseDesc This test case tests the inline functions of DIicBusChannel interface.
1.1388 +//! @SYMTestActions Call Kernel-side proxy client function to perform interface tests.
1.1389 +//! @SYMTestExpectedResults Kernel-side proxy client should return with KErrNone.
1.1390 +//! @SYMTestPriority Medium
1.1391 +//! @SYMTestStatus Implemented
1.1392 +//----------------------------------------------------------------------------------------------
1.1393 +LOCAL_C TInt IicInterfaceInlineTests()
1.1394 + {
1.1395 + if(aStandAloneChan == 1)
1.1396 + {
1.1397 + gTest.Printf(_L("\n\nStarting IicInterfaceInlineTests\n"));
1.1398 + TInt r=KErrNone;
1.1399 + r = gChanMasterSpi.TestIiicChannelInlineFunc();
1.1400 + return r;
1.1401 + }
1.1402 + else
1.1403 + {
1.1404 + gTest.Printf(_L("\nIicInterfaceInlineTests can only be run in Standalone mode\n"));
1.1405 + return KErrNone;
1.1406 + }
1.1407 + }
1.1408 +
1.1409 +LOCAL_C TInt RunTests()
1.1410 +//
1.1411 +// Utility method to invoke the separate tests
1.1412 +//
1.1413 + {
1.1414 + TInt r =KErrNone;
1.1415 + r = IicInterfaceInlineTests();
1.1416 + if(r!=KErrNone)
1.1417 + return r;
1.1418 +
1.1419 + r = MasterBasicTests();
1.1420 + if(r!=KErrNone)
1.1421 + return r;
1.1422 +
1.1423 + r = SlaveRxTxNotificationTests();
1.1424 + if(r!=KErrNone)
1.1425 + return r;
1.1426 +
1.1427 + r = SlaveChannelCaptureReleaseTests();
1.1428 + if(r!=KErrNone)
1.1429 + return r;
1.1430 +
1.1431 + r = MasterExtTests(KTransactionWithPreamble);
1.1432 + if(r!=KErrNone)
1.1433 + return r;
1.1434 +
1.1435 + r = MasterExtTests(KTransactionWithMultiTransc);
1.1436 + if(r!=KErrNone)
1.1437 + return r;
1.1438 +
1.1439 + r = MasterExtTests(KTransactionWithMultiTransc|KTransactionWithPreamble);
1.1440 + if(r!=KErrNone)
1.1441 + return r;
1.1442 +
1.1443 + r = MasterTransactionTests();
1.1444 + if(r!=KErrNone)
1.1445 + return r;
1.1446 +
1.1447 + r = MasterSlaveAcquisitionTests();
1.1448 + if(r!=KErrNone)
1.1449 + return r;
1.1450 +
1.1451 + return KErrNone;
1.1452 + }
1.1453 +
1.1454 +GLDEF_C TInt E32Main()
1.1455 +//
1.1456 +// Main
1.1457 +//
1.1458 + {
1.1459 + gTest.Title();
1.1460 + gTest.Start(_L("Test IIC API\n"));
1.1461 +
1.1462 + TInt r = KErrNone;
1.1463 +
1.1464 + // Turn off lazy dll unloading
1.1465 + RLoader l;
1.1466 + gTest(l.Connect()==KErrNone);
1.1467 + gTest(l.CancelLazyDllUnload()==KErrNone);
1.1468 + l.Close();
1.1469 +
1.1470 +#ifdef IIC_SIMULATED_PSL
1.1471 + gTest.Next(_L("Start the IIC with controller test\n"));
1.1472 + aStandAloneChan = 0;
1.1473 + gTest.Next(_L("Load Simulated IIC PSL bus driver"));
1.1474 + r = User::LoadPhysicalDevice(KIicPslFileName);
1.1475 + gTest.Printf(_L("return value r=%d"),r);
1.1476 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1477 +
1.1478 + gTest.Next(_L("Load Simulated PSL SPI bus driver"));
1.1479 + r = User::LoadPhysicalDevice(KSpiFileName);
1.1480 + gTest.Printf(_L("return value r=%d"),r);
1.1481 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1482 +
1.1483 + gTest.Next(_L("Load Simulated PSL I2C bus driver"));
1.1484 + r = User::LoadPhysicalDevice(KI2cFileName);
1.1485 + gTest.Printf(_L("return value r=%d"),r);
1.1486 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1487 +
1.1488 + gTest.Next(_L("Load kernel-side proxy IIC client"));
1.1489 + r = User::LoadLogicalDevice(KIicProxyFileName);
1.1490 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1491 +
1.1492 + gTest.Next(_L("Load kernel-side proxy IIC slave client"));
1.1493 + r = User::LoadLogicalDevice(KIicProxySlaveFileName);
1.1494 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1495 +
1.1496 + __KHEAP_MARK;
1.1497 + // First ascertain what bus options are available.
1.1498 +
1.1499 + // SPI has Master channel numbers 1,2 and 4, Slave channel number 3
1.1500 + // Open a Master SPI channel to the kernel side proxy
1.1501 + TBufC<30> proxyName(KIicProxyFileNameRoot);
1.1502 + r = gChanMasterSpi.Open(proxyName);
1.1503 + gTest(r==KErrNone);
1.1504 +
1.1505 + // I2C has Master channel numbers 10 and 11, if built with MASTER_MODE, only
1.1506 + // I2C has Slave channel numbers 12 and 13, if built with SLAVE_MODE, only
1.1507 + // I2C has Master channel number 10 and Slave channel numer 11 if built with both MASTER_MODE and SLAVE_MODE
1.1508 + // Open a Master I2C channel to the kernel side proxy
1.1509 + r = gChanMasterI2c.Open(proxyName);
1.1510 + gTest(r==KErrNone);
1.1511 + TBufC<15> proxySlaveName(KIicProxySlaveFileNameRoot);
1.1512 + r = gChanSlaveI2c.Open(proxySlaveName);
1.1513 + gTest(r==KErrNone);
1.1514 + r = gChanSlaveI2c.InitSlaveClient();
1.1515 + gTest(r==KErrNone);
1.1516 +
1.1517 + // Instigate tests
1.1518 + r = RunTests();
1.1519 + gTest(r==KErrNone);
1.1520 +
1.1521 + gTest.Printf(_L("Tests completed OK, about to close channel\n"));
1.1522 +
1.1523 + gChanMasterSpi.Close();
1.1524 + gChanMasterI2c.Close();
1.1525 + gChanSlaveI2c.Close();
1.1526 +
1.1527 + UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
1.1528 + __KHEAP_MARKEND;
1.1529 +
1.1530 + gTest.Next(_L("Free kernel-side proxy IIC client"));
1.1531 + TInt err = User::FreeLogicalDevice(KIicProxyFileNameRoot);
1.1532 + gTest(err==KErrNone || err==KErrAlreadyExists);
1.1533 +
1.1534 + gTest.Next(_L("Free kernel-side proxy IIC slave client"));
1.1535 + err = User::FreeLogicalDevice(KIicProxySlaveFileNameRoot);
1.1536 + gTest(err==KErrNone || err==KErrAlreadyExists);
1.1537 +
1.1538 + gTest.Next(_L("Free Simulated PSL I2C bus driver"));
1.1539 + err = User::FreePhysicalDevice(KI2cFileName);
1.1540 + gTest(err==KErrNone);
1.1541 +
1.1542 + gTest.Next(_L("Free Simulated PSL SPI bus driver"));
1.1543 + err = User::FreePhysicalDevice(KSpiFileName);
1.1544 + gTest(err==KErrNone);
1.1545 +
1.1546 + gTest.Next(_L("Free Simulated IIC PSL bus driver"));
1.1547 + err = User::FreePhysicalDevice(KIicPslFileNameRoot);
1.1548 + gTest(err==KErrNone);
1.1549 +
1.1550 + gTest.Next(_L("Start the controller-less IIC test\n"));
1.1551 + aStandAloneChan = 1;
1.1552 +
1.1553 + gTest.Next(_L("Load Simulated PSL SPI bus driver"));
1.1554 + r = User::LoadPhysicalDevice(KSpiFileNameCtrlLess);
1.1555 + gTest.Printf(_L("return value r=%d"),r);
1.1556 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1557 +
1.1558 + gTest.Next(_L("Load Simulated PSL I2C bus driver"));
1.1559 + r = User::LoadPhysicalDevice(KI2cFileNameCtrlLess);
1.1560 + gTest.Printf(_L("return value r=%d"),r);
1.1561 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1562 +
1.1563 + gTest.Next(_L("Load kernel-side proxy IIC client"));
1.1564 + r = User::LoadLogicalDevice(KIicProxyFileNameCtrlLess);
1.1565 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1566 +
1.1567 + gTest.Next(_L("Load kernel-side proxy IIC slave client"));
1.1568 + r = User::LoadLogicalDevice(KIicProxySlaveFileNameCtrlLess);
1.1569 + gTest(r==KErrNone || r==KErrAlreadyExists);
1.1570 +
1.1571 + // First ascertain what bus options are available.
1.1572 + __KHEAP_MARK;
1.1573 + // SPI has Master channel numbers 1,2 and 4, Slave channel number 3
1.1574 + // Open a Master SPI channel to the kernel side proxy
1.1575 + TBufC<30> proxyNameCtrlLess(KIicProxyFileNameRootCtrlLess);
1.1576 + r = gChanMasterSpi.Open(proxyNameCtrlLess);
1.1577 + gTest(r==KErrNone);
1.1578 +
1.1579 + // I2C has Master channel numbers 10 and 11, if built with MASTER_MODE, only
1.1580 + // I2C has Slave channel numbers 12 and 13, if built with SLAVE_MODE, only
1.1581 + // I2C has Master channel number 10 and Slave channel numer 11 if built with both MASTER_MODE and SLAVE_MODE
1.1582 + // Open a Master I2C channel to the kernel side proxy
1.1583 + r = gChanMasterI2c.Open(proxyNameCtrlLess);
1.1584 +
1.1585 + gTest(r==KErrNone);
1.1586 + TBufC<35> proxySlaveNameCtrlLess(KIicProxySlaveFileNameRootCtrlLess);
1.1587 +
1.1588 + r = gChanSlaveI2c.Open(proxySlaveNameCtrlLess);
1.1589 + gTest(r==KErrNone);
1.1590 + r = gChanSlaveI2c.InitSlaveClient();
1.1591 + gTest(r==KErrNone);
1.1592 +
1.1593 + // Instigate tests
1.1594 + r = RunTests();
1.1595 + gTest(r==KErrNone);
1.1596 +
1.1597 + gTest.Printf(_L("Tests completed OK, about to close channel\n"));
1.1598 +
1.1599 + gChanMasterSpi.Close();
1.1600 + gChanMasterI2c.Close();
1.1601 + gChanSlaveI2c.Close();
1.1602 +
1.1603 + UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
1.1604 + __KHEAP_MARKEND;
1.1605 +
1.1606 + gTest.Next(_L("Free kernel-side proxy IIC client"));
1.1607 +
1.1608 + err = User::FreeLogicalDevice(KIicProxyFileNameRootCtrlLess);
1.1609 + gTest(err==KErrNone || err==KErrAlreadyExists);
1.1610 + gTest.Next(_L("Free kernel-side proxy IIC slave client"));
1.1611 + err = User::FreeLogicalDevice(KIicProxySlaveFileNameRootCtrlLess);
1.1612 + gTest(err==KErrNone || err==KErrAlreadyExists);
1.1613 +
1.1614 + gTest.Next(_L("Free Simulated PSL I2C bus driver"));
1.1615 + err = User::FreePhysicalDevice(KI2cFileNameCtrlLess);
1.1616 + gTest(err==KErrNone);
1.1617 +
1.1618 + gTest.Next(_L("Free Simulated PSL SPI bus driver"));
1.1619 + err = User::FreePhysicalDevice(KSpiFileNameCtrlLess);
1.1620 + gTest(err==KErrNone);
1.1621 +#else
1.1622 + gTest.Printf(_L("Don't do the test if it is not IIC_SIMULATED_PSL"));
1.1623 +#endif
1.1624 + gTest.End();
1.1625 + return r;
1.1626 + }
1.1627 +