Changed code to display Rx Panadapter frequency markers.
// 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;
}
}
int ext_frequency_update(void *data) {
- start_vfo();
+ start_vfo(active_receiver->id);
return 0;
}
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;
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;
}
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();
gboolean duplex=FALSE;
gboolean mute_rx_while_transmitting=FALSE;
+double drive_max=100;
+
gboolean display_sequence_errors=TRUE;
gint sequence_errors=0;
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) {
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
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++) {
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++) {
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
}
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);
}
#ifdef SOAPYSDR
case SOAPYSDR_PROTOCOL:
soapy_protocol_set_tx_gain(transmitter,transmitter->drive);
-
break;
#endif
}
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;
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]);
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]);
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;
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;i<display_width;i++) {
- f = frequency - half + (long) (HzPerPixel * (i+rx->pan));
- 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<max_display) {
+ x=(double)(f-min_display)/HzPerPixel;
+ cairo_move_to(cr,(double)x,0.0);
+ cairo_line_to(cr,(double)x,(double)display_height);
+
+ sprintf(v,"%0lld.%03lld",f/1000000,(f%1000000)/1000);
+ cairo_text_extents(cr, v, &extents);
+ cairo_move_to(cr, x-(extents.width/2.0), 10.0);
+ cairo_show_text(cr, v);
+ f+=divisor;
}
cairo_stroke(cr);
scale_status=DRIVE;
scale_dialog=gtk_dialog_new_with_buttons("Drive",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
- switch(protocol) {
-#ifdef SOAPYSDR
- case SOAPYSDR_PROTOCOL:
- drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 64.0, 1.00);
- break;
-#endif
- default:
- drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
- break;
- }
-
+ drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, drive_max, 1.00);
gtk_widget_override_font(drive_scale, pango_font_description_from_string("Sans 10"));
gtk_widget_set_size_request (drive_scale, 400, 30);
gtk_range_set_value (GTK_RANGE(drive_scale),value);
drive_label=gtk_label_new("Drive:");
gtk_widget_override_font(drive_label, pango_font_description_from_string("Sans 10"));
gtk_grid_attach(GTK_GRID(sliders),drive_label,3,1,1,1);
-
- drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0);
+ drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, drive_max, 1.00);
gtk_widget_override_font(drive_scale, pango_font_description_from_string("Sans 10"));
gtk_range_set_increments (GTK_RANGE(drive_scale),1.0,1.0);
gtk_range_set_value (GTK_RANGE(drive_scale),getDrive());
void soapy_protocol_set_rx_antenna(RECEIVER *rx,int ant) {
int rc;
if(soapy_device!=NULL) {
+ if (ant >= 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) {
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) {
}
static void freq_cb(GtkWidget *widget, gpointer data) {
- start_vfo();
+ start_vfo(active_receiver->id);
}
static void mem_cb(GtkWidget *widget, gpointer data) {
GdkEventButton *event,
gpointer data)
{
- start_vfo();
+ start_vfo(event->x<300?VFO_A:VFO_B);
return TRUE;
}
} mode_settings[MODES];
+typedef struct _set_frequency {
+ int vfo;
+ long long frequency;
+} SET_FREQUENCY;
+
extern int steps[];
extern char *step_labels[];
#include "ext.h"
static GtkWidget *parent_window=NULL;
+static gint v;
static GtkWidget *dialog=NULL;
static GtkWidget *label;
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
f = ((long long)(atof(buffer)*mult)+5)/10;
sprintf(output, "<big>%lld</big>", 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;
}
}
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);
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);
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);
*
*/
-extern void vfo_menu(GtkWidget *parent);
+extern void vfo_menu(GtkWidget *parent,int vfo);