New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: T/R switching (real time half duplex) via gr-osmosdr #195

Open
kpreid opened this Issue Jul 10, 2015 · 20 comments

Comments

Projects
None yet
@kpreid

kpreid commented Jul 10, 2015

This is fairly off-topic as it relates entirely to gr-osmosdr code and not libhackrf code, but I haven't seen any active issue tracker or other forum actually used for gr-osmosdr, and I'm hoping that there is interest from this community (precedent being issue #87).

I would like to be able to use the HackRF in a half-duplex fashion from GNU Radio. Unfortunately, as currently implemented, TX or RX operations can only be stopped by destroying the gr-osmosdr sink or source object. This makes it very tricky (but possible) to perform the switch (making sure that the lifetimes of the sink and source do not overlap), and makes it impossible to query the capabilities of the device (sample rates, filter bandwidths, gains) without entering TX mode.

I would like to be able to have both source and sink objects around, and set the hardware to TX mode only on request. The request could be explicit, or implicit based on the availability of samples to transmit, or on the running state of the flowgraph containing the sink.

@miek

This comment has been minimized.

Contributor

miek commented Jul 10, 2015

I'd really like to see this too.

As far as I can tell, the standard (as used by uhd) seems to be to use the tags tx_sob and tx_eob at the start and end of a TX burst. Then the sink doesn't expect any samples between bursts, and the flowgraph can stall without lots of underflow errors.

Another benefit I see is that it makes bursty transmission a lot easier since you don't need to generate silence between packets (or drop to python to switch off between packets). It should also reduce latency since the sink isn't working through silent buffers to get to the actual burst.

@dragonyzl

This comment has been minimized.

dragonyzl commented Jul 26, 2015

Yes! This feature is very useful for me!
In order to implement the feature, I bought two hackrf one to implement the full duplex for Transciever the signal. If hackrf one can switch TX and RX with deterministic latency. It will be very very nice for me! ^_^.

Because of lack of the knowledge of hardware, I'm looking forward the feature very much and hope to take part in the development of implementation with someone's help, thanks for hints!

@KC5CQW

This comment has been minimized.

KC5CQW commented Aug 6, 2015

Please escalate the priority on this!

@herrfeuer

This comment has been minimized.

herrfeuer commented Aug 7, 2015

+1

@argilo

This comment has been minimized.

argilo commented Aug 13, 2015

I hacked T/R switching into gr-osmosdr and hackrf a while ago while building contest-sdr. See these branches:

I took some shortcuts, but it works as long as you don't need the T/R switching to be fast. My branches would probably be a good starting point for getting proper T/R support built.

@guruofquality

This comment has been minimized.

Contributor

guruofquality commented Oct 6, 2015

So I would like to give this feature a shot with the SoapyHackRF wrapper if users are interested in testing it with me. The description in the issue below, but what I am proposing is doing the automatic switching when the user provides transmit data by starting and stopping the streams.

One of the advantages of doing this in SoapyHackRF is that all of the data structures and synchronization is in one place. The Osmo source and sink blocks are just a layer on top of this, sharing the same handle to the underlying SoapySDR device.

@zeroXzero

This comment has been minimized.

zeroXzero commented Oct 21, 2015

@guruofquality +1. So what's the best way to add tag support for this feature in gnuradio? Is it better to add it in gr-sdr when compared to gr-osmosdr (a gr-uhd style "stream tag" and command port support). It seems like SoapySDR already shares the same device handle if same arguments are used (So that sink and source block can coexist).

@guruofquality

This comment has been minimized.

Contributor

guruofquality commented Oct 21, 2015

@zeroXzero Thats correct, since the device handles are in the same SoapySDR device object, its straightforward with some mutexes and a few extra indicators to implement the switching using the existing API for burst flags, etc.

Although not implemented yet, the issue is on my radar: pothosware/SoapyHackRF#7 And I will be revisiting SoapyHackRF soon to implement some of the new calls that I have added to SoapySDR recently.

As far as supporting the switching in GNU Radio blocks using tags, we have a few options here:

  1. We can add tag support to the soapy source and sink blocks in GrOsmoSDR. They are just ordinary GrBlocks that happen to get instantiated when Soapy SDR supported devices are used. So all of the tag handling glue can go into these two blocks. And any Soapy SDR devices that support timestamps and/or bursts will be able to take advantage of this.
  1. We can do exactly the same work to gr-sdr. I made gr-sdr before making the soapy block support in GrOsmoSDR. So they are similar projects. As much as I like the idea of set of clean, streamlined, and minimal dependency SDR blocks for GNU Radio, its really a matter of whatever the community wants, and GrOsmoSDR is by far more popular with the folks :-)

  2. Or use gr-uhd. Just like GrOsmoSDR, Soapy SDR devices should be usable from within this wrapper as well using SoapyUHD (https://github.com/pothosware/SoapyUHD/wiki) Users may not be comfortable with the additional layer of redirection, but that tags and timestamp features are already implemented here, which is a plus.

  3. Don't implement any tags. The SoapyHackRF async thread could detect the cessation of transmit packets within a time window and automatically switch back. That may sound a little lazy, but on the other hand, if we switch immediately when a EOB tag is consumed, will the outgoing samples become truncated before they are completely transmitted? We may need a carefully calculated timeout in any case. I will have some experiments to do.

Quite a few options here. So I would love to know what others think about this.

@guruofquality

This comment has been minimized.

Contributor

guruofquality commented Nov 14, 2015

Update: If anyone wants to try this out, @jocover implemented this feature for SoapyHackRF. It might need some additional tweaks, but it appears to work: pothosware/SoapyHackRF#7

@shaky1024

This comment has been minimized.

shaky1024 commented Sep 21, 2016

+1. Seems strange to me that this still hasn't happened.

@guruofquality

This comment has been minimized.

Contributor

guruofquality commented Sep 22, 2016

I should have posted another updated after giving this a live test. This was a while ago, but I gave this BTLE transceiver app a go with the hackrf using SoapyHackRF. The demo continuously receives BTLE advertisement packets, but it can be interrupted with a GUI click to transmit a control signal to a wireless remote.

So its not an app that transmits often, nor is it very sensitive to the timing of the switching. But it was pretty cool to see it work on the hackrf without issue. Although this is a Pothos demo, you should be able to have simultaneous gr-osmosdr source and sink block with intermittent transmits using the args "soapy=0,driver=hackrf"

Basically the act of transmitting forces the wrapper to switch. And on the receive side, it waits for tx buffers to be totally transmitted before switching back... All within the SoapyHackRF streaming implementation, no changes to libhackrf. And you shouldn't need any tags or labels to indicate end of burst on transmit.

@mike01

This comment has been minimized.

mike01 commented Oct 3, 2016

The TX/RX-switch does actually relate to libhackrf code and doesn't seem to be solvable just changing host code. The reason for this is that the libhackrf code does not make sure that samples sent in TX are fully sent out when switching mode to RX. You can observe this problem when doing a TX->RX->TX switch and receiving the signals using a 2nd SDR. The picture below shows a TX-round sending 32000 samples on a low frequency and the same amount on a high frequency. The marked section (~300us) shows the area where the SDR is in RX mode. It can be seen that the full samples are not entirely sent out before switching. Solving this probably includes changes on the host and firmware side especially regarding the USB-signalling code.
tmp

@argilo

This comment has been minimized.

argilo commented Oct 3, 2016

@mike01 Indeed. In my prototype I swept this problem under the rug by appending silence to the TX samples:

https://github.com/argilo/gr-osmosdr/blob/6e67be09da9f2e40996edb2ca8688e474946ff73/lib/hackrf/hackrf_sink_c.cc#L281-L293

But clearly that's a dirty hack that only works if you can tolerate very slow T/R switching.

@eejake52

This comment has been minimized.

eejake52 commented Oct 22, 2016

@guruofquality:
I tried with gnuradio companion: "you should be able to have simultaneous gr-osmosdr source and sink block with intermittent transmits using the args "soapy=0,driver=hackrf" ". I have both source and sink blocks using the same args. The source block transmits a burst of morse code with no repeat, so I expected the sink block would then take over. If I disable the sink, then the source works fine, and if I disable the source, then the sink works fine; but if both are enabled, then only the source block (rx) works, the rx LED comes on and I get an error from GRC as follows:
gr-osmosdr 0.1.4 (0.1.4) gnuradio 3.7.9
built-in source types: file osmosdr fcd rtl rtl_tcp uhd miri hackrf bladerf rfspace airspy redpitaya
Number of USB devices: 6
USB device 1d50:6089: 0000000000000000909864c8343e0ecf match
Using HackRF One with firmware 2015.07.2
gr-osmosdr 0.1.4 (0.1.4) gnuradio 3.7.9
built-in sink types: uhd hackrf bladerf redpitaya file
Number of USB devices: 6
USB device 1d50:6089: 0000000000000000909864c8343e0ecf match

FATAL: Failed to open HackRF device (-1000) HACKRF_ERROR_LIBUSB

So, is there a trick to getting a source and sink working?
Thanks,
Jake

@guruofquality

This comment has been minimized.

Contributor

guruofquality commented Oct 23, 2016

So, is there a trick to getting a source and sink working?

@eejake52 So my suggestion was to try out the SoapyHackRF module. To use that with gr-osmosdr, make sure that the following steps are taken care of first:

  1. Install SoapySDR
  2. Install SoapyHackRF, make sure that hackrf appears in SoapySDRUtil --info
  3. Install gr-osmosdr (soapy sdr support will be included when the development files are present), and make sure that 'soapy' appears in the supported options like the ones printed previously:file osmosdr fcd rtl rtl_tcp uhd miri hackrf bladerf rfspace airspy redpitaya

Then "soapy=0,driver=hackrf" should work. Sorry, I wish there was a failmode in the gr-osmosdr device selection, but when the key is not found it just picks the first available device.

FATAL: Failed to open HackRF device (-1000) HACKRF_ERROR_LIBUSB

This was the error we were seeing with the hackrf wrapper from gr-osmosdr (SoapyOsmo) because both the source and the sink were being instantiated at once. So that was actually the impetus for someone to contribute the SoapyHackRF support in the first place. :-)

@eejake52

This comment has been minimized.

eejake52 commented Oct 23, 2016

@guruofquality: thanks for the pointers. I now have the SoapySDR source and sinks installed and recognizing the hackrf.
However: if I just enable the sink, run the flowgraph, it works fine; but if I stop and restart the flowgraph, it hangs. I have to reset the hackrf to get it working again. Same issue with source; i.e. have to reset the hackrf to get it to work again.

Meanwhile, if I enable both source and sink, I see the tx LED flicker briefly, then the rx LED, then the tx LED comes on steady; I expected to see the tx LED for about 10 seconds, then the rx LED. I looked at your BTLE example, and I couldn't see anything obvious that I could be doing wrong. If you have any suggestions on how to go about testing, I'd appreciate that.

@eejake52

This comment has been minimized.

eejake52 commented Nov 27, 2016

I eventually got the issue resolved. I was running Ubuntu on a virtual machine, and that was causing silent glitches on the USB connection.

@ly2ss

This comment has been minimized.

ly2ss commented Jun 3, 2017

guruofquality, i did everything as you instructed few posts above. Separate graph parts work ok but once I put everything in one place I am getting this:

Executing: /usr/bin/python2 -u /home/osmo/Desktop/ok/top_block.py

gr-osmosdr v0.1.4-91-gcf954948 (0.1.5git) gnuradio 3.7.12git-119-g0e32fcaf
built-in source types: file fcd rtl rtl_tcp hackrf rfspace soapy redpitaya
[INFO] Opening HackRF One #0 406464c82332614b...
gr-osmosdr v0.1.4-91-gcf954948 (0.1.5git) gnuradio 3.7.12git-119-g0e32fcaf
built-in sink types: hackrf soapy redpitaya file

FATAL: no hackrf device matches

Trying to fill up 1 missing channel(s) with null sink(s).
This is being done to prevent the application from crashing
due to gnuradio bug #528.

screenshot at 2017-06-03 09-15-50

@guruofquality

This comment has been minimized.

Contributor

guruofquality commented Jun 3, 2017

gr-osmosdr v0.1.4-91-gcf954948 (0.1.5git) gnuradio 3.7.12git-119-g0e32fcaf
built-in source types: file fcd rtl rtl_tcp hackrf rfspace soapy redpitaya
[INFO] Opening HackRF One #0 406464c82332614b...
gr-osmosdr v0.1.4-91-gcf954948 (0.1.5git) gnuradio 3.7.12git-119-g0e32fcaf
built-in sink types: hackrf soapy redpitaya file

For whatever the reason is, hackrf_device_list() doesnt report the device once its been opened the first time. SoapyHackRF isnt trying to open a new device handle, but it relies on discovering the HackRF, even though its already opened to find and use the same device handle. This might not be anything different in libhackrf, it could just be due to the SoapyHackRF open by serial support. Looks like the solution is to stash the discovered result and use it in find_HackRF() when the device handle is claimed. brb

@ly2ss

This comment has been minimized.

ly2ss commented Jun 3, 2017

Just for curiosity I disabled all possible sinks/sources in gr-osmocom except soapy but the result is same: FATAL: no hackrf device matches

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment