Commands and Responses
Commands and Acknowledgements
Serial Controllers
Lead-in Byte
Checksum Byte
Key Byte
Software Handshaking
Hardware Handshaking
Duplex
Base I/O Port
Polled Mode
Interrupt Mode
PC-Bus Interrupt Specifics
Example1 - Display Controller Defaults and Raw Touch Coordinates
Example2 - Calibrate and Finger Paint
PACKET.C - Interface-Independent Driver Code
SERIAL.C - Machine-Independent Serial Driver Code
BUS.C - PC-Bus Code
Interrupt-Driven Code
This chapter describes the communication between the host computer and the SmartSet controllers. The basic packet structure is introduced and how packets are sent and received. The SMARTSET utility is used as a demonstration. Specifics about each interface are given next, followed by a sample driver in machine-independent C source code.
High-level communication with all SmartSet controllers is through an eight-byte packet. Packets sent to the controller are called command packets. Packets received from the controller are called response packets. The command and response packets are identical for all SmartSet controllers.
For PC-Bus and Micro Channel controllers, packets are transmitted and received through eight consecutive read/write I/O ports. For serial controllers, the eight-byte packet is transmitted over the serial line framed by two additional bytes for synchronization. Specifics on the bus and serial interfaces will be covered later in this chapter.
The first byte of each packet is the command byte, and the seven remaining bytes are the data bytes. The command byte is an ASCII character, currently from 'A' to 'T'. Chapter 6, the Command Reference, details each command and response.
A command byte in upper-case indicates a set command to the controller. The data bytes then alter an internal setting of the controller.
A command byte in lower-case indicates a query command to the controller. The data bytes in the query command are ignored by the controller. A query command tells the controller to report the internal settings of the controller as they relate to the command. The controller reports this data in a response packet.
The format of the response packet is identical to that of the set command, including the command byte being in upper-case. This allows the host to query a current setting, modify a specific parameter, and return the same packet to the controller as a set command. Unused or unknown parameters can be ignored.
The structure for each type of packet is shown below:
Note the command byte (byte 0) is in lower-case for the query command, and is in upper-case in the response packet and set commands.
Each command sent to a SmartSet controller is confirmed by an Acknowledge response. This response packet indicates any errors in the command and any other pending errors. See in the Command Reference for a list of the possible error codes.
A typical query/response/set interaction flows as follows:
|
The only commands that do not return an Acknowledge response are the Hard Reset and Quiet-all commands.
Let's use the SMARTSET utility to demonstrate this interaction. Type:
SMARTSET
(not case sensitive)
|
at the DOS prompt, select your interface, and proceed to the Main Menu. (For more information on using SMARTSET, see Chapter 4.)
Make sure touches are enabled by typing "P". (PC-Bus and Micro Channel controllers are not enabled by default). Change Touch Reporting to Report as necessary.
Next select the Touch Mode submenu by typing "M". Initial Touches, Stream Touches, and Untouches should all be Enabled.
Now type "A" for ASCII Setup. Touch the touchscreen and notice the stream of packets received by SMARTSET. A sample display is shown below in Figure 5-1.
The "T" in byte 0 indicates the packets are Touch packets. Click here for detailed information on the contents of the Touch packet. Byte 1 contains the Status bits, the X coordinate is the Intel (byte swapped) integer formed by bytes 2 & 3, Y is in bytes 4 & 5, and Z follows in bytes 6 & 7. As you move your finger, bytes 2-5 should change. Byte 1 should indicate your Initial Touch, Stream Touches, and Untouch with 1, 2, and 4 respectively. These values correspond to the bit positions defined for the Touch packet. Bytes 6 & 7 are constant on AccuTouch controllers as they do not support a Z-axis (pressure).
Figure 5-1. SmartSet Utility ASCII Setup Display with Touch Packets
Next, let's send a command to the controller. Type "m" and press [Enter]. Commands in lower-case indicate a query. The Mode command is described in Chapter 6. Pressing [Enter] causes SMARTSET to fill any unentered bytes will nulls, and transmit the complete packet to the controller.
Figure 5-2. SmartSet Utility ASCII Setup Showing Mode Query
Notice that the Mode query returned a Mode response followed by an Acknowledge response. Byte 2 of the Mode response is 87 (hex), indicating the Initial Touch, Stream, and Untouch bits are set, corresponding to what we observed on the Touch Mode submenu.
Let's change the controller into Single-Point Mode by clearing the Initial Touch and Stream bits in the Mode packet. Type "M", "$00", "$81", [Enter]. Note the command byte is in upper-case because this is a set command. The '$' keystroke signals SMARTSET that you are entering a binary value in hex, rather than an ASCII value. Note the controller returns an Acknowledge response after the set command. If the "A" is followed by anything but '0's, click here for a list of possible error codes. Retry the Mode set command as necessary.
Now touch the touchscreen again to verify you selected Single-Point Mode. Press [ESC] and return to the Main Menu. Examine the Mode settings and you will see that SMARTSET reflects the changes you made manually in ASCII Setup. When writing a driver, the SMARTSET utility is valuable for understanding the query/response/set interaction for the various commands and for verifying the settings you program into the controller.
You may wish to experiment with other queries in ASCII Setup. Type "o" to query the Owner string. Type "g" to download the whole configuration of the controller. You should be able to identify each packet and their contents by referring to Chapter 6.
From the Main Menu, type "R" and select Soft Reset to restore the default settings of the controller. Exit SMARTSET.
In the next section, we will detail the communication at an even lower level-the specifics for each type of interface: serial, PC-Bus, and Micro Channel. The SMARTSET utility hides these details, just as you may hide them at a certain level when developing a driver that supports multiple interfaces.
The serial interface uses the eight-byte packet with an additional Lead-in byte and a trailing Checksum byte for a total of ten bytes.
<Lead in byte><8-byte Command or Response><Checksum byte>
An optional Key byte may also be included.
The Lead-in byte is used to signal the start of a packet. The standard Lead-in byte is an ASCII 'U' (55h). This character was chosen due to its distinctive alternating bit pattern.
The Lead-in byte is different if the optional Key byte is included in the packet. See Key Byte for more information.
The trailing Checksum byte may be used to validate the serial communication and to synchronize with the received data stream.
The Checksum is calculated as follows:
Checksum byte = <AAh> + <Lead in byte> + <8 Data bytes>
where the addition is performed with 8-bit unsigned numbers and overflow is ignored.
By default, the host is not required to send a properly calculated Checksum in command packets. A dummy value, such as 0, is required to provide the correct packet length.
If a higher confidence is needed in the serial communications, the host may use the Parameter command to enable Checksum verification by the controller. With this function enabled, the controller checks each command packet for a valid Checksum value before processing the command.
An optional format, available on some controllers, extends the standard serial packet by adding a Key byte. This extended packet is used in specialized installations where more than one serial controller is to be connected on a single serial communication link. In such an installation, a unique Key value may be programmed into each controller with the Key command and stored in NVRAM.
A command intended for only one of the interconnected controllers is sent in an extended packet. Although all controllers on the link receive the command, only the one with the matching Key processes the command. If a standard packet is sent along the link, all the interconnected controllers will process the command (it acts as a global command).
Similarly, responses from each controller contain the programmed Key byte. This permits the host to discriminate between touch data generated by the controllers.
As there is no standard way of allowing the controllers in this type of installation to send data on the same serial data line, a custom wired OR configuration is necessary for the hardware to function properly. The controllers must also have automatic touch reporting disabled with the Mode command and be polled with a Touch query issued to each controller. See Touch command. Other hardware considerations must also be evaluated when attempting this type of installation.
The structure of the extended serial communications packet is:
<Lead In byte><8 byte Command or Response><Key byte><Checksum
byte>
The Lead In byte of an extended packet is an ASCII Control-V character (16h). The host can check for either a 'U' or ^V as the Lead-in byte. If the byte is a 'U', the host knows 9 bytes will follow. If the byte is a ^V, 10 bytes will follow.
As with the standard packet, the Checksum is calculated by summing the bytes without regard to overflow. The Key byte is included in the sum.
Checksum byte = <AAh> + <Lead in byte> + <8 Data bytes>
+ <Key byte>
The Key byte is not used by factory default.
Some controllers recognize the software flow control convention of XON/ XOFF (ASCII "Control Q" and "Control S"). If the host sends a ^S character to the controller, outside the context of a command packet, the controller will stop sending data to the host. Upon receipt of a ^Q, the controller will once again be enabled to send data to the host.
The controller can also send XOFF/XON characters to the host as a software handshaking method. Upon receipt of a valid command, a ^S character may be sent to the host. When the command is processed completely, a corresponding ^Q is sent. This will allow devices which do not properly handle hardware handshaking signals to use software flow control.
Software handshaking may be enabled or disabled with the Parameter command. It is disabled by factory default.
The controller supports hardware handshake signals typically implemented in EIA RS-232 communications. If the handshaking signals are not connected, the controller defaults to a transmit-enabled mode.
If the handshaking signals are connected, the following protocol should be used:
The signal DSR (Data Set Ready) is kept asserted by the controller. This signal indicates to the host that a controller is present and powered on.
The signal DTR (Data Terminal Ready) tells the controller that the host is present. The controller will only transmit if DTR is asserted by the host. Typically, the host should keep DTR asserted.
When the controller receives a valid command, it de-asserts the handshaking signal CTS (Clear To Send). The host should suppress further output until the controller has processed the command and is ready to receive another, indicated by when it asserts CTS.
The host should assert RTS (Request To Send) when it is ready to accept data, and de-assert RTS when it cannot accept data. Typically, the host will de-assert RTS while it is processing a complete packet, then reassert RTS when it is ready to receive another packet.
To ease troubleshooting of the initial installation, jumper J3 can be used to force the controller to ignore hardware handshaking.
On some controllers, Hardware handshaking may also be enabled, disabled, or inverted with the Parameter command. It is enabled by factory default.
When full-duplex is selected, each character sent to the controller is echoed. When half-duplex is selected, the controller does not retransmit each received character.
Full-duplex mode is useful when a dumb terminal, also in full-duplex mode, is used to manually test or set up the controller. Half-duplex mode is used if the terminal is also in half-duplex mode.
Half-duplex mode is normally used when software is communicating directly with the controller.
Full or half-duplex is selected with the Parameter command. Half-duplex is the factory default.
The PC-Bus and Micro Channel SmartSet controllers use read/write I/O ports for communicating the eight-byte packet. The Micro Channel controller is obsolete.
The Base I/O Port is the location of first I/O port through which the controller and the host exchange data. The Base I/O Port is selected from jumpers or NVRAM with the E271-2201 PC-Bus controller, and through "automatic configuration" with the E271-2202 Micro Channel controller. For more information on Base I/O Port selection, see Chapter 2.
A block of eight consecutive ports are used for the eight-byte packet. They are denoted as "Base Port", "Base Port + 1", etc., through "Base Port + 7".
To receive a packet from the controller, the host reads the eight I/O ports in ascending order starting with the Base Port. The controller senses the completion of the transfer when all eight ports have been read.
To send a packet to the controller, the host writes to the same eight I/O ports in ascending order starting with the Base Port. The controller processes the command after all eight ports have been written. A command received by the controller takes priority over any background processing. This includes the processing of another command. Therefore, the host must wait for an Acknowledge response before issuing another command.
The controller informs the host that data is available by clearing a status bit and optionally asserting an interrupt request line (IRQ). This allows the host driver software to be polled or interrupt-driven.
Polled Mode is commonly used in computer systems which do not have a hardware interrupt signal available to assign to the touchscreen controller. Polled drivers are easier to write but do not allow multi-tasking or event-driven programming. (Elo drivers are interrupt-driven).
Bit 7 of the Base Port (the command byte), is the Not Ready bit. If the host is polling the controller, it should wait until the Not Ready bit is 0 before reading the remaining bytes. This negative logic is used so bit 7 does not need to be cleared in response packets before they are resent to the controller as set commands. It also makes packets received from bus controllers identical to those received from serial controllers.
If Interrupt Mode is enabled either by jumpers or software setup, the controller asserts the selected IRQ signal when data becomes available (as it clears the Not Ready bit). It is not necessary for the host to poll the Not Ready bit in Interrupt Mode. Upon interrupt, the host jumps to a corresponding interrupt service routine (ISR) whose location is stored in its interrupt vector table. The ISR retrieves the data from the controller and then returns to the interrupted process. A full discussion on writing interrupt-driven code is language and operating system dependent, and is beyond the scope of this manual. It is possible to setup the controller through polling, then switch to interrupt-driven code to receive touch packets.
An IRQ signal can be used by only one device at a time in the PC architecture. It is possible, however, for the E271-2201 PC-Bus controller to share an IRQ signal with another device if the other device can release (tri-state) its interrupt line drivers. Most serial and parallel controllers on the PC have this feature (see the IBM Technical Reference Manuals).
To share an IRQ, the E271-2201 controller should be programmed to use the IRQ only when the other device is tri stated. When the other device needs the IRQ, the host must reprogram the E271-2201 to IRQ0 (Polled Mode). This way, only one device is driving the interrupt line at a time.
The E271-2201 is shipped without an IRQ jumpered. For information on selecting an interrupt, see Chapter 2. For the most flexibility, an interrupt-driven driver should use the Parameter command to select an interrupt as the driver is loaded.
The rest of this chapter provides sample application and driver code for SmartSet touchscreen controllers. The example source code is written in ANSI C, and can be found on the SmartSet Companion Disk available for download on www.elotouch.com. The code is organized in modules as follows:
Figure 5-3. Example Code Organization
EXAMPLE1.C and EXAMPLE2.C are sample applications. Each uses high-level interface-independent controller interface functions in PACKET.C, such as querycommand ( ) and setcommand ( ). The interface-dependent functions are supplied in SERIAL.C for the E271-2210 or 2500S serial controllers, or BUS.C for the E271-2201 PC-Bus controller and the E271-2202 Micro Channel controller.
BUS.C contains some code that is Micro Channel specific. This code is commented for easily deletion if support on this architecture is not required. SERIAL.C is written to be machine-independent. The PC-dependent serial port configuration and character input/output code is given in PC_COMM.C. PC_MISC.C contains miscellaneous PC-dependent code to clear the screen, hide the cursor, etc. PC_COMM and PC_MISC can be rewritten for other architectures. Source code for all modules is included in this chapter, except for PC_COMM.C and PC_MISC.C.
EXAMPLE1.C polls Elo SmartSet touchscreen controllers. The controller ID, jumper settings, and power on diagnostics results are displayed, as shown in Figure 5-4 below. Raw touch coordinates are then displayed, along with the status flag, indicating initial touch, stream touches, and untouch.
Figure 5-4. EXAMPLE1.C Output
In the following source code, initcontroller(), defined in SERIAL.C or BUS.C, detects and initializes the controller. An error condition aborts the program with a message describing the problem. The querycommand(), checkdiags(), and gettouch() functions are defined in PACKET.C. Source code for these modules is included later in this chapter. Refer to the Command Reference in Chapter 6 for the structure of the Owner, ID, Jumpers, and Diag packets used in displayjumpers().
EXAMPLE2.C also polls Elo SmartSet touchscreen controllers. The controller is first set up for calibration by changing the Mode to report raw coordinates. The calibration screen appears as follows:
Figure 5-5. EXAMPLE2.C Calibration Screen
A three-point calibration sequence is used. The touch points are taken near the corners of the screen image, then extrapolated to the actual edges of the image. This reduces the effects on calibration of "pin cushion" and other non-linearities at the edges of the image. The calibration sequence causes the origin to be in the upper-left, regardless of the orientation of the touchscreen. Untouch coordinates are used in the calibration, so the user can carefully position their finger before release.
The program then displays the results of the calibration, important information if troubleshooting is necessary:
Figure 5-6. EXAMPLE2.C Calibration Results Output
Next, the controller is programmed for 80x25 Scaling and the Mode is set to Calibration, Scaling, Trim, and Stream. The point of touch can now be mapped to the display, as in this example:
Figure 5-7. EXAMPLE2.C Finger Painting
In the following source code, the Mode, Calibration, and Scaling commands are queried, modified, then set. This preserves the contents of reserved bytes. Refer to the Command Reference in Chapter 6 for details on each command.
![]()
PACKET.C - Interface-Independent Driver Code
The following code implements high-level functions querycommand() and setcommand(). The protocol for querying commands, setting commands, and receiving acknowledgements is described in this chapter. Touch packets are sent automatically (a query is not necessary). The gettouch() function accepts these packets, and returns the coordinates and status byte. Click here for the structure of the Touch packet.
Functions getpacket() and sendpacket() are implemented in SERIAL.C or BUS.C.
SERIAL.C - Machine-Independent Serial Driver Code
The following machine-independent code implements the getpacket() and sendpacket() functions for the E271-2210 and 2500S serial controllers. Machine-dependent code to initialize the serial port, enable and disable it, and send and receive characters, is supplied in a separate module, such as PC_COMM.C (found on the SmartSet Companion Disk).
The getpacket() function discards all packets until the requested packet is received. The getanypacketserial() function synchronizes with the packets in the data stream by looking for a 'U' Lead-in byte and verifying the trailing Checksum byte. The sendpacket() function computes and transmits the trailing Checksum. See Serial Controllers for information on communicating with serial controllers.
BUS.C - PC-Bus Code
The following machine-dependent code implements the getpacket() and sendpacket() functions for the E271-2201 PC-Bus and E271-2202 Micro Channel controllers. The Micro Channel controller is obsolete.
The getpacket() function discards all packets until the requested packet is received. The getanypacketbus() function polls the Not Ready bit and reads the eight I/O ports. The sendpacket() function writes to the I/O ports. See Bus Controllers for information on communicating with bus controllers.
The E271-2202 is located by checking the POS registers for the ID of the "adapter" in each slot. Once the E271-2202 is located, the Base I/O Port (and optionally the Interrupt) can be read. This auto-detect procedure can only be run after a hard system reset, a soft reset (Control-Alt-Delete), or after sending a Quiet-all command to the E271-2202. Therefore, call disablecontroller() when you are finished with the controller so others may locate and use it. For more information on the interrupt 15h BIOS calls used in this code, see the IBM Personal System/2 and Personal Computer BIOS Interface Technical Reference.
Interrupt-Driven Code
Interrupt-driven code is hardware and operating system dependent, and is therefore beyond the scope of this manual. To simplify the code required, you may use the polled code in the previous examples to locate and set up the controller, then operate with one-way communication only. The interrupt service routine then only has to accept Touch packets.
For more information on bus controller interrupts see Interrupt Mode.