/* Example of DIO with software.

   Author: Winson Chen
*/

/* File level history (record changes for this file here.)

   This example for test DIO software mode.

   v 0.0.0 26 Mar 2025 by Winson Chen
     create */

#include "pcidio.h"

#define DIO_S0 0x04
#define PortA 0
#define PortB 1

int main()
{
  int fd, ret;
  char *dev_file;
  WORD status, direction, DOvalue, DIvalue;

  dev_file = "/dev/ixpci1";

  /* open device file */
  fd = PCIDA_Open(dev_file);

  if (fd < 0){
    printf("Can't open device\n");
    return FAILURE;
  }

  /* init device */
  if (PCIDA_DriverInit(fd)) return FAILURE;

  PCIFC16_GetJumpStatus(fd, &status);
  printf("Jumper status is %d\n\n",status);

  printf("                DIO Port Configuration\n");
  printf("Jumper S0 S1 S2 JP1-S0 Port A Port B\n0x0    0  x  x  SW     x      x\n0x4    1  0  0  HW     DI     DI\n0x5    1  0  1  HW     DI     DO\n0x6    1  1  0  HW     DO     DI\n0x7    1  1  1  HW     DO     DO\n");

  if ((status & DIO_S0) != 0){
    puts("The jumper DIO-S0 isn't the software programmable mode.");
    PCIDA_Close(fd);
    return FAILURE;
  }

  //Bit   1   0    0 for DI, 1 for DO
  //-------------
  //Data  PB  PA

  direction = 2;  //set PB = DO, PA = DI
  ret = PCIFC16_SetPortsConfig(fd, direction);
  if (ret){
    printf("Error numbur %d\n",ret);
    PCIDA_Close(fd);
    return FAILURE;
  }

  switch (direction){
    case 0:
      printf("set PortA DI, PortB DI\n");
      break;
    case 1:
      printf("set PortA DO, PortB DI\n");
      break;
    case 2:
      printf("set PortA DI, PortB DO\n");
      break;
    case 3:
      printf("set PortA DO, PortB DO\n");
      break;
  }

  DOvalue = 1;

  puts("ESC and Enter to go out. Enter to continue.");
  while (getchar() != 27){
    PCIFC16_WriteDO(fd, PortB, DOvalue);
    printf("DO = 0x%04x\t", DOvalue);

    PCIFC16_ReadDI(fd, PortA, &DIvalue);
    printf("DI = 0x%04x\n", DIvalue);

    DOvalue == 0x8000 ? DOvalue = 1 : (DOvalue <<= 1);
  }

  /* close device */
  PCIDA_Close(fd);
  puts("End of program");
  return SUCCESS;
}

