/*********************************************************************************************\ former Version of VIEWEVENT ist now called printdatay print content of FAD raw-data in an Excel readable format :-) dn, 08.06.10 should work with data format version no. 0x0100, 0x0101 and 0x0102 all 16 and 32 bit values must be converted from big to little endian!!! (ntohs (), ntohl ()) kw, 05.10 \*********************************************************************************************/ #ifndef PATH_MAX #define PATH_MAX 1000 #endif #include #include #include #include #include #include "printdata.h" int main(int argc, char **argv) { int opt, evnt_cnt; int max_roi=0; // static array to store data, for printing coloumn wise. unsigned short evnt_data[36][1024]; for (int col=0; col<1024; col++) { for (int row=0; row<36; row++) { evnt_data[row][col]=0; } } unsigned short ch_id[36]; unsigned short ch_start_cell[36]; unsigned short ch_roi[36]; const char *optstring = "h"; static struct option long_options[] = { {"no-data", 0, 0, 1}, {"dec",0,0,2}, {"offsbin",0,0,3}, {"twoscompl",0,0,4}, {0, 0, 0, 0} }; char fname[PATH_MAX]; int print_data = 1; //1 int print_hex=1; int print_dec=0; //2 int print_offsbin=0; //3 int print_twoscompl=0; //4 if (argc <= 1) { usage (argv[0]); exit (1); } while ((opt = getopt_long (argc, argv, optstring, long_options, 0)) != -1) { switch (opt) { // no channel data case 1: print_data = 0; break; case 2: print_hex = 0; print_dec=1; break; case 3: print_hex = 0; print_offsbin=1; break; case 4: print_hex = 0; print_twoscompl=1; break; default: usage (argv[0]); exit (1); break; } } if (optind < argc) { strncpy (fname, argv[optind], PATH_MAX); } else { usage (argv[0]); exit (1); } FILE *fhandle; size_t fresult; EVNT *evnt; // open input file if ((fhandle = fopen (fname, "r")) == NULL) { // Oops... printf ("Error: File %s not found\n", fname); exit (1); } else { for (evnt_cnt = 0;; evnt_cnt++) { // allocate memory for evnt structure evnt =( EVNT*) calloc (1, sizeof (EVNT)); // read and print package header if ((fresult = fread (&evnt->evnt_header.start_package_flag, sizeof (evnt->evnt_header.start_package_flag), 1, fhandle)) == 1) { printf ("--------------\nEvent No.: %d\n--------------\n", evnt_cnt); printf ("Start Package Flag: 0x%.4X\n", ntohs (evnt->evnt_header.start_package_flag)); fread (&evnt->evnt_header.package_length, sizeof (evnt->evnt_header.package_length), 1, fhandle); printf ("Package Length: 0x%.4X\n", ntohs (evnt->evnt_header.package_length)); fread (&evnt->evnt_header.version_no, sizeof (evnt->evnt_header.version_no), 1, fhandle); printf ("Version Number: 0x%.4X\n", ntohs (evnt->evnt_header.version_no)); fread (&evnt->evnt_header.trigger_id, sizeof (evnt->evnt_header.trigger_id), 1, fhandle); printf ("Trigger-ID: 0x%.8X\n", ntohl (evnt->evnt_header.trigger_id)); fread (&evnt->evnt_header.trigger_type, sizeof (evnt->evnt_header.trigger_type), 1, fhandle); printf ("Trigger Type: 0x%.2X\n", evnt->evnt_header.trigger_type); fread (&evnt->evnt_header.trigger_crc, sizeof (evnt->evnt_header.trigger_crc), 1, fhandle); printf ("Trigger CRC: 0x%.2X\n", evnt->evnt_header.trigger_crc); fread (&evnt->evnt_header.local_trigger_id, sizeof (evnt->evnt_header.local_trigger_id), 1, fhandle); printf ("Local Trigger-ID: 0x%.8X\n", ntohl (evnt->evnt_header.local_trigger_id)); fread (&evnt->evnt_header.local_trigger_type, sizeof (evnt->evnt_header.local_trigger_type), 1, fhandle); printf ("Local Trigger Type: 0x%.2X\n", evnt->evnt_header.local_trigger_type); fread (&evnt->evnt_header.local_trigger_crc, sizeof (evnt->evnt_header.local_trigger_crc), 1, fhandle); printf ("Local Trigger CRC: 0x%.2X\n", evnt->evnt_header.local_trigger_crc); fread (&evnt->evnt_header.board_id, sizeof (evnt->evnt_header.board_id), 1, fhandle); printf ("Board-ID: 0x%.4X\n", ntohs (evnt->evnt_header.board_id)); for (int i = 0; i < 4; i++) { fread (&evnt->evnt_header.drs_temperature[i], sizeof (evnt->evnt_header.drs_temperature[i]), 1, fhandle); if ((ntohs (evnt->evnt_header.drs_temperature[i]) & 0x8000) == 0x8000) { printf ("Temperature %d: %d\n", i, 0xE000 | (ntohs (evnt->evnt_header.drs_temperature[i])) >> 3); } else { printf ("Temperature %d: %d\n", i, ntohs (evnt->evnt_header.drs_temperature[i]) >> 3); } } // DAC Values, only if version > 0x0101 if (ntohs (evnt->evnt_header.version_no) > 0x0101) { for (int i = 0; i < 8; i++) { fread (&evnt->evnt_header.dac[i], sizeof (evnt->evnt_header.dac[i]), 1, fhandle); printf ("DAC %d: %d\n", i, ntohs (evnt->evnt_header.dac[i])); } } // read channels, no error checking... for (int i = 0; i < (4 * 9); i++) { // read channel header fread (&ch_id[i], sizeof (evnt->channel[i].channel_id), 1, fhandle); fread (&ch_start_cell[i], sizeof (evnt->channel[i].channel_start_cell), 1, fhandle); fread (&ch_roi[i], sizeof (evnt->channel[i].channel_roi), 1, fhandle); if (max_roi < ntohs (ch_roi[i])) {max_roi = ntohs (ch_roi[i]);} fread ((evnt_data[i]), sizeof (unsigned short), ntohs (ch_roi[i]), fhandle); } // loop over event_data to adjust endianess! for (int row=0; row<36; row++) { ch_id[row]=ntohs(ch_id[row]); ch_start_cell[row]=ntohs(ch_start_cell[row]); ch_roi[row]=ntohs(ch_roi[row]); for (int col=0; col<1024; col++) { evnt_data[row][col] = ntohs(evnt_data[row][col]); } } printf("Channel IDs:\n"); for (int ch=0; ch<36; ch++){ printf("0x%.2X ",ch_id[ch]); } printf("\n"); printf("Channel Start Cells:\n"); for (int ch=0; ch<36; ch++){ printf("%4d ",ch_start_cell[ch]); } printf("\n"); printf("Channel ROIs:\n"); for (int ch=0; ch<36; ch++){ printf("%4d ",ch_roi[ch]); } printf("\n"); printf ("maximal ROI was %d \n\n", max_roi); // print channel data in hex format if (print_data && print_hex) { for (int col = 0; col < max_roi; col++) { for (int row = 0; row < 36; row++) { printf ("0x%.4X ", evnt_data[row][col] ); } printf ("\n"); } } // print channel data in decimal format if (print_data && print_dec) { for (int col = 0; col < max_roi; col++) { for (int row = 0; row < 36; row++) { printf ("%.4d ", evnt_data[row][col] ); } printf ("\n"); } } // print channel data in ad9238 offset binary format // only the first lowest 13bits should contain data, // if this is not true and some data 1s sit in the upper 3positions // strange things might happen if (print_data && print_offsbin) { short sd; // just a dummy to calculate signed adc value for (int col = 0; col < max_roi; col++) { for (int row = 0; row < 36; row++) { // the overflow bit is the 13th bit (when you say LSB = 1st bit) // to shift a 1 to this position one has to use (1<<12), not (1<<13) // 1<<0 is 0x0001 // 1<<1 is 0x0002 // 1<<12 is 0x1000 or 0001.0000.0000.0000 if ((evnt_data[row][col] & (1<<12))) // the overflow bit is set { if ((evnt_data[row][col] & ~(1<<12)) > 0 ) // this was an OVERflow { sd = 0x7FFF; // dec=32767 highest possible value of signed short! }else { // this was an UNDERflow sd = 0x8000; // dec=-32768 lowest possible value of signed short } }else{ // data is okay, no overflow or underflow // since ADC data format is 12bit offset binary // I shift the numbers from 0..4095 to -2048 .. +2047 sd = evnt_data[row][col] - (1<<11); } printf ("%.4d ", sd ); } printf ("\n"); } } // print channel data in ad9238 in twos complement format // only the first lowest 13bits should contain data, // if this is not true and some data 1s sit in the upper 3positions // strange things might happen if (print_data && print_twoscompl) { short sd; // just a dummy to calculate signed adc value for (int col = 0; col < max_roi; col++) { for (int row = 0; row < 36; row++) { // the overflow bit is the 13th bit (when you say LSB = 1st bit) // to shift a 1 to this position one has to use (1<<12), not (1<<13) // 1<<0 is 0x0001 // 1<<1 is 0x0002 // 1<<12 is 0x1000 or 0001.0000.0000.0000 if ((evnt_data[row][col] & (1<<12))) // the overflow bit is set { if ((evnt_data[row][col] & ~(1<<12)) > 0 ) // this was an OVERflow { sd = 0x7FFF; // dec=32767 highest possible value of signed short! }else { // this was an UNDERflow sd = 0x8000; // dec=-32768 lowest possible value of signed short } }else{ // data is okay, no overflow or underflow // AD9238 twos complement // positive numbers will look like: 0000.0xxx.xxxx.xxxx // negative numbers will look like: 0000.1xxx.xxxx.xxxx // the bit shift operators are smart for signed integer data types. // shifting back and forth should do the trick. sd = (evnt_data[row][col]<<4); sd = (sd>>4); } printf ("%.4d ", sd ); } printf ("\n"); } } // CRC, only if version > 0x0100 if (ntohs (evnt->evnt_header.version_no) > 0x0100) { fread (&evnt->package_crc, sizeof (evnt->package_crc), 1, fhandle); printf ("\nPackage CRC: 0x%.4X\n", ntohs (evnt->package_crc)); } // end package flag fread (&evnt->end_package_flag, sizeof (evnt->end_package_flag), 1, fhandle); printf ("\nEnd Package Flag: 0x%.4X\n\n", ntohs (evnt->end_package_flag)); } else { // end of file reached ... or something else ... printf ("\nCould not read event no.: %d (end of file?)\n", evnt_cnt); return (1); } // free memory of evnt structure free (evnt); } // close file fclose (fhandle); } exit (0); } void usage(char *argv) { printf ("\nUsage: %s [--no-data] FILE\n", argv); }