/*
 * A simple LED control for R2D-PLUS
 * (mutiple device files support)
 */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>

#ifndef MAXNAMELEN
#define MAXNAMELEN         256
#endif

int main(int argc, char *argv[])
{
    int fd, shift, i;
    unsigned short s, prev_s = 0U;
    struct timespec req;
    char devname[MAXNAMELEN];

    if (argc != 3) goto invalargs;

    /* create an appropriate device file name */
    shift = atoi(argv[1]);
    if ((shift < 0) || (shift > 7)) goto invalargs;
    sprintf(devname, "/dev/ledctrl%d", shift);

    /* set up a timer */
    req.tv_sec = 0;
    req.tv_nsec = atoi(argv[2]) * 1000 * 1000;
    if ((req.tv_nsec < 0L) || (req.tv_nsec > 999999999L)) goto invalargs;

    /* open the device file */
    if ((fd = open(devname, O_RDWR)) < 0) {
	perror("device open");
	return -1;
    }

    for (i=0; i<0x100; i++) {
	/* read the current state of specified LED */
	if (read(fd, &s, sizeof(s)) != sizeof(s)) {
	    perror("device read");
	    close(fd);
	    return -1;
	}

	/* check the status */
	if (prev_s != s)
	    printf("LED%d: %03d: MISMATCH!! (%08x != %08x)\n", 
		   shift, i, prev_s, s);

	/* reverse the value */
	s = s ? 0 : 1;

	/* update the LED */
	if (write(fd, &s, sizeof(s)) != sizeof(s)) {
	    perror("device write");
	    close(fd);
	    return -1;
	}
	
	/* save the current state */
	prev_s = s;

	/* sleep for a while */
	nanosleep(&req, NULL);
    }

    close(fd);

    return 0;

  invalargs:
    fprintf(stderr, "invalid argument\n");
    fprintf(stderr, "Usage: %s LED_NO INTERVAL(ms) \n", argv[0]);
    return -1;
}
	
