def ChangeFrequency(self, tx_freq, vfo_freq, source='', band='', event=None): if tx_freq and tx_freq > 0: self.tx_frequency = tx_freq tx = int(tx_freq - self.transverter_offset) self.pc2hermes[ 4] = tx >> 24 & 0xff # C0 index == 1, C1, C2, C3, C4: Tx freq, MSB in C1 self.pc2hermes[5] = tx >> 16 & 0xff self.pc2hermes[6] = tx >> 8 & 0xff self.pc2hermes[7] = tx & 0xff if self.vfo_frequency != vfo_freq: self.vfo_frequency = vfo_freq vfo = int(vfo_freq - self.transverter_offset) self.pc2hermes[ 8] = vfo >> 24 & 0xff # C0 index == 2, C1, C2, C3, C4: Rx freq, MSB in C1 self.pc2hermes[9] = vfo >> 16 & 0xff self.pc2hermes[10] = vfo >> 8 & 0xff self.pc2hermes[11] = vfo & 0xff if DEBUG > 1: print("Change freq Tx", tx_freq, "Rx", vfo_freq) QS.pc_to_hermes(self.pc2hermes) return tx_freq, vfo_freq
def SetControlByte(self, C0_index, byte_index, value): # Set the control byte as above. self.pc2hermes[C0_index * 4 + byte_index - 1] = value QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("SetControlByte C0_index %d byte_index %d to 0x%X" % (C0_index, byte_index, value))
def MultiRxCount( self, count ): # count == number of additional receivers besides the Tx/Rx receiver: 1, 2, 3 # C0 index == 0, C4[5:3]: number of receivers 0b000 -> one receiver; C4[2] duplex on self.pc2hermes[3] = 0x04 | count << 3 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change MultiRx count to", count)
def ChangeAGC(self, value): if value: self.pc2hermes[2] |= 0x10 # C0 index == 0, C3[4]: AGC enable else: self.pc2hermes[2] &= ~0x10 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change AGC to", value)
def DisableSyncFreq(self, value): # Thanks to Steve, KF7O if value: self.pc2hermes[4 * 0 + 2] |= 0x10 # C0 index == 0, C3 else: self.pc2hermes[4 * 0 + 2] &= ~0x10 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change SyncFreq 0x%X" % (self.pc2hermes[4*0 + 2]))
def SetLowPwrEnable(self, enable): if enable: self.pc2hermes[4 * 9 + 1] |= 0x04 # C0 index == 9, C2 else: self.pc2hermes[4 * 9 + 1] &= ~0x04 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change LpPwrEnable 0x%X" % (self.pc2hermes[4*9 + 1]))
def EnablePowerAmp(self, enable): if enable: self.pc2hermes[4 * 9 + 1] |= 0x08 # C0 index == 9, C2 else: self.pc2hermes[4 * 9 + 1] &= ~0x08 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change PwrAmp 0x%X" % (self.pc2hermes[4*9 + 1]))
def ChangeAGC(self, value): if value: self.pc2hermes[2] |= 0x10 # C0 index == 0, C3[4]: AGC enable else: self.pc2hermes[2] &= ~0x10 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change AGC to", value)
def ChangeDither(self, value): if value: self.pc2hermes[2] |= 0x08 else: self.pc2hermes[2] &= ~0x08 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change Dither to", value)
def MultiRxFrequency(self, index, vfo): # index of multi rx receiver: 0, 1, 2, ... if DEBUG: print("Change MultiRx %d frequency to %d" % (index, vfo)) index = index * 4 + 12 # index does not include first Tx/Rx receiver in C0 index == 1, 2 self.pc2hermes[index ] = vfo >> 24 & 0xff self.pc2hermes[index + 1] = vfo >> 16 & 0xff # C1, C2, C3, C4: Rx freq, MSB in C1 self.pc2hermes[index + 2] = vfo >> 8 & 0xff self.pc2hermes[index + 3] = vfo & 0xff QS.pc_to_hermes(self.pc2hermes)
def SetVNA(self, key_down=None, vna_start=None, vna_stop=None, vna_count=None, do_tx=False): if vna_count is not None: # must be called first self.vna_count = vna_count if not self.vna_started: self.pc2hermes[4 * 9] = 63 # C0 index == 0x1001, C1[7:0] Tx level self.ChangeLNA(2) # Preamp and Rx gain if vna_start is None: start = 0 stop = 0 else: # Set the start and stop frequencies and the frequency change for each point # vna_start and vna_stop must be specified together self.pc2hermes[ 4] = vna_start >> 24 & 0xff # C0 index == 1, C1, C2, C3, C4: Tx freq, MSB in C1 self.pc2hermes[ 5] = vna_start >> 16 & 0xff # used for vna starting frequency self.pc2hermes[6] = vna_start >> 8 & 0xff self.pc2hermes[7] = vna_start & 0xff N = self.vna_count - 1 ph_start = self.Freq2Phase(vna_start) # Calculate using phases ph_stop = self.Freq2Phase(vna_stop) delta = (ph_stop - ph_start + N // 2) // N delta = int(float(delta) * self.conf.rx_udp_clock / 2.0**32 + 0.5) self.pc2hermes[ 8] = delta >> 24 & 0xff # C0 index == 2, C1, C2, C3, C4: Rx freq, MSB in C1 self.pc2hermes[ 9] = delta >> 16 & 0xff # used for the frequency to add for each point self.pc2hermes[10] = delta >> 8 & 0xff self.pc2hermes[11] = delta & 0xff self.pc2hermes[4 * 9 + 2] = ( self.vna_count >> 8) & 0xff # C0 index == 0x1001, C3 self.pc2hermes[4 * 9 + 3] = self.vna_count & 0xff # C0 index == 0x1001, C4 QS.pc_to_hermes(self.pc2hermes) start = self.ReturnVfoFloat(vna_start) phase = ph_start + self.Freq2Phase(delta) * N stop = float(phase) * self.conf.rx_udp_clock / 2.0**32 start = int(start + 0.5) stop = int(stop + 0.5) if DEBUG: print("Change VNA start", vna_start, start, "stop", vna_stop, stop) if key_down is None: pass elif key_down: if not self.vna_started: self.vna_started = True self.SetControlByte(9, 2, 0x80) # turn on VNA mode QS.set_PTT(1) else: QS.set_PTT(0) return start, stop # Return actual frequencies after all phase rounding
def ChangeLNA(self, value): # value is -12 to +48 if value < 20: self.pc2hermes[2] |= 0x08 # C0 index == 0, C3[3]: LNA +32 dB disable == 1 value = 19 - value else: self.pc2hermes[2] &= ~0x08 # C0 index == 0, C3[3]: LNA +32 dB enable == 0 value = 51 - value self.pc2hermes[4 * 10 + 3] = value # C0 index == 0x1010, C4[4:0] LNA 0-32 dB gain QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change LNA to", value)
def SetControlBit(self, C0_index, bit, bit_value): # Set the control bit at C0 index and bit number 0 through 31 to value (0 or 1). byte_index = 4 - bit // 8 byte_value = self.pc2hermes[C0_index * 4 + byte_index - 1] mask = 0x01 << (bit % 8) if bit_value: # set bit to one byte_value |= mask else: # set bit to zero byte_value &= ~mask self.pc2hermes[C0_index * 4 + byte_index - 1] = byte_value QS.pc_to_hermes(self.pc2hermes)
def ChangeLNA(self, value): # LNA for Rx # value is -12 to +48 if self.hermes_code_version < 40: # Is this correct ?? if value < 20: self.pc2hermes[2] |= 0x08 # C0 index == 0, C3[3]: LNA +32 dB disable == 1 value = 19 - value else: self.pc2hermes[2] &= ~0x08 # C0 index == 0, C3[3]: LNA +32 dB enable == 0 value = 51 - value else: value = ((value+12) & 0x3f) | 0x40 self.pc2hermes[4 * 10 + 3] = value # C0 index == 0x1010, C4[4:0] LNA 0-32 dB gain QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change LNA to", value)
def EnableBiasChange(self, enable): # Bias settings are in location 12, 13, 14, 15, and are not sent unless C1 == 0x06 if enable: for base in (12, 13, 14, 15): self.pc2hermes[4 * base] = 0x06 # C1 self.pc2hermes[4 * base + 1] = 0xA8 # C2 self.pc2hermes[4 * 12 + 2] = 0x00 # C3 bias 1, volitile self.pc2hermes[4 * 13 + 2] = 0x20 # C3 bias 1, non-volitile self.pc2hermes[4 * 14 + 2] = 0x10 # C3 bias 2, volitile self.pc2hermes[4 * 15 + 2] = 0x30 # C3 bias 2, non-volitile else: for base in (12, 13, 14, 15): self.pc2hermes[4 * base] = 0x00 # C1 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Enable bias change", enable)
def SetTxLevel(self): try: tx_level = self.conf.tx_level[self.band] except KeyError: tx_level = self.conf.tx_level.get(None, 127) # The default if self.mode[0:3] in ('DGT', 'FDV'): # Digital modes; change power by a percentage reduc = self.application.digital_tx_level else: reduc = self.application.tx_level tx_level = int(tx_level *reduc/100.0) if tx_level < 0: tx_level = 0 elif tx_level > 255: tx_level = 255 self.pc2hermes[4 * 9] = tx_level # C0 index == 0x1001, C1[7:0] Tx level QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change tx_level to", tx_level)
def __init__(self, app, conf): BaseHardware.__init__(self, app, conf) self.var_index = 0 self.hermes_ip = "" self.hermes_board_id = -1 self.mode = None self.band = None self.vfo_frequency = 0 self.tx_frequency = 0 self.vna_count = 0 self.vna_started = False self.repeater_freq = None # original repeater output frequency try: self.repeater_delay = conf.repeater_delay # delay for changing repeater frequency in seconds except: self.repeater_delay = 0.25 self.repeater_time0 = 0 # time of repeater change in frequency # Create the proper broadcast address for rx_udp_ip. if False and self.conf.rx_udp_ip: nm = self.conf.rx_udp_ip_netmask.split('.') ip = self.conf.rx_udp_ip.split('.') nm = map(int, nm) ip = map(int, ip) bc = '' for i in range(4): x = (ip[i] | ~nm[i]) & 0xFF bc = bc + str(x) + '.' self.broadcast_addr = bc[:-1] else: self.broadcast_addr = '255.255.255.255' # This socket is used for the Metis Discover protocol self.discover_request = chr(0xEF) + chr(0xFE) + chr(0x02) + chr(0) * 60 self.socket_discover = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socket_discover.setblocking(0) self.socket_discover.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # This is the control data to send to the Hermes using the Metis protocol # Duplex must be on or else the first Rx frequency is locked to the Tx frequency self.pc2hermes = bytearray( 17 * 4 ) # Control bytes not including C0. Python initializes this to zero. self.pc2hermes[ 3] = 0x04 # C0 index == 0, C4[5:3]: number of receivers 0b000 -> one receiver; C4[2] duplex on for c0 in range(1, 9): # Set all frequencies to 7012352, 0x006B0000 self.SetControlByte(c0, 2, 0x6B) QS.pc_to_hermes(self.pc2hermes)
def ChangeFrequency(self, tx_freq, vfo_freq, source='', band='', event=None): if tx_freq and tx_freq > 0: self.tx_frequency = tx_freq tx = int(tx_freq - self.transverter_offset) self.pc2hermes[ 4] = tx >> 24 & 0xff # C0 index == 1, C1, C2, C3, C4: Tx freq, MSB in C1 self.pc2hermes[ 5] = tx >> 16 & 0xff self.pc2hermes[ 6] = tx >> 8 & 0xff self.pc2hermes[ 7] = tx & 0xff if self.vfo_frequency != vfo_freq: self.vfo_frequency = vfo_freq vfo = int(vfo_freq - self.transverter_offset) self.pc2hermes[ 8] = vfo >> 24 & 0xff # C0 index == 2, C1, C2, C3, C4: Rx freq, MSB in C1 self.pc2hermes[ 9] = vfo >> 16 & 0xff self.pc2hermes[10] = vfo >> 8 & 0xff self.pc2hermes[11] = vfo & 0xff if DEBUG > 1: print("Change freq Tx", tx_freq, "Rx", vfo_freq) QS.pc_to_hermes(self.pc2hermes) return tx_freq, vfo_freq
def SetTxLevel(self): try: tx_level = self.conf.tx_level[self.band] except KeyError: tx_level = self.conf.tx_level.get(None, 127) # The default if self.mode[0:3] in ('DGT', 'FDV'): # Digital modes; change power by a percentage reduc = self.application.digital_tx_level else: reduc = self.application.tx_level level = 1.0 + tx_level * 0.0326 level *= math.sqrt(reduc / 100.0) # Convert from a power to an amplitude tx_level = int((level - 1.0) / 0.0326 + 0.5) if tx_level < 0: tx_level = 0 elif tx_level > 255: tx_level = 255 self.pc2hermes[4 * 9] = tx_level # C0 index == 0x1001, C1[7:0] Tx level QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change tx_level to", tx_level)
def VarDecimSet(self, index=None): # set decimation, return sample rate if index is None: # initial call to set rate before the call to open() rate = self.application.vardecim_set # May be None or from different hardware else: rate = int(self.var_rates[index]) * 1000 if rate == 48000: self.var_index = 0 elif rate == 96000: self.var_index = 1 elif rate == 192000: self.var_index = 2 elif rate == 384000: self.var_index = 3 else: self.var_index = 0 rate = 48000 self.pc2hermes[0] = self.var_index # C0 index == 0, C1[1:0]: rate QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change sample rate to", rate) return rate
def VarDecimSet(self, index=None): # set decimation, return sample rate if index is None: # initial call to set rate before the call to open() rate = self.application.vardecim_set # May be None or from different hardware else: rate = int(self.var_rates[index]) * 1000 if rate == 48000: self.var_index = 0 elif rate == 96000: self.var_index = 1 elif rate == 192000: self.var_index = 2 elif rate == 384000: self.var_index = 3 else: self.var_index = 0 rate = 48000 self.pc2hermes[0] = self.var_index # C0 index == 0, C1[1:0]: rate QS.pc_to_hermes(self.pc2hermes) if DEBUG: print ("Change sample rate to", rate) return rate
def __init__(self, app, conf): BaseHardware.__init__(self, app, conf) self.var_index = 0 self.hermes_ip = "" self.hermes_board_id = -1 self.mode = None self.band = None self.vfo_frequency = 0 self.tx_frequency = 0 self.repeater_freq = None # original repeater output frequency try: self.repeater_delay = conf.repeater_delay # delay for changing repeater frequency in seconds except: self.repeater_delay = 0.25 self.repeater_time0 = 0 # time of repeater change in frequency # Create the proper broadcast address for rx_udp_ip. if False and self.conf.rx_udp_ip: nm = self.conf.rx_udp_ip_netmask.split('.') ip = self.conf.rx_udp_ip.split('.') nm = map(int, nm) ip = map(int, ip) bc = '' for i in range(4): x = (ip[i] | ~ nm[i]) & 0xFF bc = bc + str(x) + '.' self.broadcast_addr = bc[:-1] else: self.broadcast_addr = '255.255.255.255' # This socket is used for the Metis Discover protocol self.discover_request = chr(0xEF) + chr(0xFE) + chr(0x02) + chr(0) * 60 self.socket_discover = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socket_discover.setblocking(0) self.socket_discover.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # This is the control data to send to the Hermes using the Metis protocol self.pc2hermes = bytearray(17 * 4) # Python initializes this to zero self.pc2hermes[3] = 0x04 # C0 index == 0, C4[5:3]: number of receivers 0b000 -> one receiver; C4[2] duplex on QS.pc_to_hermes(self.pc2hermes)
def SetControlByte(self, C0_index, byte_index, value): # Set the control byte. self.pc2hermes[C0_index * 4 + byte_index - 1] = value QS.pc_to_hermes(self.pc2hermes)
def ChangeTxLNA(self, value): # LNA for Tx # value is -12 to +48 value = ((value + 12) & 0x3f) | 0x40 | 0x80 self.SetControlByte(0x0e, 3, value, False) # C0 index == 0x0e, C3 QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change Tx LNA to", value)
def ChangeAlexAtt(self, value): self.pc2hermes[2] = (self.pc2hermes[2] & ~0x03) | value QS.pc_to_hermes(self.pc2hermes) if DEBUG: print("Change Dither to", value)