From 4afaa77e0dbe8889c5054bd3f4809a513a4c05ae Mon Sep 17 00:00:00 2001 From: John Melton G0ORX Date: Tue, 24 Mar 2020 10:42:55 +0000 Subject: [PATCH] Improvements for SoapySDR devices. Changed code to display Rx Panadapter frequency markers. --- ext.c | 23 +++++++++----- gpio.c | 4 +-- new_menu.c | 6 ++-- new_menu.h | 2 +- radio.c | 26 ++++++++------- radio.h | 2 ++ radio_menu.c | 16 ++++++++-- rx_panadapter.c | 82 +++++++++++++++++++++++------------------------- sliders.c | 15 ++------- soapy_protocol.c | 2 ++ toolbar.c | 2 +- vfo.c | 2 +- vfo.h | 5 +++ vfo_menu.c | 22 +++++++------ vfo_menu.h | 2 +- 15 files changed, 116 insertions(+), 95 deletions(-) diff --git a/ext.c b/ext.c index d4f677c..29a0c77 100644 --- a/ext.c +++ b/ext.c @@ -65,13 +65,22 @@ int ext_set_frequency(void *data) { // behave as if the user had chosen the new band // via the menu prior to changing the frequency // - long long freq = *(long long *)data; - int id=active_receiver->id; - int b = get_band_from_frequency(freq); - if (b != vfo[id].band) { - vfo_band_changed(b); + SET_FREQUENCY *set_frequency=(SET_FREQUENCY *)data; +g_print("ext_set_frequency: vfo=%d freq=%lld\n",set_frequency->vfo,set_frequency->frequency); + int b=get_band_from_frequency(set_frequency->frequency); + if(active_receiver->id==set_frequency->vfo) { + if (b != vfo[set_frequency->vfo].band) { + vfo_band_changed(b); + } + setFrequency(set_frequency->frequency); + } else if(set_frequency->vfo==VFO_B) { + // just changing VFO-B frequency + vfo[set_frequency->vfo].frequency=set_frequency->frequency; + vfo[set_frequency->vfo].band=b; + if(receivers==2) { + // need to change the receiver frequency + } } - setFrequency(freq); free(data); return 0; } @@ -125,7 +134,7 @@ int ext_filter_update(void *data) { } int ext_frequency_update(void *data) { - start_vfo(); + start_vfo(active_receiver->id); return 0; } diff --git a/gpio.c b/gpio.c index 9d24dcb..4e277e9 100644 --- a/gpio.c +++ b/gpio.c @@ -2058,8 +2058,8 @@ static void encoder_changed(int action,int pos) { value+=(double)pos; if(value<0.0) { value=0.0; - } else if(value>100.0) { - value=100.0; + } else if(value>drive_max) { + value=drive_max; } set_drive(value); break; diff --git a/new_menu.c b/new_menu.c index f520c8d..2cf9f84 100644 --- a/new_menu.c +++ b/new_menu.c @@ -360,17 +360,17 @@ static gboolean diversity_cb (GtkWidget *widget, GdkEventButton *event, gpointer return TRUE; } -void start_vfo() { +void start_vfo(int vfo) { int old_menu=active_menu; cleanup(); if(old_menu!=VFO_MENU) { - vfo_menu(top_window); + vfo_menu(top_window,vfo); active_menu=VFO_MENU; } } static gboolean vfo_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - start_vfo(); + start_vfo(active_receiver->id); return TRUE; } diff --git a/new_menu.h b/new_menu.h index d087f92..3fbf617 100644 --- a/new_menu.h +++ b/new_menu.h @@ -13,7 +13,7 @@ extern void start_mode(); extern void start_filter(); extern void start_noise(); extern void start_encoder(); -extern void start_vfo(); +extern void start_vfo(int vfo); extern void start_agc(); extern void start_store(); extern void start_rx(); diff --git a/radio.c b/radio.c index d498650..19f6698 100644 --- a/radio.c +++ b/radio.c @@ -321,6 +321,8 @@ int can_transmit=0; gboolean duplex=FALSE; gboolean mute_rx_while_transmitting=FALSE; +double drive_max=100; + gboolean display_sequence_errors=TRUE; gint sequence_errors=0; @@ -444,7 +446,8 @@ void start_radio() { protocol=radio->protocol; device=radio->device; - // set the default power output + // set the default power output and max drive value + drive_max=100.0; switch(protocol) { case ORIGINAL_PROTOCOL: switch(device) { @@ -508,6 +511,11 @@ void start_radio() { break; #ifdef SOAPYSDR case SOAPYSDR_PROTOCOL: + if(strcmp(radio->name,"lime")==0) { + drive_max=64.0; + } else if(strcmp(radio->name,"plutosdr")==0) { + drive_max=89.0; + } pa_power=PA_1W; break; #endif @@ -872,7 +880,7 @@ void start_radio() { adc[0].preamp=FALSE; adc[0].attenuation=0; #ifdef SOAPYSDR - adc[0].antenna=2; // LNAL + adc[0].antenna=0; if(device==SOAPYSDR_USB_DEVICE) { adc[0].rx_gain=malloc(radio->info.soapy.rx_gains*sizeof(gint)); for (size_t i = 0; i < radio->info.soapy.rx_gains; i++) { @@ -896,7 +904,7 @@ void start_radio() { adc[1].preamp=FALSE; adc[1].attenuation=0; #ifdef SOAPYSDR - adc[1].antenna=3; // LNAW + adc[1].antenna=0; if(device==SOAPYSDR_USB_DEVICE) { adc[1].rx_gain=malloc(radio->info.soapy.rx_gains*sizeof(gint)); for (size_t i = 0; i < radio->info.soapy.rx_gains; i++) { @@ -1476,9 +1484,6 @@ void setTune(int state) { int i; if(!can_transmit) return; -#ifdef SOAPYSDR - if(protocol==SOAPYSDR_PROTOCOL && !transmitter->local_microphone) return; -#endif // if state==tune, this function is a no-op @@ -1692,10 +1697,10 @@ static int calcLevel(double d) { } void calcDriveLevel() { - transmitter->drive_level=calcLevel(transmitter->drive); - if(isTransmitting() && protocol==NEW_PROTOCOL) { - schedule_high_priority(); - } + transmitter->drive_level=calcLevel(transmitter->drive); + if(isTransmitting() && protocol==NEW_PROTOCOL) { + schedule_high_priority(); + } //g_print("calcDriveLevel: drive=%d drive_level=%d\n",transmitter->drive,transmitter->drive_level); } @@ -1709,7 +1714,6 @@ void setDrive(double value) { #ifdef SOAPYSDR case SOAPYSDR_PROTOCOL: soapy_protocol_set_tx_gain(transmitter,transmitter->drive); - break; #endif } diff --git a/radio.h b/radio.h index ef826a6..12c00b9 100644 --- a/radio.h +++ b/radio.h @@ -299,6 +299,8 @@ extern int have_rx_gain; // TRUE on HermesLite/RadioBerry extern int rx_gain_calibration; // position of the RX gain slider that // corresponds to zero amplification/attenuation +extern double drive_max; + extern gboolean display_sequence_errors; extern gint sequence_errors; diff --git a/radio_menu.c b/radio_menu.c index 765ef01..821ab5e 100644 --- a/radio_menu.c +++ b/radio_menu.c @@ -827,7 +827,13 @@ void radio_menu(GtkWidget *parent) { GtkWidget *rf_gain_label=gtk_label_new("RF Gain"); gtk_grid_attach(GTK_GRID(grid),rf_gain_label,col,row,1,1); col++; - GtkWidget *rf_gain_b=gtk_spin_button_new_with_range(0.0,60.0,1.0); + 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),active_receiver->rf_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]); @@ -865,7 +871,13 @@ void radio_menu(GtkWidget *parent) { GtkWidget *tx_gain_label=gtk_label_new("TX Gain"); gtk_grid_attach(GTK_GRID(grid),tx_gain_label,col,row,1,1); col++; - tx_gain=gtk_spin_button_new_with_range(0.0,64.0,1.0); + double max=100; + if(strcmp(radio->name,"lime")==0) { + max=64.0; + } else if(strcmp(radio->name,"plutosdr")==0) { + max=89.0; + } + tx_gain=gtk_spin_button_new_with_range(0.0,max,1.0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gain),transmitter->drive); gtk_grid_attach(GTK_GRID(grid),tx_gain,col,row,1,1); g_signal_connect(tx_gain,"value_changed",G_CALLBACK(drive_gain_value_changed_cb),&adc[0]); diff --git a/rx_panadapter.c b/rx_panadapter.c index 7771b4c..a05a45c 100644 --- a/rx_panadapter.c +++ b/rx_panadapter.c @@ -118,6 +118,9 @@ void rx_panadapter_update(RECEIVER *rx) { float *samples; char text[64]; cairo_text_extents_t extents; + long long f; + long long divisor=20000; + double x=0.0; gboolean active=active_receiver==rx; @@ -243,140 +246,133 @@ void rx_panadapter_update(RECEIVER *rx) { cairo_stroke(cr); // plot frequency markers - long long f; - long divisor=20000; switch(rx->sample_rate) { case 48000: - divisor=5000L; + divisor=5000LL; switch(rx->zoom) { case 2: case 3: case 4: - divisor=2000L; + divisor=2000LL; break; case 5: case 6: case 7: case 8: - divisor=1000L; + divisor=1000LL; break; } break; case 96000: case 100000: - divisor=10000L; + divisor=10000LL; switch(rx->zoom) { case 2: case 3: case 4: - divisor=5000L; + divisor=5000LL; break; case 5: case 6: - divisor=2000L; + divisor=2000LL; break; case 7: case 8: - divisor=1000L; + divisor=1000LL; break; } break; case 192000: - divisor=20000L; + divisor=20000LL; switch(rx->zoom) { case 2: case 3: - divisor=10000L; + divisor=10000LL; break; case 4: case 5: case 6: - divisor=5000L; + divisor=5000LL; break; case 7: case 8: - divisor=2000L; + divisor=2000LL; break; } break; case 384000: - divisor=50000L; + divisor=50000LL; switch(rx->zoom) { case 2: case 3: - divisor=25000L; + divisor=25000LL; break; case 4: case 5: case 6: - divisor=10000L; + divisor=10000LL; break; case 7: case 8: - divisor=5000L; + divisor=5000LL; break; } break; case 768000: - divisor=100000L; + divisor=100000LL; switch(rx->zoom) { case 2: case 3: - divisor=50000L; + divisor=50000LL; break; case 4: case 5: case 6: - divisor=25000L; + divisor=25000LL; break; case 7: case 8: - divisor=20000L; + divisor=20000LL; break; } break; case 1024000: case 1536000: case 2097152: - divisor=200000L; + divisor=200000LL; switch(rx->zoom) { case 2: case 3: - divisor=100000L; + divisor=100000LL; break; case 4: case 5: case 6: - divisor=50000L; + divisor=50000LL; break; case 7: case 8: - divisor=20000L; + divisor=20000LL; break; } break; } - for(i=0;ipan)); - if (f > 0) { - if ((f % divisor) < (long) HzPerPixel) { - cairo_set_line_width(cr, 1.0); - //cairo_move_to(cr,(double)x,0.0); - cairo_move_to(cr,(double)i,10.0); - cairo_line_to(cr,(double)i,(double)display_height); - cairo_select_font_face(cr, "FreeMono", + f = ((min_display/divisor)*divisor)+divisor; + cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(cr, 12); - char v[32]; - sprintf(v,"%0lld.%03lld",f/1000000,(f%1000000)/1000); - //cairo_move_to(cr, (double)i, (double)(display_height-10)); - cairo_text_extents(cr, v, &extents); - cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0); - cairo_show_text(cr, v); - } - } + cairo_set_font_size(cr, 12); + while(f= radio->info.soapy.rx_antennas) ant=radio->info.soapy.rx_antennas -1; g_print("soapy_protocol: set_rx_antenna: %s\n",radio->info.soapy.rx_antenna[ant]); rc=SoapySDRDevice_setAntenna(soapy_device,SOAPY_SDR_RX,rx->adc,radio->info.soapy.rx_antenna[ant]); if(rc!=0) { @@ -460,6 +461,7 @@ void soapy_protocol_set_rx_antenna(RECEIVER *rx,int ant) { void soapy_protocol_set_tx_antenna(TRANSMITTER *tx,int ant) { int rc; if(soapy_device!=NULL) { + if (ant >= radio->info.soapy.tx_antennas) ant=radio->info.soapy.tx_antennas -1; g_print("soapy_protocol: set_tx_antenna: %s\n",radio->info.soapy.tx_antenna[ant]); rc=SoapySDRDevice_setAntenna(soapy_device,SOAPY_SDR_TX,tx->dac,radio->info.soapy.tx_antenna[ant]); if(rc!=0) { diff --git a/toolbar.c b/toolbar.c index ba2cf94..991b456 100644 --- a/toolbar.c +++ b/toolbar.c @@ -372,7 +372,7 @@ static void xit_clear_cb(GtkWidget *widget, gpointer data) { } static void freq_cb(GtkWidget *widget, gpointer data) { - start_vfo(); + start_vfo(active_receiver->id); } static void mem_cb(GtkWidget *widget, gpointer data) { diff --git a/vfo.c b/vfo.c index c8811e7..f7823ca 100644 --- a/vfo.c +++ b/vfo.c @@ -1154,7 +1154,7 @@ vfo_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - start_vfo(); + start_vfo(event->x<300?VFO_A:VFO_B); return TRUE; } diff --git a/vfo.h b/vfo.h index f2927bc..9efd1b5 100644 --- a/vfo.h +++ b/vfo.h @@ -60,6 +60,11 @@ struct _mode_settings { } mode_settings[MODES]; +typedef struct _set_frequency { + int vfo; + long long frequency; +} SET_FREQUENCY; + extern int steps[]; extern char *step_labels[]; diff --git a/vfo_menu.c b/vfo_menu.c index 209873d..47ad316 100644 --- a/vfo_menu.c +++ b/vfo_menu.c @@ -37,6 +37,7 @@ #include "ext.h" static GtkWidget *parent_window=NULL; +static gint v; static GtkWidget *dialog=NULL; static GtkWidget *label; @@ -83,7 +84,7 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { double mult; long long f; static int set = 0; - long long *fp; + SET_FREQUENCY *fp; // Instead of messing with LOCALE settings, // we print a "0.0" and look what the decimal @@ -149,10 +150,10 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { f = ((long long)(atof(buffer)*mult)+5)/10; sprintf(output, "%lld", f); gtk_label_set_markup (GTK_LABEL (label), output); - fp = malloc(sizeof(long long)); - *fp = f; + fp=g_new(SET_FREQUENCY,1); + fp->vfo=v; + fp->frequency = f; g_idle_add(ext_set_frequency, fp); - g_idle_add(ext_vfo_update,NULL); set = 1; } } @@ -202,16 +203,17 @@ static void lock_cb(GtkWidget *widget, gpointer data) { static GtkWidget *last_mode; -void vfo_menu(GtkWidget *parent) { +void vfo_menu(GtkWidget *parent,int vfo) { int i; parent_window=parent; + v=vfo; dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); char title[64]; - sprintf(title,"piHPSDR - VFO (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + sprintf(title,"piHPSDR - VFO %s",vfo==0?"A":"B"); gtk_window_set_title(GTK_WINDOW(dialog),title); g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); @@ -226,18 +228,18 @@ void vfo_menu(GtkWidget *parent) { GtkWidget *grid=gtk_grid_new(); - gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE); gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_column_spacing (GTK_GRID(grid),4); gtk_grid_set_row_spacing (GTK_GRID(grid),4); GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + gtk_grid_attach(GTK_GRID(grid),close_b,0,0,2,1); GtkWidget *lock_b=gtk_check_button_new_with_label("Lock VFO"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lock_b), locked); - gtk_grid_attach(GTK_GRID(grid),lock_b,1,0,1,1); + gtk_grid_attach(GTK_GRID(grid),lock_b,2,0,2,1); g_signal_connect(lock_b,"toggled",G_CALLBACK(lock_cb),NULL); label = gtk_label_new (NULL); @@ -298,7 +300,7 @@ void vfo_menu(GtkWidget *parent) { g_signal_connect(enable_squelch,"toggled",G_CALLBACK(squelch_enable_cb),NULL); #ifdef PURESIGNAL - if(can_transmit) { + if(can_transmit && (protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL)) { GtkWidget *enable_ps=gtk_check_button_new_with_label("Enable Pure Signal"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_ps), transmitter->puresignal); gtk_grid_attach(GTK_GRID(grid),enable_ps,3,7,1,1); diff --git a/vfo_menu.h b/vfo_menu.h index 798da2d..28b664e 100644 --- a/vfo_menu.h +++ b/vfo_menu.h @@ -17,4 +17,4 @@ * */ -extern void vfo_menu(GtkWidget *parent); +extern void vfo_menu(GtkWidget *parent,int vfo); -- 2.45.2