|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32cons.h> |
|
20 #include <e32base.h> |
|
21 |
|
22 #include "logging.h" |
|
23 #include "portreader.h" |
|
24 #include "portwriter.h" |
|
25 #include "dbgtrcportmgr.h" |
|
26 |
|
27 //default USB settings |
|
28 _LIT(KDefaultUsbPDD, "NONE"); |
|
29 _LIT(KDefaultUsbLDD, "EUSBC"); |
|
30 _LIT(KDefaultUsbCSY, "ECACM"); |
|
31 #define KDefaultUsbPort 1 |
|
32 |
|
33 // uncomment the line below for testing with serial port on H4 or H2 board |
|
34 //#define SERIAL |
|
35 |
|
36 // |
|
37 // Static helper functions |
|
38 // |
|
39 static void BuildPortName(const TDesC& aModuleName, TUint aUnit, TDes& aCompleteName) |
|
40 { |
|
41 aCompleteName.Zero(); |
|
42 aCompleteName.Append(aModuleName); |
|
43 aCompleteName.AppendFill(':', 2); |
|
44 aCompleteName.AppendNum(aUnit); |
|
45 } |
|
46 |
|
47 static TBps TBpsRateFromDbgTrcBaudRate(TBaudRates aRate) |
|
48 { |
|
49 switch (aRate) |
|
50 { |
|
51 case EBaud50: return EBps50; |
|
52 case EBaud75: return EBps75; |
|
53 case EBaud110: return EBps110; |
|
54 case EBaud134: return EBps134; |
|
55 case EBaud150: return EBps150; |
|
56 case EBaud300: return EBps300; |
|
57 case EBaud600: return EBps600; |
|
58 case EBaud1200: return EBps1200; |
|
59 case EBaud1800: return EBps1800; |
|
60 case EBaud2000: return EBps2000; |
|
61 case EBaud2400: return EBps2400; |
|
62 case EBaud3600: return EBps3600; |
|
63 case EBaud4800: return EBps4800; |
|
64 case EBaud7200: return EBps7200; |
|
65 case EBaud9600: return EBps9600; |
|
66 case EBaud19200: return EBps19200; |
|
67 case EBaud38400: return EBps38400; |
|
68 case EBaud57600: return EBps57600; |
|
69 case EBaud115200: return EBps115200; |
|
70 case EBaud230400: return EBps230400; |
|
71 case EBaud460800: return EBps460800; |
|
72 case EBaud576000: return EBps576000; |
|
73 case EBaud1152000: return EBps1152000; |
|
74 case EBaud4000000: return EBps4000000; |
|
75 default: return EBpsAutobaud; |
|
76 } |
|
77 } |
|
78 |
|
79 |
|
80 CDbgTrcPortMgr* CDbgTrcPortMgr::NewL() |
|
81 { |
|
82 LOG_MSG("CDbgTrcPortMgr::NewL"); |
|
83 |
|
84 CDbgTrcPortMgr* self = new(ELeave) CDbgTrcPortMgr; |
|
85 CleanupStack::PushL(self); |
|
86 self->ConstructL(); |
|
87 CleanupStack::Pop(self); |
|
88 return self; |
|
89 } |
|
90 |
|
91 CDbgTrcPortMgr::~CDbgTrcPortMgr() |
|
92 { |
|
93 LOG_MSG("CDbgTrcPortMgr::~CDbgTrcPortMgr"); |
|
94 |
|
95 SafeDelete(iReader); |
|
96 SafeDelete(iWriter); |
|
97 } |
|
98 |
|
99 void CDbgTrcPortMgr::ConstructL() |
|
100 { |
|
101 LOG_MSG("CDbgTrcPortMgr::ConstructL"); |
|
102 |
|
103 iReader = NULL; |
|
104 iWriter = NULL; |
|
105 |
|
106 #ifdef SERIAL // for testing with serial on H4 or H2 board. |
|
107 iPDD.Copy(_L("EUART1")); |
|
108 iLDD.Copy(_L("ECOMM")); |
|
109 iCSY.Copy(_L("ECUART")); |
|
110 iPortNumber = 3; |
|
111 #else |
|
112 //set the default ACM port settings. |
|
113 iPDD.Copy(KDefaultUsbPDD); |
|
114 iLDD.Copy(KDefaultUsbLDD); |
|
115 iCSY.Copy(KDefaultUsbCSY); |
|
116 iPortNumber = KDefaultUsbPort; |
|
117 #endif |
|
118 |
|
119 iRate = EBaud115200; |
|
120 |
|
121 iConnected = EFalse; |
|
122 iActiveConnections = 0; |
|
123 iServerStarted = EFalse; |
|
124 |
|
125 iAcmConfig.iBaudRate = iRate; |
|
126 iAcmConfig.iPortNumber = iPortNumber; |
|
127 } |
|
128 |
|
129 void CDbgTrcPortMgr::GetPortConfig(TDes8& aDes) |
|
130 { |
|
131 LOG_MSG("CDbgTrcPortMgr::GetPortConfig"); |
|
132 |
|
133 TPtrC8 cfg((const TUint8*)&iAcmConfig, sizeof(iAcmConfig)); |
|
134 aDes.Copy(cfg); |
|
135 } |
|
136 |
|
137 TInt CDbgTrcPortMgr::SetPortConfig(const TDesC8& aDes) |
|
138 { |
|
139 LOG_MSG("CDbgTrcPortMgr::SetPortConfig"); |
|
140 |
|
141 if (iConnected) |
|
142 return KErrInUse; |
|
143 |
|
144 if (aDes.Length()<(TInt)sizeof(TAcmConfigV01)) |
|
145 return KErrGeneral; |
|
146 TAcmConfigV01 config(*(TAcmConfigV01*)aDes.Ptr()); |
|
147 |
|
148 iPortNumber = config.iPortNumber; |
|
149 iRate = config.iBaudRate; |
|
150 |
|
151 iAcmConfig.iBaudRate = iRate; |
|
152 iAcmConfig.iPortNumber = iPortNumber; |
|
153 |
|
154 return KErrNone; |
|
155 } |
|
156 |
|
157 |
|
158 // |
|
159 // CDbgTrcPortMgr::OpenPortL |
|
160 // |
|
161 // Open the ACM port |
|
162 // |
|
163 TInt CDbgTrcPortMgr::OpenPortL() |
|
164 { |
|
165 LOG_MSG("CDbgTrcPortMgr::OpenPort"); |
|
166 |
|
167 TInt error = KErrNone; |
|
168 |
|
169 if (iConnected) |
|
170 { |
|
171 iActiveConnections++; |
|
172 return error; //return KErrNone if the connection is already opened by another client. |
|
173 } |
|
174 |
|
175 if (!iServerStarted) |
|
176 { |
|
177 StartC32(); |
|
178 error = iServer.Connect(); |
|
179 if (error == KErrNone) |
|
180 { |
|
181 iServerStarted = ETrue; |
|
182 LOG_MSG("C32 Server started"); |
|
183 } |
|
184 } |
|
185 |
|
186 if (iServerStarted) |
|
187 { |
|
188 error = iServer.LoadCommModule(iCSY); |
|
189 if (error == KErrNone) |
|
190 { |
|
191 LOG_MSG("CSY Loaded:"); |
|
192 |
|
193 TInt ports = 0; |
|
194 error = iServer.NumPorts(ports); |
|
195 |
|
196 if (error == KErrNone) |
|
197 { |
|
198 LOG_MSG2("Number of ports: %d", ports); |
|
199 |
|
200 // make sure the unit number is in range |
|
201 TSerialInfo serialInfo; |
|
202 |
|
203 error = KErrNotFound; |
|
204 |
|
205 TBuf<32> csyModule; |
|
206 csyModule = iCSY; |
|
207 csyModule.LowerCase(); |
|
208 for (TInt i=0; i<ports && error; i++) |
|
209 { |
|
210 TBuf<32> module; |
|
211 TInt err1 = iServer.GetPortInfo(i, module, serialInfo); |
|
212 |
|
213 // come out of the loop and error out if we are not able |
|
214 // to get the port info. |
|
215 if (err1 != KErrNone) |
|
216 break; |
|
217 |
|
218 module.LowerCase(); |
|
219 LOG_MSG("Module name: "); |
|
220 |
|
221 if (!module.Compare(csyModule)) |
|
222 { |
|
223 error = KErrNone; |
|
224 LOG_MSG("CSY Module matched"); |
|
225 } |
|
226 } |
|
227 |
|
228 if (error == KErrNone) |
|
229 { |
|
230 LOG_MSG("CSY Module found"); |
|
231 if (iPDD.Compare(KDefaultUsbPDD)) |
|
232 error = User::LoadPhysicalDevice(iPDD); |
|
233 |
|
234 if (error == KErrNone || error == KErrAlreadyExists) |
|
235 { |
|
236 error = User::LoadLogicalDevice(iLDD); |
|
237 if (error == KErrNone || error == KErrAlreadyExists) |
|
238 { |
|
239 error = KErrNone; |
|
240 TBuf<KMaxPortName+4> portName; |
|
241 BuildPortName(serialInfo.iName, iPortNumber, portName); |
|
242 |
|
243 error = iPort.Open(iServer, portName, ECommExclusive, ECommRoleDTE); |
|
244 if (error != KErrNone) |
|
245 { |
|
246 LOG_MSG("Unable to open port in DTE mode"); |
|
247 |
|
248 error = iPort.Open(iServer, portName, ECommExclusive, ECommRoleDCE); |
|
249 } |
|
250 |
|
251 if (error == KErrNone) |
|
252 { |
|
253 LOG_MSG("Port opened"); |
|
254 |
|
255 // Configure physical and logical characteristics |
|
256 TCommConfig config; |
|
257 iPort.Config(config); |
|
258 config().iRate = TBpsRateFromDbgTrcBaudRate(iRate); |
|
259 config().iParity = EParityNone; |
|
260 config().iDataBits = EData8; |
|
261 config().iStopBits = EStop1; |
|
262 config().iFifo = EFifoEnable; |
|
263 |
|
264 config().iHandshake = 0; // no flow control at all |
|
265 |
|
266 error = iPort.SetConfig(config); |
|
267 |
|
268 if (error == KErrNone) |
|
269 { |
|
270 LOG_MSG("Port configuration set"); |
|
271 |
|
272 //iPort.SetReceiveBufferLength(MAX_BUF_SIZE); |
|
273 iConnected = ETrue; |
|
274 //reset the rx and tx buffers just in case |
|
275 //if there is any stale data lying around from the previous debug sessions |
|
276 iPort.ResetBuffers(); |
|
277 |
|
278 // now increment the active connections counter |
|
279 iActiveConnections++; |
|
280 |
|
281 // now create the port reader and writer. |
|
282 iReader = CPortReader::NewL(iPort); |
|
283 iWriter = CPortWriter::NewL(iPort); |
|
284 } |
|
285 } |
|
286 } |
|
287 } |
|
288 } |
|
289 } |
|
290 } |
|
291 } |
|
292 |
|
293 if (iServerStarted && !iConnected) |
|
294 { |
|
295 iServer.Close(); |
|
296 iServerStarted = EFalse; |
|
297 } |
|
298 |
|
299 return error; |
|
300 } |
|
301 |
|
302 |
|
303 // |
|
304 // CDbgTrcPortMgr::ClosePort |
|
305 // |
|
306 // Close the ACM port |
|
307 // |
|
308 TInt CDbgTrcPortMgr::ClosePort() |
|
309 { |
|
310 // now decrement the active connections counter |
|
311 if (iActiveConnections > 0) |
|
312 iActiveConnections--; |
|
313 |
|
314 if (iActiveConnections == 0) // close the actual port only when the number of active connections is 0 |
|
315 { |
|
316 SafeDelete(iReader); |
|
317 SafeDelete(iWriter); |
|
318 |
|
319 if (iConnected) |
|
320 { |
|
321 iPort.Close(); |
|
322 iConnected = EFalse; |
|
323 } |
|
324 |
|
325 if (iServerStarted) |
|
326 { |
|
327 iServer.Close(); |
|
328 iServerStarted = EFalse; |
|
329 } |
|
330 } |
|
331 |
|
332 return KErrNone; |
|
333 } |
|
334 |
|
335 // |
|
336 // CDbgTrcPortMgr::GetPortReader |
|
337 // |
|
338 // |
|
339 CPortReader* CDbgTrcPortMgr::GetPortReader() |
|
340 { |
|
341 if (iConnected) |
|
342 return iReader; |
|
343 |
|
344 return NULL; |
|
345 } |
|
346 |
|
347 // |
|
348 // CDbgTrcPortMgr::GetPortReader |
|
349 // |
|
350 // |
|
351 CPortWriter* CDbgTrcPortMgr::GetPortWriter() |
|
352 { |
|
353 if (iConnected) |
|
354 return iWriter; |
|
355 |
|
356 return NULL; |
|
357 } |
|
358 |
|
359 |