Tuesday, December 1, 1998

An introduction to serial communications

.KEYWORD serial
.FLYINGHEAD PROGRAMMING POWER
.TITLE An introduction to serial communications
.DEPT
.SUMMARY Most of us use the Palm device’s serial port every day — but don’t know it. A little-known secret is the HotSync port on the bottom of the Palm device is a standard RS-232 serial port. In this informative article, programming technology editor Alan Jay Weiner shows us how the serial port works and how to write programs that use it. Even if you’re not a programmer, you’ll enjoy learning about what makes the serial port tick.
.AUTHOR Alan Jay Weiner
Communications is the name of the game — without some way to get data in and out, computers are useless. Of course, you enter data directly on the Palm device using the stylus, tapping on the screen and writing with Graffiti. And the Palm device responds by displaying information on the screen. But I think the single most important feature — the one that really makes the Palm device stand out — is its ability to HotSync mobile data to the desktop. Literally in a moment or two, you update all changes and back up your data. This HotSync operation takes place over the serial port.

When not used for HotSync operations, the serial port is available for other applications to use. For example, elsewhere in this issue, Fredlet reviews the GoType keyboard, which uses the serial port to capture keystrokes and then a small software driver interprets the data from the port into letters typed.

This month we take a look at using the Palm device serial port.

.H1 Serial communications in a nutshell
As you might expect, serial ports send the data bits serially; one after another. Each bunch of bits makes up a byte of data (i.e., a character), but the data stream also includes additional bits to tell the receiver that a data character has started and finished. Each data character may also include a "parity" bit for error detection.

A special piece of hardware is usually used to handle all this. Typically referred to as a UART, there are other parts that perform similar functions and are officially known by different names. UART means Universal Asynchronous Receiver-Transmitter — but it’s much easier (and quite a bit cooler) to just say "you-art." The UART takes a byte of data from the computer, handles any control lines as needed, adds the framing (start, stop, parity) bits, and does the reverse for any received data.

The simplest serial connection consists of three physical connections (e.g., wires) — a signal ground, receive data, and transmitted data. Actually, you could have a two-wire connection if you were only transmitting or only receiving. Usually there are some additional "control" lines that tell the equipment "I’m ready for you to send to me," or "I’d like to send to you now." Examining the full serial specification (known as RS-232) is beyond this article, but for now just understand that control lines exist, and if the equipment uses them, they need to be driven appropriately or you won’t get data going back and forth.

The speed of the connection is measured in bits-per-second, although it’s usually erroneously expressed as "baud rate." Baud refers to the frequency over telecommunications lines and since it’s already measured in hertz, saying "rate" is redundant. Nevertheless, if you say something like "9600 baud" or ask "what baud rate" everyone understands what you mean.

So to send serial data, you need to set the UART to the configuration you’d like (number of bits per character, parity or not, baud rate, and any other specifics to that hardware), then pump data to it to be sent and read received data from it.

.H1 Palm OS Serial APIs
Palm OS has no implicit APIs (Application Programming Interfaces) to control the serial port; instead, they’re implemented as library routines. This means you must ask the OS to load the library, which gets you a reference number, and then use that reference number in calls to the APIs within the library.

Once the serial communications library is loaded, you use the following APIs:

.BEGIN_LIST
.BULLET SerClearErr
.BULLET SerClose
.BULLET SerGetSettings
.BULLET SerGetStatus
.BULLET SerOpen
.BULLET SerReceive
.BULLET SerReceiveCheck
.BULLET SerReceiveFlush
.BULLET SerReceiveWait
.BULLET SerSend
.BULLET SerSendWait
.BULLET SerSetReceiveBuffer
.BULLET SerSetSettings
.END_LIST

When Palm OS 2 came out, several additional APIs appeared:

.BEGIN_LIST
.BULLET SerReceive was renamed to SerReceive10 and a new SerReceive appeared.
.BULLET SerSend was renamed to SerSend10 and a new SerSend appeared.
.BULLET SerSendCheck, SerSendFlush, and SerControl were added.
.END_LIST

Beyond these calls, there are a number of undocumented APIs. I’ll get into those another time.

.H1 SerialEcho receives and sends characters
The listing (see http://www.component-net.com/pp-extras/serial.html) shows a simple program which receives characters from the serial port and then echos them back. As usual, SerialEcho is based on the Hello World application, so most of it will look familiar.

Near the beginning are five routines that talk to the serial port. These routines use the Palm OS 1 APIs, so no version checking is included.

Two header files are required: Pilot.h and SerialMgr.h. The library API (SysLibFind) is in Pilot.h, and the serial API prototypes are in the SerialMgr.h header file.

The first routine, serialOpenPort, loads the serial library and opens the port, setting a specific baud rate and default control settings. The serial library is included in the Palm device’s ROM, so it’s always available; you don’t need to specially install it on the Palm device. This routine saves the reference number in a global variable for use by the other routines.

The corresponding serialClosePort waits until all the characters have been sent, and then closes the serial port.

To send characters, call serialPrintf with a string. This isn’t a real printf function – it only accepts a single string without any printf-like formatting characters. The string is transmitted over the opened serial port. But calling it serialPrintf helps make it easier to remember and understand.

Alternatively, call serialPrintch with a buffer and its length.

To receive characters, call serialGetch with a buffer, its length, and the minimum number of characters to get. If fewer than the specified number of characters are available, no characters will be read in. Otherwise, serialGetch fills in the buffer and returns the number of characters read.

The EventLoop and MainFormHandleEvent routines are slightly different than in our original Hello, World. EventLoop’s call to EvtGetEvent uses a timeout of 1 tick. This means that after 1-tick delay, we’ll get a nilEvent. MainFormHandleEvent uses that event to check the serial port — trying to receive any characters first, then sending them right back out.

These routines are rather simplistic and aren’t terribly efficient. You wouldn’t use them as-is for most programs, but they’re fine as a starting point. They don’t use callbacks to indicate that characters are available, so the Palm device must poll to see if any characters have been received. This is wasteful since the program never goes into "sleep". It’s constantly wasting battery power saying "Any chars? Nope… Ok, so any chars?" It reminds me of my kids when they want something…

Usually serial I/O is handled by interrupts, the way a telephone or doorbell works. You don’t constantly pick up the phone and say "hello". You wait for it to interrupt you; then you stop what you’re doing and talk on the phone. This same process inside the computer is called interrupt handling. When the UART receives a character, it "pulls an interrupt" (think of ringing the phone) and the processor stops what it’s doing and handles the interrupt. When the interrupt handling is complete, the processor returns to what it was doing before.

Polling is more like when you’re waiting for a letter to arrive, so you obsessively check your mailbox every few minutes. The letter doesn’t arrive any faster, but you sure waste a lot of time and energy checking the mailbox until it does arrive!

This same waste occurs in the Palm device. If the program knew it would be interrupted for a signal that there were characters received, then it could be either doing something else or go into low-power sleep mode to preserve battery life. Internally, that’s actually going on, but the SerialEcho program keeps "checking the mailbox" so it doesn’t get to go to sleep.

Another problem with the sample routine is that there’s no error handling — they’ll work fine until an error occurs. Once that happens, SerReceive stops returning characters until SerClearErr is called. With directly-connected equipment, errors are fairly rare, though, so again, this is good enough for an introduction.

.H1 A few anomalies
The serial port on the Palm device isn’t complete, and contains several hidden "gotcha’s."

First, the RS-232 signals aren’t fully represented. The Data Terminal Ready line isn’t controlled the way the specs say it should be. Most of the time this isn’t a problem, but it does cause trouble with some modems. Other rarely-used signals aren’t supplied at all.

When the serial port is opened on Palm OS 1 or Palm OS 2, it sends a backspace character, a hex 08. When the port is closed, you sometimes get a hex 7F character. This may cause problems with other equipment that it’s connected to. Palm OS 3 (on the Palm IIIs) does not send these spurious characters.

SerClearErr on Palm OS 1 resets the UART whenever it’s called, so if you call it when there isn’t any error, you’ll glitch any characters being received right then. Only call it when SerReceive reports an error.

Finally, there is a problem with the way "Clear to Send" handshaking is implemented. As it is currently architected, it will never go low ("off" meaning "don’t send any more characters"). This means the buffer must be emptied often enough that it never fills up.

.H1 The future
Palm has indicated they’re going to rework the serial architecture. I don’t know when that will happen ("Soon", they say), nor which future machines will change to that new architecture. Just be aware that there will be future changes.

.H1 Using SerialEcho
SerialEcho is a simple program that simply receives characters and transmits them back. You can use a terminal program (HyperTerm under Windows, for example, or Zterm on the Macintosh).

To use HyperTerm, start it from Windows’ start menu, and configure its properties to use whatever serial port you desire, at 9600 baud and no handshaking. It’s convenient to use the same port HotSync is using. Stop HotSync, start HyperTerm, then just drop the Palm device in its cradle and start SerialEcho. Whatever you type on HyperTerm will be sent back, so you’ll see the characters you’re typing. Pull the Palm device out (or turn it off) and the characters stop being sent back. Follow this same approach with Zterm if you’re on the Macintosh. Zterm is shareware, so you’ll probably have to download it if you’re not already "hip" to it.

.BEGIN_KEEP
.H1 Conclusion
This is a simple introduction to serial communications and the Palm device serial port. Many books have been written and careers have been made just dealing with serial communications. I’ll write more about it again in future columns.

Palm has a lot of useful information on their web site. See the resources list below for links to several of them. In particular, the white paper and FAQs are worth reading next.

.BEGIN_SIDEBAR
.H1 Product availability and resources
Source code to SerialEcho is at my web site, located at http://www.ajw.com/PalmPower/ProgrammingPower/Dec98/SerialEcho.zip.

The Serial Hardware Development Kit which contains information about the cables and cradle, vendors for connectors, and so forth, is available at http://www.palm.com/devzone/hdk/dzhdkser.html.

The Serial port pin-out (Palm device serial connector) for the signals on each pin on the back of the Palm device is available at http://www.palm.com/devzone/hdk/images/signals.gif.

You can download Zterm from http://www.download.com or visit any of the InfoMac archives.

.H2 Serial Port FAQs
Visit the FAQ at http://www.palm.com/devzone/faqs/HHSerial.html#a111.

Palm OS Serial Manager (white paper) is available at http://www.palm.com/devzone/docs/serialma.html#40982.
.END_SIDEBAR

.BIO Alan Weiner writes software for Palm devices. His email address is alan@ajw.com.
.DISCUSS http://powerboards.zatz.com/cgi-bin/webx?13@@.ee6c4da
.END_KEEP