Trigger from Arb Waveform

Applications, development tools, FPGA, C, WEB
mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Trigger from Arb Waveform

Post by mikepage » Mon Nov 23, 2015 6:07 pm

Hi,

I need to generate a waveform and capture a block of data synchronised to that waveform. I can generate the waveform successfully and if I simply wait between calling rp_AcqStart() and rp_AcqGetBufSize(&size), I get a size of 16384 and the data looks correct when I call rp_AcqGetLatestDataV(chan, &size, buffer). But if I wait for a trigger, it never arrives.

I am checking the trigger in a loop calling rp_AcqGetTriggerState(&state) and waiting for the state to become RP_TRIG_STATE_TRIGGERED. I have set rp_AcqSetTriggerSrc(RP_TRIG_SRC_AWG_PE), assuming this will trigger on the start of the waveform in the generator memory.

Is there some sequence I need to use to make sure the trigger is detected? Should it generate a trigger event each time the generator memory wraps?

And when it does trigger, what is the correct way to ensure the block of data I read back starts with the first sample of the generated waveform? rp_AcqGetLatestDataV, rp_AcqGetOldestDataV, something else?

Also, would triggering using the ARB generator as a source work for the other waveforms (like RP_WAVEFORM_SQUARE)? I'm guessing it should, since I think they all simply write the waveform into memory and generate it like an arbitrary waveform.

Any help appreciated.
Mike.

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Trigger from Arb Waveform

Post by mikepage » Tue Nov 24, 2015 1:18 pm

Just to add, I have tried rp_GenTrigger. That didn't seem to create a trigger either and has the undesirable (for me) effect of creating just a burst of waveform. What I am after is capturing the data synchronised to the wrap point of the ARB waveform.

Mike.

User avatar
redpitaya
Site Admin
Posts: 387
Joined: Wed Mar 26, 2014 7:04 pm

Re: Trigger from Arb Waveform

Post by redpitaya » Wed Nov 25, 2015 11:32 am

Hi,

Can you post the code here.

Best, RP

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Trigger from Arb Waveform

Post by mikepage » Thu Nov 26, 2015 4:26 pm

Hi,

Here is the code I am using.

...
ECHECK(rp_AcqSetArmKeep(FALSE));
ECHECK(rp_AcqSetDecimation(decimation));
ECHECK(rp_AcqSetAveraging(FALSE));
ECHECK(rp_AcqSetGain(RP_CH_1, RP_LOW));
ECHECK(rp_AcqSetGain(RP_CH_2, RP_LOW));

ECHECK(rp_AcqSetTriggerDelay(samples));
ECHECK(rp_AcqSetTriggerLevel(0.0f));
ECHECK(rp_AcqSetTriggerHyst(0.0f));

ECHECK(rp_AcqReset());
ECHECK(rp_AcqStart());
ECHECK(rp_AcqSetTriggerSrc(trig));

if ((trig == RP_TRIG_SRC_AWG_PE) || (trig == RP_TRIG_SRC_AWG_NE))
{
gen_start(START_CH_1);
gen_start(START_CH_2);
}

timeout = (int)(acqres->delta * samples * 10000 * 1000);
// usleep(10000);
(void)rp_AcqGetTriggerState(&state);
printf ("decimation code = %d, samples = %d\n", decimation, samples);
printf ("timeout set to %d ms\n", timeout);
printf ("trigger state is %d\n", (int)state);
while ((state != RP_TRIG_STATE_TRIGGERED) && (timeout > 0))
{
usleep(1000);
timeout--;
(void)rp_AcqGetTriggerState(&state);
}

printf ("timeout value is %d ms\n", timeout);
printf ("trigger state is %d\n", (int)state);

if (timeout <= 0)
{
result = RP_TIMEOUT;
}
else
{
ECHECK(rp_AcqGetBufSize(&size));
printf("acquired %d samples\n", size);
...


The ECHECK macro is modified to print out the functions being called. Here's what I see when the trig source is RP_TRIG_SRC_AWG_PE:

Executing: rp_AcqSetArmKeep((0))
Executing: rp_AcqSetDecimation(decimation)
Executing: rp_AcqSetAveraging((0))
Executing: rp_AcqSetGain(RP_CH_1, RP_LOW)
Executing: rp_AcqSetGain(RP_CH_2, RP_LOW)
Executing: rp_AcqSetTriggerDelay(samples)
Executing: rp_AcqSetTriggerLevel(0.0f)
Executing: rp_AcqSetTriggerHyst(0.0f)
Executing: rp_AcqReset()
Executing: rp_AcqStart()
Executing: rp_AcqSetTriggerSrc(trig)
Executing: rp_GenTrigger(chan)
Executing: rp_GenTrigger(chan)
decimation code = 2, samples = 1000
timeout set to 5120 ms
trigger state is 1
timeout value is 0 ms
trigger state is 1
timed out

If I use trig source = RP_TRIG_SRC_NOW, I get the following:

Executing: rp_AcqSetArmKeep((0))
Executing: rp_AcqSetDecimation(decimation)
Executing: rp_AcqSetAveraging((0))
Executing: rp_AcqSetGain(RP_CH_1, RP_LOW)
Executing: rp_AcqSetGain(RP_CH_2, RP_LOW)
Executing: rp_AcqSetTriggerDelay(samples)
Executing: rp_AcqSetTriggerLevel(0.0f)
Executing: rp_AcqSetTriggerHyst(0.0f)
Executing: rp_AcqReset()
Executing: rp_AcqStart()
Executing: rp_AcqSetTriggerSrc(trig)
decimation code = 2, samples = 1000
timeout set to 5120 ms
trigger state is 0
timeout value is 5120 ms
trigger state is 0
Executing: rp_AcqGetBufSize(&size)
acquired 16384 samples

But the acquired samples don't seem right.

Any suggestions would be appreciated.

Mike.

User avatar
redpitaya
Site Admin
Posts: 387
Joined: Wed Mar 26, 2014 7:04 pm

Re: Trigger from Arb Waveform

Post by redpitaya » Mon Nov 30, 2015 11:07 am

Hi,
Below is the code for synchronized generating and acquiring.
Burst signal is generated on OUT2 and acquired on IN1.
Remove 3 lines for burst mode an you will have continuous signal.
Best,RP

/* Red Pitaya C API example Acquiring a signal from a buffer
* This application acquires a signal on a specific channel */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redpitaya/rp.h"

int main(int argc, char **argv){

/* Print error, if rp_Init() function failed */
if(rp_Init() != RP_OK){
fprintf(stderr, "Rp api init failed!\n");
}

/*GENERATE*/

rp_GenReset();
rp_GenWaveform(RP_CH_2, RP_WAVEFORM_SINE);
rp_GenFreq(RP_CH_2, 10000.0);
rp_GenAmp(RP_CH_2, 0.5);
rp_GenMode(RP_CH_2, RP_GEN_MODE_BURST);
rp_GenBurstCount(RP_CH_2, 3);
usleep(100);
rp_GenOutEnable(RP_CH_2);

uint32_t buff_size = 16384;
float *buff = (float *)malloc(buff_size * sizeof(float));

rp_AcqReset();
rp_AcqSetDecimation(RP_DEC_8);
rp_AcqSetTriggerLevel(0);
rp_AcqSetTriggerDelay(0);

rp_AcqStart();

/*If you have trigger delay 0, after acquisition is started some pause is
needed in order to acquire fresh samples in to buffer. Here we have used
time delay of one second but you can calculate exact value taking in
to account buffer length and smaling rate.
If you set TRIGGER DELAY to 8192 sample THEN you don’t need to have pause,
because time delay of 8192 will give you a full buffer (16384 samples) of new data.
I.e all samples will be AFTER the trigger event. With trigger delay 0,
half of a buffer are data before and half are data after trigger event.*/
sleep(1);

rp_AcqSetTriggerSrc(RP_TRIG_SRC_AWG_PE);
rp_GenTrigger(2);
rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;

while(1){
rp_AcqGetTriggerState(&state);
if(state == RP_TRIG_STATE_TRIGGERED){
break;
}
}

usleep(1000);
rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff);

int i;
for(i = 0; i < buff_size; i++){
printf("%f\n", buff);
}

rp_GenOutDisable(RP_CH_2);
/* Releasing resources */
free(buff);
rp_Release();
return 0;
}

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Trigger from Arb Waveform

Post by mikepage » Tue Dec 08, 2015 1:47 pm

Hi,

Thanks for your reply, and sorry for the delay - I got moved to another project for a few days.

Your example as written does work, and still works if I take out the burst commands as advised. But it doesn't work if I set a delay of 8192 and take out the sleep(1). Then it just hangs waiting for a trigger like my code does.

I think you mean a trigger delay as a negative value? If I set +2000, I can see the data between sample 0 and sample 6358. After that the buffer is zero. If I set -2000 I get data up to sample 11830. So logically -8192 would cause the buffer to be filled, but it doesn't. Instead as for 8192, there is no trigger and the code just hangs.

Anyway, I can live with this I think. I set a trigger delay of MINUS 8000 AND a SLEEP long enough to fill the buffer (e.g. 10ms). Then I get just about a complete buffer of data. But now the next two problems:

1. How do I locate the point in the acquisition buffer where the trigger occurred (i.e. the start of my ARB waveform)? I was hoping with a trigger offset of zero it would be the centre of the buffer (sample 8192), but it isn't.

2. It appears when I trigger the acquisition from the generator, the waveform stops being generated after acquisition is complete. Is that correct? If so, it's not the behaviour I expect, nor what I want.

And one more question if I may - can you explain the difference between rp_AcqGetLatestDataV and rp_AcqGetOldestDataV? I tried both, but they seem to be just the same.

Thanks for your help.
Mike.

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Trigger from Arb Waveform

Post by mikepage » Fri Dec 18, 2015 5:23 pm

Just thought I'd add some final comments to this post in case anyone else has the same problem.

The solution given by the RP team does not work. You can't just take the burst specification out and get continuous data. This is because the function rp_GenTrigger calls gen_Trigger which forces the generator back to burst mode with the line:

ECHECK(gen_setGenMode(RP_CH_1, RP_GEN_MODE_BURST));

This is what makes the generator stop after acquisition.

I tried taking this out and rebuilding librp.so, but that doesn't work either. The generation is continuous, but triggering doesn't work and the waveform is corrupted by configuring the trigger conditions.

I also took a quick look into the FPGA code and it looks like that requires the generator to run in burst mode in order to trigger the acquisition. This is a big limitation for me.

What is the chance of someone at RP adding a mode where you can trigger acquisition when the ARB generator counter wraps?

Mike.

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Trigger from Arb Waveform

Post by Nils Roos » Thu Jan 07, 2016 12:20 am

What is the chance of someone at RP adding a mode where you can trigger acquisition when the ARB generator counter wraps?
Can't say anything about that, but I have prepared a branch from the current master that has the logic and librp support for your request.
If you'd like to try it out, see here, it's just a new enum and getter/setter for the new 'outgoing trigger condition'-setting along with the required additional fpga logic. Use this links to see the changes.

Let me know if it does what you want or if you need anything changed. (Or fixed, I only tested it very superficially^^)

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Trigger from Arb Waveform

Post by mikepage » Fri Jan 08, 2016 6:51 pm

Hi Nils,

Thanks for responding. I have cloned your GIT branch and downloaded and installed Vivado (which I have to say is a total pain, but anyway...). Not sure what to do next. I started Vivado and it wants a project file, but the FPGA directory doesn't seem to have one. Are there instructions anywhere for building the FPGA code? I am using Windows by the way, so a lot of the handy hints in the Wiki don't really apply, although some do make sense.

I did try just creating a project and adding in the source files (rtl and tbn) and also the ip, but it did not synthesise cleanly.

I tried to search this forum for clues, but it won't let me look for useful things like "Vivado" or "FPGA", so that's not a lot of help either.

Thanks in advance,
Mike.

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Trigger from Arb Waveform

Post by Nils Roos » Sat Jan 09, 2016 5:55 pm

I tried to search this forum for clues, but it won't let me look for useful things like "Vivado" or "FPGA", so that's not a lot of help either.
Yeah, I know, the search function on this forum is effectively useless.

There's this thread on how to get a more or less functioning Vivado project. But to save you and me the time for trying to piece it all together in Windows I'll just build the modified ecosystem (again) and post it for you to download.

edit: turns out I shot myself in the foot a little when I merged in the latest commits from master, as it now needs Vivado 2015.4 to build. Give me a day or two to update my workbench...

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 6 guests