Skip to content
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

Add TX Burst Functionality #5

Merged
merged 1 commit into from
Mar 7, 2018

Conversation

razorheadfx
Copy link
Contributor

This adds TxStream::write_burst as a convenience function.

I reckon this requires some discussion since it is just a wrapper for setting the stream flags on the TxStream object for burst transmission and then calling writeStream and not a function included in the Soapy API in itself.

This also assumes the blocking behaviour of SoapyUHD (line 722 onward) also applies to all other drivers/plugins.
Unfortunately I only have access to UHD devices and not enough time to go source diving in the other plugins right now to verify this.

@kevinmehall
Copy link
Owner

I would like to also add support for the functionality of theflags field on the streaming read/write API at some point, but I like the idea of a convenience function for bursts.

This also assumes the blocking behaviour of SoapyUHD (line 722 onward) also applies to all other drivers/plugins.

That "UHDSoapy" file adapts a UHD API caller to use a Soapy device and is not the other way around. So the presence of that loop implies that the Soapy API can't be relied on to transmit the entire buffer in one call. The code that would be used to drive a USRP from this library is "SoapyUHD".

As this is a convenience function, I think it would be reasonable to have a loop to ensure the entire buffer is written.

@kevinmehall
Copy link
Owner

kevinmehall commented Feb 27, 2018

activateStream for TX is a no-op in SoapyUHD, but from what I can tell, the stream must be active to send a burst on other drivers. On many drivers, activateStream is somewhat expensive (launching threads), so this should probably document that the stream needs to be active rather than activating and deactivating for every burst.

src/device.rs Outdated
);

// configure the flags for burst mode
self.flags = SOAPY_SDR_TX as i32 + SOAPY_SDR_HAS_TIME as i32 + SOAPY_SDR_END_BURST as i32;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These flags will be applied to any subsequent write -- this should use a local variable.

My plan for this flags field in the struct is that we could avoid adding a ton of arguments to write by providing methods to set things like time that would apply to the next write. Not sure if that's a good idea or if this field should be removed.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen SOAPY_SDR_TX used as a writeStream parameter before. It's defined as zero, so it won't do anything, but I think it's intended for the Device methods to determine whether you're configuring the TX or RX chain, not for writeStream where it already knows the direction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding SOAPY_SDR_TX, I chucked it on there for good measure not for any deeper reason :-).
I could add a type alias or something that indicates what they are to be used for.

Yeah the whole flag situation is rather untidy...

From what i can tell SoapyUHD resets the flags after each call to writeStream and readStream, so that would not be that much of a issue, but other wrappers might not do it that way...
The only place the flags are actually used to convey anything (at least in SoapyUHD) is readStreamStatus (exclusive to TX streams and looks rather costly), where they are used to retrieve Error codes from async metadata (i.e. burst late etc).
If this applies to all/most wrappers we might be fine just parsing them as additional error codes if they are something other than 0 after the call.

src/device.rs Outdated
pub fn write_burst(
&mut self,
buffers: &[&[E]],
at_ns: i64,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense for this to be Option<i64>? It looks like HackRF supports burst, but not HAS_TIME, and users may want to quickly transmit a burst but not care about precise timing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I'll add that.

@razorheadfx
Copy link
Contributor Author

razorheadfx commented Feb 27, 2018

Summing up for now

TODOs

  • make the timespec on write_burst an option and update flags accordingly
  • use local variable flags for burst convenience method and check them against error codes afther the SoapySDR_writeStream call returns
  • remove SOAPY_SDR_TX and (optionally type alias SOAPY_SDR_TX and SOAPY_SDR_RX so they are indicated as something other than streamflags)
  • add loop to write_burst to ensure entire buffer is tx'ed in one blocking call
  • longterm: check flag handling in other soapy wrappers and come up with a proper soution for the flags

Did I miss anything?

@kevinmehall
Copy link
Owner

use local variable flags for burst convenience method and check them against error codes afther the SoapySDR_writeStream call returns

Not sure what you mean by the error handling part. The error codes are in the return value, not the flags param. None of the flags are documented as being returned by a write, though some drivers clear flags under various conditions.

Other than that, sounds good to me. Thanks!

longterm: check flag handling in other soapy wrappers and come up with a proper soution for the flags

I added some notes on the rest of the flags and RX bursts on a new issue #6.

@kevinmehall kevinmehall mentioned this pull request Feb 28, 2018
@razorheadfx
Copy link
Contributor Author

razorheadfx commented Mar 4, 2018

Updates and rebased onto the new master.
Added a few debug helpers and updated docs.
Also tested with a B210.

Any thoughts?

update: tested with x310
for these devices soapy writes the whole burst in one call.

@kevinmehall
Copy link
Owner

Looks good. I'll test with a LimeSDR and HackRF tomorrow to see how those assumptions hold.

@kevinmehall
Copy link
Owner

kevinmehall commented Mar 7, 2018

  • Works on B200

  • Works on HackRF, but requires activateStream, ignores the timestamps (as expected, no hardware support), and hits both of your debug!()s:

write_burst: Expected reset flags (0), encountered flag code 6
write_burst: Expected reset flags (0), encountered flag code 2
write_burst: Expected reset flags (0), encountered flag code 2
write_burst: Expected reset flags (0), encountered flag code 2
write_burst: required 4 calls to write burst of length 500000
  • Works on LimeSDR, but not super reliably. (LimeSDR TX has always been buggy for me) Requires activateStream and also requires the RX channel to have its sample rate set and stream activated for timestamps to work.

Test code

@kevinmehall kevinmehall merged commit 7afd52f into kevinmehall:master Mar 7, 2018
@kevinmehall
Copy link
Owner

Merged, but I redesigned the API with #6 in mind to separate the flags from the loop behavior:

pub fn write(
    &mut self,
    buffers: &[&[E]],
    at_ns: Option<i64>,
    end_burst: bool,
    timeout_us: i64
) -> Result<usize, Error>

pub fn write_all(
    &mut self,
    buffers: &[&[E]],
    at_ns: Option<i64>,
    end_burst: bool,
    timeout_us: i64
) -> Result<(), Error>

Your write_burst is write_all with end_burst set to true. Let me know what you think of that design.

Thanks!

@razorheadfx
Copy link
Contributor Author

Not what I had in mind but definitely cleaner, considering it could be used for things other than burst.
And its a lot rustier 👍
Thank you!

@razorheadfx razorheadfx deleted the tx_burst branch March 12, 2018 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants