jmichelp / sdrsharp-bladerf

bladeRF driver for SDR#
54 stars 26 forks source link

NativeMethods.bladerf_open returns -8 #2

Closed ghost closed 8 years ago

ghost commented 9 years ago

The plugin is working perfect with SDRSharp.

But i want to use your code to build a program that sends all the iq packets on tcp/ip.

I get a -8 return value out of the bladerf_open.

my blade is well connected to my laptop on usb3. what could be wrong? thanks

jmichelp commented 9 years ago

According to the headers, the error code you get is: BLADERF_ERR_UNSUPPORTED = -8, /**< Operation not supported */

By having a brief look at Nuand's code, this code is not returned directly by bladerf_open() but by one of the many operations that are done to open and initialize the device.

I guess that one of the arguments you are passing is not correct.

ghost commented 9 years ago

i'm looking to do the following:

do you know rtl-tcp?

it sends the iq packets on a tcp/ip port to be picked up by other program. for instance websdr.

I want to do the same thing as rtl-tcp, but with a bladeRF...

Can you assist me?

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zaterdag 27 juni 2015 19:54:53 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

According to the headers, the error code you get is: BLADERF_ERR_UNSUPPORTED = -8, /*< Operation not supported /

By having a brief look at Nuand's code, this code is not returned directly by bladerf_open() but by one of the many operations that are done to open and initialize the device.

I guess that one of the arguments you are passing is not correct.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

Their protocol doesn't look like too complex.

You can reuse the native wrapper, the device initialization part as well as the callback that receives the sample. But you will have to change the lookup table because you will have to convert the signed 11 bit samples to unsigned 8 bit samples.

And many commands have not meaningful for bladerf so you won't have to implement them. Three commands should be enough: frequency, samplerate and gain.

I can help you if you have difficulties regarding some technical points but I haven't got enough time to write the code. I already haven't got enough spare time to make some progress on my personal projects.

ghost commented 9 years ago

where can i find this native wrapper?

i know already i have to convert the 12bit i and q to a unsigned 8 bit.

i think i can do that by shifting the bits to the right 4 times correct?

my C is a bit rusty... i'm more busy this days doeing vb.net...

Would't it be faster to add "a server" mode to your code?

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zaterdag 27 juni 2015 21:31:05 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

Their protocol doesn't look like too complex.

You can reuse the native wrapper, the device initialization part as well as the callback that receives the sample. But you will have to change the lookup table because you will have to convert the signed 11 bit samples to unsigned 8 bit samples.

And many commands have not meaningful for bladerf so you won't have to implement them. Three commands should be enough: frequency, samplerate and gain.

I can help you if you have difficulties regarding some technical points but I haven't got enough time to write the code. I already haven't got enough spare time to make some progress on my personal projects.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

The native wrapper is the file NativeMethods.cs. It provides the interface in C# to use the bladeRF.

You should also be able to reuse a huge part of BladeRFDevice.cs by removing the few lines that are specific to SDR#. I am not an expert in .Net language but I think you should be able to use those C# classes even in VB.Net

Right shifting by four would be enough but if I remember correctly, RTLSDR uses unsigned samples whereas bladeRF uses signed samples. The conversion is a bit more complicated then.

Adding a server mode wouldn't be easier because, like I said, most of the classes are closely linked to SDR# and the sample conversion is different (SDR# needs float samples).

ghost commented 9 years ago

with the native wrapper i have this piece of code:

Int32 status; IntPtr _dev; string devspec = ""; UInt32 idx, Frequency = 315000000U;

status = NativeMethods.bladerf_open(out _dev, devspec); Console.WriteLine(status.ToString());

status returns -8 to me..

this is not correct.

i see in your code that you also use devspec =""

so this couldn't be the problem...

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zaterdag 27 juni 2015 22:09:17 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

The native wrapper is the file NativeMethods.cs . It provides the interface in C# to use the bladeRF.

You should also be able to reuse a huge part of BladeRFDevice.cs by removing the few lines that are specific to SDR#. I am not an expert in .Net language but I think you should be able to use those C# classes even in VB.Net

Right shifting by four would be enough but if I remember correctly, RTLSDR uses unsigned samples whereas bladeRF uses signed samples. The conversion is a bit more complicated then.

Adding a server mode wouldn't be easier because, like I said, most of the classes are closely linked to SDR# and the sample conversion is different (SDR# needs float samples).

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

Are you sure that the device is not currently being used in another program? That's the only case I can think of if you're able to use your bladeRF with SDR#.

The code is returned by the native library so if you want to understand what's happening, you can either ask on Nuand's forum or look in their code where BLADERF_ERR_UNSUPPORTED can be returned.

ghost commented 9 years ago

i'm running on win8.1 64bit maybe that has something to do with it?

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zaterdag 27 juni 2015 22:31:32 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

Are you sure that the device is not currently being used in another program? That's the only case I can think of if you're able to use your bladeRF with SDR#.

The code is returned by the native library so if you want to understand what's happening, you can either ask on Nuand's forum or look in their code where BLADERF_ERR_UNSUPPORTED can be returned.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

No. That's my setup too.

I would suggest you to open a thread on Nuand's forum. I'm following the forum too so by doing so you will get support from both Nuand team on their library and me for C#/SDR# related problems.

ghost commented 9 years ago

i came up with this code, but is this correct?

status = NativeMethods.bladerf_sync_rx(_dev, _samplesPtr, cur_len, IntPtr.Zero, SampleTimeoutMs); if (status != 0) throw new ApplicationException(String.Format("bladerf_rx() error. {0}", NativeMethods.bladerf_strerror(status))); var ptrIq = _iqPtr; var ptrSample = _samplesPtr; tx1 = new char[cur_len * 2]; for (int i = 0; i < cur_len; i++) { ptrIq->Imag = _lutPtr[_ptrSample & 0x0fff]; tx1[i_2] = Convert.ToChar(_ptrSample >> 4); ptrSample++; ptrIq->Real = _lutPtr[_ptrSample & 0x0fff]; tx1[(i * 2)+1] = Convert.ToChar(*ptrSample >> 4); ptrSample++; ptrIq++; } ComplexSamplesAvailable(_iqPtr, _iqBuffer.Length);

myserver.Senddata(tx1);

i want an array of bytes from it complex and send them off to tcp/ip socket....

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zaterdag 27 juni 2015 22:37:23 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

No. That's my setup too.

I would suggest you to open a thread on Nuand's forum. I'm following the forum too so by doing so you will get support from both Nuand team on their library and me for C#/SDR# related problems.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

Few remarks:

  1. no need to call ComplexSamplesAvailable as it is the notification callback for SDR#
  2. you don't need to create Complex samples in your case. They need float samples so that's unnecessary work (in other words you don't need ptrIq)
  3. I will repeat it once more but you cannot simply shift the value of the sample. You have to recompute the lookup table named _lutPtr and you have to keep the bitmask to trim the samples to 12 bits.
  4. You have to look into rtlsdr code to see whether the samples are sent to the wire in IQ format or in QI format.
  5. you should use byte[] instead of char[] because char is for printable unicode characters whereas a byte is an 8 bit value.
ghost commented 9 years ago

you talk about 12 bits? but isn't it 8 bits?

i see this code:

static unsafe BladeRFDevice() { _lutPtr = (float)_lutBuffer; const float scale = 1.0f / 2048.0f; for (int i = 0; i < 4096; ++i) { _lutPtr[i] = (((i + 2048) % 4096) - 2048) \ scale; } }

what does it do exactly?

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zondag 28 juni 2015 00:06:59 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

Few remarks:

  1. no need to call ComplexSamplesAvailable as it is the notification callback for SDR#
  2. you don't need to create Complex samples in your case. They need float samples so that's unnecessary work (in other words you don't need ptrIq )
  3. I will repeat it once more but you cannot simply shift the value of the sample. You have to recompute the lookup table named _lutPtr and you have to keep the bitmask to trim the samples to 12 bits.
  4. You have to look into rtlsdr code to see whether the samples are sent to the wire in IQ format or in QI format.
  5. you should use byte[] instead of char[] because char is for printable unicode characters whereas a byte an 8 bit value.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

BladeRF outputs signed 12 bit samples, rtlsdr outputs unsigned 8 bit samples and finally SDR# expects float samples in the range [-1.0,1.0). That's why it needs conversion. Shifting the values would have work if bladeRF was outputting unsigned 12 bit samples.

The function you pasted is the loop that computes the lookup table, in that case the correct mapping between the 4096 possible input values and the corresponding float value, as expected by SDR#. It is done once, during plugin initialization, so that it's more efficient to process the incoming samples (a lookup in a table vs. applying the mathematical formula twice per sample, for I and for Q).

ghost commented 9 years ago

i don't get it.... :(

isn't it only the bits that count. the signed or unsigned is just an interpretion of the bits. if i have 12 bits from the bladerf and the rtl-sdr needs only 8 i have to cut the 4 most LSB's ??

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zondag 28 juni 2015 00:34:13 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

BladeRF outputs signed 12 bit samples, rtlsdr outputs unsigned 8 bit samples and finally SDR# expects float samples in the range [0,1.0). That's why it needs conversion. Shifting the values would have work if bladeRF was outputting unsigned 12 bit samples.

The function you pasted is the loop that computes the lookup table, in that case the correct mapping between the 4096 possible input values and the corresponding float value, as expected by SDR#. It is done once, during plugin initialization, so that it's more efficient to process the incoming samples (a lookup in a table vs. applying the mathematical formula twice per sample, for I and for Q).

— Reply to this email directly or view it on GitHub .

ghost commented 9 years ago

so signed 12 bit is:

is from 0 to 2047 and from -2048 to -1 correct?

these values should been converted into values from 0 to 256 correct?

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zondag 28 juni 2015 00:34:13 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

BladeRF outputs signed 12 bit samples, rtlsdr outputs unsigned 8 bit samples and finally SDR# expects float samples in the range [0,1.0). That's why it needs conversion. Shifting the values would have work if bladeRF was outputting unsigned 12 bit samples.

The function you pasted is the loop that computes the lookup table, in that case the correct mapping between the 4096 possible input values and the corresponding float value, as expected by SDR#. It is done once, during plugin initialization, so that it's more efficient to process the incoming samples (a lookup in a table vs. applying the mathematical formula twice per sample, for I and for Q).

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

Exactly. The conversion has to be considered has 2 linear functions. -2048 (0x800) will be converted into 0, -1 (0xfff) will become 127 (0xff), 0 will become 128 (0x80) and 2047 will become 255 (0xff). You see that simply shifting the bits would give completely wrong values here.

And there's one more trap: negative values cannot be used a an index. That's why in my code you have a bit mask to only keep the interesting 12 bits out of the 16 bits and this will have the side effect of making them seen as unsigned 12 bit numbers.

ghost commented 9 years ago

your code converts the number into foalts between 0 and 1 right?

can't i just use your code and multiply the values with 255 ? so your 0 becomes 0 and 1 becomes 255.

of course i have to take the integer part of the result.

would this be ok?

this is easy to do...

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zondag 28 juni 2015 09:17:12 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

Exactly. The conversion has to be considered has 2 linear functions. -2048 (0x800) will be converted into 0, -1 (0xfff) will become 127 (0xff), 0 will become 128 (0x80) and 2047 will become 255 (0xff). You see that simply shifting the bits would give completely wrong values here.

And there's one more trap: negative values cannot be used a an index. That's why in my code you have a bit mask to only keep the interesting 12 bits out of the 16 bits and this will have the side effect of making them seen as unsigned 12 bit numbers.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

I think that replacing * scale by >> 4 would be enough here. The rest of the formula is here to handle signed/unsigned conversion.

And then you could use the lookup table to convert your incoming samples:

for (int i = 0; i < 2 * cur_len; i++, ptrSample++) {
  tx1[i] = _lutPtr[*ptrSample & 0x0fff];
}
ghost commented 9 years ago

i use this code now:

static unsafe BladeRFDevice() { int i=0; int k = 0; lutPtr = (float)_lutBuffer; try { const float scale = 1.0f / 2048.0f; for (i = 0; i < 4096; ++i) { _lutPtr[i] = (((i + 2048) % 4096) - 2048) * scale; } lutPtr2 = (byte)_lutBuffer2; for (i = 2048; i < 4096; ++i) { _lutPtr2[k] = Convert.ToByte(Math.Truncate(((_lutPtr[i] * 255) + 255)) / 2); k++; } for (i = 0; i < 2048; i++) { _lutPtr2[k] = Convert.ToByte(Math.Truncate(((_lutPtr[i] * 255) / 2) + 127)); k++; } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(i.ToString() + "," + _lutPtr[i].ToString() + "," + ex.ToString()); } }

it works, but the rsult is not as good as expected...

thanks for your help!

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zondag 28 juni 2015 09:17:12 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

Exactly. The conversion has to be considered has 2 linear functions. -2048 (0x800) will be converted into 0, -1 (0xfff) will become 127 (0xff), 0 will become 128 (0x80) and 2047 will become 255 (0xff). You see that simply shifting the bits would give completely wrong values here.

And there's one more trap: negative values cannot be used a an index. That's why in my code you have a bit mask to only keep the interesting 12 bits out of the 16 bits and this will have the side effect of making them seen as unsigned 12 bit numbers.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

All you needed was to change the line:

_lutPtr[i] = (((i + 2048) % 4096) - 2048) * scale;

into

_lutPtr[i] = (((i + 2048) % 4096) - 2048) >> 4;

ghost commented 9 years ago

i'm still using the sdrsharp....   so i can compare the signal in sdr# and websdr.  

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Zondag 28 juni 2015 21:55:17 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

All you needed was to change the line:

_lutPtr[i] = (((i + 2048) % 4096) - 2048) * scale;

into

_lutPtr[i] = (((i + 2048) % 4096) - 2048) >> 4;

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

That still doesn't change the fact that the conversion you did is wrong.

_lutPtr already takes care of the signed/unsigned conversion. By doing it again in your algorithm, you will have wrong values at the end. You can compute both lookup table in one single loop.

ghost commented 9 years ago

i tested my code and the array was filled with values from 0 to 255  

----- Oorspronkelijk bericht -----

Van: "Jean-Michel Picod" notifications@github.com Aan: "jmichelp/sdrsharp-bladerf" sdrsharp-bladerf@noreply.github.com Cc: "on4bhm" G.Roelant@telenet.be Verzonden: Maandag 29 juni 2015 00:22:47 Onderwerp: Re: [sdrsharp-bladerf] NativeMethods.bladerf_open returns -8 (#2)

That still doesn't change the fact that the conversion you did is wrong.

_lutPtr already takes care of the signed/unsigned conversion. By doing it again in your algorithm, you will have wrong values at the end. You can compute both lookup table in one single loop.

— Reply to this email directly or view it on GitHub .

jmichelp commented 9 years ago

Which doesn't mean that the values are correct