From fdab7fa894e936e6bf8c9463b9c981d8a21dae23 Mon Sep 17 00:00:00 2001 From: c vw Date: Wed, 19 May 2021 16:09:48 +0200 Subject: [PATCH] SOAPY: included SDRplay support from John's repo --- discovered.h | 5 ++ discovery.c | 3 +- radio_menu.c | 119 +++++++++++++++++++++++------------------ soapy_discovery.c | 132 ++++++++++++++++++++++++++++++++++------------ soapy_protocol.c | 23 ++++++-- 5 files changed, 195 insertions(+), 87 deletions(-) diff --git a/discovered.h b/discovered.h index dc71bfc..91e7b0b 100644 --- a/discovered.h +++ b/discovered.h @@ -117,6 +117,7 @@ struct _DISCOVERED { char hardware_key[64]; char driver_key[64]; int rtlsdr_count; + int sdrplay_count; int sample_rate; size_t rx_channels; size_t rx_gains; @@ -132,6 +133,10 @@ struct _DISCOVERED { SoapySDRRange *tx_range; size_t tx_antennas; char **tx_antenna; + size_t sensors; + char **sensor; + gboolean has_temp; + char address[64]; } soapy; #endif } info; diff --git a/discovery.c b/discovery.c index 5966027..d6e9ab7 100644 --- a/discovery.c +++ b/discovery.c @@ -335,8 +335,9 @@ fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,d->name); break; #ifdef SOAPYSDR case SOAPYSDR_PROTOCOL: - sprintf(text,"%s (Protocol SOAPY_SDR %s) via Soapy lib",d->name,d->info.soapy.version); + sprintf(text,"%s (Protocol SOAPY_SDR %s) on %s",d->name,d->info.soapy.version,d->info.soapy.address); break; + #endif #ifdef STEMLAB_DISCOVERY case STEMLAB_PROTOCOL: diff --git a/radio_menu.c b/radio_menu.c index 2b92bc8..9463907 100644 --- a/radio_menu.c +++ b/radio_menu.c @@ -546,21 +546,44 @@ void radio_menu(GtkWidget *parent) { #ifdef SOAPYSDR case SOAPYSDR_PROTOCOL: - { - GtkWidget *sample_rate_label=gtk_label_new(NULL); - gtk_label_set_markup(GTK_LABEL(sample_rate_label), "Sample Rate:"); - gtk_grid_attach(GTK_GRID(grid),sample_rate_label,col,row,1,1); - row++; + if(strcmp(radio->name,"sdrplay")==0) { + GtkWidget *sample_rate_combo_box=gtk_combo_box_text_new(); +// gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"96000"); +// gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"192000"); +// gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"384000"); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"768000"); + switch(radio_sample_rate) { + case 96000: + gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),0); + break; + case 192000: + gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),1); + break; + case 384000: + gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),2); + break; + case 768000: + gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),3); + break; + } + g_signal_connect(sample_rate_combo_box,"changed",G_CALLBACK(sample_rate_cb),radio); + gtk_grid_attach(GTK_GRID(grid),sample_rate_combo_box,col,row,1,1); + row++; + } else { + GtkWidget *sample_rate_label=gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(sample_rate_label), "Sample Rate:"); + gtk_grid_attach(GTK_GRID(grid),sample_rate_label,col,row,1,1); + row++; - char rate[16]; - sprintf(rate,"%d",radio->info.soapy.sample_rate); + char rate[16]; + sprintf(rate,"%d",radio->info.soapy.sample_rate); - GtkWidget *sample_rate=gtk_radio_button_new_with_label(NULL,rate); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate), radio->info.soapy.sample_rate); - gtk_grid_attach(GTK_GRID(grid),sample_rate,col,row,1,1); - g_signal_connect(sample_rate,"toggled",G_CALLBACK(sample_rate_cb),GINT_TO_POINTER(radio->info.soapy.sample_rate)); + GtkWidget *sample_rate=gtk_radio_button_new_with_label(NULL,rate); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate), radio->info.soapy.sample_rate); + gtk_grid_attach(GTK_GRID(grid),sample_rate,col,row,1,1); + g_signal_connect(sample_rate,"toggled",G_CALLBACK(sample_rate_cb),GINT_TO_POINTER(radio->info.soapy.sample_rate)); - col++; + col++; } break; #endif @@ -823,7 +846,6 @@ void radio_menu(GtkWidget *parent) { col=0; if(radio->device==SOAPYSDR_USB_DEVICE) { int i; -/* if(radio->info.soapy.rx_gains>0) { GtkWidget *rx_gain=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(rx_gain), "RX Gains:"); @@ -842,50 +864,47 @@ void radio_menu(GtkWidget *parent) { row++; temp_row=row; -*/ col=0; -/* - //rx_gains=g_new(GtkWidget*,radio->info.soapy.rx_gains); - for(i=0;iinfo.soapy.rx_gains;i++) { + if(strcmp(radio->name,"sdrplay")==0 || strcmp(radio->name,"rtlsdr")==0) { + for(i=0;iinfo.soapy.rx_gains;i++) { + col=0; + GtkWidget *rx_gain_label=gtk_label_new(radio->info.soapy.rx_gain[i]); + gtk_grid_attach(GTK_GRID(grid),rx_gain_label,col,row,1,1); + col++; + SoapySDRRange range=radio->info.soapy.rx_range[i]; + if(range.step==0.0) { + range.step=1.0; + } + rx_gains[i]=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step); + gtk_widget_set_name (rx_gains[i], radio->info.soapy.rx_gain[i]); + int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value); + gtk_grid_attach(GTK_GRID(grid),rx_gains[i],col,row,1,1); + g_signal_connect(rx_gains[i],"value_changed",G_CALLBACK(rx_gain_value_changed_cb),&adc[0]); + + row++; + } + } else { + // used single gain control - LimeSDR works out best setting for the 3 rx gains col=0; - GtkWidget *rx_gain_label=gtk_label_new(radio->info.soapy.rx_gain[i]); - gtk_grid_attach(GTK_GRID(grid),rx_gain_label,col,row,1,1); + GtkWidget *rf_gain_label=gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(rf_gain_label), "RF Gain"); + gtk_grid_attach(GTK_GRID(grid),rf_gain_label,col,row,1,1); col++; - SoapySDRRange range=radio->info.soapy.rx_range[i]; - if(range.step==0.0) { - range.step=1.0; + double max=100; + if(strcmp(radio->name,"lime")==0) { + max=60.0; + } else if(strcmp(radio->name,"plutosdr")==0) { + max=73.0; } - rx_gains[i]=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step); - gtk_widget_set_name (rx_gains[i], radio->info.soapy.rx_gain[i]); - int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value); - //gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)adc[0].rx_gain[i]); - gtk_grid_attach(GTK_GRID(grid),rx_gains[i],col,row,1,1); - g_signal_connect(rx_gains[i],"value_changed",G_CALLBACK(rx_gain_value_changed_cb),&adc[0]); - - gtk_widget_set_sensitive(rx_gains[i], FALSE); + GtkWidget *rf_gain_b=gtk_spin_button_new_with_range(0.0,max,1.0); + //gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),active_receiver->rf_gain); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),adc[active_receiver->id].gain); + gtk_grid_attach(GTK_GRID(grid),rf_gain_b,col,row,1,1); + g_signal_connect(rf_gain_b,"value_changed",G_CALLBACK(rf_gain_value_changed_cb),&adc[0]); row++; } -*/ - // used single gain control - LimeSDR works out best setting for the 3 rx gains - col=0; - GtkWidget *rf_gain_label=gtk_label_new(NULL); - gtk_label_set_markup(GTK_LABEL(rf_gain_label), "RF Gain"); - gtk_grid_attach(GTK_GRID(grid),rf_gain_label,col,row,1,1); - col++; - double max=100; - if(strcmp(radio->name,"lime")==0) { - max=60.0; - } else if(strcmp(radio->name,"plutosdr")==0) { - max=73.0; - } - GtkWidget *rf_gain_b=gtk_spin_button_new_with_range(0.0,max,1.0); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),adc[active_receiver->id].gain); - gtk_grid_attach(GTK_GRID(grid),rf_gain_b,col,row,1,1); - g_signal_connect(rf_gain_b,"value_changed",G_CALLBACK(rf_gain_value_changed_cb),&adc[0]); - - row++; if(radio->info.soapy.rx_has_automatic_gain) { GtkWidget *agc=gtk_check_button_new_with_label("Hardware AGC: "); diff --git a/soapy_discovery.c b/soapy_discovery.c index f5b9447..4d0918c 100644 --- a/soapy_discovery.c +++ b/soapy_discovery.c @@ -27,17 +27,23 @@ #include "soapy_discovery.h" static int rtlsdr_count=0; +static int sdrplay_count=0; static void get_info(char *driver) { size_t rx_rates_length, tx_rates_length, rx_gains_length, tx_gains_length, ranges_length, rx_antennas_length, tx_antennas_length, rx_bandwidth_length, tx_bandwidth_length; int i; SoapySDRKwargs args={}; int software_version=0; + char *version; + char *address=NULL; int rtlsdr_val=0; + int sdrplay_val=0; char fw_version[16]; char gw_version[16]; char hw_version[16]; char p_version[16]; + char** tx_antennas; + char** tx_gains; fprintf(stderr,"soapy_discovery: get_info: %s\n", driver); @@ -53,6 +59,12 @@ static void get_info(char *driver) { SoapySDRKwargs_set(&args, "rtl", count); rtlsdr_val=rtlsdr_count; rtlsdr_count++; + } else if(strcmp(driver,"sdrplay")==0) { + char label[16]; + sprintf(label,"SDRplay Dev%d",sdrplay_count); + SoapySDRKwargs_set(&args, "label", label); + sdrplay_val=sdrplay_count; + sdrplay_count++; } SoapySDRDevice *sdr = SoapySDRDevice_make(&args); SoapySDRKwargs_clear(&args); @@ -63,6 +75,9 @@ static void get_info(char *driver) { char *hardwarekey=SoapySDRDevice_getHardwareKey(sdr); fprintf(stderr,"HardwareKey=%s\n",hardwarekey); + if(strcmp(driver,"sdrplay")==0) { + address=hardwarekey; + } SoapySDRKwargs info=SoapySDRDevice_getHardwareInfo(sdr); for(i=0;i %f (%f),", tx_rates[i].minimum, tx_rates[i].maximum, tx_rates[i].minimum/48000.0); + if(tx_channels>0) { + SoapySDRRange *tx_rates=SoapySDRDevice_getSampleRateRange(sdr, SOAPY_SDR_TX, 1, &tx_rates_length); + fprintf(stderr,"Tx sample rates: "); + for (size_t i = 0; i < tx_rates_length; i++) { + fprintf(stderr,"%f -> %f (%f),", tx_rates[i].minimum, tx_rates[i].maximum, tx_rates[i].minimum/48000.0); + } + fprintf(stderr,"\n"); + free(tx_rates); } - fprintf(stderr,"\n"); - free(tx_rates); double *bandwidths=SoapySDRDevice_listBandwidths(sdr, SOAPY_SDR_RX, 0, &rx_bandwidth_length); fprintf(stderr,"Rx bandwidths: "); @@ -148,19 +176,23 @@ static void get_info(char *driver) { fprintf(stderr,"\n"); free(bandwidths); - bandwidths=SoapySDRDevice_listBandwidths(sdr, SOAPY_SDR_TX, 0, &tx_bandwidth_length); - fprintf(stderr,"Tx bandwidths: "); - for (size_t i = 0; i < tx_bandwidth_length; i++) { - fprintf(stderr,"%f, ", bandwidths[i]); + if(tx_channels>0) { + bandwidths=SoapySDRDevice_listBandwidths(sdr, SOAPY_SDR_TX, 0, &tx_bandwidth_length); + fprintf(stderr,"Tx bandwidths: "); + for (size_t i = 0; i < tx_bandwidth_length; i++) { + fprintf(stderr,"%f, ", bandwidths[i]); + } + fprintf(stderr,"\n"); + free(bandwidths); } - fprintf(stderr,"\n"); - free(bandwidths); double bandwidth=SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_RX, 0); fprintf(stderr,"RX0: bandwidth=%f\n",bandwidth); - bandwidth=SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_TX, 0); - fprintf(stderr,"TX0: bandwidth=%f\n",bandwidth); + if(tx_channels>0) { + bandwidth=SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_TX, 0); + fprintf(stderr,"TX0: bandwidth=%f\n",bandwidth); + } SoapySDRRange *ranges = SoapySDRDevice_getFrequencyRange(sdr, SOAPY_SDR_RX, 0, &ranges_length); fprintf(stderr,"Rx freq ranges: "); @@ -172,10 +204,13 @@ static void get_info(char *driver) { for (size_t i = 0; i < rx_antennas_length; i++) fprintf(stderr, "%s, ", rx_antennas[i]); fprintf(stderr,"\n"); - char** tx_antennas = SoapySDRDevice_listAntennas(sdr, SOAPY_SDR_TX, 0, &tx_antennas_length); - fprintf(stderr, "Tx antennas: "); - for (size_t i = 0; i < tx_antennas_length; i++) fprintf(stderr, "%s, ", tx_antennas[i]); - fprintf(stderr,"\n"); + + if(tx_channels>0) { + tx_antennas = SoapySDRDevice_listAntennas(sdr, SOAPY_SDR_TX, 0, &tx_antennas_length); + fprintf(stderr, "Tx antennas: "); + for (size_t i = 0; i < tx_antennas_length; i++) fprintf(stderr, "%s, ", tx_antennas[i]); + fprintf(stderr,"\n"); + } char **rx_gains = SoapySDRDevice_listGains(sdr, SOAPY_SDR_RX, 0, &rx_gains_length); @@ -185,7 +220,9 @@ static void get_info(char *driver) { gboolean has_automatic_dc_offset_correction=SoapySDRDevice_hasDCOffsetMode(sdr, SOAPY_SDR_RX, 0); fprintf(stderr,"has_automaic_dc_offset_correction=%d\n",has_automatic_dc_offset_correction); - char **tx_gains = SoapySDRDevice_listGains(sdr, SOAPY_SDR_TX, 1, &tx_gains_length); + if(tx_channels>0) { + tx_gains = SoapySDRDevice_listGains(sdr, SOAPY_SDR_TX, 1, &tx_gains_length); + } size_t formats_length; char **formats = SoapySDRDevice_getStreamFormats(sdr,SOAPY_SDR_RX,0,&formats_length); @@ -193,7 +230,18 @@ static void get_info(char *driver) { for (size_t i = 0; i < formats_length; i++) fprintf(stderr, "%s, ", formats[i]); fprintf(stderr,"\n"); - fprintf(stderr,"float=%lu double=%lu\n",sizeof(float),sizeof(double)); + size_t sensors; + char **sensor = SoapySDRDevice_listSensors(sdr, &sensors); + gboolean has_temp=FALSE; + char *ptr; + fprintf(stderr, "Sensors:\n"); + for (size_t i = 0; i < sensors; i++) { + char *value=SoapySDRDevice_readSensor(sdr, sensor[i]); + fprintf(stderr, " %s=%s\n", sensor[i],value); + if((ptr=strstr(sensor[i],"temp"))!=NULL) { + has_temp=TRUE; + } + } if(devices %f step=%f\n",tx_range.minimum,tx_range.maximum,tx_range.step); - discovered[devices].info.soapy.tx_range[i]=tx_range; + if(tx_channels>0) { + discovered[devices].info.soapy.tx_gains=tx_gains_length; + discovered[devices].info.soapy.tx_gain=tx_gains; + discovered[devices].info.soapy.tx_range=malloc(tx_gains_length*sizeof(SoapySDRRange)); + fprintf(stderr,"Tx gains: \n"); + for (size_t i = 0; i < tx_gains_length; i++) { + fprintf(stderr,"%s ", tx_gains[i]); + SoapySDRRange tx_range=SoapySDRDevice_getGainElementRange(sdr, SOAPY_SDR_TX, 1, tx_gains[i]); + fprintf(stderr,"%f -> %f step=%f\n",tx_range.minimum,tx_range.maximum,tx_range.step); + discovered[devices].info.soapy.tx_range[i]=tx_range; + } + discovered[devices].info.soapy.tx_antennas=tx_antennas_length; + discovered[devices].info.soapy.tx_antenna=tx_antennas; } - discovered[devices].info.soapy.tx_antennas=tx_antennas_length; - discovered[devices].info.soapy.tx_antenna=tx_antennas; + discovered[devices].info.soapy.sensors=sensors; + discovered[devices].info.soapy.sensor=sensor; + discovered[devices].info.soapy.has_temp=has_temp; + + + if(address!=NULL) { + strcpy(discovered[devices].info.soapy.address,address); + } else { + strcpy(discovered[devices].info.soapy.address,"USB"); + } + devices++; } + SoapySDRDevice_unmake(sdr); free(ranges); - } void soapy_discovery() { diff --git a/soapy_protocol.c b/soapy_protocol.c index 18d6684..23242fb 100644 --- a/soapy_protocol.c +++ b/soapy_protocol.c @@ -89,7 +89,13 @@ void soapy_protocol_set_mic_sample_rate(int rate) { void soapy_protocol_change_sample_rate(RECEIVER *rx) { // rx->mutex already locked - if(rx->sample_rate==radio_sample_rate) { + if(strcmp(radio->name,"sdrplay")==0) { + g_print("%s: setting samplerate=%f\n",__FUNCTION__,(double)rx->sample_rate); + rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_RX,rx->adc,(double)rx->sample_rate); + if(rc!=0) { + g_print("%s: SoapySDRDevice_setSampleRate(%f) failed: %s\n",__FUNCTION__,(double)rx->sample_rate,SoapySDR_errToStr(rc)); + } + } else if(rx->sample_rate==radio_sample_rate) { if(rx->resample_buffer!=NULL) { g_free(rx->resample_buffer); rx->resample_buffer=NULL; @@ -258,10 +264,11 @@ void soapy_protocol_init(int rx,gboolean hf) { int rc; int i; -fprintf(stderr,"soapy_protocol_init: rx=%d hf=%d\n",rx,hf); + SoapySDR_setLogLevel(SOAPY_SDR_TRACE); + +g_print("%s: hf=%d driver=%s\n",__FUNCTION__,hf,radio->name); // initialize the radio -fprintf(stderr,"soapy_protocol_init: SoapySDRDevice_make\n"); SoapySDRKwargs_set(&args, "driver", radio->name); if(strcmp(radio->name,"rtlsdr")==0) { char id[16]; @@ -273,7 +280,17 @@ fprintf(stderr,"soapy_protocol_init: SoapySDRDevice_make\n"); } else { SoapySDRKwargs_set(&args, "direct_samp", "0"); } + } else if(strcmp(radio->name,"sdrplay")==0) { + sprintf(temp,"SDRplay Dev%d",radio->info.soapy.sdrplay_count); + g_print("%s: label=%s\n",__FUNCTION__,temp); + SoapySDRKwargs_set(&args, "label", temp); } + soapy_device=SoapySDRDevice_make(&args); + if(soapy_device==NULL) { + g_print("%s: SoapySDRDevice_make failed: %s\n",__FUNCTION__,SoapySDRDevice_lastError()); + _exit(-1); + } + soapy_device=SoapySDRDevice_make(&args); if(soapy_device==NULL) { fprintf(stderr,"soapy_protocol: SoapySDRDevice_make failed: %s\n",SoapySDRDevice_lastError()); -- 2.45.2