int rp_LaAcqGetCntStatus(rp_handle_uio_t *handle, uint32_t * trig_addr, uint32_t * pst_length, bool * buf_ovfl) { rp_la_cfg_regset_t *regset = (rp_la_cfg_regset_t *) &(((rp_la_acq_regset_t*)handle->regset)->sts); rp_la_cfg_regset_t reg; reg.pre = ioread32(®set->pre); reg.pst = ioread32(®set->pst); if(*trig_addr>=rp_LaAcqBufLenInSamples(handle)){ *buf_ovfl=true; } else{ *buf_ovfl=false; } *trig_addr=(reg.pre % rp_LaAcqBufLenInSamples(handle)); *pst_length=reg.pst; // calc. real trigger address if(*trig_addr<TRIG_DELAY_SAMPLES){ *trig_addr=rp_LaAcqBufLenInSamples(handle)-TRIG_DELAY_SAMPLES+*trig_addr; } else{ *trig_addr-=TRIG_DELAY_SAMPLES; } if(!(inrangeUint32 (*trig_addr, 0, (rp_LaAcqBufLenInSamples(handle)-1)))){ return RP_EOOR; } return RP_OK; }
int rp_LaAcqGetRLEStatus(rp_handle_uio_t *handle, uint32_t * current, uint32_t * last, bool * buf_ovfl) { rp_la_acq_regset_t *regset = (rp_la_acq_regset_t *) handle->regset; *current = ioread32(®set->sts_cur); if(*last>=rp_LaAcqBufLenInSamples(handle)){ *buf_ovfl=true; } else{ *buf_ovfl=false; } *last = (ioread32(®set->sts_lst)%rp_LaAcqBufLenInSamples(handle)); if(*last>0){ *last-=1; return RP_OK; } else{ return RP_EOOR; } }
RP_STATUS rp_RunBlock(uint32_t noOfPreTriggerSamples, uint32_t noOfPostTriggerSamples, uint32_t timebase, // int16_t oversample, double * timeIndisposedMs, //uint32_t segmentIndex, rpBlockReady rpReady, void * pParameter ) { double timeIntervalNanoseconds; uint32_t maxSamples=rp_LaAcqBufLenInSamples(&la_acq_handle); if(rp_GetTimebase(timebase,0,&timeIntervalNanoseconds,&maxSamples)!=RP_API_OK){ return RP_INVALID_TIMEBASE; } printf("\r\n timeIntervalNanoseconds: %f", timeIntervalNanoseconds); if(!(inrangeUint32 (noOfPreTriggerSamples+noOfPostTriggerSamples, 10, maxSamples))){ return RP_INVALID_PARAMETER; } printf("\r\n max: %d", maxSamples); *timeIndisposedMs=(noOfPreTriggerSamples+noOfPostTriggerSamples)*timeIntervalNanoseconds/10e6; // configure FPGA to start block mode // TODO; sampling rate rp_la_decimation_regset_t dec; dec.dec=timebase; rp_LaAcqSetDecimation(&la_acq_handle, dec); rp_la_cfg_regset_t cfg; cfg.pre=noOfPreTriggerSamples; cfg.pst=noOfPostTriggerSamples; if(rp_LaAcqSetCntConfig(&la_acq_handle, cfg)!=RP_OK){ return RP_INVALID_PARAMETER; } printf("\r\nrp_LaAcqRunAcq"); // start acq. if(rp_LaAcqRunAcq(&la_acq_handle)!=RP_OK){ rp_LaAcqStopAcq(&la_acq_handle); return RP_BLOCK_MODE_FAILED; } //rp_LaAcqFpgaRegDump(&la_acq_handle); // block till acq. is complete printf("\r\nBlocking read"); g_acq_running=true; rp_LaAcqBlockingRead(&la_acq_handle); g_acq_running=false; // make sure acq. is stopped bool isStoped; rp_LaAcqAcqIsStopped(&la_acq_handle, &isStoped); if(!isStoped){ printf("\r\n not stopped!!"); rp_LaAcqStopAcq(&la_acq_handle); return RP_BLOCK_MODE_FAILED; } // rp_DmaMemDump(&la_acq_handle); uint32_t trig_sample; uint32_t last_sample; bool rle; rp_LaAcqIsRLE(&la_acq_handle,&rle); if(rle){ // in the RLE mode we only check which was the last sample where acq. stopped uint32_t current; bool buf_ovfl; rp_LaAcqGetRLEStatus(&la_acq_handle, ¤t, &last_sample, &buf_ovfl); trig_sample=0; } else{ // get trigger position uint32_t pst_length; bool buf_ovfl; if(rp_LaAcqGetCntStatus(&la_acq_handle, &trig_sample, &pst_length, &buf_ovfl)!=RP_OK){ rp_LaAcqStopAcq(&la_acq_handle); return RP_BLOCK_MODE_FAILED; } printf("\r\n trig_sample %d, pst_length %d, buf_ovfl %d", trig_sample, pst_length, buf_ovfl); // acquired number of post samples must match to req if(pst_length!=noOfPostTriggerSamples){ rp_LaAcqStopAcq(&la_acq_handle); return RP_BLOCK_MODE_FAILED; } } // save properties of current acq. acq_data.pre_samples=noOfPreTriggerSamples; acq_data.post_samples=noOfPostTriggerSamples; acq_data.trig_sample=trig_sample; acq_data.last_sample=last_sample; // acquisition is completed -> callback RP_STATUS status=RP_API_OK; (*rpReady)(status,pParameter); rp_LaAcqStopAcq(&la_acq_handle); return RP_API_OK; }
/** * This function returns block-mode data, with or without down-sampling, starting at the * specified sample number. It is used to get the stored data from the driver after data * collection has stopped. * * This function tells the driver where to store the data. * * @param startIndex A zero-based index that indicates the start point for data collection. * It is measured in sample intervals from the start of the buffer. * @param noOfSamples On entry, the number of samples required. On exit, the actual number retrieved. * The number of samples retrieved will not be more than the number requested, * and the data retrieved starts at startIndex. * @param downSampleRatio The down-sampling factor that will be applied to the raw data. * @param downSampleRatioMode Which down-sampling mode to use. * @param overflow On exit, a set of flags that indicate whether an over-voltage has occurred * on any of the channels. It is a bit field with bit 0 denoting Channel A. * */ RP_STATUS rp_GetValues(uint32_t startIndex, uint32_t * noOfSamples, uint32_t downSampleRatio, RP_RATIO_MODE downSampleRatioMode, //uint32_t segmentIndex, int16_t * overflow){ // TODO: startIndex & noOfSamples not used yet.. int16_t * map=NULL; map = (int16_t *) mmap(NULL, la_acq_handle.dma_size, PROT_READ | PROT_WRITE, MAP_SHARED, la_acq_handle.dma_fd, 0); if (map==NULL) { printf("Failed to mmap\n"); if (la_acq_handle.dma_fd) { close(la_acq_handle.dma_fd); } return -1; } bool rle; rp_LaAcqIsRLE(&la_acq_handle,&rle); if(rle){ // RLE mode // try to find first sample and trigger sample uint32_t first_sample=0; uint32_t samples=0; acq_data.trig_sample=0; uint32_t fist_sample_len_adj; uint32_t len=0; uint32_t i=0; uint32_t index = acq_data.last_sample; uint32_t total = acq_data.pre_samples+acq_data.post_samples; // printf("\n\rtotal: %d", total); bool trig_sample_found=false; // find first and last sample i=0; len=0; for(;;){ i++; len+=((uint8_t)(map[index]>>8))+1; // trigger position if(!trig_sample_found){ if(len>=(acq_data.post_samples-1)){ //printf("\n\rtrig. sample found: i=%d len=%d", i, len); acq_data.trig_sample=i; trig_sample_found=true; } } // first sample position if(len>=total){ first_sample=index; samples=i; // adjust first sample length so that it fits to the // length of requested data fist_sample_len_adj=len-total; //printf("len %d >= total %d\n", len, total); break; } //printf("\n\r sta: samples=%d trig=%d, ", samples, acq_data.trig_sample); //printf("\r\n %d len: %02x val: %02x ", i,(uint8_t)(map[index]>>8),(uint8_t)map[index]); if(index==0){ index=rp_LaAcqBufLenInSamples(&la_acq_handle)-1; } else{ index--; } } // printf("fist_sample_len_adj %d\n", fist_sample_len_adj); // copy data index=first_sample; for(i=0;i<samples;i++){ if(index>=rp_LaAcqBufLenInSamples(&la_acq_handle)){ index=0; } acq_data.buf[i]=map[index]; // adjust length of first sample if(i==0){ acq_data.buf[i]-=(int16_t)(fist_sample_len_adj<<8); } index++; } acq_data.trig_sample=samples-acq_data.trig_sample; printf("\n\r sta: samples=%d trig=%d", samples, acq_data.trig_sample); for(i=0;i<samples;i++){ printf("\r\n %d len: %02x val: %02x ", i,(uint8_t)(acq_data.buf[i]>>8),(uint8_t)acq_data.buf[i]); } *noOfSamples=samples; } else{
acq_data.trig_sample=samples-acq_data.trig_sample; printf("\n\r sta: samples=%d trig=%d", samples, acq_data.trig_sample); for(i=0;i<samples;i++){ printf("\r\n %d len: %02x val: %02x ", i,(uint8_t)(acq_data.buf[i]>>8),(uint8_t)acq_data.buf[i]); } *noOfSamples=samples; } else{ int32_t first_sample = acq_data.trig_sample - acq_data.pre_samples; int32_t last_sample = acq_data.trig_sample + acq_data.post_samples; int32_t buf_len = rp_LaAcqBufLenInSamples(&la_acq_handle); printf("\n\r req: pre=%d pos=%d\n\r", acq_data.pre_samples, acq_data.post_samples); printf("\n\r sta: first=%d trig=%d last=%d\n\r", first_sample, acq_data.trig_sample, last_sample); int32_t wlen; if(first_sample<0){ printf("\n\r first_sample > last_sample\n\r"); wlen=abs(first_sample); first_sample=buf_len+first_sample; printf("\n\r sta: first=%d wlen=%d\n\r", first_sample, wlen); for(int i=0; i<wlen; i++){ acq_data.buf[i]=map[first_sample+i]; }