/* -------------------------------------------------------------------------- PROGRAM: ACQUIRE.C by Michel Pioro-Ladriere 11/08/99 Version 2.33 by Andree Robichaud-Veronneau 08/21/02 -------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------ The program ACQUIRE.C uses the labtender to collect the data sent by the acquisition hardware use for the acoustic spark chamber. The signals sent to the labtender are the six gates, which the time they are high corresponds to the time it tooks for the sound wave produced by the spark to reach the six sound transducers. The six gates are sent to the six counters of the AM9513 of each labtender via connectors P5, pins 1 to 5. Each counter is used to measure the time each gate is high. We use a counting frequency of 1 MHz. The hardware open each gate after a first delay which is hardware programmable via a resistance and a capacitance. This delay equals 1.1*RC and must be added to the computed time each gate is high. To run the programm in continue, i.e. to measure time trigger after trigger of the spark chamber, a signal READ is sent to bit 0 of port A of the 8255 parallel ports of the labtenders by the acquisition hardware. When this bit is HIGH, it means that the PC can write the data on disk and re-arm the counters. The algorithm is explain at each step of the program. -------------------------------------------------------------------------- */ /*Include header files for the program*/ #include //for file processing #include //for getting current date #include //for getting time #include //for keystrokes #include //for exit () int bored (void) { if (kbhit ()) exit (1); return 0; } main(void) { /*Define the labtender address on the bis of the motherboard*/ int BASE_ADDRS = 0x330; //labtender I/O base address int BASE_ADDRS2 = 0x340; //labtender2 I/O base address int AM9513_DATA = BASE_ADDRS + 8; //labtender AM9513 addresses int AM9513_CTRL = BASE_ADDRS + 9; int AM9513_DATA2 = BASE_ADDRS2 + 8; //labtender2 AM9513 addresses int AM9513_CTRL2 = BASE_ADDRS2 + 9; int PP8255_A_DATA = BASE_ADDRS + 12; //labtender PP8255 addresses int PP8255_CTRL = BASE_ADDRS + 15; int PP8255_A_DATA2 = BASE_ADDRS2 + 12; //labtender2 PP8255 addresses int PP8255_CTRL2 = BASE_ADDRS2 + 15; /*Define the program variables*/ int DELAY = 24; //first time constant. Corresponds to the time the //delay gate is low after triggering of the spark //chamber. This constant equals 1.1*RC of the first //MC1455 in monostable mode in microsecs. float READ_LOW = 4.76; //second time constant. Corresponds to the time the //READ gate is LOW after triggering of the spark //chamber. This constant equals 1.1*RC of the second //MC1455 used in monostable mode in milliseconds int DELTA_T[6]; //time the timing gates are high to be computed by AM9513 int MAX_EVENT; //number of events to acquire int READ; //READ signal value (1 = HIGH, 0 = LOW) int LSB,MSB,WORD; //programming bytes int i,EVENT; //increment long int base_time; //base time for timing triggering char filename[6]; //filename input char both[10]; //filename+extension struct date d; //date long int a,b,bb,bbb,c,e,f,g,h,j,jj,k,kk,l; //calculations unsigned long t; //time char mona[] = "January"; char monb[] = "February"; char monc[] = "March"; char mond[] = "April"; char mone[] = "May"; char monf[] = "June"; char mong[] = "July"; char monh[] = "August"; char moni[] = "September"; char monj[] = "October"; char monk[] = "November"; char monl[] = "December"; char VERSION[] = "2.33"; char comment[200]; //display information about the program and prompt for the number of events to acquire printf("Spark Chamber Project: Data Acquisition\n"); printf("Number of events to acquire: "); scanf( "%d", &MAX_EVENT); //prompt the user for comments printf("Comments: "); scanf( "%s", comment); //prompt the user for the name of the output file B:{ printf("\nName of the output file (******.dat): "); scanf( "%s", filename); char extension[4] = ".dat"; both[0] = filename[0]; both[1] = filename[1]; both[2] = filename[2]; both[3] = filename[3]; both[4] = filename[4]; both[5] = filename[5]; both[6] = extension[0]; both[7] = extension[1]; both[8] = extension[2]; both[9] = extension[3]; //check if a file with the same filename exists already and prevent from overwriting FILE *fp; fp = fopen(both,"r"); if (fp == NULL) goto A; else { fclose(fp); printf("\nCannot overwrite an existing file. Choose another filename."); goto B; } //allow the user to stop the program A:{ printf("\nPress Esc to exit\n"); //calculate time of day getdate(&d); a = d.da_year - 1970; b = d.da_year - 1968; bb = b/4; bbb = b%4; if (bbb == 0) c = (bb-1)*366+(a-bb)*365; else c = bb*366+(a-bb)*365; for (i=1; i= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",mona, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",mona, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\nti%s %d, %d %ld:%ld:%ld",mona, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 2) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monb,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monb, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monb, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monb, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 3) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monc,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monc, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monc, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monc, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 4) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",mond,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",mond, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",mond, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",mond, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 5) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",mone,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",mone, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",mone, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",mone, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 6) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monf,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monf, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monf, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monf, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 7) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",mong,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",mong, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",mong, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",mong, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 8) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monh,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monh, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monh, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monh, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 9) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",moni,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",moni, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",moni, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",moni, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 10) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monj,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monj, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monj, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monj, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 11) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monk,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monk, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monk, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monk, d.da_day, d.da_year, l, k, kk); } } if (d.da_mon == 12) { if (k <= 9) { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:0%ld:0%ld",monl,d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:0%ld:%ld",monl, d.da_day, d.da_year, l, k, kk); } else { if (kk <= 9) fprintf(fpt,"\n%s %d, %d %ld:%ld:0%ld",monl, d.da_day, d.da_year, l, k, kk); if (kk >= 10) fprintf(fpt,"\n%s %d, %d %ld:%ld:%ld",monl, d.da_day, d.da_year, l, k, kk); } } fprintf(fpt,"\n\nProgram Version %s \n", VERSION); fprintf(fpt,"\nRUN FOR SPARK CHAMBER\n"); fprintf(fpt,"\nDELAY FOR E.M. PICKUP = %d microsecs\n",DELAY); fprintf(fpt,"\nDELAY FOR READ SIGNAL = %f millisecs\n",READ_LOW); fprintf(fpt,"\nNUMBER OF EVENTS = %d\n",MAX_EVENT); fprintf(fpt,"\nCOMMENTS = %s\n",comment); fprintf(fpt,"\nEVENT\tTIME\t\tP1\tP2\tP3\tP4\tP5\tP6\n"); /*ACQUIRE EVENTS*/ for(EVENT=1;EVENT<=MAX_EVENT;EVENT++) { /*SETUP LABTENDER PP8255*/ //PP8255 mode definition: //PP8255's port A as input //the command word is 10010000 = 0x90 for mode 0 with port A as input and //B and C as outputs (so B and C are protected from possible pick-up) //setup the PP8255 WORD = 0x90; outp(PP8255_CTRL,WORD); outp(PP8255_CTRL2,WORD); /*SETUP LABTENDER AM9513 AND ITS COUNTERS */ //master reset of the AM9513 (...just to be sure) outp(AM9513_CTRL,0xFF); outp(AM9513_CTRL2,0xFF); //select master mode register outp(AM9513_CTRL,0x17); outp(AM9513_CTRL2,0x17); //setup the master mode register for //scalar control = BCD division, data pointer control = disable increment, //databus width = 8 bits word, FOUT = ON, FOUT divider = divide by 1 //FOUT source = F1, comparators 2 and 1 = disabled, //time of day = disabled //MSB = 1000 0001= 0x81 and LSB = 000 0000 = 0x00 LSB = 0x00; MSB = 0x81; outp(AM9513_DATA,LSB); outp(AM9513_DATA,MSB); outp(AM9513_DATA2,LSB); outp(AM9513_DATA2,MSB); //SETUP COUNTERS for(i=1;i<=5;i++) { //SELECT COUNTER GROUP i MODE REGISTER outp(AM9513_CTRL,i); //SETUP MODE FOR COUNTER i TO COUNT WHEN GATE i IS ACTIVE HIGH //Gating Ctrl: Active High Level Gate i //Count on Rising Edge of source //Count Source: F1 (1 MHz) //Most significant Byte is then = 1000 1011 = 0x8b (MSB) MSB = 0x8B; //Disable Special Gate //Reload From Load //Count Once //Binary Count //Count Up //Output: inactive, HIGH Impedance //Least siginficant BYTE is then = 0000 1100 = 0x09 (LSB) LSB = 0x09; outp(AM9513_DATA,LSB); //write LSB in mode register of counter i outp(AM9513_DATA,MSB); //write MSB in mode register of counter i } //SELECT COUNTER GROUP 2 MODE REGISTER outp(AM9513_CTRL2,2); //SETUP MODE FOR COUNTER 2 TO COUNT WHEN GATE 2 IS ACTIVE HIGH //Gating Ctrl: Active High Level Gate 2 //Count on Rising Edge of source //Count Source: F1 (1 MHz)//Most significant Byte is then = 1000 1011 = 0x8b (MSB) MSB = 0x8B; //Disable Special Gate //Reload From Load //Count Once //Binary Count //Count Up //Output: inactive, HIGH Impedance //Least siginficant BYTE is then = 0000 1100 = 0x09 (LSB) LSB = 0x09; outp(AM9513_DATA2,LSB); //write LSB in mode register of counter 2 outp(AM9513_DATA2,MSB); //write MSB in mode register of counter 2 /*INITIALYZE*/ //initialyze LOAD register of all counters for(i=1;i<=5;i++) { //select LOAD REGISTER of counter i outp(AM9513_CTRL,0x8|i); //write 0x0000 in the load register of counter i outp(AM9513_DATA,0x00); outp(AM9513_DATA,0x00); } //select LOAD REGISTER of counter 2 outp(AM9513_CTRL2,0x8|2); //write 0x0000 in the load register of counter 2 outp(AM9513_DATA2,0x00); outp(AM9513_DATA2,0x00); //check if READ signal is LOW and wait until it becomes HIGH READ = 0x01&inp(PP8255_A_DATA); while((READ==0) && !bored()) READ = 0x01&inp(PP8255_A_DATA); READ = 0x01&inp(PP8255_A_DATA2); while((READ==0) && !bored()) READ = 0x01&inp(PP8255_A_DATA2); //LOAD and ARM all counters outp(AM9513_CTRL,0x7F); outp(AM9513_CTRL2,0x7F); //wait until READ signal goes LOW READ = 0x01&inp(PP8255_A_DATA); while(READ==1 && !bored()) READ = 0x01&inp(PP8255_A_DATA); READ = 0x01&inp(PP8255_A_DATA2); while(READ==1 && !bored()) READ = 0x01&inp(PP8255_A_DATA2); //wait until READ SIGNAL goes HIGH again while(READ==0 && !bored()) READ = 0x01&inp(PP8255_A_DATA); while(READ==0 && !bored()) READ = 0x01&inp(PP8255_A_DATA2); //DISARM and SAVE all counters value in their HOLD REGISTER outp(AM9513_CTRL,0x9F); outp(AM9513_CTRL2,0x9F); //READ DATA printf("\n EVENT #%d\n",EVENT); for(i=1;i<=5;i++) { //SELECT COUNTER GROUP i HOLD REGISTER outp(AM9513_CTRL,0x10|i); //assign DT1 = counter value LSB + MSB shifted 8 (pulse width in microsecs with update delay) DELTA_T[i-1] = inp(AM9513_DATA) + (inp(AM9513_DATA)<<8) + DELAY; //print DT1 on screen printf("\n %s %d \t %u","piezzo ", i ,DELTA_T[i-1]); } //SELECT COUNTER GROUP 2 HOLD REGISTER outp(AM9513_CTRL2,0x10|2); //assign DT1 = counter value LSB + MSB shifted 8 (pulse width in microsecs with update delay) DELTA_T[5] = inp(AM9513_DATA2) + (inp(AM9513_DATA2)<<8) + DELAY; //print DT1 on screen printf("\n %s %d \t %u\n","piezzo ", 6 ,DELTA_T[5]); //write data on file fprintf(fpt,"\n%d\t%lu\t%u\t%u\t%u\t%u\t%u\t%u\n",EVENT,time(NULL),DELTA_T[0], DELTA_T[1],DELTA_T[2],DELTA_T[5],DELTA_T[3],DELTA_T[4]); } return 0; } } }