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