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);
|
|
}
|