/*
 * usbio24 - Test of 'USB I/O 24' from ravar.net with Linux.
 * Copyright © by Hans Schou 2004.
 * License: BSD
 *
 * The device tested is:
 *   USB I/O 24 II
 *   Version 1 18/06/03
 *
 * Chips on device:
 *   FTDI FT245BM
 *   UBICOM SX52BD/PQ
 * 
 * For further reading:
 * http://www.elexol.com/
 * http://en.tldp.org/HOWTO/Serial-Programming-HOWTO/
 * http://www.ravar.net/
 * http://www.gigatechnology.com/
 */

/*
Example of output:

$ ./usbio24a /dev/usb/tts/0
Trying to open device: /dev/usb/tts/0
Device '/dev/usb/tts/0' open with handle '3'.
Waiting for responce from device.
ID of device is: USB I/O 24 0x0d 0x0a
Set port A for input and B and C for output. Turn on mode '2'.
Write 0x55 to port B.
Write 0x01 to port C.
Waiting. Reading input buffer.
Input: a 0x81
Restore termios and close.

*/

#include <ctype.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <termios.h>

void printbuf(char *buf, int count)
{
	int i = 0;

	while (i<count) {
		if (isprint(buf[i])) {
			printf("%c", buf[i]);
		} else {
			printf(" 0x%02x", buf[i] & 0xFF);
		}
		i++;
	}
}

int main(int argc, char **argv)
{
	char buffer[64];
	struct termios term, term_orig;
	int fd;
	int num;

	if (argc < 2) {
		printf("Usage:\n");
		printf("\t%s <device>\n", argv[0]);
		printf("Example:\n");
		printf("\t%s /dev/usb/tts/0\n", argv[0]);
		return 1;
	}

	printf("Trying to open device: %s\n", argv[1]);
	if ((fd = open(argv[1], O_RDWR | O_NOCTTY )) > 0) {
		printf("Device '%s' open with handle '%d'.\n", argv[1], fd);

		/* Delay for open device. It take some time. */
		sleep(1);

		/* Setup: Do not act on ISIG (Ctrl-C), don't convert CR/NL and so on. */
		ioctl(fd, TCGETS, &term);
		term_orig = term;
		term.c_lflag &= ~( ICANON | ISIG | ECHO );
		term.c_iflag &= ~( ICRNL );
		term.c_oflag &= ~( ONLCR );
		ioctl(fd, TCSETS, &term);

		/* Identify device */
		if (write(fd, "?", 1)) {
			printf("Waiting for responce from device.\n");
			num = read(fd, &buffer, sizeof(buffer));
			if (num) {
				printf("ID of device is: ");
				printbuf((char *)&buffer, num);
				printf("\n");
			}
		}

		printf("Set port A for input and B and C for output. Turn on mode '2'.\n");
		write(fd, ("!A\xFF!B\x00!C\x00" "2"), 3+3+3+1);
		printf("Write 0x55 to port B.\n");
		write(fd, "B\x55", 2);
		printf("Write 0x01 to port C.\n");
		write(fd, "C\x01", 2);

		printf("Waiting. Reading input buffer.\n");
		num = read(fd, &buffer, sizeof(buffer)-1);
		if (num) {
			printf("Input: ");
			printbuf((char *)&buffer, num);
			printf("\n");
		}
			
		printf("Restore termios and close.\n");
		ioctl(fd, TCSETS, &term_orig);
		close(fd);
	}

	return 0;
}

