Skip to content

Commit

Permalink
Make it work under linux with gqrx/gr-osmosdr
Browse files Browse the repository at this point in the history
Requires patched gr-osmosdr (gr3.7 only so far)
https://github.com/vladisslav2011/gr-osmosdr/tree/ngrx
No correct device listing and sample rates list.
Gain selection is still a bit buggy.

Fix test segfault.
Do not delete fx3Handler as RadioHandlerClass::~RadioHandlerClass()
have already taken care of it.
Retry opening the USB device after download for 5 times
As it may be slow to reenumerate on some platforms.
Include the firmware into libsddc binary as a BLOB
Make USB HS work at lower sampling rates/tuner at <7MHz BW
Implement r82xx bandwidth selection
Prevent freeze on close after live device disconnection
Allow low sample rates
Improve compatibility with intel hubs
Restore attenuations after band switch
  • Loading branch information
vladisslav2011 committed May 10, 2022
1 parent 3300dd6 commit cad6177
Show file tree
Hide file tree
Showing 31 changed files with 749 additions and 195 deletions.
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);
}

#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;
}

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);
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
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(const 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

0 comments on commit cad6177

Please sign in to comment.