#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "dask.h"
#include "conio.h"


void wait_pulse_start(void);

time_t time1,time2;
I16 card=-1;
char status[100];

int main(void)
{
  char func=0x00;
  U32 value;
  U16 under_flow;
  U32 old_value, new_value;
  float pulse_width, frequency;
  double period;

  setbuf( stdout, NULL );
  if ((card=Register_Card(PCI_8554, 0)) < 0) {
     printf("Register_Card Error = %d\n", card);
     exit(-1);
  }

  status[0]=0x00;
  do{
   clrscr();

   if( status[0] != 0x00 ){
     printf("\n\n");
     printf( status );
     printf("\n\n\n\n\n\n\n");
   }

   printf(" Please select the function for PCI8554 or Esc for quit:\n  (0) Square Wave\n  (1) Pluse Generator\n  (2) Measure Pulse Width\n  (3) Measure Frequency\n");

   func = getch();
   switch (func) {
     case 0x30:  //Square Wave
       CTR_8554_CK1_Config(card, CK1_C8M);
       CTR_8554_ClkSrc_Config(card, 1, CK1);
       CTR_8554_ClkSrc_Config(card, 2, CK1);
       CTR_8554_ClkSrc_Config(card, 3, CK1);
       CTR_8554_ClkSrc_Config(card, 4, CK1);
       CTR_8554_ClkSrc_Config(card, 5, CK1);
       CTR_8554_ClkSrc_Config(card, 6, CK1);
       CTR_8554_ClkSrc_Config(card, 7, CK1);
       CTR_8554_ClkSrc_Config(card, 8, CK1);
       CTR_8554_ClkSrc_Config(card, 9, CK1);
       CTR_8554_ClkSrc_Config(card, 10, CK1);
       CTR_Setup(card, 1, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 2, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 3, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 4, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 5, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 6, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 7, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 8, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 9, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       CTR_Setup(card, 10, SQ_WAVE_RATE_GENERATOR, 32, BIN);
       sprintf( status, "*** 250 KHz square wave is ready on the COUT1 ~ 11 ***\n");
       break;
     case 0x31:  //Pluse Generator
       CTR_8554_CK1_Config(card, CK1_C8M);
       CTR_8554_ClkSrc_Config(card, 1, CK1);
       CTR_8554_ClkSrc_Config(card, 2, COUTN_1);
       CTR_8554_ClkSrc_Config(card, 3, COUTN_1);
       CTR_Setup(card, 1, SQ_WAVE_RATE_GENERATOR, 200, BIN);
       CTR_Setup(card, 2, SQ_WAVE_RATE_GENERATOR, 200, BIN);
       CTR_Setup(card, 3, SQ_WAVE_RATE_GENERATOR, 200, BIN);
       sprintf( status, " *** A pulse per second is ready on the COUT3 ***\n");
       break;
     case 0x32:  //Measure Pulse Width
       CTR_8554_CK1_Config(card, CK1_C8M);
       CTR_8554_ClkSrc_Config(card, 1, CK1);
       CTR_Setup(card, 1, RATE_GENERATOR, 0, BIN);
       under_flow = 0;
       wait_pulse_start();
       time(&time1);
       CTR_Read(card, 1, &old_value);
       while (1) {
          CTR_Read(card, 1, &new_value);
          time(&time2);
          period = difftime(time2,time1);
          if ((new_value == old_value)||(period > 5)) break;
          if ( old_value < new_value ) under_flow++;
          old_value=new_value;
       }
       if (period < 5) {
           pulse_width = (65536 - new_value + under_flow * 65536 + 1) * 0.125;
           sprintf( status, "*** High level pulse width = %f micro-second ***\n", pulse_width);
       }
       else
           sprintf( status, "*** Measure inappropriate pulse width ***\n");
       break;
     case 0x33:  //Measure Frequency
       CTR_8554_ClkSrc_Config(card, 1, ECKN);
       CTR_8554_CK1_Config(card, CK1_C8M);
       CTR_8554_ClkSrc_Config(card, 2, CK1);
       CTR_8554_ClkSrc_Config(card, 3, COUTN_1);
       CTR_Setup(card, 1, RATE_GENERATOR, 65535, 0);
       CTR_Setup(card, 2, RATE_GENERATOR, 4, 0);
       CTR_Setup(card, 3, TOGGLE_OUTPUT, 65535, 0);
       usleep(1000000); // one second
       CTR_Read(card, 1, &value);
       period = 65535 - (value&0xffff);
       frequency = period * 2000000 / 65535; // 2000000 is generated by Counter2
       sprintf( status, "Measured Signal Frequency = %f Hz.\n",frequency);
       break;
       // in 65535/2000000 secs , counter "period" time ..., so the frequency = period / ( 65535/2000000)
     default:
       sprintf( status, " Unknown choice , please select again \n" );
       break;
   }

 }while( func != 0x1b );
   if (card>=0) Release_Card(card);
   return 0;
}

void wait_pulse_start(void)
{
  U32 oldvalue,newvalue;

  do
  {
     CTR_Read( card, 1, &oldvalue );
     CTR_Read( card, 1, &newvalue );
  } while( newvalue != oldvalue );
  do
  {
     CTR_Read( card, 1, &oldvalue );
     CTR_Read( card, 1, &newvalue );
  } while( newvalue == oldvalue );
}


