// Copyright Doug Lewis Sept 2017 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 client_sock_fd = 0; 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, client_sock_fd); break; case 'c' : generate_cal_data( ); break; case 'e': client_sock_fd = create_bind_accept_sock(); if (client_sock_fd != ERR) printf("Socket Successfully created \n"); printf("Entering client control mode \n"); client_main(conf, client_sock_fd, adc_pru_data0, adc_pru_data1); 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, client_sock_fd); 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 (); } int client_main(adc_conf *conf, int clientSockFd) { char sendMessage[256] = {'\0'}; char recvMessage[256]; char exit[256]; char timeString[32]; int readSize = 0; char recStartMessage[256]; size_t length = 0; strcpy(exit, "exit"); while (strncmp(exit, recvMessage, 4) != 0) { readSize = recv(clientSockFd, recvMessage, sizeof(recvMessage) , 0); printf("Received message: %s from client \n", recvMessage); if (strncmp("record", recvMessage, 6) == 0) { strncpy (sendMessage, "recstart,2000 \0 ", 13); length = strlen(sendMessage); send(clientSockFd, sendMessage, length, 0); strncpy(timeString, &recvMessage[6], 14); recording_start(conf, clientSockFd, timeString); strncpy (sendMessage, "recdone ", 16); length = strlen(sendMessage); send(clientSockFd, sendMessage, length, 0); } } close(clientSockFd); } int recording_start( adc_conf *conf, int client_sock_fd, char timeString[]) { char fileString[128] = "/home/erps/data/dataFile"; printf("Binary data collection to file \n"); printf("Data collection started \n"); //adc_pru_data1[1] = TEST; 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); strncat(fileString, timeString, 14); strncat(fileString, ".bin\0", 6); printf("Recording File = %s \n", fileString); data_to_bin_file (conf, client_sock_fd, fileString); } // 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 8888 struct sockaddr_in server, client; int addr_len = sizeof(server); int sock_descriptor, client_sock; int backlog = 5; sock_descriptor = socket(AF_INET, SOCK_STREAM, 0); if(sock_descriptor == ERR) { printf("Error opening socket\n"); return -1; } printf("Socket Created \n"); server.sin_port = htons(PORT); server.sin_addr.s_addr = INADDR_ANY; server.sin_family = AF_INET; if (bind(sock_descriptor, (struct sockaddr *)&server, sizeof(struct sockaddr_in) ) == -1) { printf("Error binding socket\n"); return (ERR); } printf("Socket Successfully bound to port %u\n", PORT); listen(sock_descriptor, backlog); addr_len = sizeof(server); client_sock = accept(sock_descriptor, (struct sockaddr *) &client, (socklen_t*) &addr_len); if (client_sock < 0) { error("ERROR on accept"); } else { printf("Client socket connection accepted \n"); } return(client_sock); } 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 sent = 0; uint8_t *addr = virt_addr; struct timeval timeout; timeout.tv_sec = 2; timeout.tv_usec = 0; while (bytesToSend > 0 || (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) > 0)) //while (bytesToSend > 0) { if ((sent = send(sock_fd, (uint8_t*)addr, bytesToSend, 0)) < 0) { printf("ERROR: Failed to send buffer contents across TCPIP.\n"); system("ifconfig eth0 192.168.8.2"); return(ERR); } bytesToSend -= sent; addr += sent; } } 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 client_sock_fd, char dataFile[]) { 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 count = 0; int network_send = TRUE; //int network_send = FALSE; 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(dataFile, "wb"); if( write_fd == NULL){ printf("Failed to open data file \n"); 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); } 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; 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 // We have to remember to set the pointer back to the beginning of shared memory addr = conf->addr + PRU1_START_OFFSET; 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 addr = conf->addr + PRU1_START_OFFSET; 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) { count += num_buffs; if (count >= 30) { printf("h = %d, t = %d, num_buffs = %d ", pru1_head, tail, num_buffs); printf("num_procd = %d, addr = %x \n", num_buffs_processed, addr); count = 0; } // if (num_buffs_processed >= 180) // { // printf("num_procd = %d, addr = %x \n", num_buffs_processed, addr); // // this is a place to set a breakpoint // } } last_count = pru1_buff_count; usleep(100); } else if (num_buffs > QUEUE_SIZE) { // We have detected an overflow condition, likely due to some linux related activity. // For now we throw out the buffers that have accumulated. Later we can explore saving // those buffers. printf("Queue overflow %d \n", num_buffs); last_count = pru1_buff_count; num_buffs_processed += num_buffs; usleep(100); } } } printf("TOTAL num_buffs_processed = %d \n", num_buffs_processed); fclose ((FILE *)write_fd); return (OK); } generate_cal_data( ) { FILE *read_5v_fd; FILE *read_0v_fd; FILE *write_fd; uint32_t average_5v[8]; uint32_t average_0v[8]; float ma[8]; uint32_t b[8]; int i; uint32_t temp; read_5v_fd = fopen("/home/erps/caldata/board1_5v_golden_063018.dat", "r"); if( read_5v_fd == NULL){ printf("Failed to open 5v cal data file \n"); return (ERR); } else printf("Cal File Opened \n"); read_and_average_cal_data(read_5v_fd, &average_5v[0]); printf("5V Averages %x %x %x %x %x %x %x %x \n\n",average_5v[0], average_5v[1], average_5v[2], average_5v[3], average_5v[4], average_5v[5], average_5v[6], average_5v[7]); read_0v_fd = fopen("/home/erps/caldata/board1_0v_golden_063018.dat", "r"); if( read_0v_fd == NULL){ printf("Failed to open 0v cal data file \n"); return (ERR); } else printf("Cal File Opened \n"); write_fd = fopen("/home/erps/caldata/board1_cal_golden_063018.dat", "w"); if( write_fd == NULL){ printf("Failed to open cal result file \n"); return (ERR); } else printf("Cal Result File Opened \n"); read_and_average_cal_data(read_0v_fd, &average_0v[0]); printf("0V Averages %x %x %x %x %x %x %x %x \n\n",average_0v[0], average_0v[1], average_0v[2], average_0v[3], average_0v[4], average_0v[5], average_0v[6], average_0v[7]); for (i = 0; i < 8; i++) { // y = mx + b //ma = (yH - yL) / (xH - xL) if (average_0v[i] & 0x800000) { temp = ~average_0v[i] & 0x00FFFFFF; ma[i] = (float)(average_5v[i] + temp) / 0x7FFFFF ; b[i] = temp * ma[i]; } else { ma[i] = (float)(average_5v[i] - average_0v[i]) / 0x7FFFFF ; b[i] = average_0v[i] * ma[i]; } } printf("\n\n"); printf(" ma:%f %f %f %f %f %f %f %f \n", ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], ma[6], ma[7]); printf(" b :%x %x %x %x %x %x %x %x \n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); fprintf(write_fd, "%f %f %f %f %f %f %f %f \n", ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], ma[6], ma[7]); fprintf(write_fd, "%x %x %x %x %x %x %x %x \n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); fclose ((FILE *)read_5v_fd); fclose ((FILE *)read_0v_fd); fclose ((FILE *)write_fd); } read_and_average_cal_data(FILE *read_fd, uint32_t *average[]) { int i = 0; int j = 0; uint32_t s[8]; uint64_t total[8]; int64_t tot[8]; for (i = 0; i < 9; 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 < 8; i ++) { for (j = 0; j < 8; j++) { fscanf(read_fd, "%x", &s[j]); s[j] &= s[j] & 0x0FFFFFF; if (s[j] & 0x800000) { s[j] = ~s[j] & 0xFFFFFF; tot[j] -= s[j]; } tot[j] += s[j]; total[j] += s[j]; } fscanf(read_fd, "\n"); } printf("Totals %x %x %x %x %x %x %x %x \n \n",total[0], total[1], total[2], total[3], total[4], total[5], total[6], total[7]); printf("Totals %x %x %x %x %x %x %x %x \n \n",(uint32_t)tot[0], (uint32_t) tot[1], (uint32_t) tot[2], (uint32_t) tot[3], (uint32_t) tot[4], (uint32_t) tot[5], (uint32_t)tot[6], (uint32_t)tot[7]); for (i = 0; i < 8; i ++) { average[i] = total[i] / 8; } }