Пример #1
0
int bogio_read_frames(const bogio_spec *spec,
                      bogio_buf *buf,
                      unsigned int frames,
                      int blocking)
{
    int bytes, i;
    sampl_t *raw; /* Place to store raw samples before normalisation */
    unsigned int framesize = buf->spf * sizeof(sampl_t);
    
    /* Don't read past the end of the buffer */
    if (frames > buf->frames)
        frames = buf->frames;
    
    if (!blocking) {
        /* If we're not going to block, find out how many samples can be read */
        unsigned int frames_ready =
                comedi_get_buffer_contents(spec->m_dev, spec->subdevice) /
                framesize;
        if (frames > frames_ready)
            frames = frames_ready;
    }
    
    /* Reserve a temporary buffer of the I/O device's type */
    raw = (sampl_t *)alloca(frames*framesize);
    comedi_poll(spec->m_dev, spec->subdevice);
//printf("Going to read %u bytes from fd %d, %d available... ", frames*framesize, comedi_fileno(spec->m_dev), comedi_get_buffer_contents(spec->m_dev, spec->subdevice)); fflush(stdout);
    /* Fill it with data */
    bytes = read(comedi_fileno(spec->m_dev), raw, frames*framesize);
//perror("read");
//printf("Got %d\n", bytes);
    /* Ensure the read completed */
    if (bytes <= 0)
        return bytes;
    
    frames = bytes/framesize;
    
    /* Convert to bogio's native type and normalise. */
    for (i = 0; i < frames * buf->spf ; i++)
        buf->samples[i] = (bogio_sample_t)comedi_to_phys(raw[i],
                                                         spec->fsd[i],
                                                         spec->m_max_sample[i]);
    return frames;
}
Пример #2
0
void ComediScope::paintEvent( QPaintEvent * ) {
        int ret;
	while (1) {
		// we need data in all the comedi devices
		for(int n=0;n<nComediDevices;n++) {
			if (!comedi_get_buffer_contents(dev[n],subdevice))
				return;
		}

		for(int n=0;n<nComediDevices;n++) {
			int subdev_flags = comedi_get_subdevice_flags(dev[n],
								      subdevice);
			int bytes_per_sample;
			if(subdev_flags & SDF_LSAMPL) {
				bytes_per_sample = sizeof(lsampl_t);
			} else {
				bytes_per_sample = sizeof(sampl_t);
			}
			
			unsigned char buffer[bytes_per_sample*channels_in_use];
			ret = read(comedi_fileno(dev[n]),
				   buffer,
				   bytes_per_sample*channels_in_use);

			if (ret==0) {
				printf("BUG! No data in buffer.\n");
				exit(1);
			}

			if (ret<0) {
				printf("\n\nError %d during read! Exiting.\n\n",ret);
				exit(1);
			}
			
			for(int i=0;i<channels_in_use;i++) {
				int sample;
				if (comediRecord->channel[n][i]->isActive()) {
					int ch = comediRecord->channel[n][i]->getChannel();
					if(subdev_flags & SDF_LSAMPL) {
						sample = ((int)((lsampl_t *)buffer)[ch]);
					} else {
						sample = ((int)((sampl_t *)buffer)[ch]);
					}
					// store raw data
					daqData[n][i] = sample;
					// convert data to physical units for plotting
					float value = comedi_to_phys(sample,
								     crange[n],
								     maxdata[n]);
					// filtering
					value = comediRecord->dcSub[n][i]->filter(value);
					value = comediRecord->hp[n][i]->filter(value);
					value = comediRecord->lp[n][i]->filter(value);
					// remove 50Hz
					if (comediRecord->filterCheckbox->checkState()==Qt::Checked) {
						value=iirnotch[n][i]->filter(value);
					}
					if ((n==fftdevno) && (ch==fftch) &&
					    (comediRecord->fftscope))
						comediRecord->fftscope->append(value);
					// average response if TB is slower than sampling rate
					adAvgBuffer[n][i] = adAvgBuffer[n][i] + value;
				}
			}
		}

		// save data
		if (comediRecord->recPushButton->checkState()==Qt::Checked) {
			writeFile();
		}

		nsamples++;
		tb_counter--;

		// enough averaged?
		if (tb_counter<=0) {
			for(int n=0;n<nComediDevices;n++) {
				for(int i=0;i<channels_in_use;i++) {
					adAvgBuffer[n][i]=adAvgBuffer[n][i]/tb_init;
				}
			}
		
			// plot the stuff
			paintData(adAvgBuffer);

			// clear buffer
			tb_counter=tb_init;
			for(int n=0;n<nComediDevices;n++) {
				for(int i=0;i<channels_in_use;i++) {
					adAvgBuffer[n][i]=0;
				}
			}
		}
	}
}
Пример #3
0
void *_laytube_toFile(void *args){

    long unsigned int expansion_size;
    void *pause_after;
    tubeID *pTube;
    rohrStation sendingStation;
    rohrStation receivingStation;

    pTube = (tubeID *) args;


    /* Populate Station Information */
    sendingStation.stationSize = comedi_get_buffer_size(pTube->dev, pTube->subdev);
    receivingStation.stationSize = _file_size(pTube->tail);
    expansion_size = 64 * sysconf(_SC_PAGESIZE); /* Set file expansion size to a mulitple of memory page size */
    if (expansion_size < sendingStation.stationSize){
        pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED;
        pthread_exit(NULL);
    }

    /* Check for empty file */
    if (receivingStation.stationSize < 1){
        receivingStation.stationSize = expansion_size; /*  Let's make the file one page-size in length */
        ftruncate(pTube->tail, receivingStation.stationSize);
    }

    /* Set up COMEDI ring buffer memory map */
    sendingStation.firstByte = mmap(NULL, sendingStation.stationSize, PROT_READ, MAP_SHARED, pTube->mouth, 0);
    if (sendingStation.firstByte == MAP_FAILED){
        pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED;
        pthread_exit(NULL);
    }
    sendingStation.address = sendingStation.firstByte;
    sendingStation.lastByte = sendingStation.firstByte + sendingStation.stationSize - 1; /* Last valid byte */

    /* Set up HDD file memory map */
    receivingStation.firstByte = mmap(NULL, receivingStation.stationSize, PROT_WRITE | MAP_HUGETLB, MAP_SHARED, pTube->tail, 0);
    if (receivingStation.firstByte == MAP_FAILED){
        pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED;
        pthread_exit(NULL);
    }
    receivingStation.address = receivingStation.firstByte;
    receivingStation.lastByte = receivingStation.firstByte + receivingStation.stationSize - 1; /* Last valid byte */


    /* Stations are setup... set status and command flags... */
    pTube->tubeCmd = 0x00;
    pTube->tubeStatus = TUBE_INPLACE; /* <-- un-blocks laytube_toFile to return to calling function */

    /* Core algorithm - This while loop handles the data transfer from ring buffer to disk */
    while( !(pTube->tubeCmd & TUBE_STOP) ){

        /* Check if the storage file is out or about to be out of space */
        if (sendingStation.stationSize >= (receivingStation.lastByte - receivingStation.address) ){
           if (_growStation(&receivingStation, pTube->tail, expansion_size) == -1){
                pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED;
                pthread_exit(NULL);
           }
        }

        pause_after = sendingStation.firstByte + comedi_get_buffer_contents(pTube->dev, pTube->subdev) - 1;

        if (pause_after < sendingStation.address){
            pTube->bytesMoved = receivingStation.address - receivingStation.firstByte;
            /* comedi_poll(pTube->dev, pTube->subdev)); */
            usleep(10); /* TODO: optimize by setting sleep number to best guess at when data might show up again */
        }
        else if (pause_after < sendingStation.lastByte) /* Confirm COMEDI ring buffer has not aliased */
        {
            do {
                *((CARRIER *)receivingStation.address++) = *((CARRIER *)sendingStation.address++);
            } while(sendingStation.address <= pause_after);
        }
        else if (pause_after >= sendingStation.lastByte) /* COMEDI ring buffer has aliased... copy up to end of ring buffer and reset */
        {
            do {
                *((CARRIER *)receivingStation.address++) = *((CARRIER *)sendingStation.address++);
            } while(sendingStation.address <= sendingStation.lastByte);

            comedi_mark_buffer_read(pTube->dev, pTube->subdev, sendingStation.stationSize); /* Reset the ring buffer mark */
            sendingStation.address = sendingStation.firstByte;
        }
        else
        {
            pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED;
            pthread_exit(0);
        }
    }

    /* Clean up Stations, truncate file, flush tube */
    expansion_size = receivingStation.address - receivingStation.firstByte; /* 'address' should point to one byte past last byte written */
    ftruncate(pTube->tail, expansion_size);
    fsync(pTube->tail);
    pTube->bytesMoved = expansion_size;

    pTube->tubeStatus = pTube->tubeStatus | TUBE_EXIT;

    pthread_exit(0);
}
Пример #4
0
void MainWindow::timerEvent(QTimerEvent *)
{
  unsigned char buffer[readSize];

  while( comedi_get_buffer_contents(dev, COMEDI_SUB_DEVICE) > 0 )
  {
    if( read(comedi_fileno(dev), buffer, readSize) == 0 )
    {
      printf("Error: end of Aquisition\n");
      exit(1);
    }

    int v;

    if( sigmaBoard )
	    v = ((lsampl_t *)buffer)[adChannel];
    else
	    v = ((sampl_t *)buffer)[adChannel];

    double yNew = comedi_to_phys(v,
				 crange,
				 maxdata);

    if (filter50HzCheckBox->checkState()==Qt::Checked) {
	    yNew=iirnotch->filter(yNew);
    }                                

    RawDataPlot->setNewData(yNew);

    int trialIndex = time % psthLength;

    if( linearAverage && psthOn )
    {
      spikeCountData[trialIndex] += yNew;

      psthData[trialIndex] = spikeCountData[trialIndex] / (time/psthLength + 1);
    }
    else if( !spikeDetected && yNew>spikeThres )
    {
      if(psthOn)
      {
        int psthIndex = trialIndex / psthBinw;

        spikeCountData[psthIndex] += 1;

        psthData[psthIndex] = ( spikeCountData[psthIndex]*1000 ) / 
		( psthBinw * (time/psthLength + 1) );

        spikeDetected = true;
      }
    }
    else if( yNew < spikeThres )
    {
      spikeDetected = false;
    }
    
    if( trialIndex == 0 )
      psthActTrial += 1;
    
    ++time;
  }
  RawDataPlot->replot();
}
Пример #5
0
int main(int argc, char *argv[])
{
	comedi_cmd c,*cmd=&c;
	struct header_info header;
	long int t_samples, t_bytes, t_sleep;
	long int ret;
	int dt_usec, usec_elapsed;
//	struct timeval start,end;
	struct parsed_options options;
	unsigned short *samples; //, *junk;
	struct timeval now,then;
	long long unsigned int exec = 0;
	time_t t;

	umask(000);

	signal(SIGINT,do_depart);

	if (geteuid() != 0) {
		fprintf(stderr,"Must be setuid root to renice self.\n");
		exit(0);
	}

	cmd_init_parsed_options(&options);
	cmd_parse_options(&options, argc, argv);

	t_samples = options.n_chan * options.samples;
	t_bytes = t_samples * 2;
	t_sleep = (long int) DMA_OVERSCAN_MULT*(1e6/options.freq)*options.samples;
	printf("freq = %f, tsamp = %li, tby = %li, tsleep = %li.\n",options.freq,t_samples,t_bytes,t_sleep);


	/* Test for failful options */
	if (options.freq <= 1/(options.cadence + 0.00005)) {
		fprintf(stderr,"Acquisition frequency is faster than sampling frequency!  FAIL!\n");
		exit(ACQERR_BADINPUT);
	}

	if (options.samples > 16777216) {
		fprintf(stderr,"acq_d can't take more than 2^24 samples per set!  Try acq_c.\n");
		exit(ACQERR_BADINPUT);
	}

	ret = nice(-20);
	fprintf(stderr,"I've been niced to %li.\n",ret);
	if (ret != -20) printf("  WARNING!! Data collection could not set nice=-20. Data loss is probable at high speed.");

	dt_usec = options.cadence * 1e6;
	gettimeofday(&then, NULL);

	/* open the device */
	dev = comedi_open(options.devfile);
	if (!dev) {
		comedi_perror(options.devfile);
		exit(ACQERR_BADDEV);
	}

//	printf("%li samples in %i-byte buffer.\n\n",t_samples,comedi_get_buffer_size(dev,options.subdevice));

	prepare_cmd_lib(dev,options,cmd);

	printf("Testing command...");
	ret = comedi_command_test(dev, cmd);
	if (ret < 0) {
		comedi_perror("comedi_command_test");
		if(errno == EIO){
			fprintf(stderr,"Ummm... this subdevice doesn't support commands\n");
		}
		exit(ACQERR_BADCMD);
	}
	printf("%s...",cmdtest_messages[ret]);
	ret = comedi_command_test(dev, cmd);
	printf("%s...",cmdtest_messages[ret]);
	ret = comedi_command_test(dev, cmd);
	printf("%s...\n",cmdtest_messages[ret]);
	if (ret < 0) {
		fprintf(stderr,"Bad command, and unable to fix.\n");
		dump_cmd(stderr, cmd);
		exit(ACQERR_BADCMD);
	}
	dump_cmd(stdout,cmd);
	comedi_close(dev);

	//fprintf(stderr,"%i scan -- %i chan -- %li samples -- %li bytes\n",options.samples,options.n_chan,t_samples,t_bytes);

	/* Print data file header */
//	sprintf(dataheader,	"[system]\n"
//				"whoami = \"%s\"")

	samples = (unsigned short*) malloc(t_bytes);
//	junk = (unsigned short*) malloc(t_bytes);
	if ((samples == NULL)) { // | (junk == NULL)) {
		fprintf(stderr,"Error allocating sample memory!\n");
		exit(ACQERR_BADMEM);
	}

	printf("Starting acquisition...\n");
	/*Open the serial port*/
	/*serial = (FILE*)fopen("/dev/ttyS0","w");*/
	

	/* Do what we're here to do */
	while (running) {
		if (exec == options.sets) {
			break;
		}
		exec++;

       serial_toggle();

		/* open the device */
		dev = comedi_open(options.devfile);
		if (!dev) {
			comedi_perror(options.devfile);
			exit(ACQERR_BADDEV);
		}

		gettimeofday(&now, NULL);
		usec_elapsed = (now.tv_sec - then.tv_sec) * 1e6 + (now.tv_usec - then.tv_usec);
		while (usec_elapsed < dt_usec) {
			usleep(USLEEP_GRAN);
			gettimeofday(&now, NULL);
			usec_elapsed = (now.tv_sec - then.tv_sec) * 1e6 + (now.tv_usec - then.tv_usec);
		}
		/* start the command */
		ret = comedi_command(dev, cmd);
		if (ret < 0) {
			comedi_perror("comedi_command");
			exit(ACQERR_BADCMD);
		}

		then = now;

		/*
		 * Insert enough waiting to get through most of the sampling
		 */
		/*serial_toggle();*/
		usleep(t_sleep);

		/*
		 * Wait until the buffer has our data.
		 */

		int exsleeps = 0;
		do {
			usleep(USLEEP_GRAN);
			comedi_poll(dev,options.subdevice);
			ret = comedi_get_buffer_contents(dev,options.subdevice);
			exsleeps++;
		} while(ret < t_bytes);

//		printf("Waited %ius for additional data.\n",exsleeps);

		/*
		 * Get teh dataz.
		 */
		ret = read(comedi_fileno(dev), samples, t_bytes);
		if (ret < t_bytes) {
			fprintf(stderr,"Read mismatch!  Got %li of %li bytes (%li/%li samples).\n",ret,t_bytes,ret/2,t_samples);
		}
		header.num_read = ret/2;

		// collect & discard overscan
/*		ret = comedi_get_buffer_contents(dev,options.subdevice);
		if (realloc(junk,ret) == NULL) {
			fprintf(stderr,"Error in oversample realloc?\n");
			exit(ACQERR_BADMEM);
		}
		if (ret > 0) {
			ret = read(comedi_fileno(dev),junk,ret);
		}*/

		comedi_close(dev);

		// Prepare header
		t = time(NULL);
		sprintf(header.site_id,"%s",site_str);
		header.start_time = t;
		header.start_timeval = now;
		header.num_channels=options.n_chan;
		header.channel_flags=0x0F;
		header.num_samples=options.samples;
		header.sample_frequency=options.freq;
		header.time_between_acquisitions=options.cadence;
		header.byte_packing=0;
		header.code_version=current_code_version;

		// Save latest to monitor file
		if (strcmp(options.monfile,"") != 0) {
			out = open(options.monfile,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
			ret = errno;
			if (out > 0) {
				ret = write(out,&header,sizeof(header));
				ret = write(out,samples,2*header.num_read);
				close(out);
			}
			else {
				fprintf(stderr,"Unable to open monitor file %s: %s.\n",options.monfile,strerror(ret));
				exit(ACQERR_BADOUT);
			}
		}

		if (options.cadence >= 1.0 && options.verbose) printf("\tSaved latest to: %s\n",options.monfile);

		// Append to output file
		if (strcmp(options.outfile,"") != 0) {
			out = open(options.outfile,O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
			ret = errno;
			if (out > 0) {
				ret = write(out,samples,2*header.num_read);
				close(out);
				if (options.cadence >= 1.0 && options.verbose) printf("\tAppended to: %s\n",options.outfile);
			}
			else {
				fprintf(stderr,"Unable to open output file %s: %s.\n",options.outfile,strerror(ret));
				exit(ACQERR_BADOUT);
			}
		}
	}

	if (dev != NULL)
		comedi_close(dev);
	if (out != 0)
		close(out);

	printf("\nEnd.\n");

	exit(0);
}
Пример #6
0
int myBoard_distributeData( int board ) {

    MY_BOARD_HARDWARE *pBoardHard = myBoard_getHardwareBoard( board );
    MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board );

    if (pBoardHard == NULL || pBoardSoft == NULL) {
        return 0;
    }

    int numAvailableByte = comedi_get_buffer_contents(
        pBoardHard->p_comediFileHandle,
        pBoardHard->subDeviceNumber
    );

    if (numAvailableByte >= pBoardHard->buffer_size_in_byte) {
        fprintf( stderr, "processing too slow, lost data for board[%d]\n", board );
    }

    size_t dataSize = (pBoardHard->valueIsLsampl_t)?sizeof(lsampl_t):sizeof(sampl_t);

    int numAvailableSample = numAvailableByte / dataSize;

    int numInput = pBoardSoft->numberOfActiveAnalogInputs;
    /* we only deal with whole scans */
    int numScan = numAvailableSample / numInput;

    int odd = numAvailableSample % numInput;

    /* fprintf( stderr, "checking data: numAvailableSample=%d, numScan=%d odd=%d\n", numAvailableSample, numScan, odd ); */

    if (numScan <= 0) {
        return 0;
    }

    numAvailableSample = numInput * numScan;

    int i;

    epicsMutexMustLock( pBoardSoft->boardLock );

    if (pBoardHard->valueIsLsampl_t) {
        lsampl_t *pBuffer = (lsampl_t*)pBoardHard->buffer;

        for (i = 0; i < numAvailableSample; ++i) {
            int offset = pBoardHard->indexRead++ % pBoardHard->buffer_size_in_sample;
            double vRaw = pBuffer[offset];
            int indexChannel = i % numInput;
            double v = vRaw * pBoardHard->channelRawToVoltA[indexChannel]
            + pBoardHard->channelRawToVoltB[indexChannel];

            appendDataToMyRingBuffer( pBoardSoft->channel_buffer + indexChannel, v, 0 );
        }
    } else {
        sampl_t *pBuffer = (sampl_t*)pBoardHard->buffer;

        for (i = 0; i < numAvailableSample; ++i) {
            int offset = pBoardHard->indexRead++ % pBoardHard->buffer_size_in_sample;
            double vRaw = pBuffer[offset];
            int indexChannel = i % numInput;
            double v = vRaw * pBoardHard->channelRawToVoltA[indexChannel]
            + pBoardHard->channelRawToVoltB[indexChannel];

            appendDataToMyRingBuffer( pBoardSoft->channel_buffer + indexChannel, v, 0 );
        }
    }

    epicsMutexUnlock( pBoardSoft->boardLock );

    int numReadByte = numAvailableSample * dataSize;
    comedi_mark_buffer_read(
        pBoardHard->p_comediFileHandle,
        pBoardHard->subDeviceNumber,
        numReadByte
    );
    scanIoRequest( pBoardSoft->ioScanPvt );

    return numScan;
}