Update contrib.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\device\t_serial.cpp
18 //#define _DEBUG_DEVCOMM
20 #define __E32TEST_EXTENSION__
22 #include <e32base_private.h>
30 #include "d_lddturnaroundtimertest.h"
33 //#define DRIVER_TRACE_ON // disables or adjusts timeout for tests affected by LDD trace
35 // Enable aggressive paging policy if required
37 #define WDP_ENABLED // affects some tests
38 #define FLUSH_WDP_CACHE UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0)
40 #define FLUSH_WDP_CACHE
43 #if defined (__WINS__)
44 #define PDD_NAME _L("ECDRV.PDD")
45 #define LDD_NAME _L("ECOMM.LDD")
47 #define PDD_NAME _L("EUART")
48 #define LDD_NAME _L("ECOMM")
51 const char KSpinner[]={'|','/','-','\\',};
53 #include "../power/async.h"
55 #define CHECK(r,v) {if ((r)!=(v)) {test.Printf(_L("Line %d Expected %d Got %d\n"),__LINE__,(v),(r)); test(0);}}
57 // constant expressions for elements in an array, and 1st address past the end
58 #define ELEMENTS(A) (sizeof(A)/sizeof(A[0]))
59 #define LIMIT(A) (A + ELEMENTS(A))
61 // Our own comms object with synchronous writes
62 class RComm : public RBusDevComm
65 TInt WriteS(const TDesC8& aDes);
66 TInt WriteS(const TDesC8& aDes,TInt aLength);
67 // Override the read functions to flush the paging cache
68 inline void Read(TRequestStatus &aStatus,TDes8 &aDes)
71 RBusDevComm::Read(aStatus, aDes);
73 inline void Read(TRequestStatus &aStatus,TDes8 &aDes,TInt aLength)
76 RBusDevComm::Read(aStatus, aDes, aLength);
78 inline void ReadOneOrMore(TRequestStatus &aStatus,TDes8 &aDes)
81 RBusDevComm::ReadOneOrMore(aStatus, aDes);
85 LOCAL_D RTest test(_L("T_SERIAL"));
86 RComm* theSerialPorts[2];
87 TCommCaps2 theCaps1Buf;
88 TCommCapsV02& theCaps1=theCaps1Buf();
89 TCommCaps2 theCaps2Buf;
90 TCommCapsV02& theCaps2=theCaps2Buf();
94 const TInt KWriteSize=250;
95 const TInt KXonNumReads=0x10;
96 const TInt KXonReadSize=0x400;
106 class TSpeedAndNameV2
115 const TSpeedAndName KSpeeds[]=
117 // {KCapsBps50,EBps50,_S("50")},
118 // {KCapsBps75,EBps75,_S("75")},
119 // {KCapsBps110,EBps110,_S("110")},
120 // {KCapsBps134,EBps134,_S("134")},
121 // {KCapsBps150,EBps150,_S("150")},
122 // {KCapsBps300,EBps300,_S("300")},
123 // {KCapsBps600,EBps600,_S("600")},
124 // {KCapsBps1200,EBps1200,_S("1200")},
125 // {KCapsBps1800,EBps1800,_S("1800")},
126 // {KCapsBps2000,EBps2000,_S("2000")},
127 // {KCapsBps2400,EBps2400,_S("2400")},
128 // {KCapsBps3600,EBps3600,_S("3600")},
129 // {KCapsBps4800,EBps4800,_S("4800")},
130 // {KCapsBps7200,EBps7200,_S("7200")},
131 {KCapsBps9600,EBps9600,_S("9600")},
132 {KCapsBps19200,EBps19200,_S("19200")},
133 // {KCapsBps38400,EBps38400,_S("38400")},
134 {KCapsBps57600,EBps57600,_S("57600")},
135 {KCapsBps115200,EBps115200,_S("115200")},
138 // These speeds are used to test break handling
139 const TSpeedAndNameV2 KBreakSpeeds[]=
141 // {KCapsBps50,EBps50,_S("50"),50},
142 // {KCapsBps75,EBps75,_S("75"),75},
143 // {KCapsBps110,EBps110,_S("110"),110},
144 // {KCapsBps134,EBps134,_S("134"),134},
145 // {KCapsBps150,EBps150,_S("150"),150},
146 {KCapsBps300,EBps300,_S("300"),300},
147 // {KCapsBps600,EBps600,_S("600"),600},
148 {KCapsBps1200,EBps1200,_S("1200"),1200},
149 // {KCapsBps1800,EBps1800,_S("1800"),1800},
150 // {KCapsBps2000,EBps2000,_S("2000"),2000},
151 // {KCapsBps2400,EBps2400,_S("2400"),2400},
152 // {KCapsBps3600,EBps3600,_S("3600"),3600},
153 {KCapsBps4800,EBps4800,_S("4800"),4800},
154 // {KCapsBps7200,EBps7200,_S("7200"),7200},
155 // {KCapsBps9600,EBps9600,_S("9600"),9600},
156 // {KCapsBps19200,EBps19200,_S("19200"),19200},
157 // {KCapsBps38400,EBps38400,_S("38400"),38400},
158 {KCapsBps57600,EBps57600,_S("57600"),57600},
159 {KCapsBps115200,EBps115200,_S("115200"),115200},
162 // Multiplying factors to give Min turnaround times in microseconds between Rx and Tx
163 #if defined (__WINS__)
164 const TUint KTurnaroundTimes[] =
172 const TUint KTurnaroundTimes[] =
174 #ifdef DRIVER_TRACE_ON
197 const TFrameAndName KFrameTypes[]=
199 {EData8,EStop1,EParityNone,_S("8,N,1")},
200 {EData8,EStop1,EParityEven,_S("8,E,1")},
201 {EData8,EStop1,EParityOdd,_S("8,O,1")},
203 {EData8,EStop2,EParityNone,_S("8,N,2")},
204 {EData8,EStop2,EParityEven,_S("8,E,2")},
205 {EData8,EStop2,EParityOdd,_S("8,O,2")},
207 {EData7,EStop2,EParityNone,_S("7,N,2")},
208 {EData7,EStop2,EParityEven,_S("7,E,2")},
209 {EData7,EStop2,EParityOdd,_S("7,O,2")},
211 {EData7,EStop1,EParityNone,_S("7,N,1")},
212 {EData7,EStop1,EParityEven,_S("7,E,1")},
213 {EData7,EStop1,EParityOdd,_S("7,O,1")},
215 // {EData6,EStop2,EParityNone,_S("6,N,2")},
216 // {EData6,EStop2,EParityEven,_S("6,E,2")},
217 // {EData6,EStop2,EParityOdd,_S("6,O,2")},
219 // {EData6,EStop1,EParityNone,_S("6,N,1")},
220 // {EData6,EStop1,EParityEven,_S("6,E,1")},
221 // {EData6,EStop1,EParityOdd,_S("6,O,1")},
223 // {EData5,EStop1,EParityNone,_S("5,N,1")},
224 // {EData5,EStop1,EParityEven,_S("5,E,1")},
225 // {EData5,EStop1,EParityOdd,_S("5,O,1")},
228 class THandShakeAndName
235 THandShakeAndName KHandshakes[]=
237 // {KConfigObeyDSR,_S("DSR/DTR")}, // most cables don't actually support this
238 {KConfigObeyCTS,_S("CTS/RTS")},
239 // {KConfigObeyDCD,_S("DCD")},
242 enum TSerialTestFault
246 _LIT(KLddFileName, "D_LDDTURNAROUNDTIMERTEST.LDD");
249 #ifdef _DEBUG_DEVCOMM
250 void CommDebug(RBusDevComm& aComm)
252 TCommDebugInfoPckg infopckg;
253 TCommDebugInfo& info = infopckg();
254 aComm.DebugInfo(infopckg);
256 test.Printf(_L(" LDD State : TX RX \r\n"));
257 test.Printf(_L(" Busy : %10d %10d\r\n"), info.iTxBusy, info.iRxBusy);
258 test.Printf(_L(" Held : %10d %10d\r\n"), info.iTxHeld, info.iRxHeld);
259 test.Printf(_L(" Length : %10d %10d\r\n"), info.iTxLength, info.iRxLength);
260 test.Printf(_L(" Offset : %10d %10d\r\n"), info.iTxOffset, info.iRxOffset);
261 test.Printf(_L(" Int Count : %10d %10d\r\n"), info.iTxIntCount, info.iRxIntCount);
262 test.Printf(_L(" Err Count : %10d %10d\r\n"), info.iTxErrCount, info.iRxErrCount);
263 test.Printf(_L(" Buf Count : %10d %10d\r\n"), info.iTxBufCount, info.iRxBufCount);
264 test.Printf(_L(" Fill/Drain : %10d %10d\r\n"), info.iFillingTxBuf, info.iFillingTxBuf);
265 test.Printf(_L(" XON : %10d %10d\r\n"), info.iTxXon, info.iRxXon);
266 test.Printf(_L(" XOFF : %10d %10d\r\n"), info.iTxXoff, info.iRxXoff);
267 test.Printf(_L(" Chars : %10d %10d\r\n"), info.iTxChars, info.iRxChars);
268 // test.Printf(_L(" DFC Pending : %10d %10d\r\n"), info.iTxDfcPend, info.iTxDfcPend);
269 // test.Printf(_L(" DFC Run/Count : %10d %10d\r\n"), info.iRunningDfc, info.iDfcCount);
270 // test.Printf(_L(" DFC Req/Do/Drain : %10d %10d %10d\r\n"), info.iDfcReqSeq, info.iDfcHandlerSeq, info.iDoDrainSeq);
273 void CommDebug(RBusDevComm& /*aComm*/)
275 test.Printf(_L("Debug Dump not available\r\n"));
279 TInt RComm::WriteS(const TDesC8& aDes)
285 return(WriteS(aDes,aDes.Length()));
289 TInt RComm::WriteS(const TDesC8& aDes,TInt aLength)
297 // Force there to be paging events
301 Write(s,aDes,aLength);
302 User::WaitForRequest(s);
306 void Panic(TSerialTestFault const& aFault)
308 // Panic the test code
311 User::Panic(_L("Comm Test"),aFault);
314 void StripeMem(TDes8& aBuf,TUint aStartChar,TUint anEndChar)
316 // Mark a buffer with repeating byte pattern
320 __ASSERT_ALWAYS(aStartChar<=anEndChar,Panic(EBadArg));
321 if (aStartChar==anEndChar)
323 aBuf.Fill(aStartChar);
327 TUint character=aStartChar;
328 for (TInt i=0;i<aBuf.Length();i++)
330 aBuf[i]=(TText8)character;
331 if(++character>anEndChar)
332 character=aStartChar;
336 #define COLUMN_HEADER _L(" InBuf | outbuf\n\r")
338 bool CompareDescriptors(TDes8 &aLeft,TDes8 &aRight)
340 // Compare a couple of descriptors and dump them if they don't match
343 TInt lLen=aLeft.Length();
344 TInt rLen=aRight.Length();
345 TInt minLen=Min(lLen,rLen);
347 aRight.SetLength(minLen);
348 aLeft.SetLength(minLen);
349 bool r = (aLeft.Compare(aRight)==0);
352 RDebug::Print(_L("Compare failed - dumping descriptors\n\r"));
353 TInt len=aLeft.Length();
354 RDebug::Print(COLUMN_HEADER);
356 for (TInt i=0;i<=len/8;i++)
360 buf.AppendFormat(_L8("%4d: "),i*8);
362 for (TInt j=0;j<8;j++)
366 TInt v=aLeft[(i*8)+j];
367 buf.AppendFormat(_L8("%02x "),v);
370 buf.AppendFormat(_L8(" "));
372 buf.AppendFormat(_L8(" | "));
373 for (TInt k=0;k<8;k++)
377 TInt v=aRight[(i*8)+k];
378 buf.AppendFormat(_L8("%02x "),v);
380 buf.AppendFormat(_L8("\r\n"));
381 RDebug::RawPrint(buf);
386 theSerialPorts[0]->Close();
387 theSerialPorts[1]->Close();
388 aRight.SetLength(rLen);
389 aLeft.SetLength(lLen);
394 TInt CheckedWrite(TInt aBufSize)
396 // Write a buffer from one serial port to the other and vice versa.
399 TUint8* inBuf=new TUint8[aBufSize];
401 TUint8* outBuf=new TUint8[aBufSize];
403 TPtr8 outDes(outBuf,aBufSize,aBufSize);
404 TPtr8 inDes(inBuf,aBufSize,aBufSize);
408 TRequestStatus readStatus;
409 TRequestStatus timeStatus;
411 StripeMem(outDes,'A','Z');
414 const TInt KReadFirstPort=0;
415 const TInt KWriteFirstPort=1;
417 // Check the driver rejects an attempt to read more data than the buffer allows
418 theSerialPorts[KReadFirstPort]->Read(readStatus,inDes,aBufSize+1);
419 test(readStatus==KErrGeneral);
421 // Start reading for real
422 theSerialPorts[KReadFirstPort]->Read(readStatus,inDes);
423 test_Equal(KRequestPending, readStatus.Int());
426 TInt ret=theSerialPorts[KWriteFirstPort]->WriteS(outDes,aBufSize);
429 // Set a 6 second timer going
430 const TUint KTimeOut=12000000;
431 tim.After(timeStatus,KTimeOut);
432 test(timeStatus==KRequestPending);
434 // Wait for EITHER the read to complete, OR for the timer to timeout
435 User::WaitForRequest(readStatus,timeStatus);
436 if (timeStatus==KErrNone) // timer completed normally... oh dear, what happened to the read??
438 test.Printf(_L("RComm::Read() timed out!\n\r"));
439 theSerialPorts[KReadFirstPort]->ReadCancel();
440 test(EFalse); // fail
445 if (readStatus!=KErrNone)
446 test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
447 test(readStatus==KErrNone);
449 test.Printf(_L("\rRead %d of %d\n\r"),inDes.Length(),outDes.Length());
450 test(CompareDescriptors(outDes,inDes));
453 test.Printf(_L("\t\t\tReverse\n"));
454 theSerialPorts[KWriteFirstPort]->Read(readStatus,inDes,aBufSize);
455 theSerialPorts[KReadFirstPort]->WriteS(outDes,aBufSize);
456 User::WaitForRequest(readStatus);
457 tim.After(timeStatus,KTimeOut);
458 test(timeStatus==KRequestPending);
459 User::WaitForRequest(readStatus,timeStatus);
460 if (timeStatus==KErrNone)
462 test.Printf(_L("Timed Out!\n\r"));
463 theSerialPorts[KWriteFirstPort]->ReadCancel();
464 test(EFalse); // fail
469 if (readStatus!=KErrNone)
470 test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
471 test(readStatus==KErrNone);
473 test.Printf(_L("\rRead %d of %d\n\r"),inDes.Length(),outDes.Length());
474 outDes.SetLength(inDes.Length());
475 test(CompareDescriptors(outDes,inDes));
482 return inDes.Length();
485 TUint CheckZeroTurnaround(TInt aBufSize, TUint aDirection)
487 // Checks that when a Turnaround of 0ms was selected the write takes place immediately
488 // aBufSize is selected such as it takes only slightly less than User timer granularity
489 // at the Baud rate selected to transmit that buffer.
490 // Checks that it takes less than a User side timer tick to complete a Write request
491 // at the selected Baud rate. Therefore proving the write is not being delayed in the driver
494 TUint8* inBuf=new TUint8[aBufSize];
496 TUint8* outBuf=new TUint8[aBufSize];
498 TPtr8 outDes(outBuf,aBufSize,aBufSize);
499 TPtr8 inDes(inBuf,aBufSize,aBufSize);
502 TTimeIntervalMicroSeconds32 aTimeOut=0;
503 UserHal::TickPeriod(aTimeOut);
506 timeoutTimer.CreateLocal();
507 TRequestStatus readStatus;
508 TRequestStatus writeStatus;
509 TRequestStatus timeStatus;
511 StripeMem(outDes,'A','Z');
514 const TUint port_A = aDirection?1:0;
515 const TUint port_B = 1 - port_A;
517 // queue a read on port_A
518 test.Printf(_L("\r\nRead %d \r\n"), port_A);
519 theSerialPorts[port_A]->Read(readStatus,inDes);
520 test(readStatus==KRequestPending);
522 // write on port_B to complete read
523 theSerialPorts[port_B]->SetMinTurnaroundTime(0);
524 theSerialPorts[port_B]->Write(writeStatus,outDes,aBufSize);
525 test(writeStatus==KRequestPending || writeStatus==KErrNone );
527 // start the local turnaround timer
528 timeoutTimer.After(timeStatus, (20*aTimeOut.Int())); // give it a 20% margin
529 test(timeStatus==KRequestPending);
531 User::WaitForRequest(readStatus, timeStatus);
533 if(timeStatus == KErrNone)
535 // if timeout first -> BAD
536 test.Printf(_L("Timed out!\r\n"));
537 theSerialPorts[port_A]->ReadCancel();
538 test(EFalse); // fail
542 // else read was first -> GOOD
543 timeoutTimer.Cancel();
545 if (readStatus!=KErrNone)
546 test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
547 test(readStatus==KErrNone);
548 test(writeStatus==KErrNone);
549 test.Printf(_L("Good, read OK and took less than timeout\r\n"));
550 test(CompareDescriptors(outDes,inDes));
551 numberRead = inDes.Length();
553 timeoutTimer.Close();
561 TUint TimedCheckedWrite(TInt aBufSize, TUint aTurnaround, TUint aDirection)
563 // Checks that Write requests are delayed if a Turnaround != 0 is selected.
564 // aTurnarund is chosen to be significantly greater than the time it takes to transmit
565 // a buffer of aBufSize at the Baud rate.
566 // Checks that for a given Turnaround time it always takes > that time to transmit
567 // a buffer of aBufSize.
568 // aDirection specifies the direction of transmission.
571 TUint8* inBuf=new TUint8[aBufSize];
573 TUint8* outBuf=new TUint8[aBufSize];
575 TPtr8 outDes(outBuf,aBufSize,aBufSize);
576 TPtr8 inDes(inBuf,aBufSize,aBufSize);
579 TTimeIntervalMicroSeconds32 p=0;
580 UserHal::TickPeriod(p);
581 TInt tPeriod = p.Int();
583 const TUint KTimeOut = 1500000; // 1500 milliseconds
585 timeoutTimer.CreateLocal();
586 TRequestStatus readStatus;
587 TRequestStatus writeStatus;
588 TRequestStatus timeStatus;
590 RTimer turnaroundTimer;
591 turnaroundTimer.CreateLocal();
592 TRequestStatus turnaroundTimerStatus;
594 StripeMem(outDes,'A','Z');
597 const TUint port_A = aDirection?1:0;
598 const TUint port_B = 1 - port_A;
600 // set turnaround on port_A
601 TInt r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround+tPeriod);
603 r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
606 // queue a short read on port_A
607 test.Printf(_L("\r\nRead %d to set turnaround %d\r\n"), port_A, aTurnaround+tPeriod);
608 theSerialPorts[port_A]->Read(readStatus,inDes);
609 test(readStatus==KRequestPending);
611 // start the local turnaround timer
612 turnaroundTimer.After(turnaroundTimerStatus, aTurnaround);
613 test(turnaroundTimerStatus==KRequestPending);
615 // write on port_B to complete read and start the driver's turnaround timer on A
616 theSerialPorts[port_B]->Write(writeStatus,outDes,aBufSize);
617 test((writeStatus==KRequestPending)||(writeStatus==KErrNone)); // may complete before coming back here as buffer size's small
619 User::WaitForRequest(readStatus);
620 test(readStatus==KErrNone);
621 test(writeStatus==KErrNone);
622 test(CompareDescriptors(outDes,inDes));
625 // queue a short read on port_B
626 theSerialPorts[port_B]->Read(readStatus, inDes);
627 test(readStatus==KRequestPending);
630 theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
631 test(writeStatus==KRequestPending);
633 // wait on both the read on port_B and the local turnaround timer
634 User::WaitForRequest(readStatus, turnaroundTimerStatus);
636 if(turnaroundTimerStatus == KErrNone)
638 // if local turnaround timeout first -> GOOD
639 // start big timeout and wait on either timeout or read on port_B
640 timeoutTimer.After(timeStatus, KTimeOut);
641 test(timeStatus==KRequestPending);
643 User::WaitForRequest(readStatus, timeStatus);
644 if(timeStatus == KErrNone)
646 // if timeout first -> BAD
647 test.Printf(_L("Timed out!\r\n"));
649 theSerialPorts[port_B]->ReadCancel();
650 test(EFalse); // fail
654 // else read was first -> GOOD
655 timeoutTimer.Cancel();
657 if (readStatus!=KErrNone)
658 test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
659 test(readStatus==KErrNone);
660 test(writeStatus==KErrNone);
661 test.Printf(_L("Good, read OK, write took longer than turnaround\r\n"));
662 test(CompareDescriptors(outDes,inDes));
663 numberRead = inDes.Length();
666 else if(readStatus == KErrNone)
668 TInt timerStatus = turnaroundTimerStatus.Int();
669 // else read was first -> BAD
670 turnaroundTimer.Cancel();
671 test.Printf(_L("read completed before turnaround\r\n"));
672 test.Printf(_L("turnaroundTImer status %d ms!\r\n"),timerStatus);
673 test(EFalse); // fail
676 timeoutTimer.Close();
677 turnaroundTimer.Close();
684 // Checks that setting the turnaround first time before any read or write, will start the
685 // turnaround timer. It is make sure that first write will be delayed atleast min turnaround
687 void TestFirstDelayedWrite(TInt aBufSize, TUint aTurnaround, TUint aDirection)
689 test.Printf(_L("Loading logical device for getting kernel timer tick & count\n"));
690 TInt r=User::LoadLogicalDevice(KLddFileName);
691 test(r == KErrNone || r == KErrAlreadyExists);
693 test.Printf(_L("Opening of logical device\n"));
695 test(r == KErrNone || r == KErrAlreadyExists);
698 // Create input and an output buffers
699 TUint8* inBuf=new TUint8[aBufSize];
701 TUint8* outBuf=new TUint8[aBufSize];
704 // Fill the output buffer with stuff and empty the input buffer
705 TPtr8 outDes(outBuf,aBufSize,aBufSize);
706 TPtr8 inDes(inBuf,aBufSize,aBufSize);
707 StripeMem(outDes,'A','Z');
711 // Configure both ports to 9600bps.
713 TCommConfigV01& c1=cBuf1();
714 theSerialPorts[0]->Config(cBuf1);
716 TCommConfigV01& c2=cBuf2();
717 theSerialPorts[0]->Config(cBuf2);
720 c2.iFifo=EFifoDisable;
721 c2.iDataBits=c1.iDataBits=EData8;
722 c2.iStopBits=c1.iStopBits=EStop1;
723 c2.iParity=c1.iParity=EParityNone;
724 c2.iRate=c1.iRate=EBps9600;
725 r = theSerialPorts[0]->SetConfig(cBuf1);
726 test_Equal(KErrNone, r);
727 r = theSerialPorts[1]->SetConfig(cBuf2);
732 timeoutTimer.CreateLocal();
733 TRequestStatus readStatus = 0xbaadf00d;
734 TRequestStatus writeStatus = 0xbaadf00d;
735 //TRequestStatus timeStatus = 0xbaadf00d;
737 const TUint port_A = aDirection?1:0;
738 const TUint port_B = 1 - port_A;
740 TUint time1 = 0, time2 = 0, time3 = 0;
741 // set turnaround on port_A
742 r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround);
745 //Capture the turnaround time
746 ldd.Test_getTimerCount(time1);
748 // set turnaround on port_B
749 r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
752 // queue a short read on port_B
753 theSerialPorts[port_B]->Read(readStatus, inDes);
754 /* BOGUS TEST: Zero-length reads complete immediately.
755 test_Equal(KRequestPending, readStatus.Int());
759 theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
761 test(writeStatus==KRequestPending);
765 The turnaround timer exists to introduce small delays between SUCCESSIVE reads & writes,
766 so as not to flummox IrDA transceivers which are slow in changing between write & read
767 modes. Setting a timer value does not have an immediate effect, it will
768 apply *after* the next read/write.
770 // start a local timeout with aTurnaround/3 and wait on it
771 timeoutTimer.After(timeStatus, aTurnaround/3);
772 test(timeStatus==KRequestPending);
773 User::WaitForRequest(timeStatus);
774 test(timeStatus==KErrNone);
776 // check that read on port_B has not completed yet (write on port_A has been delayed in the driver)
777 test_Equal(KRequestPending, readStatus.Int());
780 // wait for write to complete
781 User::WaitForRequest(writeStatus);
782 if(writeStatus == KErrNone)
784 //record the time of write complete
785 ldd.Test_getTimerCount(time2);
788 //Wait for read to complete
789 User::WaitForRequest(readStatus);
790 test(readStatus==KErrNone);
792 //Covert turnaround time to timer ticks
793 time3 = aTurnaround / 1000;
794 ldd.Test_getTimerTicks(time3);
796 test.Printf(_L("Time1 %d\n"), time1);
797 test.Printf(_L("Time2 %d\n"), time2);
798 test.Printf(_L("Time3 %d\n"), time3);
799 //Write takes apporximately 250 ticks to write.
800 time2 = (time2 - time1); //Includes turnaround time + write time
801 time1 = time3 > time2 ? time3 - time2 : time2 - time3;
802 test.Printf(_L("Time differece %d\n"), time1);
803 //test(time1 == 0 || time1 == 1); <-- Apparently unreasonable on SMP hardware
805 timeoutTimer.Close();
806 test.Printf(_L("Closing the channel\n"));
809 test.Printf(_L("Freeing logical device\n"));
810 r = User::FreeLogicalDevice(KLddFileName);;
821 TUint ChangeTurnaroundTimeInDelayedWrite(TInt aBufSize, TUint aTurnaround, TUint aNewTurnaround, TUint aDirection)
823 // Checks that a delayed write will go based on the new timeout value if the Turnaround time is changed
824 // when a write is being delayed in the driver
825 // aBufSize is such that transmission of a buffer of that size at the baud rate selected << aTurnaround
826 // Check that a Write is being delayed by a previous Read and that changing the turnaround will adjust
827 // the turnaround timer based on the new value and write will happend after minturnaround time has elapsed
830 test.Printf(_L("Loading logical device for getting kernel timer tick & count\n"));
831 TInt r=User::LoadLogicalDevice(KLddFileName);
832 test(r == KErrNone || r == KErrAlreadyExists);
834 test.Printf(_L("Opening of logical device\n"));
836 test(r == KErrNone || r == KErrAlreadyExists);
838 TUint8* inBuf=new TUint8[aBufSize];
840 TUint8* outBuf=new TUint8[aBufSize];
842 TPtr8 outDes(outBuf,aBufSize,aBufSize);
843 TPtr8 inDes(inBuf,aBufSize,aBufSize);
846 StripeMem(outDes,'A','Z');
850 timeoutTimer.CreateLocal();
851 TRequestStatus readStatus;
852 TRequestStatus writeStatus;
853 TRequestStatus timeStatus;
855 const TUint port_A = aDirection?1:0;
856 const TUint port_B = 1 - port_A;
858 // set turnaround on port_A
859 r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround);
861 // set turnaround on port_B
862 r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
865 // Issue a zero length read on port_A
866 theSerialPorts[port_A]->Read(readStatus,inDes,0);
867 User::WaitForRequest(readStatus);
868 test(readStatus==KErrNone);
869 //Record the start of turnaround time on port_A
870 TUint time1 = 0, time2 = 0, time3 = 0;
871 ldd.Test_getTimerCount(time1);
873 // queue a short read on port_B
874 theSerialPorts[port_B]->Read(readStatus, inDes);
875 test(readStatus==KRequestPending);
878 theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
879 test(writeStatus==KRequestPending);
881 // start a local timeout with aTurnaround/3 and wait on it
882 timeoutTimer.After(timeStatus, aTurnaround/3);
883 test(timeStatus==KRequestPending);
884 User::WaitForRequest(timeStatus);
885 test(timeStatus==KErrNone);
887 // check that read on port_B has not completed yet (write on port_A has been delayed in the driver)
888 #ifndef WDP_ENABLED // lots of paging screws up timing assumptions
889 test(readStatus==KRequestPending);
890 test(writeStatus==KRequestPending);
893 // change turnaround on port_A (should adjust turnaround time accordingly)
894 r = theSerialPorts[port_A]->SetMinTurnaroundTime(aNewTurnaround);
897 //Check read on port_B & write on port_A is still delayed.
898 #if !defined(DRIVER_TRACE_ON) && !defined(WDP_ENABLED)
899 test(readStatus==KRequestPending);
900 test(writeStatus==KRequestPending);
902 // wait for write to complete
903 User::WaitForRequest(writeStatus);
904 if(writeStatus == KErrNone)
906 //record the time of write complete
907 ldd.Test_getTimerCount(time2);
910 //Wait for read to complete
911 User::WaitForRequest(readStatus);
912 test(readStatus==KErrNone);
914 //Calculate the turnaround time, write should be delayed.
915 time3 = aNewTurnaround/1000;
916 //Convert to timer ticks
917 ldd.Test_getTimerTicks(time3);
918 test.Printf(_L("aTurnaround = %d, aNewTurnaround = %d\n"), aTurnaround, aNewTurnaround);
919 test.Printf(_L("Time1 = %d\n"), time1);
920 test.Printf(_L("Time2 = %d\n"), time2);
921 test.Printf(_L("Time3 = %d\n"), time3);
922 time1 = time2 - time1;
923 time1 = time3 > time1 ? (time3 - time1) : (time1 - time3);
924 test.Printf(_L("Time difference %d\n"), time1);
925 #if !defined(DRIVER_TRACE_ON) && !defined(WDP_ENABLED)
926 // test((time1 == 1) || (time1 == 0));
928 test.Printf(_L("Write delayed for requested time\r\n"));
929 test(CompareDescriptors(outDes,inDes));
930 numberRead = inDes.Length();
932 timeoutTimer.Close();
933 test.Printf(_L("Closing the channel\n"));
936 test.Printf(_L("Freeing logical device\n"));
937 r = User::FreeLogicalDevice(KLddFileName);;
947 TUint StopInDelayedWrite(TInt aBufSize, TUint aTurnaround, TUint aDirection)
949 // Checks that when a write is being delayed and then is cancelled the driver's turnaround timer continues
950 // ticking and if another write is queued it will be delayed by the remaining time
951 // aBufSize is such that transmission of a buffer of that size at the baud rate selected << aTurnaround
952 // Check that a Write is being delayed by a previous Read and that changing the Turnaround will make it
953 // go ahead immediately
956 TUint8* inBuf=new TUint8[aBufSize];
958 TUint8* outBuf=new TUint8[aBufSize];
960 TPtr8 outDes(outBuf,aBufSize,aBufSize);
961 TPtr8 inDes(inBuf,aBufSize,aBufSize);
964 TTimeIntervalMicroSeconds32 p=0;
965 UserHal::TickPeriod(p);
966 TInt tPeriod = p.Int();
968 const TUint KTimeOut = 1500000; // 150 milliseconds
970 timeoutTimer.CreateLocal();
971 TRequestStatus readStatus;
972 TRequestStatus writeStatus;
973 TRequestStatus timeStatus;
975 RTimer turnaroundTimer;
976 turnaroundTimer.CreateLocal();
977 TRequestStatus turnaroundTimerStatus;
979 StripeMem(outDes,'A','Z');
982 const TUint port_A = aDirection?1:0;
983 const TUint port_B = 1 - port_A;
985 // set turnaround on port_A
986 TInt r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround+tPeriod);
988 r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
992 // queue a zero length read to start the turnaround on port_A
993 test.Printf(_L("\r\nRead Zero Length on %d to start turnaround %d\r\n"), port_A, aTurnaround);
994 test.Printf(_L("\r\nUsing %d character buffers\r\n"),aBufSize);
996 theSerialPorts[port_A]->Read(readStatus,inDes,0);
997 User::WaitForRequest(readStatus);
998 test(readStatus==KErrNone);
1000 // start the local turnaround timer
1001 turnaroundTimer.After(turnaroundTimerStatus, aTurnaround);
1002 test(turnaroundTimerStatus==KRequestPending);
1004 // queue a short read on port_B
1005 theSerialPorts[port_B]->Read(readStatus, inDes);
1006 test(readStatus==KRequestPending);
1009 theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
1010 test(writeStatus==KRequestPending);
1012 // start a local timeout with aTurnaround/3 and wait on it
1013 timeoutTimer.After(timeStatus, aTurnaround/3);
1014 test(timeStatus==KRequestPending);
1015 User::WaitForRequest(timeStatus);
1016 test(timeStatus==KErrNone);
1018 // check that read on port_B has not completed yet (write on port_A has been delayed in the driver)
1019 test(readStatus==KRequestPending);
1021 // cancel write on port_A
1022 theSerialPorts[port_A]->WriteCancel();
1023 test(writeStatus==KErrCancel);
1025 // ...and restart it again
1026 theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
1027 #ifndef DRIVER_TRACE_ON
1028 test(writeStatus==KRequestPending);
1031 // wait on both the read on port_B and the local turnaround timer
1032 User::WaitForRequest(readStatus, turnaroundTimerStatus);
1034 // We are expecting this to have gone off by now...
1035 if(turnaroundTimerStatus == KErrNone) // this local timer is LESS than the driver turnaround
1037 // if local turnaround timeout first -> GOOD
1038 // start big timeout and wait on either timeout or read on port_B
1039 timeoutTimer.After(timeStatus, KTimeOut);
1040 test(timeStatus==KRequestPending);
1042 User::WaitForRequest(readStatus, timeStatus);
1043 if(timeStatus == KErrNone)
1045 // if timeout first -> BAD
1046 test.Printf(_L("Timed out!\r\n"));
1048 theSerialPorts[port_B]->ReadCancel();
1049 test(EFalse); // fail
1053 // else read was first -> GOOD
1054 timeoutTimer.Cancel();
1056 if (readStatus!=KErrNone)
1057 test.Printf(_L("Read Failed! (%d) - should have completed (on delayed write data)\n\r"),readStatus.Int());
1058 test(readStatus==KErrNone);
1059 test(writeStatus==KErrNone);
1060 test.Printf(_L("OK, write later than turnaround\r\n"));
1061 test(CompareDescriptors(outDes,inDes));
1062 numberRead = inDes.Length();
1065 // failed here => second write has gone off faster than expected...
1066 else if(readStatus == KErrNone)
1068 // else read was first -> BAD
1069 TInt timerStatus = turnaroundTimerStatus.Int();
1070 turnaroundTimer.Cancel();
1071 test.Printf(_L("read completed before turnaround\r\n"));
1072 test.Printf(_L("Turnaround timer status = %d\r\n"),timerStatus);
1073 test(EFalse); // fail
1076 timeoutTimer.Close();
1077 turnaroundTimer.Close();
1084 void turnaroundTestReadWrite()
1086 // Read and write at various speeds, with various turnarounds
1087 // Check that the data received data matches sent data
1089 // Open both serial ports
1090 TInt r=theSerialPorts[0]->Open(PortA);
1092 r=theSerialPorts[0]->QueryReceiveBuffer();
1094 r=theSerialPorts[1]->Open(PortB);
1096 r=theSerialPorts[1]->QueryReceiveBuffer();
1099 // Perform the read/write test at each baudrate for 8N1, no handshaking
1101 TCommConfigV01& c1=cBuf1();
1102 theSerialPorts[0]->Config(cBuf1);
1104 TCommConfigV01& c2=cBuf2();
1105 theSerialPorts[0]->Config(cBuf2);
1108 c2.iFifo=EFifoDisable;
1110 c2.iDataBits=c1.iDataBits=EData8;
1111 c2.iStopBits=c1.iStopBits=EStop1;
1112 c2.iParity=c1.iParity=EParityNone;
1113 c2.iRate=c1.iRate=EBps9600;
1117 test.Start(_L("Read/write test with default turnaround and at 9600 Bps"));
1119 TTimeIntervalMicroSeconds32 p=0;
1120 UserHal::TickPeriod(p);
1121 TInt tPeriod = p.Int();
1122 test.Printf(_L("Tick period %d\r\n"), tPeriod);
1124 TUint aBufLength = 96*p.Int()/10000;
1125 test.Printf(_L("Need to transmit %d chars at 9600 Bps\r\n"), aBufLength); // let's try with 10*tick period (approx)
1127 theSerialPorts[0]->SetConfig(cBuf1);
1128 theSerialPorts[1]->SetConfig(cBuf2);
1131 test(CheckZeroTurnaround(aBufLength, 0)==aBufLength);
1132 test(CheckZeroTurnaround(aBufLength, 1)==aBufLength);
1134 test.Next(_L("Read/write test at various speeds and min turnarounds"));
1135 #if defined (__WINS__)
1136 const TUint KShortBufferSize=100;
1138 const TUint KShortBufferSize=10;
1141 for(TUint i = 0; i < ELEMENTS(KSpeeds); ++i)
1144 turnaround = KTurnaroundTimes[i]*p.Int();
1146 if (theCaps1.iRate&KSpeeds[i].iMask && theCaps2.iRate&KSpeeds[i].iMask)
1148 msg.Format(_L("\r\nRead/write @ %s Bps with %d millisec turnaround\r\n"), KSpeeds[i].iName, turnaround/1000);
1151 c1.iRate=KSpeeds[i].iSpeed;
1152 TInt r=theSerialPorts[0]->SetConfig(cBuf1);
1154 c2.iRate=KSpeeds[i].iSpeed;
1155 r=theSerialPorts[1]->SetConfig(cBuf2);
1158 test.Printf(_L("Do TimedCheckedWrite\r\n"));
1159 test(TimedCheckedWrite(KShortBufferSize, turnaround, direction)==KShortBufferSize);
1163 msg.Format(_L("%s Bps not supported\r\n"),KSpeeds[i].iName);
1167 direction=1-direction;
1169 msg.Format(_L("\r\nRead turnaround time back\r\n"));
1172 TInt n = theSerialPorts[0]->MinTurnaroundTime();
1173 test(n==turnaround+tPeriod);
1175 msg.Format(_L("Value returned was %d\r\n"), n/1000);
1178 test.Printf(_L("Decrease turnaroundtime during delayed write\n"));
1179 test(ChangeTurnaroundTimeInDelayedWrite(KShortBufferSize, turnaround, turnaround - 10000, direction)==KShortBufferSize);
1181 test.Printf(_L("Increase turnaroundtime during delayed write\n"));
1182 test(ChangeTurnaroundTimeInDelayedWrite(KShortBufferSize, turnaround, turnaround + 30000 ,direction)==KShortBufferSize);
1184 direction=1-direction;
1186 test.Printf(_L("\r\nDo StopInDelayedWrite @ %s Bps\r\n"), KSpeeds[i].iName);
1187 test(StopInDelayedWrite(KShortBufferSize, turnaround, direction)==KShortBufferSize);
1190 // return defaults for following tests
1192 msg.Format(_L("\r\nSet default turnaround (0) on both ports \r\n"));
1195 test(theSerialPorts[0]->SetMinTurnaroundTime(0)==KErrNone);
1196 test(theSerialPorts[1]->SetMinTurnaroundTime(0)==KErrNone);
1198 theSerialPorts[0]->Close();
1199 theSerialPorts[1]->Close();
1201 msg.Format(_L("\r\n... End of turnaround tests ...\r\n"));
1207 void testReadWrite()
1209 // Read and write at various speeds
1211 test.Start(_L("Testing read and write"));
1213 TInt r=theSerialPorts[0]->Open(PortA);
1215 r=theSerialPorts[0]->QueryReceiveBuffer();
1217 r=theSerialPorts[1]->Open(PortB);
1219 r=theSerialPorts[1]->QueryReceiveBuffer();
1223 TCommConfigV01& c1=cBuf1();
1224 theSerialPorts[0]->Config(cBuf1);
1226 TCommConfigV01& c2=cBuf2();
1227 theSerialPorts[0]->Config(cBuf2);
1230 c2.iFifo=EFifoDisable;
1232 c2.iDataBits=c1.iDataBits=EData8;
1233 c2.iStopBits=c1.iStopBits=EStop1;
1234 c2.iParity=c1.iParity=EParityNone;
1235 c2.iRate=c1.iRate=EBps9600;
1238 test.Printf(_L("Delayed first write\n"));
1239 TestFirstDelayedWrite(0, 2343750, 1);
1241 TInt numTests=sizeof(KSpeeds)/sizeof(TSpeedAndName);
1242 for (TInt i=0;i<numTests;i++)
1244 if (theCaps1.iRate&KSpeeds[i].iMask && theCaps2.iRate&KSpeeds[i].iMask)
1246 mess.Format(_L("read/write @ %s Bps"),KSpeeds[i].iName);
1248 c1.iRate=KSpeeds[i].iSpeed;
1249 TInt r=theSerialPorts[0]->SetConfig(cBuf1);
1251 c2.iRate=KSpeeds[i].iSpeed;
1252 r=theSerialPorts[1]->SetConfig(cBuf2);
1254 test.Printf(_L("DoCheckedWrite\r\n"));
1255 test(CheckedWrite(KWriteSize)==KWriteSize);
1259 mess.Format(_L("%s Bps not supported"),KSpeeds[i].iName);
1264 theSerialPorts[0]->Close();
1265 theSerialPorts[1]->Close();
1272 // Read and write at various speeds
1275 test.Start(_L("Testing read and write speed"));
1276 const TInt KSamples=10;
1277 const TInt KNumWrites=100;
1278 const TInt KBufSize=2000;
1279 test.Printf(_L("%d sets of %d by %d characters @ 19200\n\r"),KSamples,KNumWrites,KBufSize);
1282 TCommConfigV01& c1=cBuf1();
1283 theSerialPorts[0]->Config(cBuf1);
1285 TCommConfigV01& c2=cBuf2();
1286 theSerialPorts[0]->Config(cBuf2);
1289 c2.iFifo=EFifoDisable;
1291 c2.iDataBits=c1.iDataBits=EData8;
1292 c2.iStopBits=c1.iStopBits=EStop1;
1293 c2.iParity=c1.iParity=EParityNone;
1294 c2.iRate=c1.iRate=EBps19200;
1296 TInt r=theSerialPorts[0]->SetConfig(cBuf1);
1298 r=theSerialPorts[1]->SetConfig(cBuf2);
1301 TUint samples[KSamples];
1303 for (TInt i=0;i<KSamples;i++)
1305 test.Printf(_L("."));
1307 TUint8* inBuf=new TUint8[KBufSize];
1308 TUint8* outBuf=new TUint8[KBufSize];
1309 TPtr8 outDes(outBuf,KBufSize,KBufSize);
1310 TPtr8 inDes(inBuf,KBufSize,KBufSize);
1315 TRequestStatus readStatus;
1316 TRequestStatus timeStatus;
1318 StripeMem(outDes,'A','Z');
1322 startTime.HomeTime();
1323 for (TInt l=0;l<KNumWrites;l++)
1325 inDes.SetLength(KBufSize/3);
1326 theSerialPorts[0]->Read(readStatus,inDes);
1328 TInt ret=theSerialPorts[1]->WriteS(outDes,KBufSize);
1329 const TUint KTimeOut=6000000;
1330 tim.After(timeStatus,KTimeOut);
1332 User::WaitForRequest(readStatus,timeStatus);
1335 if (timeStatus==KErrNone)
1337 test.Printf(_L("Timed Out!\n\r"));
1338 theSerialPorts[0]->ReadCancel();
1343 if (readStatus!=KErrNone)
1344 test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
1345 test(readStatus==KErrNone);
1346 test(ret==KErrNone);
1347 test(inDes.Length()==inDes.MaxLength());
1348 test(inDes.Length()==KBufSize);
1349 test(CompareDescriptors(outDes,inDes));
1356 TInt64 delta=endTime.MicroSecondsFrom(startTime).Int64();
1358 TInt delta32=I64INT(delta);
1360 test.Printf(_L("Read/Write %d time = %d ms\n\r"),KNumWrites*KBufSize,delta32);
1364 for (TInt j=0;j<KSamples;j++)
1369 test.Printf(_L(" Average time = %d ms\n\r"),avg);
1370 test.Printf(_L("Press a key\n\r"));
1378 /// Tests serial breaks
1382 test.Next(_L("Testing breaks"));
1385 TCommConfigV01& c0=cBuf0();
1387 TCommConfigV01& c1=cBuf1();
1389 TRequestStatus breakStatus;
1390 TRequestStatus readStatus;
1391 TRequestStatus writeStatus;
1392 TRequestStatus timerStatus;
1394 TInt r=theSerialPorts[0]->Open(PortA);
1396 r=theSerialPorts[0]->QueryReceiveBuffer();
1398 r=theSerialPorts[1]->Open(PortB);
1400 r=theSerialPorts[1]->QueryReceiveBuffer();
1403 theSerialPorts[0]->Config(cBuf0);
1404 theSerialPorts[1]->Config(cBuf1);
1405 c0.iRate=c1.iRate=EBps110;
1406 c0.iParityError=c1.iParityError=0;
1407 c0.iHandshake=c1.iHandshake=0;
1409 c0.iDataBits=c1.iDataBits=EData8;
1410 c0.iStopBits=c1.iStopBits=EStop1;
1411 c0.iParity=c1.iParity=EParityNone;
1414 r=theSerialPorts[0]->SetConfig(cBuf0);
1416 r=theSerialPorts[1]->SetConfig(cBuf1);
1419 for(TUint i = 0; i < ELEMENTS(KBreakSpeeds) ; ++i)
1421 if (theCaps1.iRate&KBreakSpeeds[i].iMask && theCaps2.iRate&KBreakSpeeds[i].iMask)
1423 msg.Format(_L("Break tests @ %s Bps"), KBreakSpeeds[i].iName);
1426 c0.iRate=KBreakSpeeds[i].iSpeed;
1427 TInt r=theSerialPorts[0]->SetConfig(cBuf0);
1429 c1.iRate=KBreakSpeeds[i].iSpeed;
1430 r=theSerialPorts[1]->SetConfig(cBuf1);
1434 // should take more than 1.5s
1436 HBufC8* bigReadBuffer=HBufC8::NewL(KWriteSize);
1437 HBufC8* bigWriteBuffer=HBufC8::NewMaxL(KWriteSize);
1438 TPtr8 bigReadBufferPtr(bigReadBuffer->Des());
1439 TPtr8 bigWriteBufferPtr(bigWriteBuffer->Des());
1441 StripeMem(bigWriteBufferPtr, 'A', 'Z');
1442 bigReadBufferPtr.FillZ();
1445 const TUint KWriteSize=1024 + KBreakSpeeds[i].iBps/4;
1446 const TInt KTimerTime=1500000;
1447 const TInt KBreakTime=3000000;
1448 const TInt KMinTurnaroundTime=150000;
1451 test(timer.CreateLocal()==KErrNone);
1455 test.Start(_L("Break after write"));
1456 //- start a user timer which will expire just after the TX would complete with no break
1457 timer.After(timerStatus, KTimerTime);
1459 //- request TX (and RX) and request a break
1460 theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
1461 theSerialPorts[0]->Break(breakStatus, KBreakTime);
1462 theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
1464 // Make sure the timer completes first
1465 User::WaitForRequest(writeStatus, readStatus);
1466 User::WaitForRequest(breakStatus);
1468 test(readStatus!=KErrNone && readStatus!=KRequestPending);
1469 test(breakStatus==KErrNone);
1470 test(writeStatus==KErrNone || writeStatus==KRequestPending); // Can be still pending, since if the read is completed with an error then the write won't complete since the buffers may fill up
1471 test(timerStatus==KErrNone);
1473 if (writeStatus==KRequestPending)
1474 theSerialPorts[0]->WriteCancel();
1477 test.Next(_L("Write after break"));
1478 //- start a user timer which will expire just after the TX would complete with no break
1479 timer.After(timerStatus, KTimerTime);
1481 //- request TX (and RX) and request a break
1482 theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
1483 theSerialPorts[0]->Break(breakStatus, KBreakTime);
1484 theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
1486 // Make sure the timer completes first
1487 User::WaitForRequest(breakStatus);
1488 User::WaitForRequest(writeStatus, readStatus);
1490 test(readStatus!=KErrNone && readStatus!=KRequestPending);
1491 test(breakStatus==KErrNone);
1492 test(writeStatus==KErrNone || writeStatus==KRequestPending); // write may not be able to cmoplete due to no remaining pending read
1493 test(timerStatus==KErrNone);
1495 if (writeStatus==KRequestPending)
1496 theSerialPorts[0]->WriteCancel();
1499 test.Next(_L("Cancellation of break"));
1500 //- Check cancellation of breaks
1502 //- request TX (and RX) and request a break
1503 theSerialPorts[0]->Break(breakStatus, KBreakTime);
1504 theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
1505 theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
1508 theSerialPorts[0]->BreakCancel();
1510 User::WaitForRequest(breakStatus);
1511 test(breakStatus.Int()==KErrCancel);
1513 User::WaitForRequest(readStatus);
1515 if (writeStatus==KRequestPending)
1516 theSerialPorts[0]->WriteCancel();
1520 test.Next(_L("Break during turnaround"));
1521 //- Check break still works during turnaround
1522 test (KErrNone==theSerialPorts[0]->SetMinTurnaroundTime(KMinTurnaroundTime));
1524 theSerialPorts[0]->Read(readStatus, bigReadBufferPtr, 1);
1525 theSerialPorts[1]->Write(writeStatus, *bigWriteBuffer, 1);
1526 User::WaitForRequest(readStatus);
1527 User::WaitForRequest(writeStatus);
1529 //- start a user timer which will expire just after the TX would complete with no break
1530 timer.After(timerStatus, KTimerTime);
1532 //- request TX (and RX) and request a break
1533 theSerialPorts[0]->Break(breakStatus, KBreakTime);
1534 theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
1535 theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
1537 // Make sure the timer completes first
1538 User::WaitForRequest(writeStatus, readStatus);
1539 User::WaitForRequest(breakStatus);
1541 test(readStatus!=KErrNone && readStatus!=KRequestPending);
1542 test(breakStatus==KErrNone);
1543 test(writeStatus==KErrNone || writeStatus==KRequestPending);
1544 test(timerStatus==KErrNone);
1546 if (writeStatus==KRequestPending)
1547 theSerialPorts[0]->WriteCancel();
1549 test (KErrNone==theSerialPorts[0]->SetMinTurnaroundTime(0));
1558 msg.Format(_L("%s Bps not supported"),KBreakSpeeds[i].iName);
1563 theSerialPorts[0]->Close();
1564 theSerialPorts[1]->Close();
1574 test.Start(_L("Testing framing"));
1576 TInt r=theSerialPorts[0]->Open(PortA);
1578 r=theSerialPorts[0]->QueryReceiveBuffer();
1580 r=theSerialPorts[1]->Open(PortB);
1582 r=theSerialPorts[1]->QueryReceiveBuffer();
1586 TCommConfigV01& c0=cBuf0();
1588 TCommConfigV01& c1=cBuf1();
1591 theSerialPorts[0]->Config(cBuf0);
1594 theSerialPorts[1]->Config(cBuf1);
1598 TInt numTests=sizeof(KFrameTypes)/sizeof(TFrameAndName);
1599 for (TInt i=0;i<numTests;i++)
1601 c0.iDataBits=KFrameTypes[i].iData;
1602 c0.iStopBits=KFrameTypes[i].iStop;
1603 c0.iParity=KFrameTypes[i].iParity;
1604 TInt r=theSerialPorts[0]->SetConfig(cBuf0);
1608 c1.iDataBits=KFrameTypes[i].iData;
1609 c1.iStopBits=KFrameTypes[i].iStop;
1610 c1.iParity=KFrameTypes[i].iParity;
1611 r=theSerialPorts[1]->SetConfig(cBuf1);
1614 mess.Format(_L("read/write using %s "),KFrameTypes[i].iName);
1616 test(CheckedWrite(KWriteSize)==KWriteSize);
1621 test.Printf(_L("%s not supported\n\r"),KFrameTypes[i].iName);
1624 theSerialPorts[0]->Close();
1625 theSerialPorts[1]->Close();
1629 void testTerminators()
1631 // Test termination masks - assumes that Checked write stripes memory starting with 'A'
1635 test.Next(_L("Testing termination masks"));
1638 TCommConfigV01& c=cBuf();
1640 theSerialPorts[0]->Close();
1641 theSerialPorts[1]->Close();
1643 TInt r=theSerialPorts[0]->Open(PortA);
1645 r=theSerialPorts[0]->QueryReceiveBuffer();
1647 r=theSerialPorts[1]->Open(PortB);
1649 r=theSerialPorts[1]->QueryReceiveBuffer();
1651 theSerialPorts[0]->Config(cBuf);
1652 c.iTerminator[0]='C';
1653 c.iTerminatorCount=1;
1658 c.iParity=EParityNone;
1660 r=theSerialPorts[0]->SetConfig(cBuf);
1664 TCommConfigV01& c1=cBuf1();
1665 theSerialPorts[1]->Config(cBuf1);
1667 c1.iDataBits=EData8;
1668 c1.iStopBits=EStop1;
1669 c1.iParity=EParityNone;
1671 c1.iTerminator[0]='C';
1672 c1.iTerminatorCount=1;
1675 r=theSerialPorts[1]->SetConfig(cBuf1);
1678 User::After(100000);
1679 theSerialPorts[0]->ResetBuffers();
1680 theSerialPorts[1]->ResetBuffers();
1682 test(CheckedWrite(KWriteSize)==3);
1684 // Clear the ldd buffers
1685 theSerialPorts[0]->ResetBuffers();
1686 theSerialPorts[1]->ResetBuffers();
1688 c.iTerminator[0]='Z';
1689 c.iTerminator[1]='X';
1690 c.iTerminator[2]='Y';
1691 c.iTerminator[3]='D';
1693 c1.iTerminator[0]='Z';
1694 c1.iTerminator[1]='X';
1695 c1.iTerminator[2]='Y';
1696 c1.iTerminator[3]='D';
1698 /* Not yet - we have too much buffering in the driver & device.
1699 Unfortunately the ResetBuffers() above doesn't (and really can't) go
1700 deep enough. Under WINS NT buffers up some data and the following read
1701 (inside checked write) completes before the WriteS (and infact, after
1702 reading a semi random number of characters)
1704 c.iTerminatorCount=4;
1705 c1.iTerminatorCount=4;
1706 r=theSerialPorts[0]->SetConfig(cBuf);
1708 r=theSerialPorts[1]->SetConfig(cBuf1);
1711 test(CheckedWrite(KWriteSize)==4);
1712 theSerialPorts[0]->Config(cBuf);
1714 // Reset termination mask.
1715 c.iTerminatorCount=0;
1716 c1.iTerminatorCount=0;
1717 r=theSerialPorts[0]->SetConfig(cBuf);
1719 r=theSerialPorts[1]->SetConfig(cBuf1);
1722 theSerialPorts[0]->Close();
1723 theSerialPorts[1]->Close();
1731 test.Next(_L("Testing xon xoff"));
1732 test.Start(_L("Setup"));
1734 TInt r=theSerialPorts[0]->Open(PortA);
1736 r=theSerialPorts[0]->QueryReceiveBuffer();
1738 r=theSerialPorts[1]->Open(PortB);
1740 r=theSerialPorts[1]->QueryReceiveBuffer();
1744 TCommConfigV01& c=cBuf();
1746 theSerialPorts[0]->Config(cBuf);
1747 c.iHandshake=KConfigObeyXoff|KConfigSendXoff;
1749 c.iParity=EParityNone;
1754 c.iParityError=KConfigXonXoffDebug;
1755 c.iTerminatorCount=0;
1756 test(theSerialPorts[0]->SetConfig(cBuf)==KErrNone);
1758 theSerialPorts[1]->Config(cBuf);
1759 c.iHandshake=KConfigObeyXoff|KConfigSendXoff;
1761 c.iParity=EParityNone;
1766 c.iParityError=KConfigXonXoffDebug;
1767 c.iTerminatorCount=0;
1768 test(theSerialPorts[1]->SetConfig(cBuf)==KErrNone);
1770 theSerialPorts[0]->SetReceiveBufferLength(0x400);
1771 theSerialPorts[1]->SetReceiveBufferLength(0x400);
1773 const TInt KXonWriteSize=KXonNumReads*KXonReadSize;
1775 TUint8* inBuf=new TUint8[KXonReadSize];
1776 TUint8* outBuf=new TUint8[KXonWriteSize];
1777 TPtr8 outDes(outBuf,KXonWriteSize,KXonWriteSize);
1778 TPtr8 inDes(inBuf,KXonReadSize,KXonReadSize);
1780 TRequestStatus readStatus;
1781 TRequestStatus writeStatus;
1782 TRequestStatus timeStatus;
1784 timer.CreateLocal();
1787 StripeMem(outDes,'A','Z');
1790 test.Next(_L("Write bytes to com1"));
1791 test.Printf(_L("Reading after delay (1 of %d) avail = %d\n\r"),KXonNumReads, theSerialPorts[0]->QueryReceiveBuffer());
1792 theSerialPorts[0]->Read(readStatus,inDes,KXonReadSize);
1793 theSerialPorts[1]->Write(writeStatus,outDes,KXonWriteSize);
1794 timer.After(timeStatus,1000000);
1795 User::WaitForRequest(readStatus,timeStatus);
1796 test(readStatus==KErrNone);
1797 test(timeStatus==KRequestPending);
1798 TPtrC8 aOutDes = outDes.Mid(writePos,KXonReadSize);
1799 test(CompareDescriptors(inDes,(TDes8&)aOutDes));
1801 writePos+=KXonReadSize;
1803 if (timeStatus==KRequestPending)
1804 User::WaitForRequest(timeStatus);
1807 for (i=0;i<KXonNumReads-1;++i)
1810 timer.After(timeStatus,450000);
1811 User::WaitForRequest(timeStatus);
1812 test(timeStatus==KErrNone);
1814 test.Printf(_L("Reading after delay (%d of %d) avail = %d\n\r"),i+2,KXonNumReads, theSerialPorts[0]->QueryReceiveBuffer());
1815 theSerialPorts[0]->Read(readStatus,inDes,KXonReadSize);
1816 timer.After(timeStatus,1000000);
1817 User::WaitForRequest(readStatus,timeStatus);
1818 if (readStatus!=KErrNone)
1819 test.Printf(_L("Read error %d\n\r"),readStatus.Int());
1820 test(readStatus==KErrNone);
1821 test(timeStatus==KRequestPending);
1822 TPtrC8 aOutDes = outDes.Mid(writePos,KXonReadSize);
1823 test(CompareDescriptors(inDes,(TDes8&)aOutDes));
1825 writePos+=KXonReadSize;
1828 test.Next(_L("2nd Large Write complete"));
1829 test(writeStatus==KErrNone);
1834 theSerialPorts[0]->Close();
1835 theSerialPorts[1]->Close();
1841 void testHWHandshaking()
1843 // test hardware hand shaking
1847 #if defined (__WINS__)
1848 const TInt KHWReadSize=0x2000;
1850 const TInt KHWReadSize=0x400;
1853 test.Start(_L("Testing hardware handshaking"));
1855 TInt r=theSerialPorts[0]->Open(PortA);
1857 r=theSerialPorts[0]->QueryReceiveBuffer();
1859 r=theSerialPorts[1]->Open(PortB);
1861 r=theSerialPorts[1]->QueryReceiveBuffer();
1865 TCommConfigV01& c0=cBuf0();
1867 theSerialPorts[0]->Config(cBuf0);
1868 c0.iRate=EBps115200;
1873 TCommConfigV01& c1=cBuf1();
1874 test(theSerialPorts[0]->SetConfig(cBuf0)==KErrNone);
1876 theSerialPorts[1]->Config(cBuf1);
1877 c1.iRate=EBps115200;
1880 test(theSerialPorts[1]->SetConfig(cBuf1)==KErrNone);
1882 const TInt KXonWriteSize=KXonNumReads*KHWReadSize;
1884 TUint8* inBuf=new TUint8[KHWReadSize];
1885 TUint8* outBuf=new TUint8[KXonWriteSize];
1886 TPtr8 outDes(outBuf,KXonWriteSize,KXonWriteSize);
1887 TPtr8 inDes(inBuf,KHWReadSize,KHWReadSize);
1889 //TUint8* inBuf2=new TUint8[KXonWriteSize];
1890 //TPtr8 inDes2(inBuf2,KXonWriteSize,KXonWriteSize);
1892 #if defined (__WINS__)
1893 theSerialPorts[0]->SetReceiveBufferLength(0x50);
1894 theSerialPorts[1]->SetReceiveBufferLength(0x50);
1896 theSerialPorts[0]->SetReceiveBufferLength(0x400);
1897 theSerialPorts[1]->SetReceiveBufferLength(0x400);
1900 TInt numTests=sizeof(KHandshakes)/sizeof(THandShakeAndName);
1901 for(TInt j=0;j<numTests;j++)
1903 mess.Format(_L("read/write using %s "),KHandshakes[j].iName);
1905 c0.iHandshake=c1.iHandshake=KHandshakes[j].iHandshake;
1907 if((theCaps1.iHandshake & KHandshakes[j].iHandshake)
1908 && (theCaps2.iHandshake & KHandshakes[j].iHandshake))
1910 test(theSerialPorts[0]->SetConfig(cBuf0)==KErrNone);
1911 test(theSerialPorts[1]->SetConfig(cBuf1)==KErrNone);
1912 TRequestStatus readStatus;
1913 TRequestStatus writeStatus;
1915 StripeMem(outDes,'A','Z');
1918 theSerialPorts[1]->Write(writeStatus,outDes,KXonWriteSize);
1920 //TRequestStatus writeStatus2;
1921 //theSerialPorts[0]->Write(writeStatus2,outDes,KXonWriteSize);
1924 for (i=0;i<KXonNumReads;i++)
1927 #if defined (__WINS__)
1928 User::After(600000);
1930 User::After(300000);
1932 test.Printf(_L("Reading %d after delay (%d of %d) avail = %d\r\n"),KHWReadSize, i+1,KXonNumReads, theSerialPorts[0]->QueryReceiveBuffer());
1933 theSerialPorts[0]->Read(readStatus,inDes,KHWReadSize);
1934 User::WaitForRequest(readStatus);
1935 test(readStatus==KErrNone);
1936 TPtrC8 aOutDes = outDes.Mid(KHWReadSize*i,KHWReadSize);
1937 test(CompareDescriptors(inDes,(TDes8&)aOutDes));
1938 test(inDes.Length()==KHWReadSize);
1941 test.Next(_L("2nd Large Write complete"));
1942 User::WaitForRequest(writeStatus);
1943 test(writeStatus==KErrNone);
1945 //theSerialPorts[1]->Read(readStatus,inDes2,KXonWriteSize);
1946 //User::WaitForRequest(writeStatus2);
1947 //test(writeStatus2==KErrNone);
1949 //User::WaitForRequest(readStatus);
1950 //test(readStatus==KErrNone);
1955 test.Printf(_L("Config not supported\r\n"));
1961 theSerialPorts[0]->Close();
1962 theSerialPorts[1]->Close();
1967 void testWriteZero()
1969 // Test a write of 0 bytes is still blocked by CTS flow control.
1970 // Test does a flow controlled Write(0) which is blocked by the remote
1971 // port state being closed (hence remote RTS disasserted, hence writer's
1972 // CTS likewise). Then it opens the remote port and asserts RTS - this
1973 // unblocks the original Write(0).
1976 TInt r=theSerialPorts[0]->Open(PortA);
1978 r=theSerialPorts[0]->QueryReceiveBuffer();
1981 test.Next(_L("Testing Write 0"));
1984 TCommConfigV01& c1=cBuf1();
1985 theSerialPorts[0]->Config(cBuf1);
1988 c1.iHandshake=KConfigObeyCTS;
1990 r=theSerialPorts[0]->SetConfig(cBuf1);
1993 test.Start(_L("Test Write(0) with remote RTS disasserted blocks"));
1994 TRequestStatus writeStat;
1995 theSerialPorts[0]->Write(writeStat,TPtr8(NULL,0),0);
1998 timer.CreateLocal();
1999 TRequestStatus timeStatus;
2000 timer.After(timeStatus,1000000);
2001 User::WaitForRequest(timeStatus,writeStat);
2003 test(timeStatus==KErrNone);
2004 test(writeStat==KRequestPending);
2006 r=theSerialPorts[1]->Open(PortB);
2008 r=theSerialPorts[1]->QueryReceiveBuffer();
2012 TCommConfigV01& c2=cBuf2();
2013 theSerialPorts[1]->Config(cBuf2);
2016 c2.iHandshake |= KConfigFreeRTS;
2017 r=theSerialPorts[1]->SetConfig(cBuf2);
2020 test.Next(_L("Test Write(0) with remote RTS asserted completes"));
2021 timer.After(timeStatus,10000000);
2022 theSerialPorts[1]->SetSignals(KSignalRTS,0);
2024 User::WaitForRequest(timeStatus,writeStat);
2025 if (writeStat==KRequestPending)
2026 test.Printf(_L(" Timed out!\n"));
2027 User::After(2000000);
2029 test(writeStat==KErrNone);
2030 test(timeStatus==KRequestPending);
2034 theSerialPorts[0]->Close();
2035 theSerialPorts[1]->Close();
2041 void testSingleCharacterReads()
2043 // Test reading one character at a time.
2046 const TInt KWriteSize=100;
2047 test.Start(_L("Test partial reads"));
2049 TInt r=theSerialPorts[0]->Open(PortA);
2051 r=theSerialPorts[0]->QueryReceiveBuffer();
2053 r=theSerialPorts[1]->Open(PortB);
2055 r=theSerialPorts[1]->QueryReceiveBuffer();
2059 TCommConfigV01& c0=cBuf0();
2060 theSerialPorts[0]->Config(cBuf0);
2063 TCommConfigV01& c1=cBuf1();
2064 theSerialPorts[1]->Config(cBuf1);
2066 c0.iRate=c1.iRate=EBps9600;
2067 c0.iParityError=c1.iParityError=0;
2068 c0.iHandshake=c1.iHandshake=KConfigObeyCTS;
2070 c0.iDataBits=c1.iDataBits=EData8;
2071 c0.iStopBits=c1.iStopBits=EStop1;
2072 c0.iParity=c1.iParity=EParityNone;
2074 r=theSerialPorts[0]->SetConfig(cBuf0);
2076 r=theSerialPorts[1]->SetConfig(cBuf1);
2078 test.Printf(_L("Setconfig OK\r\n"));
2080 TInt bufSiz=KWriteSize+3+(KWriteSize/2);
2082 r=theSerialPorts[0]->SetReceiveBufferLength(bufSiz);
2084 test.Printf(_L("Setting buffers to %d bytes for com0 failed %d\n\r"),bufSiz,r);
2085 r=theSerialPorts[1]->SetReceiveBufferLength(bufSiz+1);
2087 test.Printf(_L("Setting buffers to %d bytes for com1 failed %d\n\r"),bufSiz,r);
2089 TUint8* singleCharReadBuf=new TUint8[1];
2090 test(singleCharReadBuf!=NULL);
2091 TPtr8 singleCharReadDes(singleCharReadBuf,1,1);
2092 TUint8* multiCharWriteBuf=new TUint8[KWriteSize];
2093 test(multiCharWriteBuf!=NULL);
2094 TPtr8 multiCharWriteDes(multiCharWriteBuf,KWriteSize,KWriteSize);
2095 multiCharWriteDes.Fill('m');
2100 for (TInt j=0;j<2;j++)
2108 message.Format(_L("Reading single chars from port %d, writing %d to port %d"),readPort,multiCharWriteDes.Length(),writePort);
2111 TRequestStatus readZeroStat;
2112 theSerialPorts[readPort]->Read(readZeroStat,singleCharReadDes,0);//a zero length read completes immediately and
2113 User::WaitForRequest(readZeroStat); //will wake up the receiver
2114 test.Printf(_L("Have done a read zero: %d\n\r"),readZeroStat.Int());
2115 User::After(1000000);
2117 TRequestStatus multiWriteStat;
2118 theSerialPorts[writePort]->Write(multiWriteStat,multiCharWriteDes);
2119 // User::WaitForRequest(multiWriteStat);
2120 // test.Printf(_L("Have done a write: %d\n\r"),multiWriteStat.Int());
2122 TRequestStatus timStat;
2124 for (TInt i=0;i<KWriteSize;i++)
2126 tim.After(timStat,10000000);
2127 TRequestStatus readStat;
2128 singleCharReadDes.SetLength(0);
2129 theSerialPorts[readPort]->Read(readStat,singleCharReadDes);
2130 User::WaitForRequest(readStat,timStat);
2132 test.Printf(_L("r"));
2134 test.Printf(_L("\r%c"),KSpinner[spin++%4]);
2136 if (readStat!=KErrNone)
2139 if (readStat==KRequestPending)
2141 message.Format(_L("\n\rRead timed out after %d chars (of %d)\n\r"),i,KWriteSize);
2142 /*if (multiWriteStat==KErrNone)
2144 User::WaitForRequest(multiWriteStat);
2145 theSerialPorts[readPort]->ReadCancel();
2146 theSerialPorts[writePort]->Write(multiWriteStat,multiCharWriteDes);
2150 if (readStat!=KErrOverflow && readStat!=KErrCommsOverrun)
2151 message.Format(_L("\n\rRead Failed %d after %d chars (of %d)\n\r"),readStat.Int(),i,KWriteSize);
2153 test.Printf(message);
2154 User::After(2000000);
2159 if (singleCharReadDes[0]!='m')
2161 test.Printf(_L("Received character: 0x%02x\n"),singleCharReadDes[0]);
2166 test.Printf(_L("Done\n\r"));
2168 tim.After(timStat,1000000);
2169 User::WaitForRequest(timStat,multiWriteStat);
2170 if (timStat.Int()==KErrNone)
2172 test.Printf(_L("Lost at least one char!\n\r"));
2173 theSerialPorts[writePort]->WriteCancel();
2182 TUint8* singleCharWriteBuf=new TUint8[1];
2183 test(singleCharWriteBuf!=NULL);
2184 TPtr8 singleCharWriteDes(singleCharWriteBuf,1,1);
2185 singleCharWriteDes.Fill('s');
2186 TUint8* multiCharReadBuf=new TUint8[KWriteSize];
2187 test(multiCharReadBuf!=NULL);
2188 TPtr8 multiCharReadDes(multiCharReadBuf,KWriteSize,KWriteSize);
2190 for (TInt k=0;k<2;k++)
2198 TRequestStatus multiReadStat;
2199 theSerialPorts[readPort]->Read(multiReadStat,multiCharReadDes);
2202 message.Format(_L("Writing single chars to port %d"),readPort);
2205 TRequestStatus timStat;
2207 for (TInt i=0;i<KWriteSize;i++)
2209 TRequestStatus writeStat;
2210 tim.After(timStat,5000000);
2211 theSerialPorts[writePort]->Write(writeStat,singleCharWriteDes);
2212 User::WaitForRequest(writeStat,timStat);
2215 test.Printf(_L("\r%c"),KSpinner[spin++%4]);
2217 if (writeStat!=KErrNone)
2220 if (writeStat==KRequestPending)
2221 message.Format(_L("\n\rWrite timed out after %d chars (of %d)\n\r"),i,KWriteSize);
2223 message.Format(_L("\n\rWrite Failed %d after %d chars (of %d)\n\r"),writeStat.Int(),i,KWriteSize);
2225 test.Printf(message);
2227 test(writeStat==KErrNone);
2230 test.Printf(_L("Done\n\r"));
2232 tim.After(timStat,1000000);
2233 User::WaitForRequest(timStat,multiReadStat);
2234 if (timStat.Int()==KErrNone)
2236 test.Printf(_L("Lost at least one char!\n\r"));
2237 theSerialPorts[readPort]->ReadCancel();
2243 test(multiReadStat==KErrNone);
2244 test(multiCharWriteDes.Length()==multiCharWriteDes.MaxLength());
2251 delete [] multiCharWriteBuf;
2252 delete [] singleCharReadBuf;
2253 delete [] singleCharWriteBuf;
2254 delete [] multiCharReadBuf;
2256 theSerialPorts[0]->Close();
2257 theSerialPorts[1]->Close();
2260 void testBiDirectionalSingleCharacterReads()
2262 // Test reading and writing one character at a time.
2266 test.Start(_L("Test concurrent partial reads and writes"));
2268 TInt r=theSerialPorts[0]->Open(PortA);
2270 r=theSerialPorts[0]->QueryReceiveBuffer();
2272 r=theSerialPorts[1]->Open(PortB);
2274 r=theSerialPorts[1]->QueryReceiveBuffer();
2278 TCommConfigV01& c0=cBuf0();
2279 theSerialPorts[0]->Config(cBuf0);
2282 TCommConfigV01& c1=cBuf1();
2283 theSerialPorts[1]->Config(cBuf1);
2285 c0.iRate=c1.iRate=EBps9600;
2286 c0.iParityError=c1.iParityError=0;
2287 c0.iHandshake=c1.iHandshake=KConfigObeyCTS;
2289 c0.iDataBits=c1.iDataBits=EData8;
2290 c0.iStopBits=c1.iStopBits=EStop1;
2291 c0.iParity=c1.iParity=EParityNone;
2293 r=theSerialPorts[0]->SetConfig(cBuf0);
2295 r=theSerialPorts[1]->SetConfig(cBuf1);
2298 const TInt KWriteSize=4000;
2299 TUint8* singleCharReadBuf=new TUint8[1];
2300 test(singleCharReadBuf!=NULL);
2301 TPtr8 singleCharReadDes(singleCharReadBuf,1,1);
2302 TUint8* multiCharWriteBuf=new TUint8[KWriteSize];
2303 test(multiCharWriteBuf!=NULL);
2304 TPtr8 multiCharWriteDes(multiCharWriteBuf,KWriteSize,KWriteSize);
2305 multiCharWriteDes.Fill('m');
2306 TUint8* singleCharWriteBuf=new TUint8[1];
2307 test(singleCharWriteBuf!=NULL);
2308 TPtr8 singleCharWriteDes(singleCharWriteBuf,1,1);
2309 singleCharWriteDes.Fill('s');
2310 TUint8* multiCharReadBuf=new TUint8[KWriteSize];
2311 test(multiCharReadBuf!=NULL);
2312 TPtr8 multiCharReadDes(multiCharReadBuf,KWriteSize,KWriteSize);
2314 TRequestStatus multiWriteStat;
2315 TRequestStatus multiReadStat;
2316 theSerialPorts[0]->Write(multiWriteStat,multiCharWriteDes);
2317 theSerialPorts[0]->Read(multiReadStat,multiCharReadDes);
2320 for (TInt i=0;i<KWriteSize;i++)
2323 test.Printf(_L("\r%c"),KSpinner[spin++%4]);
2325 TRequestStatus readStat;
2326 TRequestStatus writeStat;
2327 theSerialPorts[1]->Read(readStat,singleCharReadDes);
2328 theSerialPorts[1]->Write(writeStat,singleCharWriteDes);
2329 User::WaitForRequest(readStat);
2330 User::WaitForRequest(writeStat);
2332 if (readStat!=KErrNone)
2334 test.Printf(_L("Read Failed %d after %d chars\n\r"),readStat.Int(),i);
2337 if (writeStat!=KErrNone)
2339 test.Printf(_L("Write Failed %d after %d chars\n\r"),writeStat.Int(),i);
2344 test.Printf(_L("\n\r"));
2348 TRequestStatus timStat;
2349 tim.After(timStat,3000000);
2350 User::WaitForRequest(multiWriteStat,timStat);
2351 test(timStat==KRequestPending);
2353 User::WaitForRequest(timStat);
2354 test(timStat==KErrCancel);
2355 test(multiWriteStat==KErrNone);
2356 tim.After(timStat,3000000);
2357 User::WaitForRequest(multiReadStat,timStat);
2358 test(timStat==KRequestPending);
2361 User::WaitForRequest(timStat);
2362 test(timStat==KErrCancel);
2363 test(multiReadStat==KErrNone);
2364 test(multiCharWriteDes.Length()==multiCharWriteDes.MaxLength());
2368 delete [] multiCharWriteBuf;
2369 delete [] singleCharReadBuf;
2370 delete [] singleCharWriteBuf;
2371 delete [] multiCharReadBuf;
2373 theSerialPorts[0]->Close();
2374 theSerialPorts[1]->Close();
2377 void testMultiTerminatorCompletion()
2379 // Test multiple terminator completions
2382 test.Next(_L("Test partial reads with terminators"));
2384 TInt r=theSerialPorts[0]->Open(PortA);
2386 r=theSerialPorts[0]->QueryReceiveBuffer();
2388 r=theSerialPorts[1]->Open(PortB);
2390 r=theSerialPorts[1]->QueryReceiveBuffer();
2394 TCommConfigV01& c0=cBuf0();
2395 theSerialPorts[0]->Config(cBuf0);
2397 TCommConfigV01& c1=cBuf1();
2398 theSerialPorts[1]->Config(cBuf1);
2400 c0.iRate=c1.iRate=EBps9600;
2401 c0.iParityError=c1.iParityError=0;
2403 c0.iHandshake=c1.iHandshake=KConfigObeyCTS;
2405 c0.iDataBits=c1.iDataBits=EData8;
2406 c0.iStopBits=c1.iStopBits=EStop1;
2407 c0.iParity=c1.iParity=EParityNone;
2409 r=theSerialPorts[0]->SetConfig(cBuf0);
2411 c1.iTerminator[0]='a';
2412 c1.iTerminatorCount=1;
2413 r=theSerialPorts[1]->SetConfig(cBuf1);
2415 const TInt KWriteSize=4000;
2416 TUint8* writeBuf=new TUint8[KWriteSize];
2417 test(writeBuf!=NULL);
2418 TPtr8 writeDes(writeBuf,KWriteSize,KWriteSize);
2420 TUint8* readBuf=new TUint8[KWriteSize];
2421 test(readBuf!=NULL);
2422 TPtr8 readDes(readBuf,KWriteSize,KWriteSize);
2423 TRequestStatus writeStat;
2424 theSerialPorts[0]->Write(writeStat,writeDes);
2425 test(writeStat==KRequestPending);
2427 for (TInt i=0;i<KWriteSize;i++)
2430 test.Printf(_L("\r%c"),KSpinner[spin++%4]);
2431 TRequestStatus readStat;
2432 readDes.SetLength(KWriteSize/2);
2433 theSerialPorts[1]->Read(readStat,readDes);
2434 User::WaitForRequest(readStat);
2435 test(readStat==KErrNone);
2436 test(readDes.Length()==1);
2438 test.Printf(_L("\n\r"));
2439 User::WaitForRequest(writeStat);
2444 theSerialPorts[0]->Close();
2445 theSerialPorts[1]->Close();
2448 void TestSimpleWriting()
2450 test.Next(_L("Test we can still write 0->1"));
2451 const TPtrC8 string1=_L8("If you strike me down, I shall become more powerful than you can possibly imagine.");
2453 TRequestStatus stat;
2454 theSerialPorts[1]->Read(stat,inBuf,string1.Length());
2455 test(stat==KRequestPending);
2456 TInt r=theSerialPorts[0]->WriteS(string1,string1.Length());
2458 User::WaitForRequest(stat);
2459 test(stat==KErrNone);
2460 test(inBuf==string1);
2462 test.Next(_L("Test we can still write 1->0"));
2463 const TPtrC8 string2=_L8("Who's the more foolish... the fool or the fool who follows him?");
2464 theSerialPorts[0]->Read(stat,inBuf,string2.Length());
2465 test(stat==KRequestPending);
2466 r=theSerialPorts[1]->WriteS(string2,string2.Length());
2468 User::WaitForRequest(stat);
2469 test(stat==KErrNone);
2470 test(inBuf==string2);
2475 test.Next(_L("Power up and down"));
2477 TInt r=theSerialPorts[0]->Open(PortA);
2479 r=theSerialPorts[0]->QueryReceiveBuffer();
2481 r=theSerialPorts[1]->Open(PortB);
2483 r=theSerialPorts[1]->QueryReceiveBuffer();
2486 test.Start(_L("Power down while writing 0->1"));
2488 TCommConfigV01& c1=cBuf1();
2489 theSerialPorts[0]->Config(cBuf1);
2491 TCommConfigV01& c2=cBuf2();
2492 theSerialPorts[1]->Config(cBuf2);
2493 c1.iFifo=EFifoEnable;
2495 c2.iDataBits=c1.iDataBits=EData8;
2496 c2.iStopBits=c1.iStopBits=EStop1;
2497 c2.iParity=c1.iParity=EParityEven;
2498 c1.iRate=c2.iRate=EBps19200;
2499 c1.iHandshake=c2.iHandshake=0;
2501 r=theSerialPorts[0]->SetConfig(cBuf1);
2503 r=theSerialPorts[1]->SetConfig(cBuf2);
2507 test(timer.CreateLocal()==KErrNone);
2510 wakeup+=TTimeIntervalSeconds(10);
2511 TRequestStatus done;
2512 timer.At(done,wakeup);
2513 test(done==KRequestPending);
2514 RAsyncSwitchOff async;
2515 r=async.Start(2000000);
2518 // test(PowerCheckedWrite(KWriteSize*200)==KErrNone);
2520 const TUint bigWriteSize=KWriteSize*200;
2521 TUint8* inBuf=new TUint8[bigWriteSize];
2523 TUint8* outBuf=new TUint8[bigWriteSize];
2525 TPtr8 outDes(outBuf,bigWriteSize,bigWriteSize);
2526 TPtr8 inDes(inBuf,bigWriteSize,bigWriteSize);
2530 TRequestStatus readStatus;
2531 TRequestStatus timeStatus;
2533 StripeMem(outDes,'A','Z');
2536 theSerialPorts[0]->Read(readStatus,inDes,bigWriteSize);
2537 test(readStatus==KRequestPending);
2539 test.Printf(_L("Write........."));
2540 r=theSerialPorts[1]->WriteS(outDes,bigWriteSize);
2542 test.Printf(_L("Aborted by power down\n"));
2545 r=async.Start(2000000);
2547 const TUint KTimeOut=6000000;
2548 tim.After(timeStatus,KTimeOut);
2549 User::WaitForRequest(readStatus,timeStatus);
2550 if (timeStatus==KErrNone)
2552 test.Printf(_L("Timed Out!\n\r"));
2553 theSerialPorts[0]->ReadCancel();
2557 test(readStatus==KErrAbort);
2561 User::WaitForRequest(done);
2562 test(done==KErrNone);
2564 test.Next(_L("Reset config"));
2565 TestSimpleWriting();
2566 test.Next(_L("Close and reopen"));
2567 theSerialPorts[0]->Close();
2568 theSerialPorts[1]->Close();
2570 r=theSerialPorts[0]->Open(PortA);
2572 r=theSerialPorts[1]->Open(PortB);
2575 theSerialPorts[0]->Config(cBuf1);
2576 theSerialPorts[1]->Config(cBuf2);
2577 c1.iFifo=EFifoEnable;
2578 c2.iDataBits=c1.iDataBits=EData8;
2579 c2.iStopBits=c1.iStopBits=EStop1;
2580 c2.iParity=c1.iParity=EParityNone;
2581 c1.iRate=c2.iRate=EBps19200;
2582 c1.iHandshake=c2.iHandshake=0;
2584 r=theSerialPorts[0]->SetConfig(cBuf1);
2586 r=theSerialPorts[1]->SetConfig(cBuf2);
2589 TestSimpleWriting();
2591 test.Next(_L("Power down while writing 1->0"));
2592 theSerialPorts[0]->Config(cBuf1);
2593 theSerialPorts[1]->Config(cBuf2);
2594 c1.iFifo=EFifoEnable;
2596 c2.iDataBits=c1.iDataBits=EData8;
2597 c2.iStopBits=c1.iStopBits=EStop1;
2598 c2.iParity=c1.iParity=EParityEven;
2599 c1.iRate=c2.iRate=EBps9600;
2600 c1.iHandshake=c2.iHandshake=0;
2602 r=theSerialPorts[0]->SetConfig(cBuf1);
2604 r=theSerialPorts[1]->SetConfig(cBuf2);
2608 wakeup+=TTimeIntervalSeconds(10);
2609 timer.At(done,wakeup);
2610 test(done==KRequestPending);
2611 r=async.Start(2000000);
2614 // test(PowerCheckedWrite(KWriteSize*200)==KErrNone);
2615 StripeMem(outDes,'A','Z');
2618 theSerialPorts[1]->Read(readStatus,inDes,bigWriteSize);
2619 test(readStatus==KRequestPending);
2621 test.Printf(_L("Write........."));
2622 r=theSerialPorts[0]->WriteS(outDes,bigWriteSize);
2624 test.Printf(_L("Aborted by power down\n"));
2625 tim.After(timeStatus,KTimeOut);
2626 User::WaitForRequest(readStatus,timeStatus);
2627 if (timeStatus==KErrNone)
2629 test.Printf(_L("Timed Out!\n\r"));
2630 theSerialPorts[1]->ReadCancel();
2634 CHECK(readStatus.Int(),KErrAbort);
2638 User::WaitForRequest(done);
2639 test(done==KErrNone);
2641 test.Next(_L("Reset config"));
2642 TestSimpleWriting();
2643 test.Next(_L("Close and reopen"));
2644 theSerialPorts[0]->Close();
2645 theSerialPorts[1]->Close();
2647 r=theSerialPorts[0]->Open(PortA);
2649 r=theSerialPorts[0]->QueryReceiveBuffer();
2651 r=theSerialPorts[1]->Open(PortB);
2653 r=theSerialPorts[1]->QueryReceiveBuffer();
2656 theSerialPorts[0]->Config(cBuf1);
2657 theSerialPorts[1]->Config(cBuf2);
2658 c1.iFifo=EFifoEnable;
2659 c2.iDataBits=c1.iDataBits=EData8;
2660 c2.iStopBits=c1.iStopBits=EStop1;
2661 c2.iParity=c1.iParity=EParityNone;
2662 c1.iRate=c2.iRate=EBps19200;
2663 c1.iHandshake=c2.iHandshake=0;
2665 r=theSerialPorts[0]->SetConfig(cBuf1);
2667 r=theSerialPorts[1]->SetConfig(cBuf2);
2670 TestSimpleWriting();
2672 theSerialPorts[0]->Close();
2673 theSerialPorts[1]->Close();
2675 test.Next(_L("Test signals are preserved"));
2677 r=theSerialPorts[0]->Open(PortA);
2679 r=theSerialPorts[0]->QueryReceiveBuffer();
2681 r=theSerialPorts[1]->Open(PortB);
2683 r=theSerialPorts[1]->QueryReceiveBuffer();
2686 if((theCaps1.iHandshake & KCapsFreeRTSSupported) && (theCaps2.iHandshake & KCapsFreeRTSSupported))
2687 {//should also check for KConfigFreeDTR
2688 theSerialPorts[0]->Config(cBuf1);
2689 theSerialPorts[1]->Config(cBuf2);
2691 c1.iHandshake=KConfigFreeRTS|KConfigFreeDTR;
2692 c2.iHandshake=KConfigFreeRTS|KConfigFreeDTR;
2693 r=theSerialPorts[0]->SetConfig(cBuf1);
2695 r=theSerialPorts[1]->SetConfig(cBuf2);
2698 theSerialPorts[0]->SetSignals(KSignalRTS,KSignalDTR);
2699 theSerialPorts[1]->SetSignals(KSignalDTR,KSignalRTS);
2701 TUint signals=theSerialPorts[0]->Signals();
2702 //test(signals==(KSignalRTS|KSignalDSR));//something weird happens here under WINS - the CD line is set(?)
2703 CHECK((signals&(KSignalRTS|KSignalDSR)) , (KSignalRTS|KSignalDSR));
2704 signals=theSerialPorts[1]->Signals();
2705 CHECK(signals,(KSignalDTR|KSignalCTS));
2708 wakeup+=TTimeIntervalSeconds(10);
2709 timer.At(done,wakeup);
2710 r=async.Start(5000000);
2712 test(done==KRequestPending);
2713 User::WaitForRequest(done);
2714 test(done==KErrNone);
2718 User::After(100000); // wait for both ports to power back up
2719 signals=theSerialPorts[0]->Signals();
2720 //test(signals==(KSignalRTS|KSignalDSR));
2721 CHECK((signals&(KSignalRTS|KSignalDSR)) , (KSignalRTS|KSignalDSR));
2722 signals=theSerialPorts[1]->Signals();
2723 CHECK(signals,(KSignalDTR|KSignalCTS));
2728 r=theSerialPorts[0]->SetConfig(cBuf1);
2730 r=theSerialPorts[1]->SetConfig(cBuf2);
2733 theSerialPorts[0]->Close();
2734 theSerialPorts[1]->Close();
2739 void testSwitchIrDA()
2741 test.Next(_L("Switch to IrDA"));
2742 //Open the serial port channel.
2744 TInt r=theSerialPorts[0]->Open(PortA);
2746 r=theSerialPorts[0]->QueryReceiveBuffer();
2749 theSerialPorts[0]->Caps(theCaps1Buf);
2750 if (!(theCaps1.iSIR&KCapsSIR115kbps))
2752 theSerialPorts[0]->Close();
2753 test.Printf(_L("\t\tIrDA not supported\n"));
2757 r=theSerialPorts[0]->QueryReceiveBuffer();
2761 //Configure the channel for IrDA at 115.2k baud.
2763 TCommConfigV01& c1=cBuf1();
2764 theSerialPorts[0]->Config(cBuf1);
2765 c1.iSIREnable=ESIREnable;
2766 c1.iRate=EBps115200;
2767 c1.iDataBits=EData8;
2768 c1.iParity=EParityNone;
2769 c1.iStopBits=EStop1;
2771 c1.iHandshake|=KConfigFreeDTR;
2772 c1.iHandshake|=KConfigFreeRTS;
2773 r=theSerialPorts[0]->SetConfig(cBuf1);
2775 r=theSerialPorts[0]->QueryReceiveBuffer();
2777 const TUint8 KData[1] ={0x00};
2778 const TPtrC8 KDataPtr(KData,1);
2779 TRequestStatus stat;
2780 theSerialPorts[0]->Write(stat,KDataPtr);
2781 User::WaitForRequest(stat);
2782 r=theSerialPorts[0]->QueryReceiveBuffer();
2783 test.Printf(_L("ReceiveBuf = %d\n"),r);
2786 theSerialPorts[0]->Write(stat,KDataPtr);
2787 User::WaitForRequest(stat);
2788 User::After(1000000);
2789 r=theSerialPorts[0]->QueryReceiveBuffer();
2790 test.Printf(_L("ReceiveBuf = %d\n"),r);
2791 while (theSerialPorts[0]->QueryReceiveBuffer())
2794 theSerialPorts[0]->Read(stat,buf,1);
2795 test.Printf(_L("Data = "),&buf);
2796 User::WaitForRequest(stat);
2797 test.Printf(_L("%d\n"),buf[0]);
2799 r=theSerialPorts[0]->QueryReceiveBuffer();
2800 test.Printf(_L("ReceiveBuf = %d\n"),r);
2801 theSerialPorts[0]->Write(stat,KDataPtr);
2802 User::WaitForRequest(stat);
2803 //Check for any received data pending (the answer is 1! Which is incorrect as nothing has sent me any IrDA data)
2804 r=theSerialPorts[0]->QueryReceiveBuffer();
2805 test.Printf(_L("ReceiveBuf = %d\n"),r);
2807 theSerialPorts[0]->Write(stat,KDataPtr);
2808 User::WaitForRequest(stat);
2809 User::After(1000000);
2810 r=theSerialPorts[0]->QueryReceiveBuffer();
2812 theSerialPorts[0]->Close();
2815 GLDEF_C TInt E32Main()
2821 #if defined (__WINS__)
2822 test.SetLogged(ETrue); // log to $TEMP/EPOCWIND.OUT
2824 test.SetLogged(EFalse); //turn off serial port debugging!
2829 test.Start(_L("Serial loopback test"));
2832 test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
2834 TBool isAssabet=(muid==HAL::EMachineUid_Assabet);
2837 PortB=3; // used to be 1 but it apparently doesn't exist
2839 User::CommandLine(cmd);
2841 TBool stress = EFalse;
2844 if (cmd.Length() == 1)
2846 if ((cmd[0] == 'S') || (cmd[0] == 's'))
2851 if (cmd[0]>='0' && cmd[0]<='9')
2852 PortA=(TInt)(cmd[0]-'0');
2853 if (cmd[2]>='0' && cmd[2]<='9')
2854 PortB=(TInt)(cmd[2]-'0');
2855 if ((cmd[cmd.Length()-1] == 'S') || (cmd[cmd.Length()-1] == 's'))
2861 test.Printf(_L("Primary Port:%d Secondary Port:%d\n\r"),PortA,PortB);
2865 TBuf<10> pddName=PDD_NAME;
2866 test.Next(_L("Load PDDs"));
2868 const TInt KMaxPdds=0;
2870 const TInt KMaxPdds=10;
2873 for (i=-1; i<KMaxPdds; ++i)
2876 pddName.Append(TChar('0'));
2878 pddName[pddName.Length()-1] = (TText)('0'+i);
2879 r=User::LoadPhysicalDevice(pddName);
2880 if (r==KErrNone || r==KErrAlreadyExists)
2881 test.Printf(_L("PDD %S loaded\n"),&pddName);
2884 test.Next(_L("Load LDD"));
2885 r=User::LoadLogicalDevice(LDD_NAME);
2886 test.Printf(_L("Load LDD Return %d\n\r"),r);
2888 test.Next(_L("Create RComm objects"));
2889 theSerialPorts[0]=new RComm;
2890 theSerialPorts[1]=new RComm;
2891 test(theSerialPorts[0]!=NULL);
2892 test(theSerialPorts[1]!=NULL);
2898 test.Next(_L("Open:"));
2899 r=theSerialPorts[0]->Open(PortA);
2900 test.Printf(_L("Open(Unit0)=%d\n\r"),r);
2902 r=theSerialPorts[1]->Open(PortB);
2903 test.Printf(_L("Open(Unit1)=%d\n\r"),r);
2906 test.Next(_L("Get caps"));
2907 theSerialPorts[0]->Caps(theCaps1Buf);
2909 theSerialPorts[1]->Caps(theCaps2Buf);
2912 theSerialPorts[0]->Close();
2913 theSerialPorts[1]->Close();
2919 turnaroundTestReadWrite();
2922 testHWHandshaking();
2924 if((theCaps1.iHandshake & KCapsObeyXoffSupported) && (theCaps2.iHandshake & KCapsObeyXoffSupported))
2927 if((theCaps1.iHandshake & KCapsObeyCTSSupported) && (theCaps2.iHandshake & KCapsObeyCTSSupported))
2929 testSingleCharacterReads();
2931 //CF - see description of problem with testTerminators()
2932 if (!isAssabet) testMultiTerminatorCompletion();
2933 testBiDirectionalSingleCharacterReads();
2941 User::After(3000000);