Friday, May 23, 2008

Interfacing UART in Symbian

Accessing any port in symbian needs the following steps

  1. Load physical DD
  2. Load logical DD
  3. Connect to RCommServer
  4. Connect RComm client to Server
  5. Load the specific port module (.CSY file)
  6. Configure and Open
  7. Do the operation

Here is a piece of code explains how to interface with UART in symbian





TInt err = User::LoadPhysicalDevice(PDD_NAME);




if (err != KErrNone && err != KErrAlreadyExists)


{


RDebug::Printf("Loading of Physical drive failed\n");


User::Leave(err);


}





// Load the logical device driver.


err = User::LoadLogicalDevice(LDD_NAME);


if (err != KErrNone && err != KErrAlreadyExists)


{


RDebug::Printf("Loading of Logical drive failed\n");


User::Leave(err);


}








#if 1 //!defined (__WINS__)


// Start the comms server process


err = StartC32();


if (err != KErrNone && err != KErrAlreadyExists)


{


RDebug::Printf("StartC32 failed\n");


User::Leave(err);


}


#endif



// Connect to the Serial comms server.


User::LeaveIfError(iCommServer.Connect());


RDebug::Printf("Success: CommServer connect\n");


// Load the CSY module.


User::LeaveIfError(iCommServer.LoadCommModule(RS232));


RDebug::Printf("Success: CommServer RS232 Loading\n");





TInt numPorts;


User::LeaveIfError(iCommServer.NumPorts (numPorts));


RDebug::Printf("Success: CommServer returned number of ports & the number of ports = %d", numPorts);



//we are really only interested in using the CSY that we've


// just loaded up ourselves. We could find out its portInfo by


// comparing the moduleName returned by the version of GetPortInfo we


// just used to the name of the CSY we loaded, but there's a better


// version of GetPortInfo we can use, which just takes the name of a CSY


// as a parameter. We'd expect to find this informtion is an exact


// duplicate of the indexed portInfo for the last loaded CSY


// Our example code will use the lowest possible port (why not?)



TSerialInfo portInfo;





TBuf16 <> moduleName;



for (TInt index=0 ; index <>
{


User::LeaveIfError(iCommServer.GetPortInfo (index, moduleName, portInfo));


RDebug::Print(_L("module name = %S"), &moduleName);


RDebug::Print(_L("Port name = %S"), &(portInfo.iName));


RDebug::Print(_L("Port Description = %S"), &(portInfo.iDescription));


RDebug::Printf("Port high unit = %d", portInfo.iHighUnit);


RDebug::Printf("Port Low unit = %d", portInfo.iLowUnit);


}




User::LeaveIfError(iCommServer.GetPortInfo (RS232, portInfo));


RDebug::Printf("Success: CommServer returned port information \n");





RDebug::Print(_L("Port name = %S"), &(portInfo.iName));


RDebug::Print(_L("Port Description = %S"), &(portInfo.iDescription));


RDebug::Printf("Port high unit = %d", portInfo.iHighUnit);


RDebug::Printf("Port Low unit = %d", portInfo.iLowUnit);








// Now let's use a few Symbian OS functions to construct a descriptor for the


// name of the lowest port our CSY supports -


// The name can be as long as a TSerialInfo.iName plus a


// couple of colons and digits



TBuf16 <> portName; // declare an empty descriptor buffer


portName.Num (portInfo.iLowUnit); // put in the port number in ASCII


portName.Insert (0, KColons); // stick in a couple of colons


portName.Insert (0, portInfo.iName); // and lead off with the iName



// and at last we can open the first serial port,which we do here in exclusive mode



RComm commPort;


User::LeaveIfError(commPort.Open (iCommServer, portName, ECommExclusive));


RDebug::Printf("Success: Commport Open\n");



// Now we can configure our serial port


// we want to run it at 115200 bps 8 bits no parity (why not?)


// so maybe we ought to get of its capabilities and check it can


// do what we want before going ahead



TCommCaps ourCapabilities;


commPort.Caps (ourCapabilities);



if (((ourCapabilities ().iRate & KCapsBps115200) == 0) ||


((ourCapabilities ().iDataBits & KCapsData8) == 0) ||


((ourCapabilities ().iStopBits & KCapsStop1) == 0) ||


((ourCapabilities ().iParity & KCapsParityNone) == 0))


User::Leave (KErrNotSupported);




TCommConfig portSettings;


commPort.Config (portSettings);


portSettings ().iRate = EBps115200;


portSettings ().iParity = EParityNone;


portSettings ().iDataBits = EData8;


portSettings ().iStopBits = EStop1;



// as well as the physical characteristics, we need to set various logical ones


// to do with handshaking, behaviour of reads and writes and so so



portSettings ().iFifo = EFifoEnable;





//portSettings ().iHandshake = (KConfigObeyCTS | KConfigFreeRTS); // for cts/rts





portSettings ().iHandshake = (KConfigObeyXoff | KConfigSendXoff); // for xon/xoff





// portSettings ().iHandshake = KConfigFailDSR;





portSettings ().iTerminator[0] = 10;


portSettings ().iTerminatorCount = 1; // so that we terminate a read on each line feed arrives



User::LeaveIfError(commPort.SetConfig (portSettings));


RDebug::Printf("Success: Commport Config\n");



// now turn on DTR and RTS, and set our buffer size



commPort.SetSignals (KSignalDTR, 0);


commPort.SetSignals (KSignalRTS, 0);


TInt curlenth = commPort.ReceiveBufferLength ();


commPort.SetReceiveBufferLength (4096);


curlenth = commPort.ReceiveBufferLength ();





const TTimeIntervalMicroSeconds32 KTimeOut(4000000);


TRequestStatus stat;


commPort.Write (stat, KTimeOut, (TDesC8&)KFileName);


User::WaitForRequest (stat);


err = stat.Int ();


if (err != KErrNone) // Write has failed for some reason


{


RDebug::Printf("Failure: Commport Write and the reason is %d\n", err);


//Failed


}





RDebug::Printf("Success: Commport Write\n");



TBuf8 <> localInputBuffer;


localInputBuffer.FillZ();


TRequestStatus readStat;



//Reading the written buffer


commPort.Read (readStat, localInputBuffer, 20);


User::WaitForRequest(readStat);


User::LeaveIfError (readStat.Int ());


RDebug::Printf("Success: Commport Read\n");





RDebug::Print(_L("Read buffer is %S"), &localInputBuffer);



commPort.Close ();


iCommServer.Close ();



0 comments:

 
Template design by Amanda @ Blogger Buster