// ./pts -a 0x1000000 -v 1 -w 2 turn LED ON
 
// ./pts -a 0x1000000 -v 1 -w 1 turn LED OFF
 
#include <stdlib.h>
 
#include <stdio.h>
 
#include <stdint.h>
 
#include <ctype.h>
 
#include <unistd.h>
 
#include <string.h>
 
#include "PtsModule.h"
 
#include <getopt.h>
 
 
 
void Delay(double t){
 
usleep(t*1e6);
 
}
 
 
 
 
 
uint32_t ptaddr=0;
 
 
 
int Pts_write(uint32_t addr, uint32_t data ){
 
VME_A32D32_W(ptaddr+addr,&data);
 
return 0;
 
}
 
 
 
int Pts_read(uint32_t addr, uint32_t *data ){
 
VME_A32D32_R(ptaddr+addr,data);
 
return 0;
 
}
 
 
 
 
 
int Pts_erase( int verbose ) {
 
  uint32_t dum;
 
  Pts_write( ADR_CSR1, 0 );
 
  Delay(0.1);
 
  Pts_read( ADR_CSR1, &dum);
 
  if( verbose 
) printf( "CSR1(0x%02x) = 0x%04x\n", ADR_CSR1
,  
                        dum & 0xffff );
 
  Pts_write( ADR_CSR1, CSR1_PROGRAM_ );
 
  Delay(0.1);
 
  Pts_read( ADR_CSR1, &dum);
 
  if( verbose 
) printf( "CSR1(0x%02x) = 0x%04x\n", ADR_CSR1
,  
                        dum & 0xffff );
 
  return 1;
 
}
 
/*
 
int Pts_configure( const char *filename, int mode, int verbose ) {
 
  int len = strlen( filename );
 
  if( len > 4 ) {
 
    const char *p = filename+len-4;
 
    if( strcmp(p,".bit")==0 ) return Pts_configure_bit( filename, mode, verbose );
 
    if( strcmp(p,".rbt")==0 ) return Pts_configure_rbt( filename, mode, verbose );
 
  }
 
  if( verbose ) fprintf( stderr, "Bad filename: \"%s\" .\n" );
 
  return -1;
 
}
 
 
 
int PtsModule::configure_rbt( const char *filename, int mode, int verbose ) {
 
  long n, pos;
 
  char cs[1024];
 
  FILE *fp;
 
  if( ( fp = fopen( filename, "r" ) ) == NULL ) {
 
    if( verbose ) fprintf( stderr, "cannot open \"%s\"\n", filename );
 
    return -1;
 
  }
 
  if( verbose ) printf( "file \"%s\" opened.\n", filename );
 
  
 
  do{
 
    pos = ftell(fp);
 
    fgets( cs, sizeof(cs), fp );
 
    puts(cs);
 
    n=strlen(cs);
 
  } while( n==0 || strspn( cs, " \t\n01" )!=n );
 
  fseek( fp, pos, SEEK_SET );
 
 
 
  long nchar = 0;
 
  if( mode == SLAVESERIAL_MODE ) {
 
    write( ADR_MODE, SLAVESERIAL_MODE );
 
    erase( verbose );
 
    int c;
 
    const long bit_per_dot = BYTE_PER_DOT*8;
 
    while( (c=getc(fp))!=EOF ){
 
      if( c=='0' || c=='1' ) {
 
        write( ADR_CFG, c=='0' ? 0 : 1 );
 
        nchar++;
 
        if( verbose && ++nchar%bit_per_dot==0 ) putchar('.');
 
      }
 
      else if( isspace(c) ) continue;
 
      else {
 
        fprintf( stderr, "(%ld) illegal character : %c\n", nchar, c );
 
        fclose(fp);
 
        return -1;
 
      }
 
    }
 
  } else if(mode == SELECTMAP_MODE) {
 
    if(verbose) fprintf(stderr, "\nselectmap mode (rbt file) not supported\n");
 
    return -1;
 
  } else {
 
    if(verbose) fprintf(stderr, "\nIllegal mode\n");
 
    return -1;
 
  }
 
  if(verbose) printf("\ntotal %ld bits\n", nchar);
 
  fclose(fp);
 
  return check_configure( verbose );
 
}
 
*/
 
int Pts_configure_bit( const char *filename, int mode, int verbose ) {
 
  int c,j;
 
  int dummyword;
 
  FILE *fp;
 
  const long byte_per_dot = BYTE_PER_DOT;
 
  unsigned long nchar = 0;
 
 
 
  if( ( fp 
= fopen( filename
, "rb" ) ) == NULL 
) {  
    if( verbose 
) fprintf( stderr
, "cannot open \"%s\"\n", filename 
);  
    return -1;
 
  }
 
  if(verbose
) printf( "file \"%s\" opened.\n", filename 
);  
 
 
  /* ------------------------------------------------------------ *\
 
    The data for the configuration start from 0xffff_ffff_aa99_aa66
 
    ( cf. xapp138; we don't know the definition of the BIT file )
 
  \* ------------------------------------------------------------ */
 
  dummyword = 0;
 
  do{
 
    if( (c 
= getc( fp 
)) == EOF 
) {  
      if(verbose
) fprintf(stderr
, "EOF detected. Exit.\n");  
      return -1;
 
    }
 
    (c == 0xff) ? dummyword++ : (dummyword=0);
 
  } while( dummyword < 4 );
 
 
 
//  const long byte_per_dot = BYTE_PER_DOT;
 
//  unsigned long nchar = 0;
 
  if( mode == SLAVESERIAL_MODE ) {
 
    if(verbose
) puts("slave serial mode");  
    Pts_write( ADR_MODE, mode );
 
    Pts_erase( verbose );
 
    for( j=0; j<32; j++ ) Pts_write( ADR_CFG, 0x1 );
 
    while( (c
=getc(fp
))!=EOF 
){  
      for( j=0; j<8; j++ ) Pts_write( ADR_CFG, (c>>(7-j))&0x1 );
 
      nchar++;
 
      if( verbose 
&& nchar
%byte_per_dot
==0 ) putchar('.');  
    }
 
  } else if( mode == SELECTMAP_MODE ) {
 
    if( verbose 
) puts("select map mode");  
    Pts_write( ADR_MODE, SELECTMAP_MODE );
 
    Pts_erase( verbose );
 
    for( j=0; j<4; j++ ) Pts_write( ADR_CFG, 0xff );
 
    while( (c
=getc(fp
))!=EOF 
){  
      int cc = 0;
 
      for(j=0; j<8; j++) cc |= ((c&(1<<j))>>j)<<(7-j);
 
      Pts_write( ADR_CFG, cc );
 
      nchar++;
 
      if( verbose 
&& nchar
%byte_per_dot
==0 ) putchar('.');  
    }
 
  } else {
 
    if(verbose
) fprintf(stderr
, "\nIllegal mode\n");  
    return -1;
 
  }
 
  if(verbose
) printf("\ntotal %ld bits\n", nchar
);  
  return Pts_check_configure( verbose );
 
}
 
 
 
int Pts_check_configure( int verbose ) {
 
  uint32_t csr1_value;
 
  Pts_read(ADR_CSR1,&csr1_value);
 
  if(verbose
) printf("CSR1(0x%02x)=0x%04x\n",ADR_CSR1
,csr1_value
&0xffff);  
  if(csr1_value&CSR1_DONE) {
 
    if(verbose
) puts("configure complete.");  
    return 1;
 
  } else {
 
    if(verbose
) puts("configure not complete.");  
    return -1;
 
  }
 
}
 
 
 
int Pts_reset( int verbose ) {
 
  Pts_write(ADR_CSR0,1);
 
  if( verbose 
) printf( "CSR0(0x%02x) = 0x01\n", ADR_CSR0 
);  
  return 1;
 
}
 
 
 
int Pts_write_csr( int verbose, uint32_t value ) {
 
  Pts_write(ADR_CSR0,value);
 
  if( verbose 
) printf( "Pts_write_csr 0x%08x\n", value  
);  
  return 1;
 
}
 
 
 
 
 
void help(char *argv){
 
 printf("Usage: %s -a <ptsaddr> -v <verbose> -c  .... Pts_check_configure\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -i <filename> -b mode (2) ... Pts_configure_bit\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -e  .... Pts_erase\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -x  .... Pts_reset\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -c  .... Pts_check_configure\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -r  .... vme read\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -w <value> .... vme write\n", argv
);  
 printf("Usage: %s -a <ptsaddr> -v <verbose> -s <value> .... Pts_write_csr\n", argv
);  
 printf("Example: %s  --address  0x1000000 --verbose 1 --erase\n", argv
);  
 printf("Example: %s --address  0x1000000 --verbose 1 --input pts_scaler.bit --load-bit 2\n", argv
);  
 printf("Example: %s --address  0x1000004 --write-csr 0x7600\n", argv
);  
}
 
 
 
 
 
 
 
static const char *optString = "v:rxea:cs:w:i:b:h";
 
static const struct option longOpts[] = {
 
    { "verbose", required_argument, NULL, 'v' },
 
    { "reset"  , no_argument, NULL, 'x' },
 
    { "erase"  , no_argument, NULL, 'e' },
 
    { "address", required_argument, NULL, 'a' },
 
    { "check-configure", no_argument, NULL, 'c' },
 
    { "write-csr", required_argument , NULL, 's' },
 
    { "input", required_argument , NULL, 'i' },
 
    { "load-bit", required_argument , NULL, 'b' },
 
    { "read", no_argument , NULL, 'r' },
 
    { "write",required_argument , NULL, 'w' },
 
    { "help", no_argument, NULL, 'h' },
 
    { NULL, no_argument, NULL, 0 }
 
};
 
 
 
int main (int argc, char ** argv){
 
 
 
uint32_t value;
 
 
 
 int verbose=0;
 
 char filename[256]="file.bit";
 
 int c;
 
 opterr = 0;
 
int longIndex = 0;
 
 
 
if (argc<2) {
 
  help(argv[0]);
 
}
 
 
 
VME_START(NULL);
 
 
 
c = getopt_long( argc, argv, optString, longOpts, &longIndex );
 
        while( c != -1 ) 
 
 
 
// while ((c = getopt (argc, argv, "v:xrea:csw:i:b:h")) != -1)
 
{
 
         switch (c)
 
           {
 
          case 'v':
 
            break; 
 
          case 'x':
 
            Pts_reset(verbose);
 
            break;             // reset
 
          case 'e':
 
            Pts_erase(verbose);
 
            break;             // erase
 
          case 'a':
 
            break;             // address
 
          case 'c':
 
            Pts_check_configure( verbose );
 
            break;
 
          case 'w':
 
            Pts_write( 0 , value );
 
            break;
 
          case 'r':
 
            value = 0;
 
            Pts_read( 0 , &value );
 
            break;
 
          case 's':
 
            Pts_write_csr( verbose, value );
 
            break;
 
          case 'i':
 
            break;             // data width
 
          case 'b':
 
//#define SELECTMAP_MODE 2
 
//#define SLAVESERIAL_MODE 3
 
             Pts_configure_bit( filename, value,  verbose );
 
             break;           
 
          case 'h':
 
            help(argv[0]);
 
            break;
 
           default:
 
             printf("Unknown command %c\n",c
);  
           }
 
    c = getopt_long( argc, argv, optString, longOpts, &longIndex );
 
}
 
VME_STOP();
 
}