808 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			808 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | // Copyright Doug Lewis Sept 2017  | ||
|  | 
 | ||
|  | #include <stdio.h> | ||
|  | #include <stdlib.h> | ||
|  | #include <prussdrv.h> | ||
|  | #include <pruss_intc_mapping.h> | ||
|  | #include <stdint.h> | ||
|  | #include <unistd.h> | ||
|  | #include <string.h> | ||
|  | #include <errno.h> | ||
|  | #include <signal.h> | ||
|  | #include <fcntl.h> | ||
|  | #include <ctype.h> | ||
|  | #include <termios.h> | ||
|  | #include <sys/types.h> | ||
|  | #include <sys/mman.h> | ||
|  | #include <sys/socket.h> | ||
|  | #include <netinet/in.h> | ||
|  | #include <netdb.h> | ||
|  | #include <arpa/inet.h> | ||
|  | 
 | ||
|  | 
 | ||
|  | #include </home/erps/daq2/pruSrc/pruadc.h> | ||
|  | 
 | ||
|  |   | ||
|  | unsigned int adc_pru_data0[ADC_PRU_DATA_SIZE]; | ||
|  | unsigned int adc_pru_data1[ADC_PRU_DATA_SIZE]; | ||
|  | 
 | ||
|  | typedef struct adc_conf_t { | ||
|  |    unsigned int cycles_per_clock; | ||
|  |    unsigned int down_sample; | ||
|  |    unsigned int control_string; | ||
|  |    unsigned int num_blocks;  // File size in number of 128k blocks to record | ||
|  |    unsigned int block_size; | ||
|  |    unsigned int mode; | ||
|  |    unsigned int addr; | ||
|  |    unsigned int size; | ||
|  |    } adc_conf; | ||
|  |     | ||
|  | 
 | ||
|  | 
 | ||
|  | unsigned int readFileValue(char filename[]){ | ||
|  |    FILE* fp; | ||
|  |    unsigned int value = 0; | ||
|  |    fp = fopen(filename, "rt"); | ||
|  |    fscanf(fp, "%x", &value); | ||
|  |    fclose(fp); | ||
|  |    return value; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | unsigned int adc_conf_set_address(adc_conf *conf) { | ||
|  |     //conf->addr = ADC_PRU_DATA_SIZE + readFileValue(MMAP1_LOC "addr"); | ||
|  |     conf->addr = readFileValue(MMAP1_LOC "addr"); | ||
|  | } | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_address(adc_conf *conf) { | ||
|  |     return (conf->addr); | ||
|  | } | ||
|  | 
 | ||
|  | unsigned int adc_conf_set_size(adc_conf *conf) { | ||
|  |     conf->size = readFileValue(MMAP1_LOC "size"); | ||
|  | } | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_size(adc_conf *conf) { | ||
|  |     return(conf->size); | ||
|  | } | ||
|  | 
 | ||
|  | int adc_conf_set_cycles_per_clock (adc_conf *conf, unsigned int cycles) { | ||
|  |     conf->cycles_per_clock = cycles; | ||
|  | } | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_cycles_per_clock (adc_conf *conf) { | ||
|  |     return (conf->cycles_per_clock) ; | ||
|  | } | ||
|  | 
 | ||
|  | int adc_conf_set_mode(adc_conf *conf, unsigned int mode){ | ||
|  |     conf->mode = mode; | ||
|  | }  | ||
|  | 
 | ||
|  | int adc_conf_set_block_size(adc_conf *conf, unsigned int block_size){ | ||
|  |     conf->block_size = block_size; | ||
|  | }  | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_mode (adc_conf *conf) { | ||
|  |     return (conf->mode) ; | ||
|  | } | ||
|  | 
 | ||
|  | int adc_conf_set_down_sample(adc_conf *conf, unsigned int down_sample){ | ||
|  |     conf->down_sample = down_sample; | ||
|  | }  | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_down_sample(adc_conf *conf){ | ||
|  |     return (conf->down_sample);  | ||
|  | }  | ||
|  | int adc_conf_set_control_string(adc_conf *conf, unsigned int control_string){ | ||
|  |     conf->control_string = control_string; | ||
|  | }  | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_control_string(adc_conf *conf){ | ||
|  |     return (conf->control_string);  | ||
|  | }  | ||
|  | 
 | ||
|  | int adc_conf_set_data_file_size(adc_conf *conf, unsigned int data_file_size){ | ||
|  |     conf->num_blocks = data_file_size; | ||
|  | }  | ||
|  | 
 | ||
|  | unsigned int adc_conf_get_data_file_size(adc_conf *conf){ | ||
|  |     return (conf->num_blocks);  | ||
|  | } | ||
|  | 
 | ||
|  | int default_daq_init(adc_conf *conf) { | ||
|  |     adc_conf_set_cycles_per_clock(conf, ADS_CLOCKS); | ||
|  |     adc_conf_set_mode(conf, STOP); | ||
|  |     adc_conf_set_down_sample(conf, ADS_SAMPLE_DIVISOR); | ||
|  |     adc_conf_set_control_string(conf, ADS_CONTROL_STRING); | ||
|  |     adc_conf_set_block_size(conf, BUFSIZE);  // Default block size is 128k | ||
|  |     adc_conf_set_data_file_size(conf, DAQ_FILE_SIZE); | ||
|  |     adc_conf_set_address(conf); | ||
|  |     adc_conf_set_size(conf); | ||
|  | }  | ||
|  | 
 | ||
|  | int adc_conf_settings(adc_conf *conf) { | ||
|  |      | ||
|  | return (OK); | ||
|  | } | ||
|  | 
 | ||
|  | int main(int argc, char **argv)  | ||
|  | { | ||
|  |     char in_char = '0'; | ||
|  |     struct adc_conf *conf; | ||
|  |     unsigned int *sample; | ||
|  |     void *addr; | ||
|  |     int read_fd; | ||
|  |     int i = 0; | ||
|  |   | ||
|  |     conf = malloc(sizeof (adc_conf)); | ||
|  |     sample = malloc(sizeof(unsigned int) * 8); | ||
|  | 
 | ||
|  |     if(getuid()!=0){ | ||
|  |         printf("You must run this program as root. Exiting.\n"); | ||
|  |         exit(EXIT_FAILURE); | ||
|  |     } | ||
|  |     // Initialize structure used by prussdrv_pruintc_intc | ||
|  |     // PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h | ||
|  |     tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; | ||
|  | 
 | ||
|  |     // Read in the location and address of PRU shared memory. This value changes | ||
|  |     // each time a new block of memory is allocated. | ||
|  | 
 | ||
|  |     default_daq_init((adc_conf *) conf); | ||
|  | 
 | ||
|  | 
 | ||
|  |     // data for setting up the ADC on PRU0.  | ||
|  |     adc_pru_data0[0] = adc_conf_get_cycles_per_clock ((adc_conf *)conf); | ||
|  |     adc_pru_data0[1] = adc_conf_get_mode ((adc_conf *)conf);  | ||
|  |     adc_pru_data0[2] = adc_conf_get_control_string ((adc_conf *)conf);  | ||
|  |     adc_pru_data0[3] = CHANGE;   // First time through, set to reflect changed. | ||
|  |     adc_pru_data0[4] = adc_conf_get_address((adc_conf *)conf); | ||
|  |     adc_pru_data0[5] = adc_conf_get_size((adc_conf *)conf); | ||
|  |     adc_pru_data0[6] = adc_conf_get_down_sample ((adc_conf *)conf);  | ||
|  |     adc_pru_data0[7] = adc_conf_get_data_file_size ((adc_conf *)conf); | ||
|  | 
 | ||
|  |     // data for setting up the ADC on PRU1.  | ||
|  |     adc_pru_data1[0] = adc_conf_get_cycles_per_clock ((adc_conf *)conf); | ||
|  |     adc_pru_data1[1] = adc_conf_get_mode ((adc_conf *)conf);  | ||
|  |     adc_pru_data1[2] = adc_conf_get_control_string ((adc_conf *)conf);  | ||
|  |     adc_pru_data1[3] = CHANGE;   // First time through, set to reflect changed. | ||
|  |     adc_pru_data1[4] = adc_conf_get_address((adc_conf *)conf);  | ||
|  |     adc_pru_data1[5] = adc_conf_get_size((adc_conf *)conf); | ||
|  |     adc_pru_data1[6] = adc_conf_get_down_sample ((adc_conf *)conf);  | ||
|  |     adc_pru_data1[7] = adc_conf_get_data_file_size ((adc_conf *)conf); | ||
|  | 
 | ||
|  |     for (i = 8; i < 32; i ++) | ||
|  |         adc_pru_data1[i] = 0; | ||
|  |     printf("PRU1 Clock Counter %d \n", adc_pru_data1[0]); | ||
|  |     printf("PRU1 ADC State   %d \n", adc_pru_data1[1]); | ||
|  |     printf("ADC1 Control String   %x \n", adc_pru_data1[2]); | ||
|  |     printf("ADC1 Control String Modified    %d \n", adc_pru_data1[3]); | ||
|  |     printf("PRU Shared Memory Address Pool: 0x%x\n", adc_pru_data1[4]); | ||
|  |     printf("PRU Shared Memory Pool Size: 0x%x\n", adc_pru_data1[5]); | ||
|  |     printf("Sample Divisor: 0x%x\n", adc_pru_data1[6]); | ||
|  |     printf("Number of 128k blocks to record 0x%x\n", adc_pru_data1[7]); | ||
|  | 
 | ||
|  |     // Allocate and initialize memory | ||
|  |     prussdrv_init (); | ||
|  |     prussdrv_open (PRU_EVTOUT_0); | ||
|  |   | ||
|  |     // Write the address and size into PRU0 Data RAM0.  | ||
|  |     prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, 32); | ||
|  | 
 | ||
|  |     // Map PRU's interrupts | ||
|  |     prussdrv_pruintc_init(&pruss_intc_initdata); | ||
|  |   | ||
|  |     // Load and execute the PRU program on the PRU | ||
|  |     prussdrv_exec_program (PRU1_ADC_CONTROL_PRU, "./pruadc1.bin"); | ||
|  |     printf("ADC Control PRU1 program running on PRU %x \n", PRU1_ADC_CONTROL_PRU); | ||
|  | 
 | ||
|  |     //prussdrv_exec_program (PRU0_ADC_CONTROL_PRU, "./pruadc0.bin"); | ||
|  |     //printf("ADC Control PRU0 program running on PRU %x \n", PRU0_ADC_CONTROL_PRU); | ||
|  |   | ||
|  |     if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ | ||
|  |         printf("Failed to open memory!"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  | 
 | ||
|  |     while (in_char != 'q') { | ||
|  |         printf("Enter Command : \n"); | ||
|  |         scanf( " %c", &in_char); | ||
|  |         switch (in_char) { | ||
|  | 
 | ||
|  |             // Write the file to a binary file. It cannot be opened to look at  | ||
|  |             // and will require postprocessing. | ||
|  |             case  'b' : | ||
|  |                printf("Binary data collection to file \n"); | ||
|  |                printf("Data collection started \n"); | ||
|  |                adc_pru_data0[1] = RUN; | ||
|  |                adc_pru_data0[3] = CHANGE; | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE); | ||
|  |               // prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE); | ||
|  |                data_to_bin_file (conf);            | ||
|  |                break; | ||
|  | 
 | ||
|  |             case 'c' : | ||
|  |                read_and_average_cal_data( ); | ||
|  |                break; | ||
|  | 
 | ||
|  |             // Write the file in a formatted hex value, with space separation  | ||
|  |             // between each of the channels in a sample so that the file is | ||
|  |             // human readable for quick looks. | ||
|  |             case 'f' :  | ||
|  |                printf("Formatted data collection \n"); | ||
|  |                printf("Data collection started \n"); | ||
|  |                adc_pru_data1[1] = RUN; | ||
|  |                adc_pru_data1[3] = CHANGE; | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE); | ||
|  |                //prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE); | ||
|  |                write_file_formatted ((adc_conf *)conf, 1);            | ||
|  |                //write_file_formatted ((adc_conf *)conf, 0);            | ||
|  |                break; | ||
|  | 
 | ||
|  |             case 'h' : | ||
|  |                printf("Data collection halted \n"); | ||
|  |                adc_pru_data1[1] = STOP; | ||
|  |                adc_pru_data1[3] = CHANGE; | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE); | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE); | ||
|  |                break; | ||
|  | 
 | ||
|  |             // Get a single sample, print it to the screen | ||
|  |             case 'o': | ||
|  |                printf("getting a single sample \n"); | ||
|  |                adc_pru_data1[1] = RUN; | ||
|  |                adc_pru_data1[3] = CHANGE; | ||
|  |                adc_conf_set_block_size((adc_conf *)conf, 32); | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE); | ||
|  |                sampleGet((adc_conf *)conf, 1, sample); | ||
|  |                break; | ||
|  | 
 | ||
|  |             // Write the file as binary. Indicate to PRU1 that this is a throughput test. | ||
|  |             // The data from PRU1 will contain a 24 bit counter which is incremented for  | ||
|  |             // each sample.` | ||
|  |             case 't' : | ||
|  |             printf("Throughput Test Mode, Binary data collection to file \n"); | ||
|  |                printf("Data generation started \n"); | ||
|  |                adc_pru_data1[1] = TEST; | ||
|  |                adc_pru_data1[3] = CHANGE; | ||
|  |                addr = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, adc_pru_data1[4] & ~MAP_MASK); | ||
|  |                bzero((void *) addr, (size_t) (PRU1_START_OFFSET + BUF_HDR_SIZE));  | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE); | ||
|  |                data_to_bin_file ((adc_conf *)conf); | ||
|  |                break; | ||
|  | 
 | ||
|  |             case 's' : | ||
|  |                printf("Start PRU Data collection, and return \n"); | ||
|  |                adc_pru_data1[1] = TEST; | ||
|  |                adc_pru_data1[3] = CHANGE; | ||
|  |                prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE); | ||
|  |                break; | ||
|  | 
 | ||
|  |             case 'p' : | ||
|  |                get_buff_stats((adc_conf *)conf); | ||
|  |                break; | ||
|  |             default : | ||
|  |                printf("Command not recognized %c \n", in_char); | ||
|  |         } | ||
|  |     } | ||
|  |     prussdrv_exit (); | ||
|  | } | ||
|  |   | ||
|  | 
 | ||
|  | // Write data to a file so that the hex info can be looked at raw. | ||
|  | // Formatting makes it easy to look at hex values of each channel per sample. | ||
|  | // Also, this operation takes a relatively small set of samples, as opposed to | ||
|  | // a longer duration continuous recording. | ||
|  | int write_file_formatted (adc_conf *conf, int pru_num) | ||
|  | { | ||
|  | 
 | ||
|  |     int read_fd; | ||
|  |     FILE *write_fd; | ||
|  |     void *map_base, *virt_addr; | ||
|  |     unsigned long read_result; | ||
|  |     int result; | ||
|  |     unsigned int addr = conf->addr; | ||
|  |     unsigned int size = conf->size; | ||
|  | 
 | ||
|  |     if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ | ||
|  |         printf("Failed to open memory!"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  |     printf("Memory file open successfully \n"); | ||
|  | 
 | ||
|  |     if (pru_num == 1) { | ||
|  |         if((write_fd = fopen("/home/erps/data/outfile1.dat", "w")) == NULL){ | ||
|  |             printf("Failed to open data file \n"); | ||
|  |            return (ERR); | ||
|  |            addr += PRU1_START_OFFSET; | ||
|  |            printf("waiting on interrupt \n"); | ||
|  |            prussdrv_pru_wait_event (PRU_EVTOUT_0); | ||
|  |         } | ||
|  |     } else if (pru_num == 0) {  | ||
|  |         if((write_fd = fopen("/home/erps/data/outfile0.dat", "w")) == NULL){ | ||
|  |             printf("Failed to open data file \n"); | ||
|  |            return (ERR); | ||
|  |            addr += PRU0_START_OFFSET; | ||
|  |         } | ||
|  |     } else { | ||
|  |         printf("Invalid PRU %d \n", pru_num); | ||
|  |         return(ERR); | ||
|  |     }  | ||
|  |     | ||
|  |     printf("Data file open successfully \n"); | ||
|  | 
 | ||
|  |     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, addr & ~MAP_MASK); | ||
|  | 
 | ||
|  |     if(map_base == (void *) -1) { | ||
|  |        printf("Failed to map base address"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     printf("Reading data \n"); | ||
|  |     int i = 0; | ||
|  |     int j = 0; | ||
|  |     for(i = 0; i < size; i+= (8 * BYTES_PER_SAMPLE)){ | ||
|  | 
 | ||
|  |         for (j = 0; j < 8; j++) { | ||
|  |             virt_addr = map_base + (addr & MAP_MASK); | ||
|  |             read_result = *((uint32_t *) virt_addr); | ||
|  |            fprintf( write_fd, "0x%08x ", read_result); | ||
|  |            addr += BYTES_PER_SAMPLE; | ||
|  |         } | ||
|  |         fprintf(write_fd, "\n"); | ||
|  |     } | ||
|  | 
 | ||
|  |     if ((result = fclose (write_fd)) != 0) { | ||
|  |        printf("Error closing data file %d \n", result); | ||
|  |     } | ||
|  | 
 | ||
|  |     return (OK); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int sampleGet (adc_conf *conf, int pru_num, uint32_t *sample) | ||
|  | { | ||
|  | 
 | ||
|  |     int read_fd; | ||
|  |     FILE *write_fd; | ||
|  |     void *map_base, *virt_addr; | ||
|  |     unsigned long read_result; | ||
|  |     int result; | ||
|  |     unsigned int addr = conf->addr; | ||
|  | 
 | ||
|  |     if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ | ||
|  |         printf("Failed to open memory!"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  |     printf("Memory file open successfully \n"); | ||
|  | 
 | ||
|  | 
 | ||
|  |     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, conf->addr & ~MAP_MASK); | ||
|  | 
 | ||
|  |     if(map_base == (void *) -1) { | ||
|  |        printf("Failed to map base address"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     printf("Reading data \n"); | ||
|  |     int i = 0; | ||
|  |     int j = 0; | ||
|  |     for(i = 0; i < conf->size; i+= (8 * BYTES_PER_SAMPLE)){ | ||
|  | 
 | ||
|  |         for (j = 0; j < 8; j++) { | ||
|  |            virt_addr = map_base + (addr & MAP_MASK); | ||
|  |            //read_result = *((uint32_t *) virt_addr); | ||
|  |            *sample  = *((uint32_t *) virt_addr); | ||
|  |            sample ++; | ||
|  |            printf( "0x%08x ", sample); | ||
|  |            addr += BYTES_PER_SAMPLE; | ||
|  |         } | ||
|  |         fprintf(write_fd, "\n"); | ||
|  |     } | ||
|  | 
 | ||
|  |     return (OK); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int get_buff_stats(adc_conf *conf)  | ||
|  | { | ||
|  | 
 | ||
|  |     int i, buffs, buff_head_ptr; | ||
|  |     int read_fd; | ||
|  |     void *map_base, *virt_addr; | ||
|  |     unsigned long read_result; | ||
|  |     unsigned int addr = conf->addr; | ||
|  | 
 | ||
|  |     unsigned int pru1_wr_flag = addr; | ||
|  |     unsigned int pru1_buff_count = addr + 4; | ||
|  |     unsigned int pru1_head = addr + 8; | ||
|  |     unsigned int pru1_wrap_count = addr +12; | ||
|  | 
 | ||
|  |     unsigned int pru0_wr_flag = addr + 0x80; | ||
|  |     unsigned int pru0_buff_count = addr + 0x84; | ||
|  |     unsigned int pru0_head = addr + 0x88; | ||
|  |     unsigned int pru0_wrap_count = addr + 0x92; | ||
|  | 
 | ||
|  |     if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ | ||
|  |         printf("Failed to open memory!"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  |     printf("Memory file open successfully \n"); | ||
|  | 
 | ||
|  | 
 | ||
|  |     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, addr & ~MAP_MASK); | ||
|  | 
 | ||
|  |     if(map_base == (void *) -1) { | ||
|  |        printf("Failed to map base address"); | ||
|  |        return (ERR); | ||
|  | 
 | ||
|  |     } | ||
|  | 
 | ||
|  |     virt_addr = map_base + (pru1_wr_flag & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU1_WR_FLAG = %x ", read_result); | ||
|  |      | ||
|  |     virt_addr = map_base + (pru1_buff_count & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU1_BUFF_COUNT = %x ", read_result); | ||
|  | 
 | ||
|  |     addr += 4; | ||
|  |     virt_addr = map_base + (pru1_head & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU1_HEAD = %x ", read_result); | ||
|  | 
 | ||
|  |     virt_addr = map_base + (pru1_wrap_count & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU1_WRAP_COUNT = %x  \n", read_result); | ||
|  | 
 | ||
|  |     virt_addr = map_base + (addr & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU0_WR_FLAG = %x ", read_result); | ||
|  | 
 | ||
|  |     virt_addr = map_base + (addr & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU0_BUFF_COUNT = %x ", read_result); | ||
|  | 
 | ||
|  |     virt_addr = map_base + (addr & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU0_HEAD = %x ", read_result); | ||
|  | 
 | ||
|  |     virt_addr = map_base + (addr & MAP_MASK); | ||
|  |     read_result = *((uint32_t *) virt_addr); | ||
|  |     printf ("PRU0_WRAP_COUNT = %x  \n\n", read_result); | ||
|  | 
 | ||
|  |     return (OK); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | int tail_increment(int tail, int num) | ||
|  | { | ||
|  |     tail += num; | ||
|  |     if (tail == QUEUE_SIZE) | ||
|  |         tail = 0; | ||
|  |     return (tail); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int create_bind_accept_sock() | ||
|  | { | ||
|  |     #define PORT 12345 | ||
|  |     struct sockaddr_in addr; | ||
|  |     int addr_len = sizeof(addr); | ||
|  |     int new_sock_fd, server_fd; | ||
|  |     int backlog = 5; | ||
|  | 
 | ||
|  |     new_sock_fd = socket(AF_INET, SOCK_STREAM, 0); | ||
|  |     if(server_fd == ERR) | ||
|  |     { | ||
|  |         printf("Error opening socket\n"); | ||
|  |         return -1; | ||
|  |     } | ||
|  | 
 | ||
|  |     addr.sin_port = htons(PORT); | ||
|  |     addr.sin_addr.s_addr = 0; | ||
|  |     addr.sin_addr.s_addr = INADDR_ANY; | ||
|  |     addr.sin_family = AF_INET; | ||
|  | 
 | ||
|  |     if(bind(server_fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1) | ||
|  |     { | ||
|  |         printf("Error binding socket\n"); | ||
|  |         return (ERR); | ||
|  |     } | ||
|  | 
 | ||
|  |     printf("Socket Successfully bound to port %u\n", PORT); | ||
|  | 
 | ||
|  |     listen(server_fd, backlog); | ||
|  |     addr_len = sizeof(addr); | ||
|  |     new_sock_fd = accept(server_fd, (struct sockaddr *) &addr, (socklen_t*) &addr_len); | ||
|  |      if (new_sock_fd < 0)  | ||
|  |           error("ERROR on accept");  | ||
|  |     return(new_sock_fd); | ||
|  | } | ||
|  | 
 | ||
|  | int send_buffs_to_host (void *virt_addr, int num_buffs_to_write, int sock_fd) { | ||
|  | 
 | ||
|  |     int32_t bytesToSend = num_buffs_to_write * BUFSIZE; | ||
|  |     int32_t send_left = 0; | ||
|  |     uint8_t *addr = virt_addr; | ||
|  |     struct timeval timeout; | ||
|  | 
 | ||
|  |     timeout.tv_sec = 5; | ||
|  |     timeout.tv_usec = 0; | ||
|  | 
 | ||
|  |     while (bytesToSend > 0 || (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) > 0)) | ||
|  |                                                                                                                    | ||
|  |     { | ||
|  | 	if ((send_left = send(sock_fd, (uint8_t*)addr, bytesToSend, 0)) < 0) | ||
|  | 	{ | ||
|  |             printf("ERROR: Failed to send buffer contents across TCPIP.\n"); | ||
|  |             return(ERR); | ||
|  |         } | ||
|  |         bytesToSend -= send_left; | ||
|  |         addr += send_left; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | process_buffers(void *virt_addr, int num_buffs_to_write, int sock_fd, FILE *write_fd, int8_t flash_record, int8_t network_send) | ||
|  | { | ||
|  |     uint32_t wr_num; | ||
|  | 
 | ||
|  |     if (flash_record == ENABLED)  | ||
|  |          wr_num = write_buffs_to_flash (virt_addr, num_buffs_to_write, write_fd);  | ||
|  | 
 | ||
|  |     if (network_send == ENABLED) | ||
|  |         send_buffs_to_host (virt_addr, num_buffs_to_write, sock_fd); | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int write_buffs_to_flash (void *virt_addr, int num_buffs_to_write, FILE * write_fd) { | ||
|  |     int wr_num = 0; | ||
|  | 
 | ||
|  |     wr_num = fwrite ( virt_addr, sizeof(uint8_t),   num_buffs_to_write * BUFSIZE, write_fd); | ||
|  | 
 | ||
|  |     if (wr_num != num_buffs_to_write * BUFSIZE)  | ||
|  |     { | ||
|  |       printf ("Error writing flash file %d \n", errno); | ||
|  |       strerror(errno); | ||
|  |     } | ||
|  |     return (wr_num); | ||
|  | } | ||
|  |   | ||
|  | int data_to_bin_file (adc_conf *conf) | ||
|  | {             | ||
|  |     int i, j, k; | ||
|  |     int  buffs = 0; | ||
|  |     unsigned long read_result; | ||
|  |     int read_fd; | ||
|  |     FILE *write_fd; | ||
|  |     void *map_base, *virt_addr; | ||
|  |     void *pru1_wr_flag_addr; | ||
|  |     void *pru1_buff_count_addr; | ||
|  |     void *pru1_head_addr; | ||
|  |     void *pru1_wrap_count_addr; | ||
|  |     int wr_num = 0; | ||
|  |     int tail = 0; | ||
|  |     int num_buffs = 0; | ||
|  |     int num_buffs_to_write = 0; | ||
|  |     int last_count = 0; | ||
|  |     int num_buffs_processed = 0; | ||
|  |     volatile unsigned long pru1_wr_flag = 0; | ||
|  |     volatile unsigned long pru1_buff_count = 0; | ||
|  |     volatile unsigned long pru1_head = 0;  | ||
|  |     volatile unsigned long pru1_wrap_count = 0;  | ||
|  |     unsigned int addr = conf->addr; | ||
|  |     unsigned int pru1_conf_addr = conf->addr; | ||
|  |     int iteration = 0; | ||
|  |     int client_sock_fd = 0; | ||
|  |     int network_send = TRUE; | ||
|  |     int flash_record = TRUE; | ||
|  | 
 | ||
|  |     if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ | ||
|  |         printf("Failed to open memory!"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  |     printf("Memory file open successfully \n"); | ||
|  | 
 | ||
|  |     write_fd =  fopen("/home/erps/data/outfile.bin", "wb"); | ||
|  |     if( write_fd  == NULL){ | ||
|  |         printf("Failed to open data file \n"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  | 
 | ||
|  |     printf("Data file open successfully \n"); | ||
|  | 
 | ||
|  |     client_sock_fd = create_bind_accept_sock(); | ||
|  |     if (client_sock_fd != ERR) | ||
|  |        printf("Socket Successfully created \n"); | ||
|  | 
 | ||
|  |     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, addr & ~MAP_MASK); | ||
|  | 
 | ||
|  |     if(map_base == (void *) -1) { | ||
|  |        printf("Failed to map base address"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  |     else { | ||
|  |        printf("Base Address = %x \n", map_base); | ||
|  |     } | ||
|  |   | ||
|  | #if DEBUG  | ||
|  |     printf("Dumping header data \n"); | ||
|  |     i = 0; | ||
|  |     j = 0; | ||
|  |     for(i = 0; i < (PRU1_START_OFFSET + 256); i+= (8 * BYTES_PER_SAMPLE)){ | ||
|  | 
 | ||
|  |         for (j = 0; j < 8; j++) { | ||
|  |             virt_addr = map_base + (addr & MAP_MASK); | ||
|  |             read_result = *((uint32_t *) virt_addr); | ||
|  |            printf(  "0x%08x ", read_result); | ||
|  |            addr += BYTES_PER_SAMPLE; | ||
|  |         } | ||
|  |         printf("\n"); | ||
|  |     } | ||
|  | #endif  | ||
|  |     pru1_conf_addr = conf->addr; | ||
|  | 
 | ||
|  |     addr = conf->addr + PRU1_START_OFFSET;  | ||
|  |     pru1_wr_flag_addr = map_base + ((pru1_conf_addr + PRU1_WR_FLAG) & MAP_MASK); | ||
|  |     pru1_wr_flag = *((uint32_t *) pru1_wr_flag_addr); | ||
|  | 
 | ||
|  |     pru1_buff_count_addr = map_base + ((pru1_conf_addr + PRU1_BUFF_COUNT) & MAP_MASK); | ||
|  |     pru1_buff_count = *((uint32_t *) pru1_buff_count_addr); | ||
|  | 
 | ||
|  |     pru1_head_addr = map_base + ((pru1_conf_addr + PRU1_HEAD) & MAP_MASK); | ||
|  |     pru1_head = *((uint32_t *) pru1_head_addr); | ||
|  | 
 | ||
|  |     pru1_wrap_count_addr = map_base + ((pru1_conf_addr + PRU1_WRAP_COUNT) & MAP_MASK); | ||
|  |     pru1_wrap_count = *((uint32_t *) pru1_wrap_count_addr); | ||
|  | 
 | ||
|  |     tail = 0; | ||
|  |     //tail = 4;   // this is for test purposes only | ||
|  | 
 | ||
|  |     while (num_buffs_processed < DAQ_FILE_SIZE)   | ||
|  |     {  | ||
|  |         virt_addr  = map_base + ((pru1_conf_addr + PRU1_WR_FLAG) & MAP_MASK); | ||
|  |         pru1_wr_flag = *((uint32_t *) pru1_wr_flag_addr); | ||
|  | 
 | ||
|  |         pru1_buff_count_addr = map_base + ((pru1_conf_addr + PRU1_BUFF_COUNT) & MAP_MASK); | ||
|  |         pru1_buff_count = *((uint32_t *) pru1_buff_count_addr); | ||
|  | 
 | ||
|  |         pru1_head_addr = map_base + ((pru1_conf_addr + PRU1_HEAD) & MAP_MASK); | ||
|  |         pru1_head = *((uint32_t *) pru1_head_addr); | ||
|  | 
 | ||
|  |         pru1_wrap_count_addr = map_base + ((pru1_conf_addr + PRU1_WRAP_COUNT) & MAP_MASK); | ||
|  |         pru1_wrap_count = *((uint32_t *) pru1_wrap_count_addr); | ||
|  | 
 | ||
|  |         if (pru1_wr_flag == 1) | ||
|  |         {  | ||
|  |             num_buffs = pru1_buff_count - last_count; | ||
|  |              | ||
|  |             if (num_buffs > 0) | ||
|  |             { | ||
|  |                 printf("h = %d, t = %d, num_buffs = %d ", pru1_head, tail, num_buffs); | ||
|  |             } | ||
|  |             if (num_buffs <= QUEUE_SIZE)  | ||
|  |             { | ||
|  |                 if (tail < pru1_head)  | ||
|  |                 { | ||
|  |                     num_buffs_to_write = pru1_head - tail; | ||
|  |                     virt_addr =  map_base + (addr & MAP_MASK); | ||
|  |                     process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send); | ||
|  |                     num_buffs_processed += num_buffs_to_write; | ||
|  |                     addr += num_buffs_to_write * BUFSIZE; | ||
|  |                     tail = tail_increment(tail, num_buffs_to_write); | ||
|  |                     pru1_wr_flag = 0; | ||
|  |                 } | ||
|  |                 else if (tail > pru1_head) | ||
|  |                 { | ||
|  |                     // Write the buffers from the tail to the end of the queue. | ||
|  |                     virt_addr =  map_base + (addr & MAP_MASK); | ||
|  |                     num_buffs_to_write = QUEUE_SIZE - tail; | ||
|  |                     process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send); | ||
|  | 
 | ||
|  |                     addr += num_buffs_to_write * BUFSIZE;  | ||
|  |                     tail = tail_increment(tail, num_buffs_to_write); | ||
|  |                     num_buffs_processed += num_buffs_to_write; | ||
|  | 
 | ||
|  |                     // Write the buffers from the beginning of the queue (zeroth element) to the head | ||
|  |                     virt_addr =  map_base + (addr & MAP_MASK); | ||
|  |                     num_buffs_to_write = pru1_head; | ||
|  | 
 | ||
|  |                     process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send); | ||
|  |                     addr += num_buffs_to_write * BUFSIZE; | ||
|  |                     num_buffs_processed += num_buffs_to_write; | ||
|  |                     tail = tail_increment(tail, num_buffs_to_write); | ||
|  |                 } | ||
|  |                 else if ((tail == pru1_head) && (num_buffs == QUEUE_SIZE)) | ||
|  |                 { | ||
|  |                     // Write the buffers from the tail to the end of the queue. | ||
|  |                     virt_addr =  map_base + (addr & MAP_MASK); | ||
|  |                     num_buffs_to_write += QUEUE_SIZE  - tail; | ||
|  | 
 | ||
|  |                     process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send); | ||
|  |                     num_buffs_processed += num_buffs_to_write; | ||
|  |                     addr += num_buffs_to_write * BUFSIZE;  | ||
|  |                     tail = tail_increment(tail, num_buffs_to_write); | ||
|  | 
 | ||
|  |                     // Write the buffers from the beginning of the queue to the head | ||
|  |                     virt_addr =  map_base + (addr & MAP_MASK); | ||
|  |                     num_buffs_to_write = pru1_head; | ||
|  | 
 | ||
|  |                     process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send); | ||
|  |                     addr += num_buffs_to_write * BUFSIZE;  | ||
|  |                     num_buffs_processed += num_buffs_to_write; | ||
|  |                     tail = tail_increment(tail, num_buffs_to_write); // This may look funny, but we are incrementing tail by tail. | ||
|  |                 } | ||
|  |                 pru1_wr_flag = 0; | ||
|  |                 if (num_buffs > 0) | ||
|  |                 { | ||
|  |                     printf("num_buffs_processed = %d \n", num_buffs_processed); | ||
|  |                 } | ||
|  |                 last_count = pru1_buff_count; | ||
|  |                 usleep(1000); | ||
|  |             } | ||
|  |             else if (num_buffs > QUEUE_SIZE)  | ||
|  |             { | ||
|  |                 printf("Queue overflow %d \n", num_buffs); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     printf("TOTAL num_buffs_processed = %d \n", num_buffs_processed); | ||
|  |     fclose ((FILE *)write_fd); | ||
|  | 
 | ||
|  |     return (OK); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | read_and_average_cal_data( ) { | ||
|  |     FILE *read_fd; | ||
|  |     int i = 0; | ||
|  |     int j = 0; | ||
|  |     uint32_t s[8]; | ||
|  |     uint32_t total[8]; | ||
|  |     uint32_t average[8]; | ||
|  | 
 | ||
|  |     read_fd =  fopen("/home/erps/caldata/5Vcal_with2p2res.dat", "r"); | ||
|  |     if( read_fd  == NULL){ | ||
|  |         printf("Failed to open data file \n"); | ||
|  |        return (ERR); | ||
|  |     } | ||
|  |     else | ||
|  |         printf("Cal File Opened \n"); | ||
|  |      | ||
|  |     for (i = 0; i < 8; i ++){ | ||
|  |         fscanf(read_fd, "%x %x %x %x %x %x %x %x \n", &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7]); | ||
|  | //        printf("%x %x %x %x %x %x %x %x \n", s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]); | ||
|  |     } | ||
|  | 
 | ||
|  |     for (i = 0; i < 8; i ++) { | ||
|  |         total[i] = 0; | ||
|  |         s[i] = 0; | ||
|  |         average[i] = 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     for (i = 0; i < 100; i ++) { | ||
|  |         for (j = 0; j < 8; j++) { | ||
|  |             fscanf(read_fd, "%x", &s[j]); | ||
|  |             s[j] &= s[j] & 0x0FFFFFF; | ||
|  |             total[j] += s[j]; | ||
|  |         } | ||
|  |         fscanf(read_fd, "\n"); | ||
|  |         printf("%x %x %x %x %x %x %x %x \n",s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]); | ||
|  |         printf("%x %x %x %x %x %x %x %x \n",total[0], total[1], total[2], total[3], total[4], total[5], total[6], total[7]); | ||
|  |     } | ||
|  | 
 | ||
|  |     for (i = 0; i < 8; i ++) | ||
|  |     { | ||
|  |         average[i] = total[i] / 100; | ||
|  |     } | ||
|  | 
 | ||
|  |     printf("%x %x %x %x %x %x %x %x \n",average[0], average[1], average[2], average[3], average[4], average[5], average[6], average[7]); | ||
|  |     fclose ((FILE *)read_fd); | ||
|  | } |