diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_glass_term_8cpp-source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_glass_term_8cpp-source.html Tue Mar 30 11:56:28 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,416 +0,0 @@ - -
-00001 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). -00002 // All rights reserved. -00003 // This component and the accompanying materials are made available -00004 // under the terms of "Eclipse Public License v1.0" -00005 // which accompanies this distribution, and is available -00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html". -00007 // -00008 // Initial Contributors: -00009 // Nokia Corporation - initial contribution. -00010 // -00011 // Contributors: -00012 // -00013 // Description: -00014 // Purpose: Glass Term : read/Write from keyboard/serial port : example code for SDK -00015 // This uses the first serial port on the system, and offers a choice between different -00016 // handshaking modes. All control characters apart from carriage returns and line feeds are -00017 // displayed on the screen with ^ carets in from of the the ASCII equivalent (so tab = ^I) -00018 // The ESC key is used to end the program -00019 // Note : -00020 // In order for this program to do anything, the serial port should be connected to something. -00021 // A modem is of course quite suitable. In the absence of a modem, a loopback plug with the -00022 // receive and transmit lines connected will echo all serial port output to the screen. In -00023 // the absence of a loopback plug, a bent paper clip or somethings similar connecting pins 2 and 3 -00024 // on any 25 or 9 way serial connector will do exactly the same thing. This last suggestion -00025 // is something that is carried out entirely at your own risk, and you should be very careful -00026 // neither to connect any other pins nor to push the paper clip in too far ! -00027 // If using the bent paper clip, you'll find that in order for the hardware handshaking option -00028 // to work, a second bent paper clip connecting pins 4 and 5 on a 25-way connector or pin 7 and 8 -00029 // on a 9-way connector will also be needed - this second paper clip is needed to connect RTS to CTS -00030 // Note: this sample program now shows how to support infra-red as well -00031 // as RS232 and also systems with multiple serial ports and multiple -00032 // possible CSYs. -00033 // -00034 -00035 #include <e32base.h> -00036 #include <e32test.h> -00037 #include <e32svr.h> -00038 #include <c32comm.h> -00039 #include <f32file.h> -00040 -00041 #include "CommonFiles.h" -00042 -00043 // first define our device driver names -00044 -00045 _LIT(LDD_NAME,"ECOMM"); -00046 -00047 #if defined (__WINS__) -00048 _LIT(PDD_NAME,"ECDRV"); -00049 #else -00050 _LIT(PDD_NAME,"EUART"); -00051 #endif -00052 -00053 // next define an arbitrary buffer size and Hundred seconds in microseconds -00054 -00055 const TInt KBufSize (512); -00056 const TInt KOneHundredSecond (100000000); -00057 -00058 // short literals for use in doExampleL() declared at file scope -00059 _LIT(KMessage2,"%c\n"); -00060 _LIT(KMessage14,"^%c"); -00061 _LIT(KMessage15,"%c"); -00062 _LIT(KColons,"::"); -00063 -00064 // utility function to print received text -00065 void printReceivedText(TDes8& localInputBuffer,TInt numberRead); -00066 -00067 LOCAL_C void doExampleL () -00068 { -00069 _LIT(KMessage0,"Select S for RS232 Serial or R for InfraRed port : "); -00070 _LIT(KMessage1,"Select 0 for no handshaking, 1 for CTS/RTS and 2 for XON/XOFF :"); -00071 _LIT(KMessage4,"Loading device drivers\n"); -00072 _LIT(KMessage5,"Starting comms server\n"); -00073 _LIT(KMessage6,"Connecting to comms server\n"); -00074 _LIT(KMessage7,"Loading %S.CSY module\n"); -00075 _LIT(KMessage8,"%S has %S available as %S::%u to %S::%u\n"); -00076 _LIT(KMessage9,"Opened %S\n"); -00077 _LIT(KMessage10,"Configuring Serial port for 115200 bps 8 bits no parity 1 stop\n"); -00078 _LIT(KMessage11,"Powering up port\n"); -00079 _LIT(KMessage12,"\nDisconnecting\n"); -00080 _LIT(KMessage13,"\nWrite Failed %d\n"); -00081 _LIT(KMessage16,"\nRead failed %d\n"); -00082 _LIT(KMessage17,"Closed %S\n"); -00083 _LIT(KMessage18,"Closing server connection\n"); -00084 _LIT(KMessage19,"Comms server reports we have %u comms modules loaded\n"); -00085 _LIT(KMessage20,"Using the lowest %S out of %S::%u to %S::%u\n"); -00086 -00087 _LIT(KPanic,"StraySignal"); -00088 _LIT(RS232,"ECUART"); -00089 _LIT(IRCOMM,"IRCOMM"); -00090 -00091 TBuf16 < 6 > csyName; -00092 -00093 TUint8 csyMode; -00094 const TUint8 mask=0xdf; // this mask 0xdf turns lower to upper case -00095 -00096 console->Printf (KMessage0); -00097 do -00098 csyMode = STATIC_CAST(TUint8,console->Getch () & mask); -00099 while ((csyMode < 'R') || (csyMode > 'S')); -00100 console->Printf (KMessage2, csyMode); -00101 -00102 if (csyMode=='S') -00103 csyName.Copy(RS232); -00104 else -00105 csyName.Copy(IRCOMM); -00106 -00107 -00108 -00109 TKeyCode handshakingMode; -00110 console->Printf (KMessage1); -00111 do -00112 handshakingMode = console->Getch (); -00113 while ((handshakingMode < '0') || (handshakingMode > '2')); -00114 console->Printf (KMessage2, handshakingMode); -00115 -00116 -00117 // Under WINS we must force a link to the file server -00118 // so that we're sure we'll be able to load the device drivers. -00119 // On a MARM implementation, this code would not -00120 // be required because higher level components -00121 // will automatically have started the services. -00122 -00123 #if defined (__WINS__) -00124 _LIT(KMessage3,"Connect to file server\n"); -00125 console->Printf (KMessage3); -00126 RFs fileServer; -00127 User::LeaveIfError (fileServer.Connect ()); -00128 fileServer.Close (); -00129 #endif -00130 -00131 -00132 // Load the physical and logical device drivers -00133 // Symbian platform will automatically append .PDD and .LDD and -00134 // search /System/Libs on all drives starting from C: -00135 // If EIKON has done this, they'll already exist - -00136 // no harm will have been done -00137 -00138 console->Printf (KMessage4); -00139 TInt r = User::LoadPhysicalDevice (PDD_NAME); -00140 if (r != KErrNone && r != KErrAlreadyExists) -00141 User::Leave (r); -00142 r = User::LoadLogicalDevice (LDD_NAME); -00143 if (r != KErrNone && r != KErrAlreadyExists) -00144 User::Leave (r); -00145 -00146 // Both WINS and EIKON will have started the comms server process. -00147 // (this is only really needed for ARM hardware development racks) -00148 -00149 #if !defined (__WINS__) -00150 console->Printf (KMessage5); -00151 r = StartC32 (); -00152 if (r != KErrNone && r != KErrAlreadyExists) -00153 User::Leave (r); -00154 #endif -00155 -00156 // Now (at last) we can actually connect to the comm server -00157 -00158 console->Printf (KMessage6); -00159 RCommServ server; -00160 User::LeaveIfError (server.Connect ()); -00161 -00162 // Load the CSY module -00163 // Symbian platform will automatically search \System\Libs -00164 // on all drives starting from C: -00165 -00166 console->Printf (KMessage7,&csyName); -00167 r = server.LoadCommModule (csyName); -00168 User::LeaveIfError (r); -00169 -00170 // if we know our machine architecture we can just go ahead and open (say) COMM::0 -00171 // however, for machine independence we are better off looking up that information -00172 -00173 // the oddly-named NumPorts function actually tells us how many CSYs are loaded -00174 // this isn't 0 since we've just loaded one ... -00175 -00176 TInt numPorts; -00177 r = server.NumPorts (numPorts); -00178 User::LeaveIfError (r); -00179 console->Printf (KMessage19,numPorts); -00180 -00181 // we can get port information for each loaded CSY in turn (note we -00182 // index them from 0) - we can find out the number of ports supported -00183 // together with their names, and their description. The information is -00184 // returned in a TSerialInfo structure together with the name of the -00185 // CSY that we've indexed -00186 -00187 TSerialInfo portInfo; -00188 TBuf16 < 12 > moduleName; -00189 -00190 for (TInt index=0 ; index < numPorts ; index++) -00191 { -00192 r = server.GetPortInfo (index, moduleName, portInfo); -00193 User::LeaveIfError (r); -00194 console->Printf (KMessage8, -00195 &moduleName, -00196 &portInfo.iDescription, -00197 &portInfo.iName, -00198 portInfo.iLowUnit, -00199 &portInfo.iName, -00200 portInfo.iHighUnit); -00201 } -00202 -00203 // However, we are really only interested in using the CSY that we've -00204 // just loaded up ourselves. We could find out its portInfo by -00205 // comparing the moduleName returned by the version of GetPortInfo we -00206 // just used to the name of the CSY we loaded, but there's a better -00207 // version of GetPortInfo we can use, which just takes the name of a CSY -00208 // as a parameter. We'd expect to find this informtion is an exact -00209 // duplicate of the indexed portInfo for the last loaded CSY -00210 // Our example code will use the lowest possible port (why not?) -00211 -00212 r = server.GetPortInfo (csyName, portInfo); -00213 console->Printf (KMessage20, -00214 &portInfo.iDescription, -00215 &portInfo.iName, -00216 portInfo.iLowUnit, -00217 &portInfo.iName, -00218 portInfo.iHighUnit); -00219 -00220 // Now let's use a few Symbian platform functions to construct a descriptor for the -00221 // name of the lowest port our CSY supports - -00222 // The name can be as long as a TSerialInfo.iName plus a -00223 // couple of colons and digits -00224 -00225 TBuf16 < KMaxPortName + 4 > portName; // declare an empty descriptor buffer -00226 portName.Num (portInfo.iLowUnit); // put in the port number in ASCII -00227 portName.Insert (0, KColons); // stick in a couple of colons -00228 portName.Insert (0, portInfo.iName); // and lead off with the iName -00229 -00230 // and at last we can open the first serial port,which we do here in exclusive mode -00231 -00232 RComm commPort; -00233 console->Printf (KMessage9, &portName); -00234 r = commPort.Open (server, portName, ECommExclusive); -00235 User::LeaveIfError (r); -00236 -00237 // Now we can configure our serial port -00238 // we want to run it at 115200 bps 8 bits no parity (why not?) -00239 // so maybe we ought to get of its capabilities and check it can -00240 // do what we want before going ahead -00241 -00242 TCommCaps ourCapabilities; -00243 commPort.Caps (ourCapabilities); -00244 -00245 if (((ourCapabilities ().iRate & KCapsBps115200) == 0) || -00246 ((ourCapabilities ().iDataBits & KCapsData8) == 0) || -00247 ((ourCapabilities ().iStopBits & KCapsStop1) == 0) || -00248 ((ourCapabilities ().iParity & KCapsParityNone) == 0)) -00249 User::Leave (KErrNotSupported); -00250 -00251 console->Printf (KMessage10); -00252 -00253 TCommConfig portSettings; -00254 commPort.Config (portSettings); -00255 portSettings ().iRate = EBps115200; -00256 portSettings ().iParity = EParityNone; -00257 portSettings ().iDataBits = EData8; -00258 portSettings ().iStopBits = EStop1; -00259 -00260 // as well as the physical characteristics, we need to set various logical ones -00261 // to do with handshaking, behaviour of reads and writes and so so -00262 -00263 portSettings ().iFifo = EFifoEnable; -00264 if (handshakingMode == '2') -00265 portSettings ().iHandshake = (KConfigObeyXoff | KConfigSendXoff); // for xon/xoff -00266 else if (handshakingMode == '1') -00267 portSettings ().iHandshake = (KConfigObeyCTS | KConfigFreeRTS); // for cts/rts -00268 else -00269 portSettings ().iHandshake = KConfigFailDSR; // for no handshaking -00270 -00271 portSettings ().iTerminator[0] = 10; -00272 portSettings ().iTerminatorCount = 1; // so that we terminate a read on each line feed arrives -00273 -00274 r = commPort.SetConfig (portSettings); -00275 User::LeaveIfError (r); -00276 -00277 // now turn on DTR and RTS, and set our buffer size -00278 -00279 commPort.SetSignals (KSignalDTR, 0); -00280 commPort.SetSignals (KSignalRTS, 0); -00281 TInt curlenth = commPort.ReceiveBufferLength (); -00282 commPort.SetReceiveBufferLength (4096); -00283 curlenth = commPort.ReceiveBufferLength (); -00284 -00285 // now we can start using the port -00286 -00287 TKeyCode key; -00288 TPtrC8 outputByte ((TUint8 *) & key, 1); -00289 TBuf8 < KBufSize > localInputBuffer; -00290 TRequestStatus readStat, keyStat; -00291 -00292 // a null read or write powers up the port -00293 -00294 console->Printf (KMessage11); -00295 commPort.Read (readStat, localInputBuffer, 0); -00296 User::WaitForRequest(readStat); -00297 r = readStat.Int (); -00298 User::LeaveIfError (r); -00299 -00300 // now the main glass terminal -00301 // this could be either an active object -00302 // or, as in this case, an asynchronous loop -00303 -00304 // note that we use Read() with a timeout - we have configured the port so that -00305 // line feeds trigger early completion of reads, which optimizes text based reception. -00306 -00307 // if we'd used the request commPort.ReadOneOrMore (readStat, localInputBuffer) we -00308 // could well have ended up calling the server once per character (up to 2000 times -00309 // per second!) so a regular re-issuing of the read request once in every 100 second is no -00310 // big deal (to retain echoing of keyboard characters) -00311 -00312 -00313 console->Read (keyStat); -00314 commPort.Read (readStat, KOneHundredSecond, localInputBuffer); -00315 for (;;) -00316 { -00317 User::WaitForRequest (readStat, keyStat); -00318 -00319 // From keyboard -00320 -00321 if (keyStat != KRequestPending) -00322 { -00323 key = console->KeyCode (); -00324 -00325 if (key == 0x1b) // ESCAPE - Disconnect -00326 { -00327 console->Printf (KMessage12); -00328 commPort.ReadCancel (); // Cancel Read -00329 User::WaitForRequest (readStat); -00330 break; -00331 } -00332 -00333 if (key < 256) // ASCII - Write to serial port -00334 { -00335 TRequestStatus stat; -00336 commPort.Write (stat, outputByte); -00337 User::WaitForRequest (stat); -00338 r = stat.Int (); -00339 if (r != KErrNone) // Write has failed for some reason -00340 console->Printf (KMessage13, r); -00341 } -00342 -00343 console->Read (keyStat); // When complete, read again -00344 } -00345 -00346 // From serial port - we display printable characters, line feeds and carriage returns -00347 // but control characters are displayed as a caret ^ followed by the printable equivalent -00348 -00349 // timeout errors are OK here, but we do need to check that there really is data in the -00350 // buffer before printing it to the screen as we might have timed out with no data -00351 -00352 else if (readStat != KRequestPending) -00353 { -00354 if (readStat == KErrNone || readStat == KErrTimedOut) -00355 { -00356 // check descriptor and print any characters -00357 TInt numberRead = localInputBuffer.Length (); -00358 if (numberRead != 0) -00359 printReceivedText(localInputBuffer,numberRead); -00360 else -00361 // else check the input buffer and print any characters -00362 { -00363 numberRead = commPort.QueryReceiveBuffer(); -00364 if (numberRead != 0) -00365 { -00366 commPort.ReadOneOrMore(readStat, localInputBuffer); -00367 User::WaitForRequest (readStat); -00368 if (readStat == KErrNone) printReceivedText(localInputBuffer,numberRead); -00369 } -00370 } -00371 } -00372 else // An error occured on reading -00373 console->Printf (KMessage16, readStat.Int ()); -00374 commPort.Read (readStat, KOneHundredSecond, localInputBuffer); -00375 } -00376 -00377 // help !! a request we can't cater for -00378 -00379 else -00380 { -00381 User::Panic (KPanic, 0); -00382 } -00383 -00384 } -00385 -00386 // Close port -00387 -00388 commPort.Close (); -00389 console->Printf (KMessage17, &portName); -00390 console->Printf (KMessage18); -00391 server.Close (); -00392 } -00393 -00394 void printReceivedText(TDes8& localInputBuffer,TInt numberRead) -00395 { -00396 TUint8 *nextByte = &localInputBuffer[0]; -00397 for (int i = 0; i < numberRead; i++, nextByte++) -00398 { -00399 if ((*nextByte < 32) && (*nextByte != 10) && (*nextByte != 13)) -00400 console->Printf (KMessage14, (*nextByte) + 64); -00401 else -00402 console->Printf (KMessage15, *nextByte); -00403 } -00404 } -