From 038d98f426d68efbab9c6bfa0ad2920539d66293 Mon Sep 17 00:00:00 2001 From: c vw Date: Fri, 26 Jul 2019 18:05:53 +0200 Subject: [PATCH] Finalized things. --- Makefile | 5 +- Makefile.mac | 5 +- README.MacOS | 1 - alex.h | 18 +- new_protocol.c | 78 +++++++-- old_discovery.c | 4 +- old_protocol.c | 429 ++++++++++++++++++++++++++---------------------- ps_menu.c | 38 +++-- radio.c | 4 +- rx_menu.c | 13 +- transmitter.c | 1 + 11 files changed, 351 insertions(+), 245 deletions(-) diff --git a/Makefile b/Makefile index f3a8cf4..8bf0d14 100644 --- a/Makefile +++ b/Makefile @@ -33,9 +33,6 @@ GIT_VERSION := $(shell git describe --abbrev=0 --tags) # uncomment the line below to include support for STEMlab discovery (WITHOUT AVAHI) #STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI -# uncommment this line for circumventing problems with RedPitya HPSDR apps. -#STEMLAB_FIX_OPTION=-DSTEMLAB_FIX - # uncomment the line below to include support for Pi SDR #PI_SDR_INCLUDE=PI_SDR @@ -214,7 +211,7 @@ AUDIO_LIBS=-lasound OPTIONS=-g -Wno-deprecated-declarations $(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) \ $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(RADIOBERRY_OPTIONS) \ - $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) $(STEMLAB_FIX_OPTION) \ + $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) \ -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3 LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) $(STEMLAB_LIBS) $(MIDI_LIBS) diff --git a/Makefile.mac b/Makefile.mac index e3fc050..0095644 100644 --- a/Makefile.mac +++ b/Makefile.mac @@ -30,9 +30,6 @@ PURESIGNAL_INCLUDE=PURESIGNAL # uncomment the line below to include support for STEMlab discovery (WITHOUT AVAHI) STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI -# uncommment this line for circumventing problems with RedPitya HPSDR apps. -STEMLAB_FIX_OPTION=-DSTEMLAB_FIX - # uncomment the line below to include support for Pi SDR #PI_SDR_INCLUDE=PI_SDR @@ -199,7 +196,7 @@ PORTAUDIO_OPTIONS=-DPORTAUDIO AUDIO_LIBS=-lportaudio OPTIONS=-g -Wno-deprecated-declarations $(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) \ - $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(RADIOBERRY_OPTIONS) $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) $(STEMLAB_FIX_OPTION) \ + $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(RADIOBERRY_OPTIONS) $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) \ -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(PORTAUDIO_OPTIONS) $(DEBUG_OPTION) -O3 LIBS=-lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) $(STEMLAB_LIBS) $(MIDI_LIBS) diff --git a/README.MacOS b/README.MacOS index b2a88d2..02253d7 100644 --- a/README.MacOS +++ b/README.MacOS @@ -107,7 +107,6 @@ That's easy. Just adjust the Makefile according to the instructions found there and type "make". In my case (I have a HAMLAB RedPitaya-based SDR box), I need the following options in the Makefile (and have all others commented out): -STEMLAB_FIX_OPTION=-DSTEMLAB_FIX STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_MAC diff --git a/alex.h b/alex.h index ca9c38b..6341cac 100644 --- a/alex.h +++ b/alex.h @@ -28,11 +28,21 @@ // For ANAN-7000/8000, there are furthermore ALEX1 bits for the filter // board of the second RX. // +// One note about bit 11 (controlling relay K36) +// +// On older (Rev 15/16) filter boards, K36 switches an output (ByPass) +// On newer (Rev 24) filter boards, K36 switches an input (ByPass) +// +// That is, we use bit 11 ONLY when "RX BYPASS" is selected as the *input* +// for the PS feedback signal. If you select "RX BYPASS" for the old +// ANAN-100 boards PS will not work, you have to use EXT1. +// +// #define ALEX_RX_ANTENNA_NONE 0x00000000 // route Ant1,2,2 to RX1 -#define ALEX_RX_ANTENNA_XVTR 0x00000900 // route XVTR-in to RX1 -#define ALEX_RX_ANTENNA_EXT1 0x00000A00 // route EXT1 to RX1 -#define ALEX_RX_ANTENNA_EXT2 0x00000C00 // jOUTE EXT2 to RX1 -#define ALEX_RX_ANTENNA_BYPASS 0x00000800 // disconnect RX1 from Ant1,2,3 +#define ALEX_RX_ANTENNA_XVTR 0x00000100 // route XVTR-in to RX1 (bit 8) +#define ALEX_RX_ANTENNA_EXT1 0x00000200 // route EXT1 to RX1 (bit 9) +#define ALEX_RX_ANTENNA_EXT2 0x00000400 // route EXT2 to RX1 (bit 10) +#define ALEX_RX_ANTENNA_BYPASS 0x00000800 // connect BYPASS to RX1 (bit 11) #define ALEX_TX_ANTENNA_1 0x01000000 // route TX to ANT1 #define ALEX_TX_ANTENNA_2 0x02000000 // route TX to ANT2 diff --git a/new_protocol.c b/new_protocol.c index 5d83fa3..dc784c3 100644 --- a/new_protocol.c +++ b/new_protocol.c @@ -816,6 +816,31 @@ static void new_protocol_high_priority() { long alex0=0x00000000; long alex1=0x00000000; + if (device != NEW_DEVICE_ORION2) { + // + // ANAN7000 and 8000 do not have ALEX attenuators. + // Even worse, ALEX0(14) bit used to control these attenuators + // on ANAN-10/100/200 is now used differently. + // + // Note: ALEX attenuators are not much used anyway since we + // have step attenuators on most boards. + // + switch (receiver[0]->alex_attenuation) { + case 0: + alex0 |= ALEX_ATTENUATION_0dB; + break; + case 1: + alex0 |= ALEX_ATTENUATION_10dB; + break; + case 2: + alex0 |= ALEX_ATTENUATION_20dB; + break; + case 3: + alex0 |= ALEX_ATTENUATION_30dB; + break; + } + } + if(isTransmitting()) { alex0 |= ALEX_TX_RELAY; if(transmitter->puresignal) { @@ -856,8 +881,14 @@ static void new_protocol_high_priority() { default: // // Old (ANAN-100/200) high-pass filters +// Bypass HPFs while using EXT1 for PURESIGNAL feedback! // - if(rxFrequency<1800000L) { + i=0; // flag used here for "filter bypass" + if (rxFrequency<1800000L) i=1; +#ifdef PURESIGNAL + if (isTransmitting() && transmitter->puresignal && receiver[PS_RX_FEEDBACK]->alex_antenna == 6) i=1; +#endif + if (i) { alex0|=ALEX_BYPASS_HPF; } else if(rxFrequency<6500000L) { alex0|=ALEX_1_5MHZ_HPF; @@ -929,12 +960,15 @@ static void new_protocol_high_priority() { // ANAN-7000 routes signals differently (these bits have no function on ANAN-80000) // and uses ALEX0(14) to connnect Ext/XvrtIn to the RX. // - i=receiver[0]->alex_antenna; + i=receiver[0]->alex_antenna; // 0,1,2 or 3,4,5 +#ifdef PURESIGNAL if (isTransmitting() && transmitter->puresignal) { - i=receiver[PS_RX_FEEDBACK]->alex_antenna; // 0, 3, or 4 + i=receiver[PS_RX_FEEDBACK]->alex_antenna; // 0, 6, or 7 } +#endif if (device == NEW_DEVICE_ORION2) i +=100; switch(i) { + case 6: // EXT 1 for PS feedback case 3: // EXT 1 alex0|=ALEX_RX_ANTENNA_EXT1; break; @@ -944,32 +978,33 @@ static void new_protocol_high_priority() { case 5: // XVTR alex0|=ALEX_RX_ANTENNA_XVTR; break; + case 7: // RX_Bypass_In for PS feedback + alex0|=ALEX_RX_ANTENNA_BYPASS; + break; case 103: // EXT1 on ANAN-7000 + case 106: // EXT1 on ANAN-7000 for PS feedback alex0|=ALEX_ANAN7000_RX_ANT_EXT1; break; - case 104: // EXT2 means RxBypass on ANAN-7000 - alex0|=ALEX_ANAN7000_RX_ANT_BYPASS; + case 104: + // no EXT2 jacket on ANAN7000! break; case 105: alex0|=ALEX_ANAN7000_RX_ANT_XVTR; break; + case 107: // RxBypassIn on ANAN-7000 + alex0|=ALEX_ANAN7000_RX_ANT_BYPASS; + break; } // // Now we set the bits for Ant1/2/3 (RX and TX may be different) -// If RX is from none of Ant1/2/3, do not switch (leave these relays -// in TX state) // - if(isTransmitting() || (receiver[0]->alex_antenna > 2)) { + if(isTransmitting()) { i=transmitter->alex_antenna; } else { i=receiver[0]->alex_antenna; } - // i has value 0, 1, or 2. switch(i) { - default: - // should not happen, ignore silently and connect to ANT1 - /* FALLTHROUGH */ case 0: // ANT 1 alex0|=ALEX_TX_ANTENNA_1; break; @@ -979,6 +1014,15 @@ static void new_protocol_high_priority() { case 2: // ANT 3 alex0|=ALEX_TX_ANTENNA_3; break; + default: + // this should not happen in TX case. Out of paranoia, + // connect ANT1 in this case + if (isTransmitting()) { + fprintf(stderr,"WARNING: illegal TX antenna chosen, using ANT1\n"); + transmitter->alex_antenna=0; + alex0|=ALEX_TX_ANTENNA_1; + } + break; } high_priority_buffer_to_radio[1432]=(alex0>>24)&0xFF; @@ -992,7 +1036,15 @@ static void new_protocol_high_priority() { // Orion2 boards: set RX2 filters according ro VFOB frequency // if (device == NEW_DEVICE_ORION2) { - rxFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; + // + // Note that while using DIVERSITY, the second RX filter settings must match + // those of the first RX + // + if (diversity_enabled) { + rxFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; + } else { + rxFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; + } // // new ANAN-7000/8000 band-pass RX filters // This info comes from file bpf2_select.v in the diff --git a/old_discovery.c b/old_discovery.c index 086a3b9..48c48e5 100644 --- a/old_discovery.c +++ b/old_discovery.c @@ -428,8 +428,8 @@ fprintf(stderr,"discover_receive_thread\n"); strcpy(discovered[devices].name,"Orion2"); break; case DEVICE_STEMLAB: - // This is in principle the same as HERMES so pretend a HERMES - discovered[devices].device = DEVICE_HERMES; + // This is in principle the same as HERMES but has two ADCs + // (and therefore, can do DIVERSITY). strcpy(discovered[devices].name,"STEMlab"); break; default: diff --git a/old_protocol.c b/old_protocol.c index 38b16c6..42f0b6b 100644 --- a/old_protocol.c +++ b/old_protocol.c @@ -535,29 +535,189 @@ static gpointer receive_thread(gpointer arg) { return NULL; } +// +// To avoid overloading code with handling all the different cases +// at various places, +// we define here the channel number of the receivers, as well as the +// number of HPSDR receivers to use (up to 5) +// These are FIXED numbers and depend on the device and whether the code +// is compiled with or without PURESIGNAL +// Furthermore, we provide a function that determines the frequency for +// a given (HPSDR) receiver. This makes the code below much more transparent. +// + +static int rx_feedback_receiver() { + // + // Depending on the device, return channel number of RX feedback receiver + // + int ret; + switch (device) { + case DEVICE_METIS: + ret=0; + break; + case DEVICE_HERMES: + case DEVICE_STEMLAB: + ret=2; + break; + case DEVICE_ANGELIA: + case DEVICE_ORION: + case DEVICE_ORION2: + ret=3; + default: + ret=0; + break; + } + return ret; +} + +static int tx_feedback_receiver() { + // + // Depending on the device, return channel number of RX feedback receiver + // + int ret; + switch (device) { + case DEVICE_METIS: + ret=1; + break; + case DEVICE_HERMES: + case DEVICE_STEMLAB: + ret=3; + break; + case DEVICE_ANGELIA: + case DEVICE_ORION: + case DEVICE_ORION2: + ret=4; + default: + ret=1; + break; + } + return ret; +} + +static int first_receiver() { + // + // Depending on the device and whether we compiled for PURESIGNAL, + // return the number of the first receiver + // + return 0; +} + +static int second_receiver() { + // + // Depending on the device and whether we compiled for PURESIGNAL, + // return the number of the second receiver + // +#ifdef PURESIGNAL + return 2; +#else + return 1; +#endif +} + +static long long channel_freq(int chan) { + // + // Depending on PURESIGNAL and DIVERSITY, return + // the frequency associated with the current HPSDR + // RX channel (0 <= chan <= 4). + // Note that for the RX channels which the firmware + // associates with the TX DAC the frequency need not + // be set. + // + // This function returns the TX frequency if chan is + // outside the allowed range, and thus can be used + // to determine the TX frequency. + // + int v; + long long freq; + + switch (chan) { +#ifdef PURESIGNAL + case 0: + case 1: + v=receiver[0]->id; + break; + case 2: + case 3: + if (diversity_enabled) { + v=receiver[0]->id; + } else { + v=receiver[1]->id; + } + break; +#else + case 0: + v=receiver[0]->id; + break; + case 1: + if (diversity_enabled) { + v=receiver[0]->id; + } else { + v=receiver[1]->id; + } + break; +#endif + } + if (v < 0) { + // + // v=-1 indicates that there is no VFO associated, + // in this case we take the TX frequency. So we can use this + // function also to determine the TX frequency + // + if(active_receiver->id==VFO_A) { + if(split) { + freq=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; + } else { + freq=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; + } + } else { + if(split) { + freq=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; + } else { + freq=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; + } + } + } else { + // + // determine frequency associated with VFO v + // + freq=vfo[v].frequency-vfo[v].lo; + if(vfo[v].rit_enabled) { + freq+=vfo[v].rit; + } + if(vfo[v].mode==modeCWU) { + freq-=(long long)cw_keyer_sidetone_frequency; + } else if(vfo[v].mode==modeCWL) { + freq+=(long long)cw_keyer_sidetone_frequency; + } + } + return freq; +} + static int how_many_receivers() { // // Depending on how the program is compiled and which board we have, // we use a FIXED number of receivers except for RADIOBERRY and PI_SDR, // where the number may be dynamically changed // - int num; + int ret; #if defined(RADIOBERRY) || defined(PI_SDR) - num = receivers; // 1 or 2 + ret = receivers; // 1 or 2 #else - num = RECEIVERS; // 2 + ret = RECEIVERS; // 2 #endif #ifdef PURESIGNAL // for PureSignal, the number of receivers needed is hard-coded below. - // we need at least 3 (for RX), and up to 5 for Orion2 boards, since - // the TX DAC channel is hard-wired to RX5. - num = 3; - if (device == DEVICE_HERMES) num = 4; - if (device == DEVICE_ANGELIA || device == DEVICE_ORION || device == DEVICE_ORION2) num = 5; + // we need at least 2, and up to 5 for Orion2 boards. This is so because + // the TX DAC is hard-wired to RX4 for HERMES,STEMLAB and to RX5 for ANGELIA + // and beyond. + ret = 2; // METIS? + if (device == DEVICE_HERMES || device == DEVICE_STEMLAB) ret = 4; + if (device == DEVICE_ANGELIA || device == DEVICE_ORION || device == DEVICE_ORION2) ret = 5; #endif - return num; + return ret; } + static void process_ozy_input_buffer(unsigned char *buffer) { int i,j; int r; @@ -586,6 +746,10 @@ static void process_ozy_input_buffer(unsigned char *buffer) { int tx_vfo=split?VFO_B:VFO_A; int num_hpsdr_receivers=how_many_receivers(); + int rxfdbk = rx_feedback_receiver(); + int txfdbk = tx_feedback_receiver(); + int rx1channel = first_receiver(); + int rx2channel = second_receiver(); if(buffer[b++]==SYNC && buffer[b++]==SYNC && buffer[b++]==SYNC) { // extract control bytes @@ -661,114 +825,55 @@ static void process_ozy_input_buffer(unsigned char *buffer) { left_sample_double=(double)left_sample/8388607.0; // 24 bit sample 2^23-1 right_sample_double=(double)right_sample/8388607.0; // 24 bit sample 2^23-1 -#ifdef PURESIGNAL if (isTransmitting() && transmitter->puresignal) { // - // case: transmitting with PURESIGNAL. Get sample pairs and feed to pscc + // transmitting with PURESIGNAL. Get sample pairs and feed to pscc // - switch(r) { - case 0: - if(device==DEVICE_METIS) { - left_sample_double_rx=left_sample_double; - right_sample_double_rx=right_sample_double; - } - break; - case 1: - if(device==DEVICE_METIS) { - left_sample_double_tx=left_sample_double; - right_sample_double_tx=right_sample_double; - add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx); - } - break; - case 2: - if(device==DEVICE_HERMES) { - left_sample_double_rx=left_sample_double; - right_sample_double_rx=right_sample_double; - } - break; - case 3: - if(device==DEVICE_HERMES) { - left_sample_double_tx=left_sample_double; - right_sample_double_tx=right_sample_double; - add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx); - } else if(device==DEVICE_ANGELIA || device==DEVICE_ORION || device==DEVICE_ORION2) { - left_sample_double_rx=left_sample_double; - right_sample_double_rx=right_sample_double; - } - break; - case 4: - if(device==DEVICE_ANGELIA || device==DEVICE_ORION || device==DEVICE_ORION2) { - left_sample_double_tx=left_sample_double; - right_sample_double_tx=right_sample_double; - add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx); - } - break; + if (r == rxfdbk) { + left_sample_double_rx=left_sample_double; + right_sample_double_rx=right_sample_double; + } else if (r == txfdbk) { + left_sample_double_tx=left_sample_double; + right_sample_double_tx=right_sample_double; } - } - if (!isTransmitting() && diversity_enabled) { - // - // case: compiled for PURESIGNAL and RX with DIVERSITY. Feed sample pair to diversity mixer for RX1 and original RX2 sample to RX2 - // - switch(r) { - case 0: - left_sample_double_rx=left_sample_double; - right_sample_double_rx=right_sample_double; - break; - case 2: - left_sample_double_tx=left_sample_double; - right_sample_double_tx=right_sample_double; - add_div_iq_samples(receiver[0], left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx); - if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double); - break; + // this is pure paranoia, it allows for txfdbk < rxfdbk + if (r+1 == num_hpsdr_receivers) { + add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx); } } - if (!isTransmitting() && !diversity_enabled) { + + if (!isTransmitting() && diversity_enabled) { // - // case: compiled for PURESIGNAL and RX without DIVERSITY. Feed samples to RX1 and RX2 + // receiving with DIVERSITY. Get sample pairs and feed to diversity mixer // - switch(r) { - case 0: - add_iq_samples(receiver[0], left_sample_double,right_sample_double); - break; - case 2: - if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double); - break; + if (r == rx1channel) { + left_sample_double_rx=left_sample_double; + right_sample_double_rx=right_sample_double; + } else if (r == rx2channel) { + left_sample_double_tx=left_sample_double; + right_sample_double_tx=right_sample_double; } - } -#else - // no PURESIGNAL - if (diversity_enabled) { - // - // case: compiled without PURESIGNAL and using DIVERSITY: Feed sample pair to diversity mixer for RX1 and original RX2 sample to RX2 - // - switch(r) { - case 0: - left_sample_double_rx=left_sample_double; - right_sample_double_rx=right_sample_double; - break; - case 1: - left_sample_double_tx=left_sample_double; - right_sample_double_tx=right_sample_double; - add_div_iq_samples(receiver[0], left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx); - if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double); - break; + // this is pure paranoia, it allows for div_main < div_aux + if (r+1 == num_hpsdr_receivers) { + add_div_iq_samples(receiver[0], left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx); + // if we have a second receiver, display "auxiliary" receiver as well + if (receivers >1) add_iq_samples(receiver[1], left_sample_double_tx,right_sample_double_tx); } - } - if (!diversity_enabled) { + } + + if (!isTransmitting() && !diversity_enabled) { // - // case: compiled without PURESIGNAL and not using DIVERSITY: Feed samples to RX1 and RX2 + // RX without DIVERSITY. Feed samples to RX1 and RX2 // - switch(r) { - case 0: - add_iq_samples(receiver[0], left_sample_double,right_sample_double); - break; - case 1: - if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double); - break; + if (r == rx1channel) { + add_iq_samples(receiver[0], left_sample_double,right_sample_double); + } else if (r == rx2channel ]] receivers > 1) { + add_iq_samples(receiver[1], left_sample_double,right_sample_double); } - } -#endif - } + } + } // end of loop over the receiver channels + + // TX without PURESIGNAL: receivers are shut down -- do nothing mic_sample = (short)(buffer[b++]<<8); mic_sample |= (short)(buffer[b++]&0xFF); @@ -1002,17 +1107,21 @@ void ozy_send_buffer() { // if (isTransmitting() && transmitter->puresignal) i=receiver[PS_RX_FEEDBACK]->alex_antenna; switch(i) { - case 3: // Alex: RX2 IN, ANAN: EXT1, ANAN7000: still uses internal feedback - output_buffer[C3]|=0x80; + case 6: // EXT1 used for PS feedback + case 3: // EXT1 (RX2_IN) + output_buffer[C3]|=0x40; break; - case 4: // Alex: RX1 IN, ANAN: EXT2, ANAN7000: RX BYPASS - output_buffer[C3]|=0xA0; + case 4: // EXT2 (RX1_IN) + output_buffer[C3]|=0x20; break; case 5: // XVTR - output_buffer[C3]|=0xE0; + output_buffer[C3]|=0x60; break; + case 7: // RX Bypass In + output_buffer[C3]|=0x80; + break; default: - // RX1_OUT and RX1_ANT bits remain zero + // RX1_ANT bits remain zero break; } @@ -1072,20 +1181,7 @@ void ozy_send_buffer() { switch(command) { case 1: // tx frequency output_buffer[C0]=0x02; - long long txFrequency; - if(active_receiver->id==VFO_A) { - if(split) { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; - } else { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; - } - } else { - if(split) { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; - } else { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; - } - } + long long txFrequency=channel_freq(-1); output_buffer[C1]=txFrequency>>24; output_buffer[C2]=txFrequency>>16; output_buffer[C3]=txFrequency>>8; @@ -1094,51 +1190,14 @@ void ozy_send_buffer() { case 2: // rx frequency if(current_rxid; - // for the "last" receiver, v is out of range. In this case, - // use TX frequency also while receiving - if((isTransmitting() && transmitter->puresignal) || (v >= MAX_VFOS)) { - long long txFrequency; - if(active_receiver->id==VFO_A) { - if(split) { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; - } else { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; - } - } else { - if(split) { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; - } else { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; - } - } - output_buffer[C1]=txFrequency>>24; - output_buffer[C2]=txFrequency>>16; - output_buffer[C3]=txFrequency>>8; - output_buffer[C4]=txFrequency; - } else { -#else - int v=receiver[current_rx]->id; -#endif - long long rxFrequency=vfo[v].frequency-vfo[v].lo; - if(vfo[v].rit_enabled) { - rxFrequency+=vfo[v].rit; - } - if(vfo[v].mode==modeCWU) { - rxFrequency-=(long long)cw_keyer_sidetone_frequency; - } else if(vfo[v].mode==modeCWL) { - rxFrequency+=(long long)cw_keyer_sidetone_frequency; - } - output_buffer[C1]=rxFrequency>>24; - output_buffer[C2]=rxFrequency>>16; - output_buffer[C3]=rxFrequency>>8; - output_buffer[C4]=rxFrequency; -#ifdef PURESIGNAL - } -#endif + long long rxFrequency=channel_freq(current_rx); + output_buffer[C1]=rxFrequency>>24; + output_buffer[C2]=rxFrequency>>16; + output_buffer[C3]=rxFrequency>>8; + output_buffer[C4]=rxFrequency; current_rx++; } + // if we have reached the last RX channel, wrap around if(current_rx>=num_hpsdr_receivers) { current_rx=0; } @@ -1147,7 +1206,6 @@ void ozy_send_buffer() { { BAND *band=band_get_current_band(); int power=0; -#ifdef STEMLAB_FIX // // Some HPSDR apps for the RedPitaya generate CW inside the FPGA, but while // doing this, DriveLevel changes are processed by the server, but do not become effective. @@ -1162,9 +1220,6 @@ void ozy_send_buffer() { mode=vfo[0].mode; } if(isTransmitting() || (mode == modeCWU) || (mode == modeCWL)) { -#else - if(isTransmitting()) { -#endif if(tune && !transmitter->tune_use_drive) { power=(int)((double)transmitter->drive_level/100.0*(double)transmitter->tune_percent); } else { @@ -1220,7 +1275,8 @@ void ozy_send_buffer() { output_buffer[C3]=0x00; output_buffer[C4]=0x00; - if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) { + if(device==DEVICE_HERMES || device==DEVICE_ANGELIA || device==DEVICE_ORION + || device==DEVICE_ORION2 || device == DEVICE_STEMLAB) { // if attenuation is zero, then disable attenuator i = adc_attenuation[receiver[0]->adc] & 0x1F; if (i >0) output_buffer[C4]=0x20| i; @@ -1235,7 +1291,8 @@ void ozy_send_buffer() { output_buffer[C0]=0x16; output_buffer[C1]=0x00; if(receivers==2) { - if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) { + if(device==DEVICE_HERMES || device==DEVICE_ANGELIA || device==DEVICE_ORION + || device==DEVICE_ORION2 || device==DEVICE_STEMLAB) { // if attenuation is zero, then disable attenuator i = adc_attenuation[receiver[1]->adc] & 0x1F; if (i > 0) output_buffer[C1]=0x20|i; @@ -1449,6 +1506,7 @@ static int metis_write(unsigned char ep,unsigned char* buffer,int length) { } static void metis_restart() { + int i; // // In TCP-ONLY mode, we possibly need to re-connect // since if we come from a METIS-stop, the server @@ -1463,34 +1521,17 @@ static void metis_restart() { // reset current rx current_rx=0; -#ifdef STEMLAB_FIX // // Some (older) HPSDR apps on the RedPitaya have very small // buffers that over-run if too much data is sent // to the RedPitaya *before* sending a METIS start packet. - // Therefore we send only four OZY buffers here. + // We fill the DUC FIFO here with about 500 samples before + // starting. // - command=1; // ship out a "C0=0" and a "set tx" command - ozy_send_buffer(); - ozy_send_buffer(); - command=2; // ship out a "C0=0" and a "set rx" command for RX1 - ozy_send_buffer(); - ozy_send_buffer(); - - current_rx=0; - command=1; -#else - // DL1YCF: this is the original code, which does not do what it pretends .... - // send commands twice command=1; - do { + for (i=1; i<8; i++) { ozy_send_buffer(); - } while (command!=1); - - do { - ozy_send_buffer(); - } while (command!=1); -#endif + } sleep(1); diff --git a/ps_menu.c b/ps_menu.c index acadd84..fb80d26 100644 --- a/ps_menu.c +++ b/ps_menu.c @@ -261,15 +261,21 @@ static int info_thread(gpointer arg) { } // -// Set "RX1 ANT", "RX1 OUT", and ADC settings for the PS feedback signal +// select route for PS feedback signal. +// note: we need new code numbers such that we can +// distinguish "normal RX" and "feedback" use +// of EXT1. In the latter case, any RX filters have +// to by bypassed, which is of particular importance +// on the 6m band. +// // static void ps_ant_cb(GtkWidget *widget, gpointer data) { int val = (int) (uintptr_t) data; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { switch (val) { - case 0: // AUTO (Internal), feedback goes to first ADC - case 3: // EXT1, feedback goes to first ADC - case 4: // EXT2, feedback goes to first ADC + case 0: // Internal + case 6: // EXT1; RX filters switched to "BYPASS" + case 7: // Bypass receiver[PS_RX_FEEDBACK]->alex_antenna = val; if (protocol == NEW_PROTOCOL) { schedule_high_priority(); @@ -330,7 +336,6 @@ static void twotone_cb(GtkWidget *widget, gpointer data) { void ps_menu(GtkWidget *parent) { GtkWidget *b; int i; - const char *cp; parent_window=parent; @@ -420,15 +425,17 @@ void ps_menu(GtkWidget *parent) { // // AUTO Using internal feedback (to ADC0) // EXT1 Using EXT1 jacket (to ADC0), ANAN-7000: still uses AUTO - // EXT2 Using EXT2 jacket (to ADC0), ANAN-7000: "EXT2 is called RX Bypass" - // RX2 Using RX2 jacket (to ADC1) + // BYPASS Using BYPASS. Not available with ANAN-100/200 up to Rev. 16 filter boards + // + // In fact, we provide the possibility of using EXT1 only to support these older + // (before February, 2015) ANAN-100/200 devices. // GtkWidget *ps_ant_label=gtk_label_new("PS FeedBk ANT:"); gtk_widget_show(ps_ant_label); gtk_grid_attach(GTK_GRID(grid), ps_ant_label, col, row, 1, 1); col++; - GtkWidget *ps_ant_auto=gtk_radio_button_new_with_label(NULL,"AUTO"); + GtkWidget *ps_ant_auto=gtk_radio_button_new_with_label(NULL,"Internal"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps_ant_auto), (receiver[PS_RX_FEEDBACK]->alex_antenna == 0) ); gtk_widget_show(ps_ant_auto); @@ -438,23 +445,18 @@ void ps_menu(GtkWidget *parent) { GtkWidget *ps_ant_ext1=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ps_ant_auto),"EXT1"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps_ant_ext1), - (receiver[PS_RX_FEEDBACK]->alex_antenna==3) ); + (receiver[PS_RX_FEEDBACK]->alex_antenna==6) ); gtk_widget_show(ps_ant_ext1); gtk_grid_attach(GTK_GRID(grid), ps_ant_ext1, col, row, 1, 1); - g_signal_connect(ps_ant_ext1,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 3); + g_signal_connect(ps_ant_ext1,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 6); col++; - cp="EXT2"; - // On ANAN-7000 there is no EXT2 jacket. This function is now called "RX ByPass" - // On ANAN-8000 this must be done by physical re-wiring - if ((protocol == ORIGINAL_PROTOCOL && device == DEVICE_ORION2) || - (protocol == NEW_PROTOCOL && device == NEW_DEVICE_ORION2)) cp="RxByPass"; - GtkWidget *ps_ant_ext2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ps_ant_auto),cp); + GtkWidget *ps_ant_ext2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ps_ant_auto),"ByPass IN"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps_ant_ext2), - (receiver[PS_RX_FEEDBACK]->alex_antenna==4) ); + (receiver[PS_RX_FEEDBACK]->alex_antenna==7) ); gtk_widget_show(ps_ant_ext2); gtk_grid_attach(GTK_GRID(grid), ps_ant_ext2, col, row, 1, 1); - g_signal_connect(ps_ant_ext2,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 4); + g_signal_connect(ps_ant_ext2,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 7); col++; row++; diff --git a/radio.c b/radio.c index c719191..3abb01d 100644 --- a/radio.c +++ b/radio.c @@ -492,9 +492,7 @@ void start_radio() { switch(protocol) { case ORIGINAL_PROTOCOL: switch(device) { - case DEVICE_METIS: - n_adc=1; // No support for multiple MERCURY cards on a single ATLAS bus. - break; + case DEVICE_METIS: // No support for multiple MERCURY cards on a single ATLAS bus. case DEVICE_HERMES: case DEVICE_HERMES_LITE: n_adc=1; diff --git a/rx_menu.c b/rx_menu.c index 4cff08f..6ac0d1f 100644 --- a/rx_menu.c +++ b/rx_menu.c @@ -32,6 +32,7 @@ #include "radio.h" #include "receiver.h" #include "sliders.h" +#include "new_protocol.h" static GtkWidget *parent_window=NULL; @@ -59,14 +60,23 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d static void dither_cb(GtkWidget *widget, gpointer data) { active_receiver->dither=active_receiver->dither==1?0:1; + if (protocol == NEW_PROTOCOL) { + schedule_high_priority(); + } } static void random_cb(GtkWidget *widget, gpointer data) { active_receiver->random=active_receiver->random==1?0:1; + if (protocol == NEW_PROTOCOL) { + schedule_high_priority(); + } } static void preamp_cb(GtkWidget *widget, gpointer data) { active_receiver->preamp=active_receiver->preamp==1?0:1; + if (protocol == NEW_PROTOCOL) { + schedule_high_priority(); + } } static void alex_att_cb(GtkWidget *widget, gpointer data) { @@ -243,8 +253,7 @@ void rx_menu(GtkWidget *parent) { // On SDRs other than CHARLY25, preamps or Alex attenuators may be present or not, and we // do not try to find out whether they are. This would overload the code, and we then // also must have a menu to check e.g. which ANAN model is actually present. - // Instead, we offer these checkboxes in either case and must rely on the user - // not playing around with features that are not there. + // Instead, we offer these checkboxes in either case. // // NOTE: Preamps are not present on most current HPSDR models, and ALEX attenuators // are not present e.g. in ANAN-7000. diff --git a/transmitter.c b/transmitter.c index bc4cf61..68b7082 100644 --- a/transmitter.c +++ b/transmitter.c @@ -369,6 +369,7 @@ static gboolean update_display(gpointer data) { constant2=0.09; break; case DEVICE_HERMES: + case DEVICE_STEMLAB: constant1=3.3; constant2=0.095; break; -- 2.45.2