From 83361731e4617e442efec4548b958e5e5b9e94bf Mon Sep 17 00:00:00 2001 From: c vw Date: Mon, 12 Aug 2019 18:01:01 +0200 Subject: [PATCH] a) Fixing CTUNE in new protocol. b) Displaying signals at the correct frequency in RX panadapter while doing CW. --- hpsdrsim.c | 10 ++++--- new_protocol.c | 16 +++++++---- old_protocol.c | 2 +- rx_panadapter.c | 74 +++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 83 insertions(+), 19 deletions(-) diff --git a/hpsdrsim.c b/hpsdrsim.c index 4535a15..fa48ca3 100644 --- a/hpsdrsim.c +++ b/hpsdrsim.c @@ -9,7 +9,7 @@ * * This device has four "RF sources" * - * RF1: ADC noise plus a 800 Hz signal at -73dBm + * RF1: ADC noise plus a 800 Hz signal plus 5000 Hz signal at -73dBm * RF2: ADC noise * RF3: TX feedback signal with some distortion. * RF4: normalized undistorted TX signal @@ -251,13 +251,15 @@ int main(int argc, char *argv[]) noiseQtab[i]= ((double) rand_r(&seed) / j - 1.0) * 0.00003; } - fprintf(stderr,".... producing an 800 Hz signal\n"); + fprintf(stderr,".... producing signals\n"); // Produce an 800 Hz tone at 0 dBm run=0.0; + off=0.0; for (i=0; iid==VFO_A) { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; if(split) { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; } } else { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; if(split) { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; } } @@ -802,9 +802,13 @@ static void new_protocol_high_priority() { } // -// ANAN-7000/8000: route TXout to XvtrOut out when not using PA +// ANAN-7000/8000: route TXout to XvtrOut out when using XVTR input +// (this is the condition also implemented in old_protocol) +// Note: the firmware does a logical AND with the T/R bit +// such that upon RX, Xvtr port is input, and on TX, Xvrt port +// is output if the XVTR_OUT bit is set. // - if ((device==NEW_DEVICE_ORION2) && band->disablePA) { + if ((device==NEW_DEVICE_ORION2) && receiver[0]->alex_antenna == 5) { high_priority_buffer_to_radio[1400] |= ANAN7000_XVTR_OUT; } diff --git a/old_protocol.c b/old_protocol.c index 89a1e30..88b7a3a 100644 --- a/old_protocol.c +++ b/old_protocol.c @@ -1447,7 +1447,7 @@ void ozy_send_buffer() { output_buffer[C2]=0x02; // Alex2 XVTR enable } if(transmitter->puresignal) { - output_buffer[C2]|=0x40; // Synchronize RX5 and TX frequency on transmit + output_buffer[C2]|=0x40; // Synchronize RX5 and TX frequency on transmit (ANAN-7000) } output_buffer[C3]=0x00; // Alex2 filters output_buffer[C4]=0x00; // Alex2 filters diff --git a/rx_panadapter.c b/rx_panadapter.c index ebad2a9..52a2eb8 100644 --- a/rx_panadapter.c +++ b/rx_panadapter.c @@ -169,13 +169,70 @@ void rx_panadapter_update(RECEIVER *rx) { } } + double cwshift; + int begin,end,icwshift; + + // + // In this program, when using CW, we will always transmit on exactly + // the frequency which is the "VFO display" frequency, not 800 Hz above + // or below. Therfore, the RX center frequency sent to the SDR is shifted + // by the sidetone frequency. + // Previous versions showed a "shifted" RX spectrum where the CW signal that + // was received exactly on the VFO frequency was shifted to the right (CWU) + // or to the left (CWL), the exact position shown by a yellow line. + // + // Alternatively, one could arrange things such that the RX spectrum is + // shown correctly and that in CWU you "hear" a CW signal at 7000,0 kHz + // when the VFO display frequency is 7000.0 kHz. Then, the TX signal must + // have an offset, that is, you send a CW signal at 7000.8 kHz when the + // VFO display shows 7000.0 kHz, and the yellow line is at 7000.8 kHz. + // + // Instead of drawing a "yellow line" to show where the received CW + // signal is, we shift the displayed spectrum by the side tone such + // that the received signals occur at the nominal frequencies + // That is, in CW we TX at the VFO display frequency which is marked by + // a red line, and we also receive CW signals from exactly that position in + // the RX spectrum. Furthermore, when switching between CWU and CWL, the + // displayed RX spectrum remains unchanged except for the part at the right + // or left margin of the display. + // + // For me (DL1YCF) this seems more logical. + // + switch (vfo[rx->id].mode) { + case modeCWU: + // spectrum must be shifted to the left + cwshift=(double) cw_keyer_sidetone_frequency / rx->hz_per_pixel; + icwshift=(int) cwshift; + begin=0; + end=display_width-icwshift; + break; + case modeCWL: + // spectrum must shifted to the right + cwshift=-(double) cw_keyer_sidetone_frequency / rx->hz_per_pixel; + icwshift=(int) cwshift; + begin=-cwshift; + end=display_width; + break; + default: + cwshift=0.0; + icwshift=0; + begin=0; + end=display_width; + break; + } + + // filter cairo_set_source_rgba (cr, 0.25, 0.25, 0.25, 0.75); - filter_left=(double)display_width/2.0+(((double)rx->filter_low+vfo[rx->id].offset)/rx->hz_per_pixel); - filter_right=(double)display_width/2.0+(((double)rx->filter_high+vfo[rx->id].offset)/rx->hz_per_pixel); + filter_left =-cwshift+(double)display_width/2.0+(((double)rx->filter_low+vfo[rx->id].offset)/rx->hz_per_pixel); + filter_right=-cwshift+(double)display_width/2.0+(((double)rx->filter_high+vfo[rx->id].offset)/rx->hz_per_pixel); cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height); cairo_fill(cr); +/* + do not draw the "yellow line". Instead, shift the spectrum + such that the rx frequency offset is compensated + if(vfo[rx->id].mode==modeCWU || vfo[rx->id].mode==modeCWL) { if(active) { cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); @@ -187,6 +244,7 @@ void rx_panadapter_update(RECEIVER *rx) { cairo_line_to(cr,cw_frequency,(double)display_height); cairo_stroke(cr); } +*/ // plot the levels if(active) { @@ -351,18 +409,18 @@ void rx_panadapter_update(RECEIVER *rx) { // signal double s1,s2; - samples[0]=-200.0; - samples[display_width-1]=-200.0; - s1=(double)samples[0]+(double)adc_attenuation[rx->adc]; + samples[begin+icwshift]=-200.0; + samples[end-1+icwshift]=-200.0; + s1=(double)samples[begin+icwshift]+(double)adc_attenuation[rx->adc]; if (filter_board == ALEX && rx->adc == 0) s1 += (double)(10*rx->alex_attenuation); s1 = floor((rx->panadapter_high - s1) * (double) display_height / (rx->panadapter_high - rx->panadapter_low)); - cairo_move_to(cr, 0.0, s1); - for(i=1;iadc]; + cairo_move_to(cr, (double) begin, s1); + for(i=begin+1;iadc]; if (filter_board == ALEX && rx->adc == 0) s2 += (double)(10*rx->alex_attenuation); s2 = floor((rx->panadapter_high - s2) * (double) display_height -- 2.45.2