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

bladerf_set_sample_rate issue on multiple output (MO) mode #675

Closed
f4exb opened this Issue Oct 4, 2018 · 9 comments

Comments

Projects
None yet
2 participants
@f4exb
Copy link

f4exb commented Oct 4, 2018

I am reporting this as an issue following this post in the forum: https://nuand.com/forums/viewtopic.php?f=9&t=4999&p=9076#p9076

When both Tx are engaged the output is garbled if bladerf_set_sample_rate is set with the sample rate of one channel. I realized by chance that doubling the sample rate value would fix the problem.

However according to the post mentioned this is not expected. Indeed on the Rx side you would use the sample rate of one channel when working in multiple input (MI) mode.

A consequence of doubling the sample rate on the Tx side is that it is also doubled on the Rx side since the sample rate is common to all channels.

Edit: this is with libbladeRF 2018.08 release

@rtucker

This comment has been minimized.

Copy link
Collaborator

rtucker commented Oct 4, 2018

I believe the expected behavior for this should be that the sample rate be the sample rate of one channel; e.g. 10 MSps should be 10 MSps for each channel, whether one or two are in use. This would be the "least surprising" interpretation of it.

Thanks for the report! I will dig in...

@rtucker rtucker self-assigned this Oct 4, 2018

@rtucker rtucker added this to the 2018.10 milestone Oct 4, 2018

@rtucker

This comment has been minimized.

Copy link
Collaborator

rtucker commented Oct 4, 2018

10M samples, 10 MSps...

RX with channel=1:

[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: RX1 ch_en=1 ch_pend=1 dir_en=1 dir_pend=1 be_clr=0 reg=0xf8000001->0xf8008083 nsec=1538668660431187000 (delta: 12561629000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: RX1 ch_en=0 ch_pend=1 dir_en=0 dir_pend=1 be_clr=0 reg=0xf8008083->0xf8000001 nsec=1538668661496262000 (delta: 1065075000)

TX with channel=1:

[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=1 ch_pend=1 dir_en=1 dir_pend=1 be_clr=0 reg=0xf8000001->0xf8011005 nsec=1538668679638741000 (delta: 18142479000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=0 ch_pend=1 dir_en=0 dir_pend=1 be_clr=0 reg=0xf8011005->0xf8000001 nsec=1538668680709531000 (delta: 1070790000)

RX with channel=1,2:

[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: RX1 ch_en=1 ch_pend=1 dir_en=1 dir_pend=1 be_clr=0 reg=0xf8000001->0xf8008083 nsec=1538668692890623000 (delta: 12181092000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: RX2 ch_en=1 ch_pend=1 dir_en=1 dir_pend=0 be_clr=1 reg=0xf8008083->0xf8028283 nsec=1538668692892078000 (delta: 1455000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: RX1 ch_en=0 ch_pend=1 dir_en=1 dir_pend=0 be_clr=0 reg=0xf8028283->0xf8020203 nsec=1538668693417561000 (delta: 525483000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: RX2 ch_en=0 ch_pend=1 dir_en=0 dir_pend=1 be_clr=0 reg=0xf8020203->0xf8000001 nsec=1538668693429982000 (delta: 12421000)

TX with channel=1,2:

[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=1 ch_pend=1 dir_en=1 dir_pend=1 be_clr=0 reg=0xf8000001->0xf8011005 nsec=1538668883516623000 (delta: 190086641000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX2 ch_en=1 ch_pend=1 dir_en=1 dir_pend=0 be_clr=0 reg=0xf8011005->0xf8055005 nsec=1538668883519528000 (delta: 2905000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=0 ch_pend=1 dir_en=1 dir_pend=0 be_clr=0 reg=0xf8055005->0xf8044005 nsec=1538668884050209000 (delta: 530681000)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX2 ch_en=0 ch_pend=1 dir_en=0 dir_pend=1 be_clr=0 reg=0xf8044005->0xf8000001 nsec=1538668884060456000 (delta: 10247000)

Looking at the deltas between ch_en=1 and ch_en=0:

RX 1 ch: 1065075000 (1065 ms)
RX 2 ch: 525483000 (525 ms)
TX 1 ch: 1070790000 (1071 ms)
TX 2 ch: 530681000 (531 ms)

So this seems reasonably consistent at first glance, and it doesn't seem like what I was afraid it would be.

@f4exb , do you have a test case to reproduce this? Are you using bladeRF-cli, or your own code? I'm wondering if it's an interleaving thing.

@f4exb

This comment has been minimized.

Copy link
Author

f4exb commented Oct 4, 2018

In fact this is the code in SDRangel I am currently developing to support the 2.0 micro. It is a bit complex since both Tx streams are handled each by its own instance of the Tx code. Since the actual stream is interleaved only one thread instance takes care of the call to bladerf_sync_tx. The thread pointer is shared between all instances of the rest of the Tx code.

Everything revolves around these three files:

https://github.com/f4exb/sdrangel/blob/dev/devices/bladerf2/devicebladerf2.cpp contains common routines including an "openTx" and "closeTx" that encapsulates the call to bladerf_enable_module to enable or disable channels.

https://github.com/f4exb/sdrangel/blob/dev/plugins/samplesink/bladerf2output/bladerf2output.cpp there is one instance for each channel. It is responsible of managing the unique thread and will make calls to "openTx" and "closeTx" mentioned above

https://github.com/f4exb/sdrangel/blob/dev/plugins/samplesink/bladerf2output/bladerf2outputthread.cpp this is the unique thread described above. It will make a call to bladerf_sync_config then run bladerf_sync_tx in a loop. Before calling bladerf_sync_tx the buffer is prepared in callbackMO() where the bladerf_interleave_stream_buffer is called to interleave samples from both buffers.

The order of calls to the libbladeRF methods is thus the following:

  • bladerf_enable_module
  • bladerf_sync_config
  • in a loop:
    • bladerf_interleave_stream_buffer
    • bladerf_sync_tx

bladerf_set_sample_rate is called in bladerf2output.cpp whenever the sample rate is changed from the GUI.

Note: there are no particular issues on the Rx side using the same scheme:

I hope this helps.

@rtucker

This comment has been minimized.

Copy link
Collaborator

rtucker commented Oct 8, 2018

Hmm okay... so I'm giving this a try with the HEAD of the dev branch (39c001f95e3a09656c7f86cb147f88e663202d22), with two NBFM modulators, one at -30 kHz, one at +30 kHz. I believe I have things configured to send the -30 kHz output to TX1 and the +30 kHz output to TX2, but it turns out I am getting both modulators on TX1 and nothing at all on TX2.

I'm a first-time SDRangel user, so there is a very good chance I am doing this wrong. I'm going to crank up some debugging to see what's happening underneath, though.

Here's my setup for T1:

sdrangel-t1

And for T2:

sdrangel-t2

@f4exb

This comment has been minimized.

Copy link
Author

f4exb commented Oct 8, 2018

Hi, according to the screenshots this is correct:

  • BladeRF2[0:0] is the Tx1 (index 0) of the first (or unique) BladeRF (index 0) in the system
  • BladeRF2[0:1] is the Tx2 (index 1) of the first (or unique) BladeRF (index 0) in the system

I proceed the same way for my test just adding a bit of software interpolation (the Int combo box).

How do you conclude that only Tx1 is used? Maybe this is the issue.

@rtucker

This comment has been minimized.

Copy link
Collaborator

rtucker commented Oct 8, 2018

I tossed a bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_VERBOSE); into DeviceBladeRF2::open_bladerf_from_serial() to see what's going on in libbladeRF, and it looks like TX1 is being enabled twice:

[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=1 ch_pend=1 dir_en=1 dir_pend=1 be_clr=0 reg=0xf8000001->0xf8011005 nsec=1539029951533835785 (delta: 1539029951533835785)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=0 ch_pend=1 dir_en=0 dir_pend=1 be_clr=0 reg=0xf8011005->0xf8000001 nsec=1539029992533098616 (delta: 40999262831)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=1 ch_pend=1 dir_en=1 dir_pend=1 be_clr=0 reg=0xf8000001->0xf8011005 nsec=1539029993738350112 (delta: 1205251496)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1878] bladerf2_enable_module: TX1 ch_en=1 ch_pend=0 dir_en=1 dir_pend=0 be_clr=0 reg=0xf8011005->0xf8011005 nsec=1539029993739171494 (delta: 821382)
[DEBUG @ host/libraries/libbladeRF/src/board/bladerf2/bladerf2.c:1889] bladerf2_enable_module: reg value unchanged? (f8011005)

(Line 3 would be the first call to enable TX1, lines 4 and 5 would be the second call)

@f4exb

This comment has been minimized.

Copy link
Author

f4exb commented Oct 8, 2018

I just had another look at my DeviceBladeRF2::openTx() routine and the error was sitting there right in front of my eyes:
status = bladerf_enable_module(m_dev, BLADERF_CHANNEL_TX(0), true);
This should be changed to (of course):
status = bladerf_enable_module(m_dev, BLADERF_CHANNEL_TX(channel), true);
As done for the Rx which explains the difference of behavior between Rx and Tx.

I'll try that and close this issue if successful.

@f4exb

This comment has been minimized.

Copy link
Author

f4exb commented Oct 8, 2018

Yes. That was the issue. Thanks for directing me to the real problem and sorry for the inconvenience.
f4exb/sdrangel#225 opened to fix the issue.

@f4exb f4exb closed this Oct 8, 2018

@rtucker

This comment has been minimized.

Copy link
Collaborator

rtucker commented Oct 9, 2018

You're welcome! I've done this exact thing a few times. 🤦‍♀️

Thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.