From 7495ea66d2efa2c9f42224cea01c5f2f45a9f555 Mon Sep 17 00:00:00 2001 From: c vw Date: Thu, 5 Nov 2020 14:46:38 +0100 Subject: [PATCH] Better "drive level adjustment" for HermesLite2 --- old_protocol.c | 16 ++++++++++++++++ transmitter.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/old_protocol.c b/old_protocol.c index c66d500..4c9345d 100644 --- a/old_protocol.c +++ b/old_protocol.c @@ -1683,6 +1683,22 @@ static int last_power=0; } else { power=transmitter->drive_level; } + if (device == DEVICE_HERMES_LITE2) { + // + // from the "intended" drive level power, calculate the + // next lower TX attenuation which can be from 0.0 to -7.5 dB + // in 0.5 dB steps, encode the step in a four-bit word and shift + // it to the upper 4 bits. + // we always use the att level that produces a little bit *less* attenuation + // than required, and down-scale the IQ samples in transmitter.c + // + if (power > 0) { + int hl2power = 15+(int)lround(ceil(40.0 * log10((double) power / 255.0))); + if (hl2power < 0) hl2power=0; + // hl2power=0: -7.5 dB, hl2power=1: -7.0 dB, ..., hl2power=15: 0dB + power=hl2power << 4; // shift to upper bits + } + } } //if(last_power!=power) { diff --git a/transmitter.c b/transmitter.c index 9cba43c..6054862 100644 --- a/transmitter.c +++ b/transmitter.c @@ -1089,6 +1089,36 @@ static void full_tx_buffer(TRANSMITTER *tx) { gain=gain*(double)transmitter->drive_level*0.00392; } } + if (protocol == ORIGINAL_PROTOCOL && radio->device == DEVICE_HERMES_LITE2) { + // + // The HermesLite2 is built around the AD9866 modem chip. The TX level can + // be adjusted from 0.0 to -7.5 dB in 0.5 db steps, and these settings are + // encoded in the top 4 bits of the HPSDR "drive level". + // + // In old_protocol.c, the TX attenuator is set according to the drive level, + // here we only apply a (mostly small) additional damping of the IQ samples + // to achieve a smooth drive level adjustment. + // However, if the drive level requires an attenuation *much* larger than + // 7.5 dB we have to damp significantly at this place, which may affect IMD. + // + int power; + double f,g; + if(tune && !transmitter->tune_use_drive) { + f=sqrt((double)transmitter->tune_percent * 0.01); + power=(int)((double)transmitter->drive_level*f); + } else { + power=transmitter->drive_level; + } + g=-15.0; + if (power > 0) { + f = 40.0 * log10((double) power / 255.0); // 2* attenuation in dB + g= ceil(f); // 2* attenuation rounded to half-dB steps + if (g < -15.0) g=-15.0; // nominal TX attenuation + gain=gain*pow(10.0,0.05*(f-g)); + } else { + gain=0.0; + } + } if (txflag == 0 && protocol == NEW_PROTOCOL) { // -- 2.45.2