#include <iostream>
#include <sstream>
#include <csignal>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <DAQ++/GTimer.h>
#include <daq/random.h>
#include <daq/random.c>
#define FIFO_SIZE 4096
bool doLoop = true;
void quit(int)
{
doLoop = false;
}
#define RATE 1
#define NCHAN 20
struct ADCRecord
{
unsigned long id; // 'CSPT'
unsigned char version;
unsigned char reclen; // # of bytes in record
unsigned char status;
unsigned char CSR;
unsigned short wordcount; // number of events left (we won't use this)
unsigned short counter; // event counter (16 bits)
unsigned char boardID; // ID (8 bit switch) of this CSPRINT ADC board
unsigned char preamp3; // 20 bits to enable/disable individual preamps
unsigned char preamp2;
unsigned char preamp1;
unsigned short adc[NCHAN]; // 20 adc words, 12 bits
unsigned short adcsum; // energy sum adc
};
union Record {
ADCRecord adc;
char data[1];
};
int main(int argc, char **argv)
{
DAQpp::GTimer timer;
Record usb;
double freq = 50.;
if (argc == 1)
{
std::cout << "usage: usbsim file frequency" << std::endl;
return 1;
}
if (argv[1])
{
if ( access(argv[1], F_OK) )
{
// create the file
if ( mkfifo(argv[1], 0660) )
{
perror("Could not create the fifo:\n\t");
return 1;
}
}
}
if ( argv[2] )
{
std::istringstream os(argv[2]);
os >> freq;
}
std::cout << "Freq. should be " << freq << "Hz" << std::endl;
volatile unsigned long iloop;
unsigned long nloop = 1000000;
timer.start();
for (iloop = 0;iloop < nloop;iloop++);
nloop = (unsigned long)(((double)nloop) / timer() / freq);
std::cout << "nloop " << nloop << std::endl;
int fd = open (argv[1], O_WRONLY);
if (fd < 0)
{
std::cerr << "Could not open " << argv[1] << std::endl;
perror(":");
return 1;
}
// now we write every now and then
memset(&usb, 0, sizeof(Record));
usb.data[0] = 'C';
usb.data[1] = 'S';
usb.data[2] = 'P';
usb.data[3] = 'T';
usb.adc.counter = 0;
usb.adc.version = '1';
usb.adc.boardID = 'E';
usb.adc.reclen = sizeof(ADCRecord);
int i, j = 0;
int ichan, nleft;
double cmmd, val;
while (doLoop)
{
for (iloop = 0;iloop < nloop;iloop++);
j = usb.adc.counter;
usb.adc.counter = (++j) % 0xffff;
cmmd = 50.;
for (i = 0;i < NCHAN + 1;i++)
usb.adc.adc[i] = (short)(cmmd + randgauss(0, 5.));
ichan = (int)(randflat(0, NCHAN));
val = randgauss(250., 10.);
usb.adc.adc[ichan] += (unsigned short)val;
usb.adc.adcsum += (unsigned short)val;
// std::cout << "cmmd " << cmmd << " val " << val << " - " << usb.adc.adc[ichan] << std::endl;
ioctl(fd, FIONREAD, &nleft);
nleft = FIFO_SIZE - nleft;
if ( nleft > sizeof(ADCRecord) )
{
// std::cout << "\r" << j << "/[" << nleft << "] " << flush;
write(fd, usb.data, sizeof(usb));
}
}
close(fd);
}