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

Make it work under linux with gqrx/gr-osmosdr #223

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions Core/RadioHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ unsigned long Failures = 0;

void RadioHandlerClass::OnDataPacket()
{
auto len = outputbuffer.getBlockSize() / 2 / sizeof(float);
auto len = outputbuffer.getBlockSize();

while(run)
{
Expand All @@ -30,12 +30,6 @@ void RadioHandlerClass::OnDataPacket()
if (!run)
break;

if (fc != 0.0f)
{
std::unique_lock<std::mutex> lk(fc_mutex);
shift_limited_unroll_C_sse_inp_c((complexf*)buf, len, stateFineTune);
Copy link
Collaborator

Choose a reason for hiding this comment

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

why this get removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was unable to make decimator work as expected, so I partially removed it. Offset tuning was removed as well.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oscar may help and he is expert on that DSP code.

}

#ifdef _DEBUG //PScope buffer screenshot
if (saveADCsamplesflag == true)
{
Expand Down Expand Up @@ -74,27 +68,40 @@ RadioHandlerClass::RadioHandlerClass() :
inputbuffer.setBlockSize(transferSamples);

stateFineTune = new shift_limited_unroll_C_sse_data_t();
adcrate = adcnominalfreq;
DbgPrintf("RadioHandlerClass::RadioHandlerClass\n");
}

RadioHandlerClass::~RadioHandlerClass()
{
delete stateFineTune;
delete r2iqCntrl;
delete hardware;
delete fx3;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this class owes the fx3 instance. it is allocated by someone else. better deallocate by the owner.

Copy link
Contributor Author

@vladisslav2011 vladisslav2011 May 9, 2022

Choose a reason for hiding this comment

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

That was freed by the owner while threads were still running, resulting in random crashes/freezes. That's why I did this change. I don't think, that it is better to deallocate by the owner. I think that it is better to use std::shared_ptr. Switching to std::shared_ptr may be the next thing to do. But incorrectly using smart pointers may introduce crazy bugs too...

Copy link
Collaborator

Choose a reason for hiding this comment

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

it should not happen at least for Windows. Can you point me the crash stacks of two threads? I can help debug.

}

const char *RadioHandlerClass::getName()
{
return hardware->getName();
}

bool RadioHandlerClass::Init(fx3class* Fx3, void (*callback)(void*context, const float*, uint32_t), r2iqControlClass *r2iqCntrl, void *context)
bool RadioHandlerClass::Init(fx3class* Fx3, void (*callback)(void*context, const float*, uint32_t), r2iqControlClass *r2iqCntrlIn, void *context)
{
uint8_t rdata[4];
this->fx3 = Fx3;
this->Callback = callback;
this->callbackContext = context;

if (r2iqCntrl == nullptr)
if (r2iqCntrlIn == nullptr)
{
r2iqCntrl = new fft_mt_r2iq();
DbgPrintf("RadioHandlerClass::Init r2iqCntrl created\n");
}
else
{
r2iqCntrl = r2iqCntrlIn;
DbgPrintf("RadioHandlerClass::Init r2iqCntrl assigned\n");
}

Fx3->GetHardwareInfo((uint32_t*)rdata);

Expand Down Expand Up @@ -137,15 +144,30 @@ bool RadioHandlerClass::Init(fx3class* Fx3, void (*callback)(void*context, const
DbgPrintf("WARNING no SDR connected\n");
break;
}
adcrate = adcnominalfreq;
hardware->Initialize(adcnominalfreq);
vladisslav2011 marked this conversation as resolved.
Show resolved Hide resolved
DbgPrintf("%s | firmware %x\n", hardware->getName(), firmware);
this->r2iqCntrl = r2iqCntrl;
DbgPrintf("%s | firmware %x adcrate %u\n", hardware->getName(), firmware, adcrate);
r2iqCntrl->Init(hardware->getGain(), &inputbuffer, &outputbuffer);

return true;
}

int RadioHandlerClass::SetSampleRate(int sr)
{
adcrate = sr;
if(adcrate < 8000000)
adcrate = 8000000;
if(adcrate > 128000000)
adcrate = 128000000;

hardware->Initialize(adcrate);
return adcrate;
}

int RadioHandlerClass::GetSampleRate()
{
return adcrate;
}

bool RadioHandlerClass::Start(int srate_idx)
{
Stop();
Expand All @@ -169,6 +191,7 @@ bool RadioHandlerClass::Start(int srate_idx)
// 0,1,2,3,4 => 32,16,8,4,2 MHz
r2iqCntrl->setDecimate(decimate);
r2iqCntrl->TurnOn();

fx3->StartStream(inputbuffer, QUEUE_SIZE);

submit_thread = std::thread(
Expand Down Expand Up @@ -203,8 +226,8 @@ bool RadioHandlerClass::Stop()
submit_thread.join();
DbgPrintf("submit_thread join1\n");

hardware->FX3producerOff(); //FX3 stop the producer
}
hardware->FX3producerOff(); //FX3 stop the producer
Copy link
Collaborator

Choose a reason for hiding this comment

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

it will get called in Stop. We should either remove the other place to call this or delete this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Where is the other place?

return true;
}

Expand Down Expand Up @@ -247,6 +270,11 @@ int RadioHandlerClass::UpdateIFGain(int idx)
return 0;
}

int RadioHandlerClass::UpdateTunerBW(int bwHz)
{
return hardware->UpdateTunerBW(bwHz);
}

int RadioHandlerClass::GetRFAttSteps(const float **steps)
{
return hardware->getRFSteps(steps);
Expand Down
8 changes: 7 additions & 1 deletion Core/RadioHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class RadioHandlerClass {
public:
RadioHandlerClass();
virtual ~RadioHandlerClass();
bool Init(fx3class* Fx3, void (*callback)(void* context, const float*, uint32_t), r2iqControlClass *r2iqCntrl = nullptr, void* context = nullptr);
bool Init(fx3class* Fx3, void (*callback)(void* context, const float*, uint32_t), r2iqControlClass *r2iqCntrlIn = nullptr, void* context = nullptr);
bool Start(int srate_idx);
bool Stop();
bool Close();
Expand All @@ -41,6 +41,7 @@ class RadioHandlerClass {

int GetIFGainSteps(const float **steps);
int UpdateIFGain(int attIdx);
int UpdateTunerBW(int bwHz);

bool UpdatemodeRF(rf_mode mode);
rf_mode GetmodeRF(){return (rf_mode)modeRF;}
Expand All @@ -52,6 +53,8 @@ class RadioHandlerClass {
bool GetRand () {return randout;}
uint16_t GetFirmware() { return firmware; }

int SetSampleRate(int sr);
int GetSampleRate();
uint32_t getSampleRate() { return adcrate; }
bool UpdateSampleRate(uint32_t samplerate);

Expand Down Expand Up @@ -145,6 +148,7 @@ class RadioHardware {
virtual int getRFSteps(const float** steps ) { return 0; }
virtual int getIFSteps(const float** steps ) { return 0; }
virtual bool UpdateGainIF(int attIndex) { return false; }
virtual bool UpdateTunerBW(int bwHz) { return false; }

bool FX3producerOn() { return Fx3->Control(STARTFX3); }
bool FX3producerOff() { return Fx3->Control(STOPFX3); }
Expand All @@ -170,6 +174,7 @@ class BBRF103Radio : public RadioHardware {
uint64_t TuneLo(uint64_t freq) override;
bool UpdateattRF(int attIndex) override;
bool UpdateGainIF(int attIndex) override;
bool UpdateTunerBW(int bwHz) override;

int getRFSteps(const float** steps ) override;
int getIFSteps(const float** steps ) override;
Expand Down Expand Up @@ -203,6 +208,7 @@ class RX888R2Radio : public RadioHardware {
uint64_t TuneLo(uint64_t freq) override;
bool UpdateattRF(int attIndex) override;
bool UpdateGainIF(int attIndex) override;
bool UpdateTunerBW(int bwHz) override;

int getRFSteps(const float** steps ) override;
int getIFSteps(const float** steps ) override;
Expand Down
44 changes: 36 additions & 8 deletions Core/arch/linux/FX3handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "FX3handler.h"
#include "usb_device.h"
#include <stdlib.h>
#include <stdio.h>

fx3class* CreateUsbHandler()
{
Expand All @@ -10,16 +12,20 @@ fx3class* CreateUsbHandler()

fx3handler::fx3handler()
{
readsize = 0;
fill = 0;
}

fx3handler::~fx3handler()
{
StopStream();
if(dev)
usb_device_close(dev);
}

bool fx3handler::Open(uint8_t* fw_data, uint32_t fw_size)
{
dev = usb_device_open(0, (const char*)fw_data, fw_size);

return dev != nullptr;
}

Expand Down Expand Up @@ -51,8 +57,10 @@ bool fx3handler::GetHardwareInfo(uint32_t* data)

void fx3handler::StartStream(ringbuffer<int16_t>& input, int numofblock)
{
fprintf(stderr,"fx3handler::StartStream()\n");
inputbuffer = &input;
auto readsize = input.getWriteCount() * sizeof(uint16_t);
readsize = input.getBlockSize() * sizeof(uint16_t);
fill = 0;
stream = streaming_open_async(this->dev, readsize, numofblock, PacketRead, this);

// Start background thread to poll the events
Expand All @@ -73,20 +81,40 @@ void fx3handler::StartStream(ringbuffer<int16_t>& input, int numofblock)

void fx3handler::StopStream()
{
fprintf(stderr,"fx3handler::StopStream()\n");
if(!run)
return;
run = false;
poll_thread.join();

streaming_stop(stream);
streaming_close(stream);
fprintf(stderr,"fx3handler::StopStream() thread joined\n");
if(stream)
{
streaming_stop(stream);
fprintf(stderr,"fx3handler::StopStream() streaming_stop\n");
streaming_close(stream);
fprintf(stderr,"fx3handler::StopStream() streaming_close\n");
stream = nullptr;
}
}

void fx3handler::PacketRead(uint32_t data_size, uint8_t *data, void *context)
{
fx3handler *handler = (fx3handler*)context;

auto *ptr = handler->inputbuffer->getWritePtr();
memcpy(ptr, data, data_size);
handler->inputbuffer->WriteDone();
uint32_t written = 0;
while(written < data_size)
{
uint8_t *ptr = (uint8_t *)handler->inputbuffer->getWritePtr();
int to_copy = std::min(int(data_size - written), handler->readsize - handler->fill);
memcpy(&ptr[handler->fill], &data[written], to_copy);
handler->fill += to_copy;
written += to_copy;
if(handler->fill >= handler->readsize)
{
handler->inputbuffer->WriteDone();
handler->fill = 0;
}
}
}

bool fx3handler::ReadDebugTrace(uint8_t* pdata, uint8_t len)
Expand Down
2 changes: 2 additions & 0 deletions Core/arch/linux/FX3handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class fx3handler : public fx3class
streaming_t *stream;
ringbuffer<int16_t> *inputbuffer;
bool run;
int readsize;
int fill;
std::thread poll_thread;
};

Expand Down
10 changes: 6 additions & 4 deletions Core/arch/linux/streaming.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ typedef struct streaming {
static const uint32_t DEFAULT_SAMPLE_RATE = 64000000; /* 64Msps */
static const uint32_t DEFAULT_FRAME_SIZE = (2 * 64000000 / 1000); /* ~ 1 ms */
static const uint32_t DEFAULT_NUM_FRAMES = 96; /* we should not exceed 120 ms in total! */
const unsigned int BULK_XFER_TIMEOUT = 5000; // timeout (in ms) for each bulk transfer
const unsigned int BULK_XFER_TIMEOUT = 500; // timeout (in ms) for each bulk transfer


streaming_t *streaming_open_sync(usb_device_t *usb_device)
Expand Down Expand Up @@ -118,8 +118,9 @@ streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size,
}

/* frame size must be a multiple of max_packet_size * max_burst */
uint32_t max_xfer_size = usb_device->bulk_in_max_packet_size *
usb_device->bulk_in_max_burst;
uint32_t max_xfer_size = usb_device->bulk_in_max_packet_size;
if(usb_device->bulk_in_max_burst)
max_xfer_size *= usb_device->bulk_in_max_burst;
if ( !max_xfer_size ) {
fprintf(stderr, "ERROR: maximum transfer size is 0. probably not connected at USB 3 port?!\n");
return ret_val;
Expand Down Expand Up @@ -253,7 +254,8 @@ int streaming_stop(streaming_t *this)
}
return 0;
}

if (this->status == STREAMING_STATUS_FAILED)
return 0;
this->status = STREAMING_STATUS_CANCELLED;
/* cancel all the active transfers */
for (uint32_t i = 0; i < this->num_frames; ++i) {
Expand Down
Loading