First public contribution.
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_term.cpp
15 // T_TERM.CPP - Dumb terminal
20 #define _PC_CARD_SERIAL
29 const TPtrC KCaptureFileName=_L("C:\\CAPTURE.TXT");
30 const TPtrC KUploadFileName=_L("Z:\\UPLOAD.TXT");
35 RChunk TheCaptureChunk;
36 TPtr8 TheCapturedText(NULL,0,0);
41 TCommConfig TheConfigBuf;
42 TCommConfigV01 &TheConfig=TheConfigBuf();
43 TInt TheLastError=KErrNone;
45 const TInt KMaxDumpLength=0x100;
50 ELoadPhysicalDeviceErr,
51 ELoadLogicalDeviceErr,
74 TBuf8<KMaxDumpLength> iDumpData;
79 TBool iWaitAfterWrite;
84 LOCAL_D SSettings TheSettings;
85 LOCAL_D RBusDevComm TheCommPort;
86 LOCAL_D RConsole TheWindow;
88 LOCAL_C TInt CommWriteSync(RBusDevComm &aComm, const TDesC8 &aData)
91 aComm.Write(stat, aData);
92 User::WaitForRequest(stat);
96 LOCAL_C TInt WaitAfterWrite(RBusDevComm& aComm)
101 User::WaitForRequest(s);
105 LOCAL_C TInt RateToInt(TBps aRate)
113 case EBps230400: return 230400;
114 case EBps115200: return 115200;
115 case EBps57600: return 57600;
116 case EBps38400: return 38400;
117 case EBps19200: return 19200;
118 case EBps9600: return 9600;
119 case EBps7200: return 7200;
120 case EBps4800: return 4800;
121 case EBps3600: return 3600;
122 case EBps2400: return 2400;
123 case EBps2000: return 2000;
124 case EBps1800: return 1800;
125 case EBps1200: return 1200;
126 case EBps600: return 600;
127 case EBps300: return 300;
128 case EBps150: return 150;
129 case EBps134: return 134;
130 case EBps110: return 110;
131 case EBps75: return 75;
132 case EBps50: return 50;
137 LOCAL_C TBps IntToRate(TInt aVal)
143 if (aVal>=230400) return EBps230400;
144 if (aVal>=115200) return EBps115200;
145 if (aVal>=57600) return EBps57600;
146 if (aVal>=38400) return EBps38400;
147 if (aVal>=19200) return EBps19200;
148 if (aVal>=9600) return EBps9600;
149 if (aVal>=7200) return EBps7200;
150 if (aVal>=4800) return EBps4800;
151 if (aVal>=3600) return EBps3600;
152 if (aVal>=2400) return EBps2400;
153 if (aVal>=2000) return EBps2000;
154 if (aVal>=1800) return EBps1800;
155 if (aVal>=1200) return EBps1200;
156 if (aVal>=600) return EBps600;
157 if (aVal>=300) return EBps300;
158 if (aVal>=150) return EBps150;
159 if (aVal>=134) return EBps134;
160 if (aVal>=110) return EBps110;
161 if (aVal>=75) return EBps75;
162 if (aVal>=50) return EBps50;
166 LOCAL_C void ConfigString(TDes &aBuf, const TCommConfigV01 &aConfig, const SSettings &aSettings)
168 // Construct a Configuaration string
173 aBuf.Format(_L(" %d "), RateToInt(aConfig.iRate));
174 switch (aConfig.iParity)
176 case EParityEven: aBuf.Append(_L("E")); break;
177 case EParityOdd: aBuf.Append(_L("O")); break;
178 case EParityNone: aBuf.Append(_L("N")); break;
181 switch (aConfig.iDataBits)
183 case EData5: aBuf.Append(_L("5")); break;
184 case EData6: aBuf.Append(_L("6")); break;
185 case EData7: aBuf.Append(_L("7")); break;
186 case EData8: aBuf.Append(_L("8")); break;
189 if (aConfig.iStopBits==EStop1)
190 aBuf.Append(_L("1 "));
192 aBuf.Append(_L("2 "));
194 aBuf.Append(_L("Use:"));
195 if (aConfig.iHandshake==0)
196 aBuf.Append(_L("NoControl "));
197 if (aConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
198 aBuf.Append(_L("XonXoff "));
199 if (aConfig.iHandshake&KConfigObeyCTS)
200 aBuf.Append(_L("CTS/RTS "));
201 if (aConfig.iHandshake&KConfigObeyDSR)
202 aBuf.Append(_L("DSR/DTR "));
203 if (aConfig.iHandshake&KConfigWriteBufferedComplete)
204 aBuf.Append(_L("Early "));
205 //|KConfigObeyDCD|KConfigFailDCD|))
208 // if (aConfig.iBreak==TEiger::EBreakOn)
209 // aBuf.Append(_L(" Brk"));
210 if (aConfig.iFifo==EFifoEnable)
211 aBuf.Append(_L(" Fifo"));
214 if (aSettings.iLocalEcho)
215 aBuf.Append(_L("LocalEcho "));
216 if (aSettings.iAddLF)
217 aBuf.Append(_L("AddLF "));
218 if ((aSettings.iRxMode&~ECapture)==ELoopBack)
219 aBuf.Append(_L("LpBk"));
220 else if ((aSettings.iRxMode&~ECapture)==ECountChars)
221 aBuf.Append(_L("CtCh"));
222 aBuf.Append(_L(" "));
223 aBuf.AppendNum((TInt)(RThread().Priority()));
224 if (aSettings.iInfraRed==1)
225 aBuf.Append(_L("IR1"));
226 else if (aSettings.iInfraRed==2)
227 aBuf.Append(_L("IR2"));
228 if (aSettings.iWaitAfterWrite)
229 aBuf.Append(_L("Wait"));
231 aBuf.Append(_L("Last Err: "));
232 if (TheLastError==KErrNone)
233 aBuf.Append(_L("None "));
234 else if (TheLastError==KErrCommsLineFail)
235 aBuf.Append(_L("LineFail "));
236 else if (TheLastError==KErrCommsFrame)
237 aBuf.Append(_L("Frame "));
238 else if (TheLastError==KErrCommsOverrun)
239 aBuf.Append(_L("Overrun "));
240 else if (TheLastError==KErrCommsParity)
241 aBuf.Append(_L("Parity "));
242 else if (TheLastError==KErrAbort)
243 aBuf.Append(_L("Abort "));
244 else if (TheLastError==KErrBadPower)
245 aBuf.Append(_L("BadPower "));
246 else if (TheLastError==KErrNotReady)
247 aBuf.Append(_L("NotReady "));
249 aBuf.AppendNum(TheLastError);
252 LOCAL_C void GetRate(TBps &aRate, const TDesC &aDes)
259 if (TLex(aDes).Val(i)==KErrNone)
263 LOCAL_C void GetParity(TParity &aParity, const TDesC &aDes)
269 if (aDes.FindF(_L("O"))>=0)
271 if (aDes.FindF(_L("E"))>=0)
273 if (aDes.FindF(_L("N"))>=0)
277 LOCAL_C void GetHandshake(TUint &aHandshake, const TDesC &aDes)
283 if (aDes.FindF(_L("N"))>=0)
285 if (aDes.FindF(_L("X"))>=0)
286 aHandshake=KConfigObeyXoff|KConfigSendXoff;
287 if (aDes.FindF(_L("C"))>=0)
288 aHandshake=KConfigObeyCTS;
289 if (aDes.FindF(_L("D"))>=0)
290 aHandshake=KConfigObeyDSR|KConfigFreeRTS;
291 if (aDes.FindF(_L("E"))>=0)
292 aHandshake|=KConfigWriteBufferedComplete;
295 LOCAL_C void GetStopBit(TStopBits &aStop, const TDesC &aDes)
299 if (TLex(aDes).Val(in)==KErrNone)
315 LOCAL_C void GetLength(TDataBits &aData, const TDesC &aDes)
319 if (TLex(aDes).Val(in)==KErrNone)
323 case 5: aData=EData5; break;
324 case 6: aData=EData6; break;
325 case 7: aData=EData7; break;
326 case 8: aData=EData8; break;
332 LOCAL_C void GetInfraRedMode(TInt &aInfraRed, const TDesC &aDes)
335 if (aDes.FindF(_L("0"))>=0)
337 else if (aDes.FindF(_L("1"))>=0)
339 else if (aDes.FindF(_L("2"))>=0)
343 LOCAL_C void GetWaitMode(TBool &aWait, const TDesC &aDes)
346 if (aDes.FindF(_L("0"))>=0)
348 else if (aDes.FindF(_L("1"))>=0)
352 /*LOCAL_C void GetBreak(const TDesC &aDes)
357 if (data.iBreak==TEiger::EBreakOn)
358 data.iBreak=TEiger::EBreakOff;
360 data.iBreak=TEiger::EBreakOn;
362 if (aDes.FindF(_L("N"))>=0)
363 data.iBreak=TEiger::EBreakOn;
364 if (aDes.FindF(_L("F"))>=0)
365 data.iBreak=TEiger::EBreakOff;
369 LOCAL_C void GetFifo(TUint& aFifo, const TDesC &aDes)
374 if (aFifo==EFifoEnable)
379 if (aDes.FindF(_L("N"))>=0)
381 if (aDes.FindF(_L("F"))>=0)
385 LOCAL_C void GetEcho(TBool &aEcho, const TDesC &aDes)
395 if (aDes.FindF(_L("N"))>=0)
397 if (aDes.FindF(_L("F"))>=0)
401 LOCAL_C void GetRxMode(TRxMode &aMode, const TDesC &aDes)
404 if (aDes.FindF(_L("N"))>=0)
406 if (aDes.FindF(_L("L"))>=0)
408 if (aDes.FindF(_L("C"))>=0)
410 if (aDes.FindF(_L("S"))>=0)
412 aMode=TRxMode(TInt(aMode)|ECapture);
413 // TInt r=TheCaptureFile.Create(TheFs,KCaptureFileName,EFileWrite);
415 // User::Panic(_L("T_TERM CAP"),r);
417 if (aDes.FindF(_L("Z"))>=0)
419 aMode=TRxMode(TInt(aMode)&~ECapture);
420 // TheCaptureFile.Close();
422 if (aDes.FindF(_L("0"))>=0)
423 RThread().SetPriority(EPriorityNormal);
424 if (aDes.FindF(_L("1"))>=0)
425 RThread().SetPriority(EPriorityAbsoluteHigh);
428 LOCAL_C void GetDump(SSettings &aSettings, const TDesC &aDes)
432 if (TLex(aDes).Val(in)==KErrNone)
434 aSettings.iDump=ETrue;
435 aSettings.iDumpRepeat=in;
438 if (aDes.Length()!=0)
440 TBuf8<16> b=_L8("0123456789ABCDEF");
441 aSettings.iDumpData.Zero();
444 aSettings.iDumpData+=b;
448 TInt r=dialog.Init(_L("Type data to dump to comm. Escape to finish"),TSize(KConsFullScreen,KConsFullScreen));
449 r=dialog.Control(_L("+Maximize +NewLine"));
450 aSettings.iDumpData=_L8("");
455 if (k.Code()==EKeyEscape)
457 TText a=(TText)k.Code();
460 aSettings.iDumpData.Append(k.Code());
462 // dialog.Write(_L("\n"));
463 } while (aSettings.iDumpData.Length()<KMaxDumpLength);
471 LOCAL_C void CommandWindow(TCommConfigV01 &aConfig, SSettings &aSettings)
473 // Display some words of wisdom and get a command from the user
478 b.Num(aSettings.iCharCount);
480 b.AppendNum(aSettings.iMaxInOne);
483 TInt r=dialog.Init(_L("."),TSize(KConsFullScreen,KConsFullScreen));
484 r=dialog.Control(_L("+Maximize +NewLine"));
485 dialog.Write(_L("B<n> Set Bps to n P[Odd|Even|None] Set Parity\n"));
486 dialog.Write(_L("S[1|2] Set/Toggle stop bits L<n> Set Data Length (5<=n<=8)\n"));
487 dialog.Write(_L("K[On|Off] Set/Toggle BRK F[On|Off] Set/Toggle Fifo\n"));
488 dialog.Write(_L("H[None|X|CtsRts|DsrDtr] Handshaking\n"));
489 dialog.Write(_L("D[<n>] Set data or Dump data n times\n"));
490 dialog.Write(_L("J Toggle Add Line Feed E Toggle local Echo\n"));
491 dialog.Write(_L("U [NLC] Set Rx Mode\n"));
493 dialog.Write(_L("Q Quit\n"));
494 dialog.Write(_L("\n:"));
497 TBuf<0x80> des=_L("");
500 while ((k.Code()!='\r') && (k.Code()!=EKeyEscape))
502 TText a=(TText)k.Code();
505 des.Append(k.Code());
509 if (k.Code()!=EKeyEscape && des.Length()>0)
512 TBuf<0x80> right(des.Right(des.Length()-1));
514 GetRate(aConfig.iRate, right);
516 GetParity(aConfig.iParity, right);
518 GetStopBit(aConfig.iStopBits, right);
520 GetLength(aConfig.iDataBits, right);
522 // GetBreak(aSettings.iBreak, right);
524 GetFifo(aConfig.iFifo, right);
526 GetInfraRedMode(aSettings.iInfraRed, right);
527 if (aSettings.iInfraRed==1)
529 aConfig.iSIREnable=ESIREnable;
530 aConfig.iSIRSettings=KConfigSIRPulseWidthMinimum;
532 else if (aSettings.iInfraRed==2)
534 aConfig.iSIREnable=ESIREnable;
535 aConfig.iSIRSettings=KConfigSIRPulseWidthMaximum;
539 aConfig.iSIREnable=ESIRDisable;
540 aConfig.iSIRSettings=0;
543 GetHandshake(aConfig.iHandshake, right);
545 GetEcho(aSettings.iLocalEcho, right);
547 GetDump(aSettings, right);
549 aSettings.iAddLF=!aSettings.iAddLF;
552 GetRxMode(aSettings.iRxMode, right);
553 aSettings.iCharCount=0;
554 aSettings.iMaxInOne=0;
557 aSettings.iNotFinished=EFalse;
559 GetWaitMode(aSettings.iWaitAfterWrite, right);
566 // The following decl is a hack for the Eiger build.
567 // Without it T_TERM.EXE has no .data or .bss section. This means the data offset
568 // field in the file header is zero. When the kernel comes to copy the data sections
569 // from rom into ram it reads the data size field (which is the size of all data
570 // sections) from the header and tries to copy data from 0x00000000 (the data offset),
571 // causing a data abort.
573 #if defined (__WINS__)
574 #define PDD_NAME _L("ECDRV")
575 #define LDD_NAME _L("ECOMM")
577 #define PDD_NAME _L("EUART")
578 #define LDD_NAME _L("ECOMM")
581 LOCAL_C void ProcessError(TInt anError)
584 if (anError!=KErrNone)
586 TheLastError=anError;
587 ConfigString(buf, TheConfig, TheSettings);
588 TheWindow.SetTitle(buf);
592 LOCAL_C void HandleRx(TRequestStatus& aStatus, TBool /*aFinish*/)
595 switch(TheSettings.iRxMode & ~ECapture)
600 TheWindow.Write(buf);
605 ProcessError(CommWriteSync(TheCommPort,chw));
606 if (TheSettings.iWaitAfterWrite)
607 ProcessError(WaitAfterWrite(TheCommPort));
613 TheSettings.iCharCount+=l;
614 if (l>TheSettings.iMaxInOne)
615 TheSettings.iMaxInOne=l;
619 if ((TheSettings.iRxMode & ECapture)!=0 && TheCaptureChunk.Handle()!=0)
621 // TheCaptureFile.Write(chw);
622 TInt newLen=TheCapturedText.Length()+chw.Length();
623 TheCaptureChunk.Adjust(newLen);
624 TheCapturedText.Append(chw);
626 // if ((TheSettings.iRxMode & ~ECapture)==ELoopBack && !aFinish)
627 // TheCommPort.Read(aStatus, ch);
629 TheCommPort.ReadOneOrMore(aStatus, ch);
632 LOCAL_C TInt LoadDeviceDrivers()
634 // Load ECOMM.LDD and all PDDs with name EUART?.PDD
640 TFileName n=PDD_NAME;
641 r=User::LoadPhysicalDevice(n);
642 if (r==KErrNone || r==KErrAlreadyExists)
649 r=User::LoadPhysicalDevice(n);
650 if (r==KErrNone || r==KErrAlreadyExists)
653 r=User::LoadLogicalDevice(LDD_NAME);
654 if (r==KErrNone || r==KErrAlreadyExists)
659 GLDEF_C TInt E32Main()
665 // Open the window asap
666 TheWindow.Init(_L("TERM"),TSize(KConsFullScreen,KConsFullScreen));
669 TInt r=TheFs.Connect();
671 User::Panic(_L("T_TERM"), EConnectFsErr);
674 User::CommandLine(cmd);
676 if (cmd.Length()>0 && cmd[0]>='0' && cmd[0]<='9')
679 // Load Device Drivers
680 TConsoleKey keystroke;
681 TInt nDeviceDrivers=LoadDeviceDrivers();
682 if (nDeviceDrivers<2)
684 #if defined (VERBOSE)
686 outBuf.AppendFormat(_L("Failed(0) 0x%X\n\r"),r);
687 TheWindow.Write(outBuf);
688 TheWindow.Read(keystroke);
690 User::Panic(_L("T_TERM"), ELoadPhysicalDeviceErr);
693 r=TheCaptureChunk.CreateLocal(0x1000,0x1000000); // 16Mb
695 r=TheCaptureChunk.CreateLocal(0x1000,0x100000); // 1Mb
697 TheCaptureChunk.SetHandle(0);
699 TheCapturedText.Set(TheCaptureChunk.Base(),0,0x1000000);
701 TheSettings.iNotFinished=ETrue;
702 TheSettings.iLocalEcho=ETrue;
703 TheSettings.iAddLF=FALSE;
704 TheSettings.iDump=EFalse;
705 TheSettings.iDumpRepeat=1;
706 TheSettings.iDumpData=_L8("Some Text\r");
707 TheSettings.iRxMode=ENormal;
708 TheSettings.iCharCount=0;
709 TheSettings.iMaxInOne=0;
710 TheSettings.iInfraRed=0;
711 TheSettings.iWaitAfterWrite=EFalse;
714 r=TheCommPort.Open(port); // Comm port
716 User::Panic(_L("T_TERM"), EOpenErr);
718 TheCommPort.Config(TheConfigBuf); // get config
719 TheConfig.iHandshake=0; //KConfigObeyXoff|KConfigSendXoff;
720 TheCommPort.SetConfig(TheConfigBuf);
721 TheCommPort.SetReceiveBufferLength(8192);
723 // Set up a console window
724 TheWindow.Control(_L("+Maximize +Newline"));
725 TheWindow.Write(_L("= for command\n"));
727 ConfigString(buf, TheConfig, TheSettings);
728 TheWindow.SetTitle(buf);
731 TRequestStatus readStat, keyStat;
734 TheWindow.Read(k, keyStat);
735 TheCommPort.ReadOneOrMore(readStat, ch);
738 User::WaitForRequest(readStat, keyStat);
739 if (keyStat!=KRequestPending)
742 if (c<256 && c!='=' && c!='\x15' && c!='\x3' && c!='\x12' && c!='\x18')
748 ProcessError(CommWriteSync(TheCommPort, s8));
749 if (TheSettings.iWaitAfterWrite)
750 ProcessError(WaitAfterWrite(TheCommPort));
751 if (TheSettings.iLocalEcho)
754 if (c=='\r' && TheSettings.iAddLF) TheWindow.Write(_L("\n"));
759 TheCommPort.ReadCancel();
760 HandleRx(readStat,ETrue);
764 CommandWindow(TheConfig, TheSettings);
765 TheCommPort.ReadCancel();
766 TheCommPort.SetConfig(TheConfigBuf);
767 TheCommPort.ReadOneOrMore(readStat, ch);
768 ConfigString(buf, TheConfig, TheSettings);
769 TheWindow.SetTitle(buf);
773 TInt r=TheUploadFile.Open(TheFs,KUploadFileName,EFileRead);
775 User::Panic(_L("T_TERM"),EOpenUploadFile);
778 TheUploadFile.Read(buf);
779 ProcessError(CommWriteSync(TheCommPort,buf));
780 if (TheSettings.iWaitAfterWrite)
781 ProcessError(WaitAfterWrite(TheCommPort));
782 } while(buf.Length()!=0);
783 TheUploadFile.Close();
788 // TInt len=TheCapturedText.Length();
791 // TInt l=Min(0x100,len-i);
792 // TPtrC8 p(TheCapturedText.Ptr()+i,l);
793 // ProcessError(CommWriteSync(TheCommPort,p));
794 // if (TheSettings.iWaitAfterWrite)
795 // ProcessError(WaitAfterWrite(TheCommPort));
798 if (TheCaptureChunk.Handle())
800 ProcessError(CommWriteSync(TheCommPort,TheCapturedText));
801 if (TheSettings.iWaitAfterWrite)
802 ProcessError(WaitAfterWrite(TheCommPort));
807 if (TheCaptureChunk.Handle())
808 TheCapturedText.Zero();
810 TheWindow.Read(k, keyStat);
812 else if (readStat!=KRequestPending)
814 ProcessError(readStat.Int());
815 if (readStat!=KErrAbort && readStat!=KErrBadPower && readStat!=KErrNotReady)
816 HandleRx(readStat,EFalse);
818 TheCommPort.ReadOneOrMore(readStat, ch);
822 User::Panic(_L("T_TERM"), EStraySignal);
825 if (TheSettings.iDump)
827 TheSettings.iDump=EFalse;
829 for (i=0; i<TheSettings.iDumpRepeat; i++)
831 ProcessError(CommWriteSync(TheCommPort, TheSettings.iDumpData));
832 if (TheSettings.iWaitAfterWrite)
833 ProcessError(WaitAfterWrite(TheCommPort));
836 } while(TheSettings.iNotFinished);