189 lines
6.6 KiB
Python
189 lines
6.6 KiB
Python
# This file is part of the Multus project. See https://www.multus-sdr.com/.
|
|
# It controls what items appear on the Hardware configuration screen and
|
|
# provides logic for each radio.
|
|
|
|
|
|
################ Receivers Multus CW, A transceiver from the Multus project.
|
|
## hardware_file_name Hardware file path, rfile
|
|
# This is the file that contains the control logic for each radio.
|
|
#hardware_file_name = "multuspkg/quisk_hardware.py"
|
|
|
|
## widgets_file_name Widget file path, rfile
|
|
# This optional file adds additional controls for the radio.
|
|
#widgets_file_name = ""
|
|
|
|
## rx_max_amplitude_correct Max ampl correct, number
|
|
# If you get your I/Q samples from a sound card, you will need to correct the
|
|
# amplitude and phase for inaccuracies in the analog hardware. The correction is
|
|
# entered using the controls from the "Rx Phase" button on the config screen.
|
|
# You must enter a positive number. This controls the range of the control.
|
|
#rx_max_amplitude_correct = 0.2
|
|
|
|
## rx_max_phase_correct Max phase correct, number
|
|
# If you get your I/Q samples from a sound card, you will need to correct the
|
|
# amplitude and phase for inaccuracies in the analog hardware. The correction is
|
|
# entered using the controls from the "Rx Phase" button on the config screen.
|
|
# You must enter a positive number. This controls the range of the control in degrees.
|
|
#rx_max_phase_correct = 10.0
|
|
|
|
## tx_level Tx Level, dict
|
|
# This is the level of the Tx audio sent to SoftRock hardware after all processing as a percentage
|
|
# number from 0 to 100.
|
|
# The level should be below 100 to allow headroom for amplitude and phase adjustments.
|
|
# Changes are immediate (no need to restart).
|
|
#tx_level = {}
|
|
|
|
## digital_tx_level Digital Tx power %, integer
|
|
# Digital modes reduce power by the percentage on the config screen.
|
|
# This is the maximum value of the slider.
|
|
#digital_tx_level = 100
|
|
|
|
## keyer_speed Keyer speed WPM, integer
|
|
# This sets the keyer speed in words per minute.
|
|
#keyer_speed = 8
|
|
#keyer_speed = 13
|
|
#keyer_speed = 18
|
|
#keyer_speed = 20
|
|
#keyer_speed = 30
|
|
#keyer_speed = 40
|
|
|
|
## keyer_type Type of keyer, text choice
|
|
# Use "Straight" mode for a straight key or a bug. Connect the tip of the key to the transceiver.
|
|
# Otherwise, select Iambic-A or Iambic-B mode of operation.
|
|
#keyer_type = "Straight"
|
|
#keyer_type = "Iambic-A"
|
|
#keyer_type = "Iambic-B"
|
|
|
|
## keyer_space Keyer space, text choice
|
|
# This sets the type of spacing between elements or letters.
|
|
# "Element" attempts to provide proper spacing between the elements of a character.
|
|
# (The keyer always provides proper spacing between elements).
|
|
# "Letter" turns on letter spacing. This attempts to provide proper spacing between characters.
|
|
#keyer_space = "Element"
|
|
#keyer_space = "Letter"
|
|
|
|
## keyer_weight Keyer weight, integer choice
|
|
# A weight of 50% means that the dit time equals the inter-element time, which is standard.
|
|
# Reducing the weight increases the inter-element time, increasing the weight reduces it.
|
|
#keyer_weight = 50
|
|
#keyer_weight = 25
|
|
#keyer_weight = 75
|
|
|
|
## keyer_paddle Keyer paddle, text choice
|
|
# "Normal" means the left paddle is DIT. "Reverse" means the left paddle is DAH.
|
|
#keyer_paddle = "Normal"
|
|
#keyer_paddle = "Reverse"
|
|
|
|
import configure
|
|
import softrock
|
|
from softrock.hardware_usb import Hardware as BaseHardware
|
|
from softrock.hardware_usb import IN, OUT, UBYTE2, UBYTE4
|
|
import _quisk as QS
|
|
|
|
DEBUG = 0
|
|
|
|
class Hardware(BaseHardware):
|
|
def __init__(self, app, conf):
|
|
# Set constant parameters here:
|
|
conf.usb_vendor_id = 0x16c0
|
|
conf.usb_product_id = 0x05dc
|
|
conf.si570_i2c_address = 0x55
|
|
conf.si570_direct_control = False
|
|
conf.si570_xtal_freq = 114285000
|
|
conf.repeater_delay = 0.25
|
|
BaseHardware.__init__(self, app, conf)
|
|
QS.set_sparams(multus_cw_samples=1)
|
|
self.use_softrock = True
|
|
if DEBUG:
|
|
print ("The name of this radio is", configure.Settings[1])
|
|
print ("The hardware file type is", conf.hardware_file_type)
|
|
def TransferOut(self, address, message): # message is a bytes array or an integer 0 to 255
|
|
if isinstance(message, int):
|
|
message = message.to_bytes(1, 'big')
|
|
if self.usb_dev:
|
|
self.usb_dev.ctrl_transfer(OUT, address, self.si570_i2c_address + 0x700, 0, message)
|
|
if DEBUG:
|
|
print ("USB send to 0x%X" % address, message)
|
|
def open(self):
|
|
text = BaseHardware.open(self)
|
|
self.InitKeyer()
|
|
return text
|
|
def ChangeMode(self, mode):
|
|
ret = BaseHardware.ChangeMode(self, mode)
|
|
if mode in ("CWL", "CWU"):
|
|
cw_mode = b'C' # Adding "b" does not affect the value sent
|
|
if DEBUG:
|
|
print ("Mode is CW")
|
|
else:
|
|
cw_mode = b'U'
|
|
if DEBUG:
|
|
print ("Mode is not CW")
|
|
self.TransferOut(0x70, cw_mode)
|
|
return ret
|
|
def PollCwKey(self): # Called frequently by Quisk to check the CW key status
|
|
return # Quisk is always in Rx
|
|
def InitKeyer(self):
|
|
# Initialize the keyer parameters
|
|
conf = self.conf
|
|
if not hasattr(conf, "keyer_speed"):
|
|
conf.keyer_speed = 18
|
|
if not hasattr(conf, "keyer_type"):
|
|
conf.keyer_type = "Straight"
|
|
if not hasattr(conf, "keyer_space"):
|
|
conf.keyer_space = "Element"
|
|
if not hasattr(conf, "keyer_weight"):
|
|
conf.keyer_weight = 50
|
|
if not hasattr(conf, "keyer_paddle"):
|
|
conf.keyer_paddle = "Normal"
|
|
# We need to initialize in case the persistent hardware values differ from the Quisk values.
|
|
for name in ("keyer_speed", "keyer_type", "keyer_space", "keyer_weight", "keyer_paddle", "cwTone"):
|
|
self.ImmediateChange(name)
|
|
def ImmediateChange(self, name):
|
|
BaseHardware.ImmediateChange(self, name)
|
|
value = getattr(self.conf, name)
|
|
if DEBUG:
|
|
print ("ImmediateChange", name, value)
|
|
if name == "keyer_speed":
|
|
self.TransferOut(0x7B, value)
|
|
elif name == "keyer_type":
|
|
if value == "Straight":
|
|
mode = 0
|
|
elif value == "Iambic-A":
|
|
mode = 1
|
|
elif value == "Iambic-B":
|
|
mode = 2
|
|
else:
|
|
mode = 0
|
|
self.TransferOut(0x71, mode)
|
|
elif name == "keyer_space":
|
|
if value == "Element":
|
|
spacing = 0
|
|
elif value == "Letter":
|
|
spacing = 1
|
|
else:
|
|
spacing = 0
|
|
self.TransferOut(0x75, spacing)
|
|
elif name == "keyer_weight":
|
|
weight = int(value)
|
|
self.TransferOut(0x77, weight)
|
|
elif name == "keyer_paddle":
|
|
if value == "Normal":
|
|
paddle = 0
|
|
elif value == "Reverse":
|
|
paddle = 1
|
|
else:
|
|
paddle = 0
|
|
self.TransferOut(0x73, paddle)
|
|
elif name == "cwTone":
|
|
if value < 500:
|
|
tone_index = 0 # 400 Hz
|
|
elif 500 <= value < 700:
|
|
tone_index = 1 # 600 Hz
|
|
elif 700 <= value < 900:
|
|
tone_index = 2 # 800 Hz
|
|
else:
|
|
tone_index = 3 # 1000 Hz
|
|
self.TransferOut(0x7F, tone_index)
|
|
|
|
|