
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <time.h>
#include <string.h>

#include "firmremote.h"
#include "interfazio.h"
#include "JTAG.h"

using namespace std;

#ifdef NATINST
#include "VMEDevice.h"
#elif LINCO
#include "VMEDeviceLinco.h"
#elif DUMMY
#include "VMEDummy.h"
#endif

int main(int argc, char *argv[]) {

  int errnumbits=0;
  char stron[3000];
  unsigned short option,fpga;
  char comentario;
  char inst[10];
  int comp=-1;
  char cfilename[64];

int JTAG_Control=0x380+0xA;
int JTAG_Reg1 = 0x380+0xC;
int JTAG_TDI_Reg2=0x380+0xE;
int JTAG_TDO_Data=0x380+0x10;
int ROSVME_00=0x380;

 unsigned long out_tdo=0;
 unsigned long dr_data=0;

time_t tiempo_init,tiempo_end;
struct tm * pTiempo;

 try {
 
  FILE * filesvf;
/*
  if (argc>=2){
    sscanf(argv[1],"%s",cfilename);
  }else{
    strcpy(cfilename,"ceros_idcode.svf");
  };
  */
	cout<<endl<< " ************ Program Starts..." << endl<<endl;



	///*****************+++
	///   CREO EL BUS
	///*****************+++

#ifdef NATINST

cout<<endl<<"Creo el VMEDevice con las librerias de NATIONAL INSTRUMENTS++++++++++++++"<<endl;
cout<<"MADRID, ACCEDO a la unica ROS que hay, debe tener address 0x4000+++++++++"<<endl;

string inststr ("VXI0::257::INSTR");
VISAInstrVXI &instr = (VISAInstrVXI &) 
  VISAResourceManager::getInstrumentInstance(inststr);

InterfazIO *myInterfaz = (InterfazIO *) new VMEDevice(instr);

#elif LINCO 

cout<<endl<<"Creo el VMEDevice con las librerias de LINCO++++++++++++++"<<endl;
cout<<"CERN, tengo que elegir el crate y la direccion base+++++++++++++"<<endl;

 int sc_crate=0;
 int ROS=0;
int bus_image=7;
int memspace=0x400;
	int ROSBaseAddress = 0x1000; //change after
	int  ROSAddArray[13]={0,0x1000,0x2000,0x3000,0x4000,0x5000,0x6000,0x6000,0x5000,0x4000,0x3000,0x2000,0x1000};

 ROSBaseAddress=ROSAddArray[ROS];
int cc=0;
while(cc==0){
cout <<"Which ROS you want to address?  (Type Sectors from 1 to 12)"<<endl;
cin>>ROS;
cc=1;
if ((ROS<1)||(ROS>12)) {
cc=0;
cout<<endl<<"ERROR, WRONG ROS SELECTED!!!! TRY AGAIN"<<endl;
};//if

if (ROS>6){ //BOTTOM CRATE  sc_crate==0
 sc_crate=0;
 ROSBaseAddress=ROSAddArray[ROS];
 cout<<endl<<"You are accessing SECTOR: "<<ROS<<
	" BOTTOM CRATE, ROS Base Address 0x"<<hex<<ROSBaseAddress<<endl<<endl;
};
if (ROS<7){ //TOP CRATE  sc_crate==1
 sc_crate=1;
 ROSBaseAddress=ROSAddArray[ROS];
 cout<<endl<<"You are accessing SECTOR: "<<ROS<<
	" TOP CRATE, ROS Base Address 0x"<<hex<<ROSBaseAddress<<endl<<endl;
};
};//while

VMEBus *mybus;
mybus=new VMEBus(ROSBaseAddress,memspace,VME_ADDR16|VME_SIZE_D16,bus_image,sc_crate);

int VMEBaseAddress;
VMEBaseAddress=ROSBaseAddress;
InterfazIO *myInterfaz =
    (InterfazIO *) new VMEDeviceLinco(*mybus,VMEBaseAddress);

#elif DUMMY
InterfazIO *myInterfaz = (InterfazIO *) new VMEDummy;

#else

cout<<"(DEFINE NATINST, LINCO o DUMMY"<<endl;

#endif


JTAG *myJTAG = new JTAG( (*myInterfaz) );


///*****************************
///WHILE OPCIONES DEL PROGRAMA
///*****************************
int opt_while=1;
while(opt_while!=0){

  	printf("What do you want to do? \n\n"); 
  	printf("    %s \n","0 = exit"); 
	printf("    %s \n","1 = Read CEROS or ROSCTRL idcode"); 
	printf("    %s \n","2 = Read ROSMEM idcode"); 
  	printf("    %s \n","3 = Read CEROS or ROSCTRL usercode"); 
  	printf("    %s \n","4 = Read ROSMEM usercode"); 
  	printf("    %s \n","5 = Read ALL DEVICES idcode"); 
  	printf("    %s \n","6 = Read ALL DEVICES usercode"); 
  	printf("    %s \n","7 = Load individual CEROS file"); 
  	printf("    %s \n","8 = Load individual ROSCTRL file"); 
  	printf("    %s \n","9 = Load individual ROSMEM file"); 
  	printf("   %s \n","10 = Load ALL DEVICES file"); 
  	printf("   %s \n","11 = PROGRAM FPGAs"); 
  	printf("   %s \n\n","12 = READ if FPGAs programmed"); 
	cin >> opt_while;

int all_devices=1;
if (opt_while==0){
	all_devices=0;
};//else if opt_while

if (opt_while==11){ //program FPGAs
	all_devices=0;
	int rosvmefpgac=0x388;
	myInterfaz->write(rosvmefpgac,0x3E0);
	cout<<endl<<"Reprogramming fpgas....  "<<endl;
	sleep(1);
	unsigned short fpgasprog=0;
	int rosvmeoff=0x380;
	fpgasprog=myInterfaz->read(rosvmeoff);
	int errorprog=0;
	if ((fpgasprog&0x3C)!=0x3C) errorprog=1;
	cout<<endl<<"FPGAs programmed(reg0):0x"<<hex<<fpgasprog<<" error "<<errorprog<<endl<<endl;
};//else if opt_while

if (opt_while==12){ //Read if fpgas programmed
	all_devices=0;
	unsigned short fpgasprog=0;
	int rosvmeoff=0x380;
	fpgasprog=myInterfaz->read(rosvmeoff);
	int errorprog=0;
	if ((fpgasprog&0x3C)!=0x3C) errorprog=1;
	cout<<endl<<"FPGAs programmed(reg0):0x"<<hex<<fpgasprog<<" error "<<errorprog<<endl<<endl;
};//else if opt_while
 
string mydevice[6]={"CEROS 0", "CEROS 1", "CEROS 2", "CEROS 3", "ROSCTRL", "ROSMEM"};

///*****************
///BUCLE FOR ALL DEVICES
///*****************

int device=0;
int ask_fpga=1;

while(all_devices==1){
	if (opt_while==1){ //printf("%s \n","1 = Read CEROS or ROSCTRL idcode"); 
		ask_fpga=1;
		all_devices=0;
		strcpy(cfilename,"ceros_idcode.svf");
  	};//if opt_while=1
 	if (opt_while==2){ //printf("%s \n","2 = Read ROSMEM idcode");
		ask_fpga=0;
		all_devices=0;
		fpga = 0x20;
		strcpy(cfilename,"rosmem_idcode.svf");
  		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[5]<<" --.File: "<<cfilename<<endl;
 	};//if opt_while=2
	if (opt_while==3){ //printf("%s \n","3 = Read CEROS or ROSCTRL usercode");
		ask_fpga=1;
		all_devices=0;
		strcpy(cfilename,"ceros_usercode.svf");
  	};//if opt_while=3
 	if (opt_while==4){//printf("%s \n","4 = Read ROSMEM usercode"); 
		ask_fpga=0;
		fpga = 0x20;
		all_devices=0;
		strcpy(cfilename,"rosmem_usercode.svf");
		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[5]<<" --.File: "<<cfilename<<endl;
  	};//if opt_while=4
 	if (opt_while==5){ //printf("%s \n","5 = Read ALL DEVICES idcode");
		ask_fpga=0;
		fpga=0x1<<device;
		if (device==5) {
			all_devices=0;
			strcpy(cfilename,"rosmem_idcode.svf");
		}else{
			strcpy(cfilename,"ceros_idcode.svf");
		};//select file
		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[device]<<" --.File: "<<cfilename<<endl;
  	};//if opt_while=5
 	if (opt_while==6){ //printf("%s \n","6 = Read ALL DEVICES usercode");
		ask_fpga=0;
		fpga=0x1<<device;
		if (device==5) {
			all_devices=0;
			strcpy(cfilename,"rosmem_usercode.svf");
		}else{
			strcpy(cfilename,"ceros_usercode.svf");
		};//select file
		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[device]<<" --.File: "<<cfilename<<endl;
  	};//if opt_while=6
	if (opt_while==7){ //printf("%s \n","7 = Load individual CEROS file)");
		ask_fpga=1;
		all_devices=0;
		strcpy(cfilename,cfilename_c0);
 	};//if opt_while=7
	if (opt_while==8){ //  	//printf("%s \n","8 = Load individual ROSCTRL file)"); 
		ask_fpga=0;
		fpga = 0x10;
		all_devices=0;
		strcpy(cfilename,cfilename_rc);
		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[4]<<" --.File: "<<cfilename<<endl;
  	};//if opt_while=8
	if (opt_while==9){ //  	//printf("%s \n","9 = Load individual ROSMEM file)"); 
		ask_fpga=0;
		fpga = 0x20;
		all_devices=0;
		strcpy(cfilename,cfilename_rm);
		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[5]<<" --.File: "<<cfilename<<endl;
  	};//if opt_while=9
	if (opt_while==10){ //printf("%s \n","10 = Load ALL DEVICES file)"); 
		ask_fpga=0;
		fpga=0x1<<device;
		if (device==5) {
		//SI DESCOMENTO ESTO CARGA TAMBIEN ROSMEM  all_devices=0;
			strcpy(cfilename,cfilename_rm);
		}else{
			if (device==4){
				strcpy(cfilename,cfilename_rc);
			        all_devices=0;   //SI PONGO ESTO NO HACE ROSMEM
			}else{
				strcpy(cfilename,cfilename_c0); 
			};//device 4
		};//select file
		cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[device]<<" --.File: "<<cfilename<<endl;
  	};//if opt_while=10

if (ask_fpga==1){
  	printf("Which CEROS fpga you want to access? \n\n"); 
	printf("%s \n","0 = ceros 0"); 
	printf("%s \n","1 = ceros 1"); 
  	printf("%s \n","2 = ceros 2"); 
  	printf("%s \n","3 = ceros 3"); 
  	printf("%s \n","4 = ROSCTRL"); 
//  	printf("%s \n","5 = ROSMEM"); 
	cin >> option;
	
	if (option==0) fpga = 1;
	if (option==1) fpga = 2;
	if (option==2) fpga = 4;
	if (option==3) fpga = 8;
	if (option==4) fpga = 0x10;
//	if (option==5) fpga = 0x20;
	cout<<endl<<"*******ACCESSING FPGA: --"<<mydevice[option]<<" --.File: "<<cfilename<<endl;

};//if ask_fpga
		

///OPEN FILE
filesvf=fopen(cfilename,"r");
if (filesvf==NULL){
	cout << " FILE "<< cfilename<<" NOT FOUND... exiting" << endl<<endl;
	return 0;
}; //if file NULL


/// enable access to JTAG chain through VME
myInterfaz->write(JTAG_Control,6);
//cout<<endl<<"VME access to JTAG chain enabled.  add:0x"<<hex<<JTAG_Control<<
//"data:"<<6<<endl<<endl;


tiempo_init=time(NULL);
pTiempo=localtime(&tiempo_init);
printf("Tiempo de inicio %s \n",asctime(pTiempo));


int SIstatetofinish=0;
int SDstatetofinish=0;
int stateIam=0;

int output_tdo=0;
int contatore=0;
  while(!feof(filesvf)){
//while(contatore<5){
contatore=contatore+1;
char * errorget;
errorget=fgets(stron,3000,filesvf);
if ((errorget==NULL) && !feof(filesvf)){
cout<<"***********ERROR LEYENDO LINEA DEL FICHERO"<<endl;
delete myInterfaz;
break;
};
// printf("+++++OutPut string: %s",stron);
sscanf(stron,"%s",inst);
sscanf(stron,"%c",&comentario);

 if (comentario=='/'){// printf("Comentario  %d\n\n",comp);
 comp=0;
 };//comentario

   int numbits=0;
   int tdi=0;
   int smask=0;
   int tdo=0;
   int mask=0;
   char csir[10], csdr[10], ctdi[10],csmask[10],ctdo[10],cmask[10];
   char par;


   ///Posibles estados
   //0-IDLE,1-RESET
   //2-DRSELECT,3-DRCAPTURE,4-DRSHIFT,5-DREXIT1,6-DRPAUSE,7-DREXIT2,8-DRUPDATE
   //9-IRSELECT,10-IRCAPTURE,11-IRSHIFT,12-IREXIT1,13-IRPAUSE,14-IREXIT2,15-IRUPDATE

 comp=strcmp("ENDIR",inst);
 if (comp==0) {  //  printf("Ejecuto ENDIR %d\n\n",comp);
   char ENDIR_state[20]="";
   char auzendir[20]="";
   int pos_pch; //busca ;
   sscanf(stron,"%s %s",csir,auzendir);
 //  cout<<"ENDIR inst "<<auzendir<<endl;
   pos_pch=strcspn(auzendir,";");
   if (pos_pch!=0){
	strncat(ENDIR_state,auzendir,(pos_pch));
   }else{
	strcpy(ENDIR_state,auzendir);
   };//if pos_pch
 //  cout<<"ENDIR inst "<<ENDIR_state<<endl;
   if (strcmp(ENDIR_state,"IDLE")==0) SIstatetofinish=0;//son iguales
   if (strcmp(ENDIR_state,"IRPAUSE")==0) SIstatetofinish=13;//son iguales

 };//if ENDIR

comp=strcmp("ENDDR",inst);
 if (comp==0) {  //  printf("Ejecuto ENDDR %d\n\n",comp);
   char ENDDR_state[20]="";
   char auzenddr[20]="";
   int pos_pch; //busca ;
   sscanf(stron,"%s %s",csir,auzenddr);
 //  cout<<"ENDDR inst "<<auzenddr<<endl;
   pos_pch=strcspn(auzenddr,";");
   if (pos_pch!=0){
	strncat(ENDDR_state,auzenddr,(pos_pch));
   }else{
	strcpy(ENDDR_state,auzenddr);
   };//if pos_pch
 //  cout<<"ENDDR inst "<<ENDDR_state<<" pos_pch "<<pos_pch<<endl;
   if (strcmp(ENDDR_state,"IDLE")==0) SDstatetofinish=0;//son iguales
   if (strcmp(ENDDR_state,"DRPAUSE")==0) SDstatetofinish=6;//son iguales

 };//if ENDDR

 comp=strcmp("SIR",inst);
 if (comp==0) {  //  printf("Ejecuto SIR %d\n\n",comp);
   sscanf(stron,"%s %d %s %c %x %c %s %c %x %c %s %c %x %c %s %c %x %c",csir,&numbits,ctdi,&par,&tdi,&par,csmask,&par,&smask,&par,ctdo,&par,&tdo,&par,cmask,&par,&mask,&par);
  // printf("csir %s numbits %d  tdi  %x  smask %x tdo %x mask %x\n\n",csir,numbits,tdi,smask,tdo,mask);
   //Paso a la rutina: numbits, tdi. tdi es 1 byte, no hay problema, creo que se empieza a mandar por el menos signf
 
   myJTAG->send_IR(JTAG_Reg1,fpga,numbits,tdi,SIstatetofinish,stateIam);
   stateIam=SIstatetofinish;
    // int gg=0;
    // cin>>gg;
 
 };//if SIR

comp=strcmp("SDR",inst);
if (comp==0) {   //	printf("Ejecuto SDR %d\n\n",comp);

///Leer lineas hasta encontrar el punto y coma. Guardar en milinea la linea completa
   char * pch;  //busca ;
   int pos_pch; //busca ;
   char milinea[5000]=""; //linea completa del SVF hasta el punto y coma

   pch=strchr(stron,';');
   pos_pch=pch-stron+1;
   int intro=strcspn(stron,"\n");
   strncat(milinea,stron,(intro-1));
	while(pch==NULL){
		  fgets(stron,3000,filesvf);
		  pch=strchr(stron,';');
		  pos_pch=pch-stron+1;
 		  intro=strcspn(stron,"\n");
   		  strncat(milinea,stron,(intro-1));
	};//while pch==NULL
//    cout<<"milinea "<<milinea<<endl;
 
///Seleccionar cada parte signficativa de esa linea
char tdi_label[5000]="";
char tdi_data[5000]="";
char smask_label[5000]="";
char smask_data[5000]="";
char tdo_label[5000]="";
char tdo_data[5000]="";
char mask_label[5000]="";
char mask_data[5000]="";

   char bufflong[5000]="";
   char bufftdo[5000]="";
   int modul,divis;
   int numbitsenviados=0;
int notdo=0; //no existe el tdo
int nomask=0; //no exite la mascara
	sscanf(milinea,"%s %d %s (%s %s (%s %s (%s %s (%s",csdr,&numbits,tdi_label,tdi_data,smask_label,smask_data,tdo_label,tdo_data,mask_label,mask_data);

/*
cout<<"numbits "<<dec<<numbits<<" tdi_label "<<tdi_label<<endl;
cout<<"tdi_data "<<tdi_data<<" smask_label "<<smask_label<<" smask_data "<<smask_data<<endl;
cout<<"tdo_label "<<tdo_label<<" tdo_data "<<tdo_data<<" mask_label "<<mask_label<<endl;
cout<<" mask_data "<<mask_data<<endl;
  int gg=0;
  cin>>gg;
*/

char mi_tdi_data[5000]="";
char mi_smask_data[5000]="";
char mi_tdo_data[5000]="";
char mi_mask_data[5000]="";
int pos_parent=0; //para quitar el parentesis final

if (!strcmp(tdi_label,"TDI")){
//	cout<<"TDI label ok"<<endl;
	pos_parent=strcspn(tdi_data,")");
	strncat(mi_tdi_data,tdi_data,(pos_parent));
};
if (!strcmp(smask_label,"SMASK")){
//	cout<<"smask label ok"<<endl;
	pos_parent=strcspn(smask_data,")");
	strncat(mi_smask_data,smask_data,(pos_parent));
}else{ //No hay SMASK, copio los demas a sus respectivos
	strcpy(mask_label,tdo_label);
	strcpy(mask_data,tdo_data);	
	strcpy(tdo_label,smask_label);
	strcpy(tdo_data,smask_data);
};
if (!strcmp(tdo_label,"TDO")){
//	cout<<"TDO label ok"<<endl;
	pos_parent=strcspn(tdo_data,")");
	strncat(mi_tdo_data,tdo_data,(pos_parent));
}else{
	notdo=1;
};
if (!strcmp(mask_label,"MASK")){
//	cout<<"mask label ok"<<endl;
	pos_parent=strcspn(mask_data,")");
	strncat(mi_mask_data,mask_data,(pos_parent));
}else{
	nomask=1;
};
/*
cout<<"AFTER numbits "<<dec<<numbits<<" tdi_label "<<tdi_label<<endl;
cout<<"mi_tdi_data "<<mi_tdi_data<<" smask_label "<<smask_label<<" smask_data "<<mi_smask_data<<endl;
cout<<"tdo_label "<<tdo_label<<" tdo_data "<<mi_tdo_data<<" mask_label "<<mask_label<<endl;
cout<<" mask_data "<<mi_mask_data<<endl;
*/
//cout<<"mi_tdi_data "<<mi_tdi_data<<endl;
//int gg=0;
//cin>>gg;

modul=numbits % 8;
divis=numbits/8;
//cout<<" modul "<<dec<<modul<<" divis "<<divis<<endl;

//cout<<" bufflong: "<<bufflong<<endl;
/*
int lll=strlen(bufflong);
cout<<" longitud: "<<dec<<lll<<endl;
if (numbits!=(lll*4)){
cout<<" ERROR longitud. numbits: "<<dec<<numbits<<" lll*4="<<lll*4<<endl;
};
*/ //No hacer la comprobacion de longitud, falla si es pequeño etc

	myJTAG->prep_send_DR(JTAG_Reg1,fpga,stateIam);
	
	int bytetosend=0;
	int bytereceived=0;
	char auxiliar[10]="";
	char aux_tdo[10]="";
	char aux_tdo2[5000]="";
	int length=strlen(mi_tdi_data);
//	cout<<"length y numbits"<<length<<numbits<<endl;

	for (int ee=1;ee<divis;ee++){ //BUCLE string TDIs
	 	strncat(auxiliar,&mi_tdi_data[length-2*ee],2);
 		bytetosend=strtoul(auxiliar,NULL,16);
//cout<<"LOOP bytetosend TMS a 0 0x"<<hex<<bytetosend<<" iteracion "<<dec<<ee<<endl;
		out_tdo=myJTAG->send_DR_middle(JTAG_Reg1,fpga,JTAG_TDI_Reg2,JTAG_TDO_Data,0,8,bytetosend);
numbitsenviados=numbitsenviados+8;		
		bytereceived=out_tdo & 0xFF;
		sprintf(aux_tdo2,"%02x",bytereceived);
		strcat(aux_tdo2,bufftdo);
		strcpy(bufftdo,aux_tdo2);
//cout<<"bytereceived 0x"<<hex<<bytereceived<<" string "<<bufftdo<<" iteracion "<<dec<<ee<<endl;
		strcpy(auxiliar,"");
	};//for modulo 8

	if((modul==0)&&(divis!=0)){ //Envio el ultimo byte con el tms a 1
		strncat(auxiliar,&mi_tdi_data[length-2*divis],2);
		bytetosend=strtoul(auxiliar,NULL,16);
	//cout<<" if modul==0 divis!=0 final bytetosend TMS a 1 0x"<<hex<<bytetosend<<endl;
numbitsenviados=numbitsenviados+8;		
		out_tdo=myJTAG->send_DR_middle(JTAG_Reg1,fpga,JTAG_TDI_Reg2,JTAG_TDO_Data,1,8,bytetosend);
		bytereceived=out_tdo & 0xFF;
		sprintf(aux_tdo2,"%02x",bytereceived);
		strcat(aux_tdo2,bufftdo);
		strcpy(bufftdo,aux_tdo2);
//cout<<"bytereceived 0x"<<hex<<bytereceived<<" string "<<bufftdo<<endl;
		strcpy(auxiliar,"");
	
	}else{ //envio el penultimo byte con tms a 0 y los ultimos bits con tms a 1
	//cout<<"length y numbits "<<length<<" "<<numbits<<endl;
	//	printf("mod %d div %d \n",modul, divis);
  //  int gg=0;
  //  cin>>gg;


		if (divis!=0){
			strncat(auxiliar,&mi_tdi_data[length-2*divis],2);
			bytetosend=strtoul(auxiliar,NULL,16);
	//	cout<<"if mod!=0 dovos!=0 penultimo bytetosend TMS a 0 0x"<<hex<<bytetosend<<endl;
			numbitsenviados=numbitsenviados+8;		
			out_tdo=myJTAG->send_DR_middle(JTAG_Reg1,fpga,JTAG_TDI_Reg2,JTAG_TDO_Data,0,8,bytetosend);
			bytereceived=out_tdo & 0xFF;
			sprintf(aux_tdo2,"%02x",bytereceived);
			strcat(aux_tdo2,bufftdo);
			strcpy(bufftdo,aux_tdo2);
	//cout<<"bytereceived 0x"<<hex<<bytereceived<<" string "<<bufftdo<<endl;
			strcpy(auxiliar,"");
		};//divis!=0

strncat(auxiliar,&mi_tdi_data[0],2);
bytetosend=strtoul(auxiliar,NULL,16);
int mybyte=bytetosend;
int mybit=0;
int tdo1bit=0;
for(int ff=0;ff<(modul);ff++){
mybit=(mybyte>>ff)&0x1;
if (ff==(modul-1)){
//cout<<"ENTRO EN MI LOOPbyte to send "<<bytetosend<<" my bit "<<mybit<<endl;
out_tdo=myJTAG->send_1_bit(1,mybit,JTAG_Reg1,fpga);
//tdo1bit=(tdo1bit<<1)|(out_tdo&0x1);
tdo1bit=(tdo1bit)|((out_tdo&0x1)<<ff);
//cout<<"else "<<out_tdo<<" tdo1bit "<<tdo1bit<<endl;
}else{
//cout<<"ENTRO EN MI LOOPbyte to send "<<bytetosend<<" my bit "<<mybit<<endl;
out_tdo=myJTAG->send_1_bit(0,mybit,JTAG_Reg1,fpga);
//tdo1bit=(tdo1bit<<1)|(out_tdo&0x1);
tdo1bit=(tdo1bit)|((out_tdo&0x1)<<ff);
//cout<<"else "<<out_tdo<<" tdo1bit "<<tdo1bit<<endl;
};
};
sprintf(aux_tdo2,"%02x",tdo1bit);
strcat(aux_tdo2,bufftdo);
strcpy(bufftdo,aux_tdo2);
strcpy(auxiliar,"");
numbitsenviados=numbitsenviados+modul;		
//int gg=0;
//cin>>gg;

/*
strcpy(auxiliar,"");

		strncat(auxiliar,&bufflong[0],2);
		bytetosend=strtoul(auxiliar,NULL,16);
numbitsenviados=numbitsenviados+modul;		
	cout<<"EL QUE FALLA tras p final bytetosend TMS a 1 0x"<<hex<<bytetosend<<endl;
	cout<<"EL QUE FALLA modul"<<dec<<modul<<endl;
		out_tdo=myJTAG->send_DR_middle(JTAG_Reg1,fpga,JTAG_TDI_Reg2,JTAG_TDO_Data,1,modul,bytetosend);
		bytereceived=out_tdo & 0xFF;
		sprintf(aux_tdo2,"%02x",bytereceived);
		strcat(aux_tdo2,bufftdo);
		strcpy(bufftdo,aux_tdo2);
	cout<<"EL QUE FALLA bytereceived 0x"<<hex<<bytereceived<<" out_tdo "<<out_tdo<<endl;
//cout<<"bytereceived 0x"<<hex<<bytereceived<<" string "<<bufftdo<<endl;
		strcpy(auxiliar,"");
int gg=0;
cin>>gg;
*/

	}; //if modul==0
		

	myJTAG->exit_send_DR(JTAG_Reg1,fpga,SDstatetofinish);
	stateIam=SDstatetofinish;
 
	if (opt_while<7){	
		printf("EL DATO DE SALIDA ES: 0x%s \n ",bufftdo);
	}else{
		cout<<"."<<flush;
	};//print el idcode

///COMPARACION DEL TDO
	if ((notdo==0)&(nomask==0)){//si existe el tdo y el mask lo comparo
		char auxcompaout[10]="";
		char auxcompamask[10]="";
		char auxcompatdo[10]="";
		int compaout=0;
		int compamask=0;
		int compatdo=0;
		int errorcompa=0;
		for(int hh=0;hh<(strlen(bufftdo));hh++){
			strncat(auxcompaout,&bufftdo[hh],1);
			strncat(auxcompamask,&mi_mask_data[hh],1);
			strncat(auxcompatdo,&mi_tdo_data[hh],1);
			compaout=strtoul(auxcompaout,NULL,16);
			compamask=strtoul(auxcompamask,NULL,16);
			compatdo=strtoul(auxcompatdo,NULL,16);
			if ((compaout&compamask)!=(compatdo&compamask)){
				errorcompa=1;			
				cout<<"ERROR En la comparacion hh="<<dec<<hh<<endl;
				/*cout<<endl<<"compaout 0x"<<hex<<compaout<<endl;
				cout<<"compamask 0x"<<hex<<compamask<<endl;
				cout<<"compatdo 0x"<<hex<<compatdo<<endl;
				cout<<endl<<"milinea "<<milinea<<endl;
				printf("\n EL DATO DE SALIDA ES: 0x%s \n \n",bufftdo);
				int gg=0;
				cin>>gg;*/
			};//if compa	
			strcpy(auxcompaout,"");
			strcpy(auxcompamask,"");
			strcpy(auxcompatdo,"");
			compaout=0;
			compamask=0;
			compatdo=0;
		};//for comparison
		if (errorcompa==1){
				cout<<endl<<"milinea "<<milinea<<endl;
				printf("\n EL DATO DE SALIDA ES: 0x%s \n \n",bufftdo);
				//int gg=0;
				//cin>>gg;
		};//errorcompa

	};//notdo==0


	strcpy(bufftdo,"");

if (numbits!=numbitsenviados){
//cout<<"numbits a enviar "<<dec<<numbits<<" numbits enviados "<<numbitsenviados<<endl;
};
 
};//if SDR

comp=strcmp("RUNTEST",inst);
if (comp==0) {
	int RUNstatetofinish=0;
	int waittime=0;
	//	printf("Ejecuto RUNTEST %d\n",comp);
	//printf("%s",stron);

///ojo hay RUNTEST con mas parametros
char instr[16]="";
char miwaittime[16]="";
char mitck[16]="";
char mistate[16]="";

	sscanf(stron,"%s %s %s %s",instr,mistate,miwaittime,mitck); //waittime son microsegundos
//printf("%s",stron);
//cout<<" mitck "<<mitck<<endl;

if ((!strcmp(mitck,"TCK;"))|(!strcmp(mitck,"TCK"))){//hay state, miwaittime es miwaittime
//cout<<" ok miwaittime es miwaittime"<<endl;
   if (strcmp(mistate,"IDLE")==0) RUNstatetofinish=0;//son iguales
   if (strcmp(mistate,"DRPAUSE")==0) RUNstatetofinish=6;//son iguales
   if (strcmp(mistate,"IRPAUSE")==0) RUNstatetofinish=13;//son iguales
}else{ //No hay TCK mistate es miwaittime
	strcpy(miwaittime,mistate);
	RUNstatetofinish=stateIam;
//cout<<" NOOOO miwaittime es miwaittime"<<endl;
};
waittime=strtoul(miwaittime,NULL,10);

//	cout<<"miwaittime "<<miwaittime<<dec<<" waittime= "<<waittime<<endl;
	myJTAG->runtest(JTAG_Reg1,fpga,waittime,stateIam,RUNstatetofinish);
	stateIam=RUNstatetofinish;

	//int time_sleep=(waittime/1); //for using usleep
	//usleep(time_sleep);
};

comp=strcmp("STATE",inst);
if (comp==0) {  //	printf("Ejecuto STATE %d\n\n",comp);
  
//STATE  IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE;
//STATE  IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE;
//STATE  IDLE;
//STATE RESET;
//STATE RESET IDLE;

	int STAstatetofinish=0;

	int Stfound=0;
char st0[20],st1[20],st2[20],st3[20],st4[20],st5[20],st6[20],st7[20];

	sscanf(stron,"%s %s %s %s %s %s %s %s",st0,st1,st2,st3,st4,st5,st6,st7); //waittime son microsegundos

	if ((strcmp(st1,"IREXIT2")==0)&&(strcmp(st2,"IRUPDATE")==0)&&(strcmp(st3,"DRSELECT")==0)&&(strcmp(st4,"DRCAPTURE")==0)&&(strcmp(st5,"DREXIT1")==0)&&(strcmp(st6,"DRPAUSE;")==0)){
		//se entiende que vengo de IRUPDATE=13
		if (stateIam!=13){
			cout<<"ERRORORRRR "<<stron<<" no vengo de IRUPDATE!!! stateIam"<<stateIam<<endl;
			int gg=0;
			cin>>gg;
		};
		Stfound=1;
		STAstatetofinish=6;
		myJTAG->stateseq1(JTAG_Reg1,fpga,stateIam,STAstatetofinish);
		stateIam=STAstatetofinish;
	};
//	if ((strcmp(stron,"STATE  IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE IDLE;\n")==0)){
	if ((strcmp(st1,"IREXIT2")==0)&&(strcmp(st2,"IRUPDATE")==0)&&(strcmp(st3,"DRSELECT")==0)&&(strcmp(st4,"DRCAPTURE")==0)&&(strcmp(st5,"DREXIT1")==0)&&(strcmp(st6,"DRUPDATE")==0)&&(strcmp(st7,"IDLE;")==0)){
		//se entiende que vengo de IRUPDATE=13
		if (stateIam!=13){
			cout<<"ERRORORRRR "<<stron<<" no vengo de IRUPDATE!!! stateIam"<<stateIam<<endl;
			int gg=0;
			cin>>gg;
		};
		Stfound=1;
		STAstatetofinish=0;
		myJTAG->stateseq2(JTAG_Reg1,fpga,stateIam,STAstatetofinish);
		stateIam=STAstatetofinish;
	};
//	if ((strcmp(stron,"STATE  DRPAUSE;\n")==0)){
	if ((strcmp(st1,"DRPAUSE")==0)||(strcmp(st1,"DRPAUSE;")==0)){
		//se supone que vengo de IDLE y voy a DRPAUSE
		if (stateIam!=0){
			cout<<"ERRORORRRR "<<stron<<" no vengo de IDle!!! stateIam"<<stateIam<<endl;
			int gg=0;
			cin>>gg;
		};
		Stfound=1;
		STAstatetofinish=6;
		myJTAG->gotodrpause(JTAG_Reg1,fpga,stateIam,STAstatetofinish);
		stateIam=STAstatetofinish;
	};
	if ((strcmp(st1,"IDLE;")==0)||(strcmp(st1,"IDLE")==0)){
		//solo funciona si vengo de IDLE, DRPAUSE o IRPAUSE, si no no hace nada
		if ((stateIam!=13)&&(stateIam!=0)&&(stateIam!=6)){
			cout<<"ERRORORRRR "<<stron<<" no vengo de IDle,drpause o irpause!!! stateIam"<<stateIam<<endl;
			int gg=0;
			cin>>gg;
		};
		Stfound=1;
		STAstatetofinish=0;
		myJTAG->gotoidle(JTAG_Reg1,fpga,stateIam,STAstatetofinish);
		stateIam=STAstatetofinish;
	};
//	if ((strcmp(stron,"STATE RESET IDLE;\n")==0)||(strcmp(stron,"STATE RESET;")==0)){
	if ((strcmp(st1,"RESET")==0)||(strcmp(st1,"RESET;")==0)){
		//lo bueno es que aquí da igual de dónde venga
		Stfound=1;
		myJTAG->jtag_reset(JTAG_Reg1,fpga);
		//cout<<" instruccion diferente"<<mistate<<endl;
		STAstatetofinish=0;
		stateIam=STAstatetofinish;
	};
	if (Stfound==0){
		cout<<"ERRRORRRRRRRR STATE instruction not found among possibles!!!! "<<endl<<stron<<endl;
		int gg=0;
		cin>>gg;
	};//Stfound=0


	/*
///ojo, solo hacer state reset si eso es lo que pone la instruccion
char instr[16]="";
char mistate[16]="";
char mistate2[16]="";

	sscanf(stron,"%s %s %s",instr,mistate,mistate2); 
//printf("%s",stron);
//cout<<" mitck "<<mitck<<endl;
if ((!strcmp(mistate,"RESET;"))|(!strcmp(mistate,"RESET"))){//hay state, miwaittime es miwaittime
myJTAG->jtag_reset(JTAG_Reg1,fpga);
}else{ //No hay TCK mistate es miwaittime
//cout<<" instruccion diferente"<<mistate<<endl;
};//if strcmp

*/


};

  };//while file

if (errnumbits>0){
printf("ERROR numbites %d \n",errnumbits);
};
   fclose(filesvf);

   device=device+1;

tiempo_end=time(NULL);
pTiempo=localtime(&tiempo_end);
//printf("\nTiempo de fin %s \n",asctime(pTiempo));
double tiempo_trans=difftime(tiempo_end,tiempo_init);
printf("\n+++++++++Tiempo de ejecucion = %.2f segundos -- %.2f minutos \n\n",tiempo_trans,(tiempo_trans/60));

};//while all_decives==1

//if (dummy==0) delete mybus;

}; //while options program

   /// disable VME
//I have to do a reset  
   myInterfaz->write(JTAG_Control,7);
 myInterfaz->write(ROSVME_00,0xF000);
cout<<endl<<"Disabled access to JTAG from VME. (What SWITCH says). add:0x"<<
hex<<JTAG_Control<<"  data: "<<7<<endl;
cout<<endl<<endl<<"*************************************"<<endl;
cout<<"*************************************"<<endl;
cout<<"*************************************"<<endl<<endl;
delete myInterfaz;

#ifdef LINCO
delete mybus;
#endif
 
//VISAResourceManager::destroyInstrumentInstance(instr);
  }
  catch (exception e){
    cout << endl << "Leñazo por excepcion. Descripcion: " << e.what()
        << endl;
  }
  catch (...) {
    cout << endl << "Alguien ha matado a alguien. " << endl;
  }

  return 0;


}
