KISS Data Aquisition and Control System
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

966 lines
32 KiB

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