|
1 // vtc_serial.cpp |
|
2 // |
|
3 // Copyright (c) 2007 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #include <fshell/common.mmh> |
|
14 #include "vtc_serial.h" |
|
15 |
|
16 const TInt KMaxWriteLength = 2 * 1024; // Some serial drivers fail with KErrNoMemory if writes are too big, so they have to be broken up. |
|
17 |
|
18 #define LEAVE_IF_ERROR_ALLOW_ALREADY_EXISTS(_x) { TInt _err = _x; if ((_err < 0) && (_err != KErrAlreadyExists)) { User::Leave(_err); } } |
|
19 |
|
20 EXPORT_C CVtcSerialConsole::CVtcSerialConsole() |
|
21 { |
|
22 } |
|
23 |
|
24 EXPORT_C CVtcSerialConsole::~CVtcSerialConsole() |
|
25 { |
|
26 iCommPort.Close(); |
|
27 iCommServ.Close(); |
|
28 } |
|
29 |
|
30 TInt CVtcSerialConsole::ReadConfig(const TDesC& aConfigDes, TPortConfig& aConfig) |
|
31 { |
|
32 _LIT(KKeywordPdd, "pdd"); |
|
33 _LIT(KKeywordLdd, "ldd"); |
|
34 _LIT(KKeywordCsy, "csy"); |
|
35 _LIT(KKeywordPort, "port"); |
|
36 _LIT(KKeywordRate, "rate"); |
|
37 |
|
38 TBool keywordFound(EFalse); |
|
39 TLex lex(aConfigDes); |
|
40 while (!lex.Eos()) |
|
41 { |
|
42 TPtrC keyword; |
|
43 TPtrC value; |
|
44 TInt err = ReadKeywordValuePair(lex, keyword, value); |
|
45 if (err != KErrNone) |
|
46 { |
|
47 break; |
|
48 } |
|
49 |
|
50 if (keyword == KKeywordPdd) |
|
51 { |
|
52 aConfig.iPdd.Set(value); |
|
53 keywordFound = ETrue; |
|
54 } |
|
55 else if (keyword == KKeywordLdd) |
|
56 { |
|
57 aConfig.iLdd.Set(value); |
|
58 keywordFound = ETrue; |
|
59 } |
|
60 else if (keyword == KKeywordCsy) |
|
61 { |
|
62 aConfig.iCsy.Set(value); |
|
63 keywordFound = ETrue; |
|
64 } |
|
65 else if (keyword == KKeywordPort) |
|
66 { |
|
67 aConfig.iPort.Set(value); |
|
68 keywordFound = ETrue; |
|
69 } |
|
70 else if (keyword == KKeywordRate) |
|
71 { |
|
72 TLex lex(value); |
|
73 TUint rate; |
|
74 if (lex.Val(rate) == KErrNone) |
|
75 { |
|
76 switch (rate) |
|
77 { |
|
78 case 115200: |
|
79 aConfig.iRate = EBps115200; break; |
|
80 case 9600: |
|
81 aConfig.iRate = EBps9600; break; |
|
82 case 19200: |
|
83 aConfig.iRate = EBps19200; break; |
|
84 case 57600: |
|
85 aConfig.iRate = EBps57600; break; |
|
86 default: |
|
87 break; |
|
88 } |
|
89 } |
|
90 keywordFound = ETrue; |
|
91 } |
|
92 } |
|
93 |
|
94 if (!keywordFound) |
|
95 { |
|
96 // Treat unrecognised string as a port name (to preserve backwards compatibility with earlier releases). |
|
97 aConfig.iPort.Set(aConfigDes); |
|
98 } |
|
99 |
|
100 return KErrNone; |
|
101 } |
|
102 |
|
103 EXPORT_C void CVtcSerialConsole::ConstructL(const TDesC& aTitle) |
|
104 { |
|
105 TPortConfig portConfig; |
|
106 User::LeaveIfError(ReadConfig(aTitle, portConfig)); |
|
107 if (portConfig.iPort.Length() == 0) |
|
108 { |
|
109 User::Leave(KErrArgument); |
|
110 } |
|
111 if (portConfig.iPdd.Length()) |
|
112 { |
|
113 LEAVE_IF_ERROR_ALLOW_ALREADY_EXISTS(User::LoadPhysicalDevice(portConfig.iPdd)); |
|
114 } |
|
115 else |
|
116 { |
|
117 // If not specified, assume they probably intended the standard ones (but don't error if they fail, since the user might actually know what they're doing |
|
118 #ifdef __WINS__ |
|
119 User::LoadPhysicalDevice(_L("ecdrv")); |
|
120 #else |
|
121 User::LoadPhysicalDevice(_L("euart1")); |
|
122 #endif |
|
123 } |
|
124 |
|
125 if (portConfig.iLdd.Length()) |
|
126 { |
|
127 LEAVE_IF_ERROR_ALLOW_ALREADY_EXISTS(User::LoadLogicalDevice(portConfig.iLdd)); |
|
128 } |
|
129 else |
|
130 { |
|
131 User::LoadLogicalDevice(_L("ecomm")); |
|
132 } |
|
133 |
|
134 User::LeaveIfError(iCommServ.Connect()); |
|
135 if (portConfig.iCsy.Length()) |
|
136 { |
|
137 LEAVE_IF_ERROR_ALLOW_ALREADY_EXISTS(iCommServ.LoadCommModule(portConfig.iCsy)); |
|
138 } |
|
139 else |
|
140 { |
|
141 iCommServ.LoadCommModule(_L("ecuart")); |
|
142 } |
|
143 User::LeaveIfError(iCommPort.Open(iCommServ, portConfig.iPort, ECommExclusive)); |
|
144 |
|
145 #ifdef __WINS__ |
|
146 // For BC reasons, we always set rate on WINS |
|
147 if (portConfig.iRate == EBpsAutobaud) portConfig.iRate = EBps115200; |
|
148 #endif |
|
149 |
|
150 if (portConfig.iRate != EBpsAutobaud) |
|
151 { |
|
152 TCommConfig cfg; |
|
153 cfg().iRate = portConfig.iRate; |
|
154 cfg().iDataBits = EData8; |
|
155 cfg().iStopBits = EStop1; |
|
156 cfg().iParity = EParityNone; |
|
157 cfg().iHandshake = 0; |
|
158 cfg().iParityError = KConfigParityErrorFail; |
|
159 cfg().iFifo = EFifoEnable; |
|
160 cfg().iSpecialRate = 0; |
|
161 cfg().iTerminatorCount = 0; |
|
162 cfg().iSIREnable = ESIRDisable; |
|
163 User::LeaveIfError(iCommPort.SetConfig(cfg)); |
|
164 } |
|
165 |
|
166 User::LeaveIfError(iCommPort.ResetBuffers()); |
|
167 CVtcConsoleBase::ConstructL(aTitle); |
|
168 } |
|
169 |
|
170 EXPORT_C TInt CVtcSerialConsole::Output(const TDesC8& aDes) |
|
171 { |
|
172 TRequestStatus status; |
|
173 TInt offset = 0; |
|
174 TInt err = KErrNone; |
|
175 while ((offset < aDes.Length()) && (err == KErrNone)) |
|
176 { |
|
177 const TInt bytesToWrite = Min(aDes.Length() - offset, KMaxWriteLength); |
|
178 do |
|
179 { |
|
180 iCommPort.Write(status, aDes.Mid(offset, bytesToWrite)); |
|
181 User::WaitForRequest(status); |
|
182 err = status.Int(); |
|
183 if (err == KErrNone) |
|
184 { |
|
185 offset += bytesToWrite; |
|
186 } |
|
187 else if (err == KErrNoMemory) // Necessary because of nasty behaviour in loopback.csy where it returns KErrNoMemory when its buffer is full, rather than simply delaying completion of the request until there is enough space. |
|
188 { |
|
189 User::After(200000); |
|
190 } |
|
191 } |
|
192 #ifdef FSHELL_PLATFORM_OPP // Temporary OPP specific change - the drivers for the mid-sized prototype currently complete requests with KErrAbort just before power management sends the device to sleep. |
|
193 while ((err == KErrNoMemory) || (err == KErrAbort)); |
|
194 #else |
|
195 while (err == KErrNoMemory); |
|
196 #endif |
|
197 } |
|
198 |
|
199 return err; |
|
200 } |
|
201 |
|
202 EXPORT_C void CVtcSerialConsole::Input(TDes8& aDes, TRequestStatus& aStatus) |
|
203 { |
|
204 iCommPort.ReadOneOrMore(aStatus, aDes); |
|
205 } |
|
206 |
|
207 EXPORT_C void CVtcSerialConsole::CancelInput(TRequestStatus&) |
|
208 { |
|
209 iCommPort.ReadCancel(); |
|
210 } |