[USRP-users] Trigger Signal

Martin Braun martin.braun at ettus.com
Thu Jul 6 15:37:47 EDT 2017


Mareike,

the reason for the delays is that your software is polling the GPIO, and
that goes over network. You're adding in network latency, and SW
scheduling latency.

Also, with the DDC, once a packet leaves the computer, it needs to go
through various stages before it reaches the ADC (after the ADC, there's
still a tiny delay before your volts hit the antenna, but that's much
much smaller than what you're looking at).

If you want the signal to start Tx'ing within nanoseconds of your
trigger signal, you need to implement all of this in the FPGA. This is
an interesting use case, but unfortunately not one for which we have
examples. The quickest way to hack this up that I can think of is to
wire the GPIO lines to the time stamp comparison logic. If you're not
familiar with FPGA development, this is not a trivial task, though.

Cheers,
Martin

On 06/08/2017 02:49 AM, Mareike Hetzel via USRP-users wrote:
> I use a sample rate of 33.333333Mhz. With 20Mhz it took 420 ms! I did
> not notice that before!
> The size of my buffers is defined by
> 
> if (spb == 0) spb = tx_stream->get_max_num_samps() * 10;
> 
> what leads to spb=4960.
> 
> 
> 
> Zitat von Julian Arnold <julian at elitecoding.org>:
> 
>> Hey,
>>
>> one more question:
>> what is your sample rate and what is the size of your buffers?
>>
>> Cheers,
>>
>> On 06/08/2017 11:13 AM, Mareike Hetzel wrote:
>>> Do you mean something like this?
>>>
>>> boost::uint32_t mask = 1 << 2;
>>> usrp->set_gpio_attr("FP0", "CTRL", mask, 0);
>>> usrp->set_gpio_attr("FP0", "DDR", mask, 0);
>>>
>>> What do you mean with checking the contents of my read-back variable?
>>>
>>> I attached a photo of the oscilloscope. The yellow line shows the
>>> trigger. There is small peak which shows the trigger I generated with
>>> the function generator. The blue shows the tx stream. At first, it has
>>> a high amplitude/power and 250 ms after the trigger it is set to a
>>> smaller amplitude/power.
>>>
>>>
>>> Thank you for your time!
>>> Mareike
>>>
>>>
>>>
>>> Zitat von Julian Arnold <julian at elitecoding.org>:
>>>
>>>> Hi Mareike,
>>>>
>>>> so one thing I noticed is that you do not specify any mask in your
>>>> calls
>>>> to set_gpio_attr. Therefore, all your GPIOs on bank FP0 will be
>>>> changed.
>>>> Furthermore,  you do not check the contents of you read-back variable.
>>>> Therefore, your trigger works on all GPIOs.
>>>>
>>>> I still don't get from your code what you mean by changing the
>>>> amplitude
>>>> and how you measure the timing in that case.
>>>>
>>>> Cheers,
>>>>
>>>> On 06/06/2017 04:11 PM, Mareike Hetzel wrote:
>>>>> Hi!
>>>>>
>>>>> I generate the trigger signal with a function generator which I
>>>>> connect to the GPIO API and an oscilloscope. The x310 TX/RX output is
>>>>> connected to another channel of the oscilloscope and to a spectrum
>>>>> analyzer.
>>>>> On the oscilloscope I can see the time difference between the trigger
>>>>> signal and the reaction of the SDR. It takes 700-800 microseconds to
>>>>> start streaming and 250 milliseconds to change settings like the
>>>>> amplitude. I don't know where this big difference comes from!
>>>>>
>>>>> The GPIO setup is based on the example here:
>>>>> https://files.ettus.com/manual/page_gpio_api.html
>>>>> I used the tx_waveforms example code and from this starting point, I
>>>>> mainly changed this:
>>>>>
>>>>>
>>>>> ... URRP setup...
>>>>> #define MAN_GPIO_MASK   (1 << 2)
>>>>> #define ATR_MASKS       (AMP_GPIO_MASK | MAN_GPIO_MASK)
>>>>> // set up our values for ATR control: 1 for ATR, 0 for manual
>>>>> #define ATR_CONTROL     (AMP_GPIO_MASK & ~MAN_GPIO_MASK)
>>>>> // set up the GPIO directions: 1 for output, 0 for input
>>>>> #define GPIO_DDR        (AMP_GPIO_MASK & ~MAN_GPIO_MASK)
>>>>>
>>>>> // assume an existing USRP device handle, called "usrp_x300"
>>>>>
>>>>> // now, let's do the basic ATR setup
>>>>>     usrp->set_gpio_attr("FP0", "CTRL", 0);
>>>>>
>>>>>     usrp->set_gpio_attr("FP0", "DDR", 0);
>>>>>
>>>>>     for (size_t n = 0; n < buff.size(); n++) {
>>>>>
>>>>>         buff[n] = 0.3;
>>>>>         buffer[n] = 0.15;
>>>>>     }
>>>>>
>>>>>     int i = 0;
>>>>>     int readback = 0;
>>>>>     while (true) {
>>>>>         if (stop_signal_called) break;
>>>>>         if (total_num_samps > 0 and num_acc_samps >= total_num_samps)
>>>>> break;
>>>>>
>>>>>         readback = usrp->get_gpio_attr("FP0", "READBACK", 0);
>>>>>         if (readback == 1) {
>>>>>             i = 1;
>>>>>         }
>>>>>
>>>>>         if (i==0) {
>>>>>             num_acc_samps += tx_stream->send(
>>>>>                 buffs, buff.size(), md
>>>>>             );
>>>>>         }
>>>>>         else {
>>>>>             num_acc_samps += tx_stream->send(
>>>>> /*case 1*/            "", 0, md
>>>>> /*case 2*/            buffers, buffer.size(), md
>>>>>             );
>>>>>         }
>>>>>     }
>>>>>
>>>>>
>>>>> No, by now I don't have a wait statement in there, because it is the
>>>>> same loop in which I send the buffers. Wouldn't this only cause
>>>>> additional underflows? (At least in this case)
>>>>>
>>>>> I connected pin 2 to the function generator and I thought that
>>>>> "#define MAN_GPIO_MASK   (1 << 2)" sets pin 2 to manual control. But I
>>>>> noticed that Pin 2 still works as trigger input if I define "#define
>>>>> MAN_GPIO_MASK   (1 << 3)" or any other pin number. I wanted to trigger
>>>>> pin 2 and then use pin 3 as an output which is changed when pin 2 is
>>>>> triggered. (To measure this time difference independent of streaming)
>>>>> But in my case only pin 2 is working as an trigger input. I thought
>>>>> every data-pin can be used the same way?
>>>>>
>>>>> Thank you for your help!
>>>>> Mareike
>>>>>
>>>>>
>>>>> Zitat von Julian Arnold <julian at elitecoding.org>:
>>>>>
>>>>>> Hey Mareike,
>>>>>>
>>>>>>> I was able to implement a trigger with the GPIO API.
>>>>>> Good to hear that!
>>>>>> I don't fully understand your problem though. Could you please
>>>>>> share a
>>>>>> little bit more of your code?
>>>>>> Also, how are you calculating the mentioned timings?
>>>>>>
>>>>>>> Additionally, I notice that my program with trigger included becomes
>>>>>>> unstable. Sometimes it runs without any problems and sometimes there
>>>>>>> are a lot of underflows by running the same code! Is this normal?
>>>>>> Do you have any wait statement in you while loop? Otherwise, it
>>>>>> might be
>>>>>> that the loop is eating up too much CPU time (Just a wild guess).
>>>>>>
>>>>>> Cheers,
>>>>>>
>>>>>> On 06/02/2017 11:59 AM, Mareike Hetzel wrote:
>>>>>>> Hey!
>>>>>>>
>>>>>>> I was able to implement a trigger with the GPIO API. But I
>>>>>>> observed a
>>>>>>> strange behaviour:
>>>>>>> (case 1) If I use the trigger to start streaming, it takes
>>>>>>> approximately 700 to 800 microseconds until streaming actually
>>>>>>> starts.
>>>>>>> (case 2)If I use the trigger to change the amplitude or the
>>>>>>> frequency
>>>>>>> while it is already streaming, it takes approximately 250
>>>>>>> milliseconds
>>>>>>> to change! And this duration did not significantly change with
>>>>>>> different implementations I tried.
>>>>>>>
>>>>>>> I thought that it might have to do with the increasing time the
>>>>>>> while-loop needs in case 1 compared to case 2. In case 1 it takes
>>>>>>> approximately 50 microseconds per iteration and in case 2 150
>>>>>>> microseconds. But this is only three times the runtime and does not
>>>>>>> explain the hugh difference in reaction time to me.
>>>>>>>
>>>>>>> Here is the relevant part of my code:
>>>>>>>
>>>>>>> int readback=0;
>>>>>>> while (true) {
>>>>>>>     if (stop_signal_called) break;
>>>>>>>     if (total_num_samps > 0 and num_acc_samps >= total_num_samps)
>>>>>>> break;
>>>>>>>
>>>>>>>     readback = usrp->get_gpio_attr("FP0", "READBACK", 0);
>>>>>>>     if (readback == 1) {
>>>>>>>         i = 1;
>>>>>>>     }
>>>>>>>
>>>>>>>     if (i==1) {
>>>>>>>         num_acc_samps += tx_stream->send(
>>>>>>>             buffs, buff.size(), md
>>>>>>>         );
>>>>>>>     }
>>>>>>>     else {
>>>>>>>         num_acc_samps += tx_stream->send(
>>>>>>> /*case 1*/        "", 0, md
>>>>>>> /*case 2*/        buffers, buffer.size(), md
>>>>>>>         );
>>>>>>>     }
>>>>>>> }
>>>>>>>
>>>>>>> Do you have any idea what might cause this latency?
>>>>>>> Additionally, I notice that my program with trigger included becomes
>>>>>>> unstable. Sometimes it runs without any problems and sometimes there
>>>>>>> are a lot of underflows by running the same code! Is this normal?
>>>>>>>
>>>>>>> I would be grateful for any hint!
>>>>>>>
>>>>>>> Mareike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Zitat von Julian Arnold <julian at elitecoding.org>:
>>>>>>>
>>>>>>>> Hey Mareike,
>>>>>>>>
>>>>>>>> have you considered using the GPIO API for this task [1]?
>>>>>>>> I think using the GPIOs as a trigger source is more adequate than
>>>>>>>> using
>>>>>>>> the PPS input as the PPS should be used for time synchronization
>>>>>>>> between
>>>>>>>> multiple devices. (However, one could probably abuse it as a
>>>>>>>> trigger)
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>>
>>>>>>>> [1] https://files.ettus.com/manual/page_gpio_api.html
>>>>>>>>
>>>>>>>> On 05/22/2017 04:50 PM, hetzel--- via USRP-users wrote:
>>>>>>>>> Hi!
>>>>>>>>>
>>>>>>>>> I want to build a trigger signal for my USRP X310 using UHD
>>>>>>>>> version
>>>>>>>>> 3.10.1.1. I want to send a pulse to the USRP and after receiving
>>>>>>>>> this
>>>>>>>>> pulse my device should start/stop streaming or something similar.
>>>>>>>>>
>>>>>>>>> I found that I can use the PPS TRIG IN port and send a trigger
>>>>>>>>> signal.
>>>>>>>>> Therefore I have to set the PPS to external:
>>>>>>>>> pps = "external"   (Is this the right way to do so?)
>>>>>>>>> Afterwards the idea is to use timed commands and to start a long
>>>>>>>>> time
>>>>>>>>> from now. But with the next received PPS pulse, I set the clock to
>>>>>>>>> the
>>>>>>>>> same time. I started with a slightly changed tx_waveforms C++
>>>>>>>>> file. I
>>>>>>>>> would use these additions to the code:
>>>>>>>>>
>>>>>>>>> usrp->set_time_now(0.0); //somewhere in the beginning
>>>>>>>>> usrp->set_command_time(uhd::time_spec_t(1e6));
>>>>>>>>>
>>>>>>>>> md.has_time_spec = true;
>>>>>>>>> md.time_spec = uhd::time_spec_t(1e6); // I am not sure if this is
>>>>>>>>> needed
>>>>>>>>>
>>>>>>>>> usrp->set_time_next_pps(uhd::time_spec_t(1e6)); // and this
>>>>>>>>> directly
>>>>>>>>> before I want to start streaming
>>>>>>>>>
>>>>>>>>> usrp->clear_command_time(); // in the end
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> If I run this program my USRP seems to wait for a PPS signal
>>>>>>>>> but it
>>>>>>>>> does not react to those I send using a Function Generator. So how
>>>>>>>>> does
>>>>>>>>> a PPS input pulse has to look like? It says that it should have
>>>>>>>>> max 5V
>>>>>>>>> but how long should it be?
>>>>>>>>>
>>>>>>>>> So I have to stop the program. But if I want to re-run it there
>>>>>>>>> occurs
>>>>>>>>> a problem and I cannot run any other program until I power cycle
>>>>>>>>> the
>>>>>>>>> device. I get the following output to the console:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Win32; Microsoft Visual C++ version 14.0; Boost_105900;
>>>>>>>>> UHD_003.010.001.001-rele
>>>>>>>>> ase
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Creating the usrp device with: ...
>>>>>>>>> -- X300 initialization sequence...
>>>>>>>>> -- Determining maximum frame size... 8000 bytes.
>>>>>>>>> -- Setup basic communication...
>>>>>>>>> -- Loading values from EEPROM...
>>>>>>>>> -- Setup RF frontend clocking...
>>>>>>>>> -- Radio 1x clock:200
>>>>>>>>> -- Creating WSA UDP transport for 192.168.40.2:49153
>>>>>>>>> -- Creating WSA UDP transport for 192.168.40.2:49153
>>>>>>>>> -- [DMA FIFO] Running BIST for FIFO 0... pass (Throughput:
>>>>>>>>> 1304.3MB/s)
>>>>>>>>> -- [DMA FIFO] Running BIST for FIFO 1... pass (Throughput:
>>>>>>>>> 1304.9MB/s)
>>>>>>>>> -- Creating WSA UDP transport for 192.168.40.2:49153
>>>>>>>>> Error: EnvironmentError: IOError: Block ctrl (CE_01_Port_40) no
>>>>>>>>> response packet
>>>>>>>>> - AssertionError: bool(buff)
>>>>>>>>>   in unsigned __int64 __cdecl ctrl_iface_impl::wait_for_ack(const
>>>>>>>>> bool)
>>>>>>>>>   at
>>>>>>>>> C:\cygwin64\home\jenkins\worker\Package_Windows_x64_14\work\uhd\host\lib\rf
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> noc\ctrl_iface.cpp:205
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Do you have any idea why this happens?
>>>>>>>>>
>>>>>>>>> I use Visual Studio 2015 on Windows 7.
>>>>>>>>>
>>>>>>>>> Best regards,
>>>>>>>>> Mareike Hetzel
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> USRP-users mailing list
>>>>>>>>> USRP-users at lists.ettus.com
>>>>>>>>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>>>>>>>
>>>>>>>> -- 
>>>>>>>> Julian Arnold, M.Sc.
>>>>>>>>
>>>>>>>> Institute for Networked Systems
>>>>>>>> RWTH Aachen University
>>>>>>>>
>>>>>>>> Kackertstrasse 9
>>>>>>>> 52072 Aachen
>>>>>>>> Germany
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> -- 
>>>>>> Julian Arnold, M.Sc.
>>>>>>
>>>>>> Institute for Networked Systems
>>>>>> RWTH Aachen University
>>>>>>
>>>>>> Kackertstrasse 9
>>>>>> 52072 Aachen
>>>>>> Germany
>>>>>
>>>>>
>>>>
>>>> -- 
>>>> Julian Arnold, M.Sc.
>>>>
>>>> Institute for Networked Systems
>>>> RWTH Aachen University
>>>>
>>>> Kackertstrasse 9
>>>> 52072 Aachen
>>>> Germany
>>>
>>>
>>
>> -- 
>> Julian Arnold, M.Sc.
>>
>> Institute for Networked Systems
>> RWTH Aachen University
>>
>> Kackertstrasse 9
>> 52072 Aachen
>> Germany
> 
> 
> 
> 
> _______________________________________________
> USRP-users mailing list
> USRP-users at lists.ettus.com
> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com





More information about the USRP-users mailing list