#include "stdio.h"     
#include "unistd.h"    
#include "sys/ioctl.h"
#include "fcntl.h"     
#include "time.h"     
#include "asm/etraxgpio.h"

#define LINE_0  1<<0
#define LINE_1  1<<1
#define LINE_2  1<<2
#define LINE_3  1<<3
#define LINE_4  1<<4
#define LINE_5  1<<5
#define LINE_6  1<<6
#define LINE_7  1<<7
#define LINE_8  1<<8
#define LINE_9  1<<9
#define LINE_10 1<<10
#define LINE_11 1<<11
#define LINE_12 1<<12
#define LINE_13 1<<13
#define LINE_14 1<<14
#define LINE_15 1<<15
#define LINE_16 1<<16
#define LINE_17 1<<17
#define LINE_18 1<<18
#define LINE_19 1<<19
#define LINE_20 1<<20
#define LINE_21 1<<21
#define LINE_22 1<<22
#define LINE_23 1<<23
#define LINE_24 1<<24
#define LINE_25 1<<25
#define LINE_26 1<<26
#define LINE_27 1<<27
#define LINE_28 1<<28
#define LINE_29 1<<29

#ifndef IO_SETGET_INPUT
#define IO_SETGET_INPUT   0x12
#endif

#ifndef IO_SETGET_OUTPUT
#define IO_SETGET_OUTPUT  0x13
#endif

int main(void) {
  int fda;
  int fdb;
  int fdg;
  int iomask_a;
  int iomask_b;
  int iomask_g;
  int i;
  
  if ((fda = open("/dev/gpioa", O_RDWR))<0) {
    printf("Open error on /dev/gpioa\n");
    return 1;
  }

  if ((fdb = open("/dev/gpiob", O_RDWR))<0) {
    printf("Open error on /dev/gpiob\n");
    return 1;
  }

  if ((fdg = open("/dev/gpiog", O_RDWR))<0) {
    printf("Open error on /dev/gpiog\n");
    return 1;
  }

  // Set all the availables PA lines as output
  iomask_a = LINE_0;
  ioctl(fda, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT),&iomask_a);

  // Set all the availables PB lines as output
  iomask_b = LINE_4 | LINE_6 | LINE_7;
  ioctl(fdb, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT),&iomask_b);

  // Set all the availables IOG lines on port G as output
  iomask_g = LINE_8 | LINE_9 | LINE_10 | LINE_11 | LINE_12 | LINE_13 | LINE_14 | LINE_15 | LINE_16 | LINE_17 | LINE_18 | LINE_19 | LINE_20 | LINE_21 | LINE_22 | LINE_23 | LINE_24;
  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT),&iomask_g);

  // Add the fixed out OG lines
  iomask_g |= ( LINE_1 | LINE_2 | LINE_3 | LINE_4 | LINE_5 | LINE_25 | LINE_28 | LINE_29 );

  for (i=0;i<30;i++) {
    // Set all the output line to 3.3v
    printf("On\n");
    ioctl(fda, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),iomask_a);
    ioctl(fdb, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),iomask_b);
    ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),iomask_g);

    sleep(1);

    // Set all the output line to 0v
    printf("Off\n");
    ioctl(fda, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),iomask_a);
    ioctl(fdb, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),iomask_b);
    ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),iomask_g);

    sleep(1);
    printf("\n");
  }  
  
  close(fda);
  close(fdb);
  close(fdg);

  return 0;
}
