A simple parallel device example | Kickoff

A simple parallel device example

9 May

A simple parallel device example: Let’s build a simple parallel communication example, connect it to TINI and write some Java code to talk to it (both inputs and outputs). You can follow the parallel schematics presented previously (like what’s on the E10 and E20 socketboards) or you can implement this on a prototype board with a few simplifications. A simplified address decoder is shown in Figure 9-26. This is used to select the inputs and outputs and place them in the TINI memory map at 0×0800000 (0×0800000-0×0800003, actually).

We are only working with one set of input buffers for this example (although you can implement as many as you like and connect them to different addresses on the address decoder). We are using a 74VHC541 octal line driver for these inputs. This is enabled by both the chip select and the TINI /RD line as we are putting these inputs and the outputs at the same location in memory.

For the output latches we will use a 74VHC574 octal d-type flip-flop to hold the state on the output lines after we have written to them. For both the inputs and the outputs we will use pull-ups on all of the input and output lines, but you can just as easily change these to pull-downs as needed by your application (just change it on the resistor networks to ground).

What you connect to the input and output is up to you. You can read the position of switches for inputs and can control LEDs for some simple output. See Appendix C for examples of general-purpose circuits. In the case of this example, we will be connecting the output latches directly to the input buffers so we can easily see what’s working and what’s not. It’s not the most exciting example but it shows that the hardware and DataPorts are working.

Figure 9-28: Output latches
Listing 9-5: ParallelIO.java

import com.dalsemi.system.*;
public class ParallelIO {
public static void main(String[] args)
int d=0;
byte b=0;
// Configure the dataport
DataPort pio = new DataPort( 0×00800000 );
pio.setStretchCycles(DataPort.STRETCH2);
pio.setFIFOMode(false);
if (args.length>=1) {
// Get the command line integer
d=Integer.decode(args[0]).intValue();
b=(byte)d;
// tell me whats going on
System.out.println( “Write “ + ByteUtils.toBinaryString(b)
+ “ 0x” + ByteUtils.toHexString(b) );
// write the bit pattern to the output port
try {
pio.write( d );
}
catch( Exception e) {
System.out.println( “error in read” );
}
}
// read the bit pattern on the input port
try {
d=pio.read( );
b=(byte)d;
System.out.println( “Read                   “ + ByteUtils.toBinaryString(b)
+ “ 0x” + ByteUtils.toHexString(b) );
}
catch( Exception e) {
System.out.println( “error in read” );
}
}
}

This program is very simple and straightforward. Notice that we are doing simple single-byte reads and writes. The methods for printing bytes in hex and binary are included in the ByteUtils class (in appendix B).

Compile this program, and convert it to a .tini file

C:\> javac -bootclasspath                                                            %TINI_HOME%\bin\tiniclasses.jar
-d bin src\ParallelIO.java
C:\> java                                                                            -classpath c:\opt\tini1.02d\bin\tini.jar;. BuildDependency
-p                                                                                   %TINI_HOME%\bin\owapi_dependencies_TINI.jar
-f bin
-x                                                                                   %TINI_HOME%\bin\owapi_dep.txt
-o bin\ParallelIO.tini
-d %TINI_HOME%\bin\tini.db

Then FTP the .tini file to your TINI. When you run this program with no command line parameters it will read the value input buffers. You can optionally specify a single value on the command line (decimal or hex) that will be written to the output latches before the program reads from the inputs. Here is an example of the output from this program:

TINI /> java ParallelIO.tini 0×55
Write 01010101 0×55
Read                                                                                   01010101 0×55
TINI /> java ParallelIO.tini
Read                                                                                   01010101 0×55
TINI /> java ParallelIO.tini 0xAA
Write 10101010 0xAA
Read                                                                                   10101010 0xAA
TINI /> java ParallelIO.tini
Read                                                                                   10101010 0xAA
TINI /> java ParallelIO.tini 0xFF
Write 11111111 0xFF

Read                                                                                   11111111 0xFF
TINI /> java ParallelIO.tini
Read                  11111111 0xFF
TINI /> java ParallelIO.tini 0×00
Write 00000000 0×00
Read                  00000000 0×00

Notice that whatever value is written to the outputs is read on the inputs. If no value is written to the outputs, then the previous value is still read (that’s what the output latches do). While this is a very simple circuit and program, there are many applica- tions for simple parallel I/O lines control. These outputs could be connected to LEDs to indicate status or to relays to control appliances. The inputs could be connected to optical-isolators so you can sense switch positions or detect voltages. There are lots of possibilities.

Another example
In the previous example we read and wrote single bytes from and to the parallel I/O lines. This works well for simple device control but is somewhat slow if you are using the parallel lines for data communication with some external device. Where data speed is more important, we would want to use array reads and writes. You would also want to place the address decoder for these parallel I/O lines in the CE memory space (somewhere in /CE3, probably, but not overlapping the Ethernet controller or the real-time clock) because accesses to CE devices are faster than accesses to PCE devices. PCE device access is slower because the CPU is copying data from CE memory space (internal memory) to PCE space. The following pro- gram illustrates the differences in reading from CE space and PCE space. We are not reading any particular data, just demonstrating the differences in the speeds of array reads.

Listing 9-6: pspeed.java
import com.dalsemi.system.*;
public class pspeed {
public static void testPortBlock(int port)                                                 {
int d=0;
DataPort pio = new DataPort( port );
pio.setStretchCycles(DataPort.STRETCH0);
pio.setFIFOMode(false);
int     bytes=65100;
long   start=0, stop=0;
float time;
byte[] data = new byte[bytes];

try {
System.out.println( “Testing 0x” + Integer.toHexString(port) );
start = System.currentTimeMillis();
d=pio.read(data,0,bytes );
stop = System.currentTimeMillis();
time = ((float)(stop-start));
System.out.println( bytes + “ bytes in “ + time/1000 + “ seconds or “
+ bytes/time*1000 + “ Bytes/Sec” );
}
catch( Exception e) {
System.out.println( “error in read” );
}
}
public static void testPortSequence(int port)                           {
int d=0;
DataPort pio = new DataPort( port );
pio.setStretchCycles(DataPort.STRETCH0);
pio.setFIFOMode(false);
int     bytes=4096;
long   start=0, stop=0;
float time;
try {
System.out.println( “Testing 0x” + Integer.toHexString(port) );
start = System.currentTimeMillis();
for(int i=0; i<=bytes; i++) {
d=pio.read();
}
stop = System.currentTimeMillis();
time = ((float)(stop-start));
System.out.println( bytes + “ bytes in “ + time/1000 + “ seconds or “
+ bytes/time*1000 + “ Bytes/Sec” );
}
catch( Exception e) {
System.out.println( “error in read” );
}
}
public static void main(String[] args)                                  {
System.out.println( “DataPort Speed Test” );
System.out.println( “Block reads” );
System.out.println( “—————” );
testPortBlock( 0×00300000 );
testPortBlock( 0×00800000 );
System.out.println( “Sequential reads” );
System.out.println( “————————” );
testPortSequence( 0×00300000 );
testPortSequence( 0×00800000 );
}
}

This class declares two methods: testPortBlock(int port) reads a single large block of data from a specified address, and testPortSequence(int port) reads single bytes from a specified address. We will invoke each of these methods on a chunk of memory in both CE and PCE space. Since we are simply measuring the read speed, it doesn’t really matter what the exact section of memory is or if there is a real hardware device mapped to that section of memory or not.

Compile this program:
C:\> javac -bootclasspath                                                                   %TINI_HOME%\bin\tiniclasses.jar
-d bin src\pspeed.java
C:\> java                                                                                   -classpath c:\opt\tini1.02d\bin\tini.jar;. BuildDependency
-p                                                                                          %TINI_HOME%\bin\owapi_dependencies_TINI.jar
-f bin
-x                                                                                          %TINI_HOME%\bin\owapi_dep.txt
-o bin\pspeed.tini
-d %TINI_HOME%\bin\tini.db

FTP the .tini file to your TINI and run it. The output of this is:

TINI /> java pspeed.tini
DataPort Speed Test
Block reads

—————-
Testing 0×300000
65100 bytes in 0.1099999994 seconds or 591818.18 Bytes/Sec
Testing 0×800000
65100 bytes in 0.400000005 seconds or 162750.0 Bytes/Sec
Sequential reads

Testing 0×300000
4096 bytes in 5.4699997 seconds or 748.8117 Bytes/Sec
Testing 0×800000
4096 bytes in 5.4499998 seconds or 751.55963 Bytes/Sec

Notice that accessing memory by block reads is about three times faster from CE space than from PCE space and that reading blocks of data rather than single bytes is 200-800 times faster. If you are simply controlling the parallel I/O lines for occasion- ally sensing a status change or turning a device on or off then it doesn’t matter much. But if you are interfacing a device that sends a large amount of data, like an analog- to-digital converter, then the speed of using block reads is essential.

Other ways of handling parallel I/O
We have shown here how to implement memory-mapped parallel I/O drivers. In Chapter 11 we discuss the I2C capability of TINI and there we implement I2C devices that are capable of adding 8-bit and 16-bit parallel I/O lines.

Summary
In this chapter we have discussed the details of TINI serial ports and parallel I/O. These two interfaces will enable you to connect many devices to your TINI for control and automation tasks.

References
1.  Interfacing the standard parallel port, Craig Peacock,

http://www.beyondlogic.org/spp/parallel.htm

2.  Interfacing the standard serial port, Craig Peacock,
http://www.beyondlogic.org/serial/serial.htm (part 1 & 2)
http://www.beyondlogic.org/serial/serial1.htm                                          (part 3 & 4)
3.  Serial HOWTO, v2.15 November 2001, David S.Lawyer,

http://www.ibiblio.org/mdw/HOWTO/Serial-HOWTO.html

4.  ePanorama – WiringRS-232 to RJ-45 connector,

http://www.epanorama.net/documents/lan/rs232_rj45.html

5.  ePanorama – Common RS-232 cable wirings,

http://www.epanorama.net/documents/pc/rs232cables.html

6.  Fairchild datasheets,

http://www.fairchildsemi.com/

〱┰

敨瑥se�倍

Random Posts

Comments are closed.