Consecutive measurements

Applications, development tools, FPGA, C, WEB
Post Reply
azahonero
Posts: 5
Joined: Thu Oct 14, 2021 8:06 am

Consecutive measurements

Post by azahonero » Fri Dec 02, 2022 12:05 pm

Hello everybody

I've been working with RP more than a year in a project that involves measurements with different configurations. To that end I used the C API functions to acquire sweeps of measures with multiple thresolds and samplings. My problem is that I have been able to acquire only one measurement, given that in the second iteration of my code it always hangs. Here's a sample of my code:

Code: Select all

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "redpitaya/rp.h"
#include <signal.h>
#include <sched.h>
#include <fcntl.h>
#include <math.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define TCP_PORT 1001

#define CMA_ALLOC _IOWR('Z', 0, uint32_t)

uint64_t dna;
char id[7];
int wflag=0;
int tflag=0;
int wait_t;	
char timebuffer[16];
char ms[12];
struct timeval tv;
struct timeval tf;
time_t curtime;
char str[51]; //18 FROM DIRECTORY NAME AND 26 FROM DATE + 7 RPID
char info[20]; //FOR DECIMATION AND THLEV
rp_acq_sampling_rate_t rst;
rp_acq_decimation_t dec1;
//int dec_in = 1;
uint32_t buff_size = 16384;
rp_acq_trig_state_t statet = RP_TRIG_STATE_WAITING;	
uint32_t trigger_position;

void setup ( float thlev ) {
	if(rp_Init() != RP_OK){ /* Print error, if rp_Init() function failed */
            fprintf(stderr, "Rp api init failed!\\n");
    }
	
	rp_IdGetDNA(&dna);
	printf("RP DNA: %llu \n",dna);
	
	int status = rp_ApinSetValue(0, thlev);
	if (status != RP_OK) {
		printf("Could not set AO0 voltage.\\n");}
	status = rp_ApinSetValue(1, thlev);
	if (status != RP_OK) {
		printf("Could not set AO1 voltage.\\n");}
	status = rp_ApinSetValue(2, thlev);
	if (status != RP_OK) {
		printf("Could not set AO2 voltage.\\n");}
	status = rp_ApinSetValue(3, thlev);
	if (status != RP_OK) {
		printf("Could not set AO3 voltage.\\n");}

	rp_DpinSetState (RP_LED3, RP_HIGH);
	rp_DpinSetState (RP_LED4, RP_LOW);
	rp_DpinSetState (RP_LED5, RP_LOW);
	rp_DpinSetState (RP_LED6, RP_LOW);
	statet = RP_TRIG_STATE_WAITING;
}

void def_params ( int dec_in ){
	    
    if(dec_in==1){
        rst=RP_SMP_125M; 
        dec1=RP_DEC_1; 
        wait_t=131;
		//tsample=8;
    }
    else if(dec_in==8){
        rst=RP_SMP_15_625M; 
        dec1=RP_DEC_8;
        wait_t=1048;
		//tsample=64.026;
    }
    else if(dec_in==64){
        rst=RP_SMP_1_953M; 
        dec1=RP_DEC_64;
        wait_t=8400;
		//tsample=512.024;
    }
	else if(dec_in==256){
		rst=RP_SMP_448_281K;
		dec1=RP_DEC_256;
		wait_t=335600;
		//tsample=4093.63;
	}
    else if(dec_in==1024){
        rst=RP_SMP_122_070K;
        dec1=RP_DEC_1024; 
        wait_t=134200;
		//tsample=8192.02;
    }
    else if(dec_in==8192){
        rst=RP_SMP_15_258K;
        dec1=RP_DEC_8192; 
        wait_t=1073600;
		//tsample=65551.76;
    }
	else {
		  printf("decimation must be 1,8,64,1024,8192\\n");}

	rp_AcqReset();
    	rp_AcqSetSamplingRate(rst); // it should be this one. However, the next one is always used.
	rp_AcqSetDecimation(dec1);
    	rp_AcqSetGain(RP_CH_1,RP_HIGH);
    	rp_AcqSetGain(RP_CH_2,RP_HIGH);
	rp_AcqSetAveraging(0);
    	rp_AcqSetTriggerSrc(RP_TRIG_SRC_EXT_PE);//Trigger externo, Positive Edge
	rp_DpinSetState (RP_LED4, RP_HIGH);
}

void adq_data(float thlev, int decimation, int delay){
	float *buff1 = (float *)malloc(buff_size * sizeof(float));
	float *buff2 = (float *)malloc(buff_size * sizeof(float));
		
	rp_AcqStart();
	rp_acq_trig_state_t statet = RP_TRIG_STATE_WAITING;	
	
	gettimeofday(&tf, NULL); 
	curtime=tf.tv_sec;
	strftime(timebuffer, 16, "%Y%m%d_%H%M%S",localtime(&curtime));
	sprintf(ms, "_%ld", tf.tv_usec); //tv_nsec in nano seconds
	printf("Trigger ready at %s_%s\\n", timebuffer, ms);
	rp_DpinSetState(RP_LED5, RP_HIGH);
	int timer=0;
	while(wflag==0){
		rp_AcqGetTriggerState(&statet);
		timer++;
			if(statet == RP_TRIG_STATE_TRIGGERED){
				printf("TRIGGERED, statet is: %i \\n", statet);
				statet = RP_TRIG_STATE_WAITING;
				rp_DpinSetState (RP_LED6, RP_HIGH);
				wflag=1;} //END IF TRIGG
		if (timer>2849000*300){printf("TIMER DONE\\n"); tflag=1; break;}
	}//END WHILE
	gettimeofday(&tv, NULL); //WHEN TRIGGER IS ON=> GET TIME
	// BUFFER ACQUISITION
	if(tflag==0){
	rp_AcqGetWritePointerAtTrig(&trigger_position);
	rp_AcqGetDataV(RP_CH_1, trigger_position-delay, &buff_size, buff1);
	rp_AcqGetDataV(RP_CH_2, trigger_position-delay, &buff_size, buff2);
	// COMPLETE FILE NAME WITH EXTENSION AND OPEN IT
	curtime=tv.tv_sec;
	snprintf(info, 20,"dec=%i, th=%f\\n", decimation, thlev);
	strftime(timebuffer, 16, "%Y%m%d_%H%M%S",localtime(&curtime));
	sprintf(ms, "_%ld.bin", tv.tv_usec); //tv_nsec in nano seconds
	strcpy(str,"/home/TestMeas/");
	strcat(str, id); 
	strcat(str, timebuffer);
	strcat(str, ms);
	
	printf("%s\\n",info);
	
	FILE *f=fopen(str, "wb"); //for bin file
	
	fwrite(info, sizeof(info), sizeof(info), f);
	fwrite(buff1, sizeof(float), buff_size, f);
	fwrite(buff2, sizeof(float), buff_size, f); 
	fclose(f);
	printf("Ruta del archivo: %s \\n", str);
	printf("Adquisition finished \\n");//mqtt
	
	free(buff1); 
	free(buff2); 
 	wflag=0;
	rp_DpinSetState (RP_LED3, RP_LOW);
	rp_DpinSetState (RP_LED4, RP_LOW);
	rp_DpinSetState (RP_LED5, RP_LOW);
	rp_DpinSetState (RP_LED6, RP_LOW);
	//rp_DpinSetState (RP_DIO0_P, &statet);
	//printf("statet is: %i \\n", statet);
	}
}
	
int acq( float umbral, int decimation, int delay){//van a ser lo mismo que thlev y dec_in, respectivamente
	
	setup(umbral);
	def_params(decimation);
	sleep(1);
	adq_data(umbral, decimation, delay);  
    return EXIT_SUCCESS;
}

int main ( int argc, char **argv ){
	int i;
	int dec_array[5]={1, 8, 64, 1024, 8192};
	for (i=0; i < 5; i++){
	acq(1, dec_array[i], 8192); 
	}	
	return EXIT_SUCCESS;
}
I tried to edit it so only the relevant parts are here (I use GPIOs to configure different multiplexors in my PCB).
The output in console shows that all the code is executed in the first iteration, but it hangs waiting the trigger as the led 5 is on, which happends when the RP is waiting for a trigger event.
My guessing is that im not rearming correctly the trigger, but I tried using different functions in the API to that end without success. If someone can give any hint about that im gratefull. Moreover, I dont expect a direct solution for the code as I would prefer to understand better about the API and the HW itself. Bringing it up, is there any way to check the code from the API other than the rp.h file? In the future I'll be interested in modifying it but I haven't been able to.

Thank you all in advance,

Alex.

juretrn
Posts: 43
Joined: Tue Nov 16, 2021 11:38 am

Re: Consecutive measurements

Post by juretrn » Sat Dec 03, 2022 6:09 pm

HI,

did you check what is actually written into the acquisition control register
?

Code: Select all

monitor 0x40100000
Bit 0 must be set to 1 for the trigger to be armed. If you reset the acquisition after arming the trigger, you will have to re-arm.
Before that, you must also set the trigger source, trigger delay / number of samples to be acquired, decimation, trigger thresholds and hysteresis.

azahonero
Posts: 5
Joined: Thu Oct 14, 2021 8:06 am

Re: Consecutive measurements

Post by azahonero » Mon Dec 12, 2022 11:16 am

First of all, thank you for your answer juretrn,
I haven't been in office last week, sorry that couldn't answer earlier.
I've checked the registers before and after the first acquisition, and the registers reads 0x00000011 after the first trigger, which I don't know what means and can't find in the register map...
And how can you reset the register? I can't find any API function that resets the trigger, in my code I'm just rewritting the trigger state to RP_TRIG_STATE_WAITING after the first acquisition, I guess that's not enough?

azahonero
Posts: 5
Joined: Thu Oct 14, 2021 8:06 am

Re: Consecutive measurements

Post by azahonero » Tue Dec 13, 2022 12:42 pm

Well, somehow I solved it by using

Code: Select all

rp_AcqSetTriggerSrc(RP_TRIG_SRC_EXT_PE);
After the acquisition starts as it was done before. The register readed "ACQ delay has passed / (all data was written to buffer)" cause I was stopping the acquisition and restating the trigger source before restarting it (my guess).
Was really usefull to be able to check the register with this "monitor" utility, but I dont think im really understanding whats going on here at fpga level, so if someone can clarify that for me it would be really appreciated.

juretrn
Posts: 43
Joined: Tue Nov 16, 2021 11:38 am

Re: Consecutive measurements

Post by juretrn » Thu Dec 15, 2022 9:32 am

Hi, sorry for my late reply :/

In case you weren't able to find the register in the registry map, find the following phrase on my previous link: "Start writing data into memory (ARM trigger)."
I don't know much about the API, so I can't help you there.
But FPGA side, I do.
After arming the trigger, data starts being written into a circular buffer and waits for a trigger to arrive. During that time, the "current write pointer" register constantly updates. When a trigger arrives, N valid (decimated) samples are saved into the buffer and the write pointer of the trigger is saved into the appropriate register. N is set within "delay after trigger" register. When that number of samples is acquired, bit 4 "ACQ delay has passed / (all data was written to buffer)" is set by FPGA and stays set until the trigger is again armed.
Resetting before the end of acquisition will cause the bit 4 to be set.

azahonero
Posts: 5
Joined: Thu Oct 14, 2021 8:06 am

Re: Consecutive measurements

Post by azahonero » Fri Dec 16, 2022 10:20 am

juretrn wrote:
Thu Dec 15, 2022 9:32 am
After arming the trigger, data starts being written into a circular buffer and waits for a trigger to arrive. During that time, the "current write pointer" register constantly updates. When a trigger arrives, N valid (decimated) samples are saved into the buffer and the write pointer of the trigger is saved into the appropriate register. N is set within "delay after trigger" register. When that number of samples is acquired, bit 4 "ACQ delay has passed / (all data was written to buffer)" is set by FPGA and stays set until the trigger is again armed.
Resetting before the end of acquisition will cause the bit 4 to be set.
That makes sense, it's kind of what I thought. Sometimes its tricky to work with the API because I dont really know what the functions do at fpga level and its weird to figure that out sometimes. I'm really thankfull for your replies, helped me to understand whats going on. Thanks juretrn!

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 2 guests