This package contains a Linux device driver and utility programs for the Parker-Hannifin Compumotor AT6200/AT6400 bus-based step and direction controllers. These controllers are ISA-bus cards for controlling stepper motors. The cards run their own operating system, which must be downloaded by the host before they can do anything useful. DRIVER The "driver" subdirectory contains the source code for the at6n00 Linux device driver. It has been tested on 2.4.x kernels. It is not backwards compatible with 2.2.x kernels. It is designed to be used as a loadable module. Detailed installation and configuration instructions can be found in the file `INSTALL'. PROGRAMS This "programs" subdirectory contains the source code for two utility programs, "osload" and "terminal". "osload" is used to transfer the AT6400 operating system to the card with a command line such as $ osload AT6400.OPS /dev/at6n00 where "AT6400.OPS" is the name of the file containing the operating system and /dev/at6n00 is the device entry point for the card. Once the operating system is loaded, you can run the "terminal" program $ terminal /dev/at6n00 which provides an interactive session with the AT6400 card. EXAMPLES The device driver provides read, write, poll, fsync and fasync methods as well as a number of useful ioctls. Read and write can be configured as blocking or non-blocking, I/O can complete synchronously or asynchronously. Ex 1. Write a block of data to the device, and wait until it is completely transferred to the hardware. int fd; char buf[] = "MOVEABS"; fd = open("/dev/at6n00", O_RDWR); write(fd, buf, sizeof(buf)); fsync(fd); Ex 2. Wait up to five seconds for the device to become readable (to have data to be transferred to the host). Generate an error if it doesn't. fd_set rfds; char buf[64]; struct timeval timeout; int fd, rd; fd = open("/dev/at6n00", O_RDWR); FD_ZERO(&rfds); FD_SET(fd, &rfds); timeout.tv_sec = 5; timeout.tv_usec = 0; if(select(fd+1, &rfds, NULL, NULL, &timeout) > 0) { rd = read(fd, buf, sizeof(buf)); /* etc */ } else { fprintf(stderr, "didn't become readable\n"); exit(1); } Ex 3. Catch SIGIO when the device becomes readable. int rd, fd, flags, caught_it = 0; char buf[64]; void sigio(int signo) { caught_it = 1; } fd = open("/dev/at6n00", O_RDWR); signal(SIGIO, sigio); fcntl(fd, F_SETOWN, getpid()); flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | FASYNC); while(!caught_it) { /* do something useful */ } read(fd, buf, sizeof(buf)); Ex. 4. Use non-blocking reads to drain the input buffer. int fd, flags; char byte; fd = open("/dev/at6n00", O_RDWR); flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | O_NONBLOCK); while(read(fd, &byte, 1) > 0); /* read returns -EAGAIN when drained */ fcntl(fd, F_SETFL, flags); -- Chip Coldwell December, 2002