def __init__(self, irises, settings, parent=None): QDockWidget.__init__(self, "Control panel", parent) self.setObjectName("TopLevelControlPanel") self._irises = irises self._settings = settings widget = QWidget(self) self.setWidget(widget) layout = QHBoxLayout(widget) form = QFormLayout() layout.addLayout(form) freq = self._settings.value('TopLevelControlPanel/tddFrequency', 3.6e9, float) self._handleTddFreqChange(freq) tddFrequencyEntry = FreqEntryWidget(widget) tddFrequencyEntry.setValue(freq) tddFrequencyEntry.valueChanged.connect(self._handleTddFreqChange) form.addRow("TDD Frequency", tddFrequencyEntry) for dirName, direction in (("Tx controls", SOAPY_SDR_TX), ("Rx controls", SOAPY_SDR_RX)): groupBox = QGroupBox(dirName, widget) hbox = QHBoxLayout(groupBox) layout.addWidget(groupBox) for i, gainName in enumerate(irises[0].listGains(direction, 0)): if i % 2 == 0: form = QFormLayout() hbox.addLayout(form) value = self._settings.value( 'TopLevelControlPanel/%sGain%s' % ('Rx' if direction == SOAPY_SDR_RX else 'Tx', gainName), 0.0, float) self._handleGainChange(direction, gainName, value) edit = QDoubleSpinBox(widget) form.addRow(gainName, edit) r = irises[0].getGainRange(direction, 0, gainName) edit.setRange(r.minimum(), r.maximum()) if r.step() != 0: edit.setSingleStep(r.step()) edit.setSuffix(' dB') edit.setValue(value) edit.valueChanged.connect( functools.partial(self._handleGainChange, direction, gainName))
def __init__(self, iris, chans, parent=None): QWidget.__init__(self, parent) layout = QGridLayout(self) self._editWidgets = list() self._iris = iris self._txReplayWaveform = "" #global configuration parameters groupBox = QGroupBox("Global", self) layout.addWidget(groupBox, 0, 0, 2, 1) formLayout = QFormLayout(groupBox) for name, widgetType, setter, getter in ( ("Rx Frequency", FreqEntryWidget, lambda f: [iris.setFrequency(SOAPY_SDR_RX, ch, "RF", f) for ch in [0, 1]], functools.partial(iris.getFrequency, SOAPY_SDR_RX, 0, "RF")), ("Tx Frequency", FreqEntryWidget, lambda f: [iris.setFrequency(SOAPY_SDR_TX, ch, "RF", f) for ch in [0, 1]], functools.partial(iris.getFrequency, SOAPY_SDR_TX, 0, "RF")), ("Sample Rate", FreqEntryWidget, lambda r: [ iris.setSampleRate(d, 0, r) for d in (SOAPY_SDR_RX, SOAPY_SDR_TX) ], functools.partial(iris.getSampleRate, SOAPY_SDR_RX, 0)), ): edit = FreqEntryWidget(groupBox) formLayout.addRow(name, edit) self.loadEditWidget(edit, setter, getter, [name]) self.loadArbitrarySettings(groupBox, formLayout) info = SoapySDR.ArgInfo() info.type = info.STRING info.options.push_back("") info.options.push_back("LTS") info.optionNames.push_back("Off") info.optionNames.push_back("LTS") edit = ArbitrarySettingsWidget(info, self) formLayout.addRow("TX Replay Waveform", edit) self.loadEditWidget(edit, self.setupTxReplay, lambda: self._txReplayWaveform, ['Tx Waveform']) loadConfigButton = QPushButton("Load Config", groupBox) formLayout.addRow(loadConfigButton) loadConfigButton.pressed.connect(self._handleLoadDialog) saveConfigButton = QPushButton("Save Config", groupBox) formLayout.addRow(saveConfigButton) saveConfigButton.pressed.connect(self._handleSaveDialog) #per channel configuration parameters for ch in chans: for direction in (SOAPY_SDR_RX, SOAPY_SDR_TX): groupBox = QGroupBox( ("Rx" if direction == SOAPY_SDR_RX else "Tx") + " Ch" + "AB"[ch], self) layout.addWidget(groupBox, 0 if direction == SOAPY_SDR_RX else 1, ch + 1, 1, 1) self.loadChannelSettings(groupBox, direction, ch)
def loadChannelSettings(self, parent, direction, ch): hbox = QHBoxLayout(parent) formLayout = QFormLayout() hbox.addLayout(formLayout) factories = [ ("NCO Frequency", FreqEntryWidget, functools.partial(self._iris.setFrequency, direction, ch, "BB"), functools.partial(self._iris.getFrequency, direction, ch, "BB")), ("Filter BW", FreqEntryWidget, functools.partial(self._iris.setBandwidth, direction, ch), functools.partial(self._iris.getBandwidth, direction, ch)), ] for name, widgetType, setter, getter in factories: edit = FreqEntryWidget(parent) formLayout.addRow(name, edit) self.loadEditWidget(edit, setter, getter, [direction, ch, name]) for name in self._iris.listGains(direction, ch): edit = QDoubleSpinBox(parent) formLayout.addRow(name, edit) self.loadEditWidget( edit, functools.partial(self._iris.setGain, direction, ch, name), functools.partial(self._iris.getGain, direction, ch, name), [direction, ch, name]) r = self._iris.getGainRange(direction, ch, name) edit.setRange(r.minimum(), r.maximum()) if r.step() != 0: edit.setSingleStep(r.step()) edit.setSuffix(' dB') formLayout = QFormLayout() hbox.addLayout(formLayout) edit = StringValueComboBox(options=self._iris.listAntennas( direction, ch), parent=parent) formLayout.addRow("Antenna", edit) self.loadEditWidget( edit, functools.partial(self._iris.setAntenna, direction, ch), functools.partial(self._iris.getAntenna, direction, ch), [direction, ch, 'Antenna']) self.loadArbitrarySettings(parent, formLayout, [direction, ch]) if self._iris.hasDCOffsetMode(direction, ch): info = SoapySDR.ArgInfo() info.type = info.BOOL edit = ArbitrarySettingsWidget(info, self) formLayout.addRow("DC Removal", edit) self.loadEditWidget( edit, lambda v: iris.setDCOffsetMode(direction, ch, v == "true"), lambda: "true" if iris.getDCOffsetMode(direction, ch) else "false", [direction, ch, 'DC Removal']) sklkCalButton = QPushButton("SKLK Calibrate", parent) sklkCalButton.pressed.connect( functools.partial(self._iris.writeSetting, direction, ch, "CALIBRATE", "SKLK")) formLayout.addRow("Self Calibrate", sklkCalButton) mcuCalButton = QPushButton("MCU Calibrate", parent) mcuCalButton.pressed.connect( functools.partial(self._iris.writeSetting, direction, ch, "CALIBRATE", "")) formLayout.addRow("Self Calibrate", mcuCalButton)
def loadChannelSettings(self, parent, direction, ch): hbox = QHBoxLayout(parent) formLayout = QFormLayout() hbox.addLayout(formLayout) factories = [ ("NCO Frequency", FreqEntryWidget, functools.partial(listFuncHelper, [iris.setFrequency for iris in self._writeIrises], direction, ch, "BB"), lambda direction=direction, ch=ch: self._iris.getFrequency(direction, ch, "BB")), #functools.partial(self._iris.getFrequency, direction, ch, "BB")), # use this syntax to make direction and ch to persist, but execute self._iris when called (for switching iris readback): https://stackoverflow.com/questions/11087047/deferred-evaluation-with-lambda-in-python/11087323 ("Filter BW", FreqEntryWidget, functools.partial(listFuncHelper, [iris.setBandwidth for iris in self._writeIrises], direction, ch), lambda direction=direction, ch=ch: self._iris.getBandwidth(direction, ch)), ] for name, widgetType, setter, getter in factories: edit = FreqEntryWidget(parent) formLayout.addRow(name, edit) self.loadEditWidget(edit, setter, getter, [direction, ch, name]) for name in self._iris.listGains(direction, ch): edit = QDoubleSpinBox(parent) formLayout.addRow(name, edit) self.loadEditWidget(edit, functools.partial(listFuncHelper, [iris.setGain for iris in self._writeIrises], direction, ch, name), lambda direction=direction, ch=ch, name=name: self._iris.getGain(direction, ch, name), [direction, ch, name]) r = self._iris.getGainRange(direction, ch, name) edit.setRange(r.minimum(), r.maximum()) if r.step() != 0: edit.setSingleStep(r.step()) edit.setSuffix(' dB') formLayout = QFormLayout() hbox.addLayout(formLayout) edit = StringValueComboBox(options=self._iris.listAntennas(direction, ch), parent=parent) formLayout.addRow("Antenna", edit) self.loadEditWidget(edit, functools.partial(listFuncHelper, [iris.setAntenna for iris in self._writeIrises], direction, ch), lambda direction=direction, ch=ch: self._iris.getAntenna(direction, ch), [direction, ch, 'Antenna']) self.loadArbitrarySettings(parent, formLayout, [direction, ch]) if self._iris.hasDCOffsetMode(direction, ch): info = SoapySDR.ArgInfo() info.type = info.BOOL edit = ArbitrarySettingsWidget(info, self) formLayout.addRow("DC Removal", edit) self.loadEditWidget(edit, lambda v: [iris.setDCOffsetMode(direction, ch, v == "true") for iris in self._writeIrises], #this is a lambda in IrisControlGui, but maybe it's messing things up? lambda: "true" if self._iris.getDCOffsetMode(direction, ch) else "false", [direction, ch, 'DC Removal']) sklkCalButton = QPushButton("SKLK Calibrate", parent) sklkCalButton.pressed.connect(functools.partial(listFuncHelper, [iris.writeSetting for iris in self._writeIrises], direction, ch, "CALIBRATE", "SKLK")) formLayout.addRow("Self Calibrate", sklkCalButton) mcuCalButton = QPushButton("MCU Calibrate", parent) mcuCalButton.pressed.connect(functools.partial(listFuncHelper, [iris.writeSetting for iris in self._writeIrises], direction, ch, "CALIBRATE", "")) formLayout.addRow("Self Calibrate", mcuCalButton)
def __init__(self, irises, chans, setReadIrisCallback, setWriteIrisesCallback, parent = None): QWidget.__init__(self, parent) layout = QGridLayout(self) self._setReadIrisCallback = setReadIrisCallback self._setWriteIrisesCallback = setWriteIrisesCallback self._editWidgets = list() self._iris = irises[0] self._irises = irises self._writeIrises = irises self._txReplayWaveform = "" #global configuration parameters groupBox = QGroupBox("Global", self) layout.addWidget(groupBox, 0, 0, 2, 1) formLayout = QFormLayout(groupBox) for name, widgetType, setter, getter in ( ("Rx Frequency", FreqEntryWidget, lambda f: [[iris.setFrequency(SOAPY_SDR_RX, ch, "RF", f) for ch in [0, 1] for iris in irises]], lambda: self._iris.getFrequency(SOAPY_SDR_RX, 0, "RF")), #functools.partial(self._iris.getFrequency, SOAPY_SDR_RX, 0, "RF")), ("Tx Frequency", FreqEntryWidget, lambda f: [[iris.setFrequency(SOAPY_SDR_TX, ch, "RF", f) for ch in [0, 1] for iris in irises]], lambda: self._iris.getFrequency(SOAPY_SDR_TX, 0, "RF")), ("Sample Rate", FreqEntryWidget, lambda r: [[iris.setSampleRate(d, 0, r) for d in (SOAPY_SDR_RX, SOAPY_SDR_TX) for iris in irises]], lambda: self._iris.getSampleRate(SOAPY_SDR_RX, 0)), ): edit = FreqEntryWidget(groupBox) formLayout.addRow(name, edit) self.loadEditWidget(edit, setter, getter, [name]) self.loadArbitrarySettings(groupBox, formLayout) if len(irises) > 1: irisGroupBox = QGroupBox("Iris Read/Write Select (Experimental!)", self) layout.addWidget(irisGroupBox, 2, 0, 1, 3, Qt.AlignHCenter) irisLayout = QFormLayout(irisGroupBox) irisReadRadioLayout = QHBoxLayout(irisGroupBox) irisLayout.addRow(irisReadRadioLayout) irisReadRadioLayout.addWidget(QLabel("Readback:")) self._irisRadioButtons = [QRadioButton(iris.getHardwareInfo()['serial'], irisGroupBox) for iris in irises] #for i,r in (irises,self._irisRadioButtons): r.iris = i self._irisRadioButtons[0].setChecked(True) for i,r in zip(irises,self._irisRadioButtons): irisReadRadioLayout.addWidget(r) r.toggled.connect(functools.partial(self.setReadIris, i)) irisWriteCheckBoxLayout = QHBoxLayout(irisGroupBox) irisWriteCheckBoxLayout.addWidget(QLabel("Write:")) irisLayout.addRow(irisWriteCheckBoxLayout) self._irisWriteCheckButtons = [QCheckBox(iris.getHardwareInfo()['serial'], irisGroupBox) for iris in irises] for i,r in zip(irises,self._irisWriteCheckButtons): r.iris = i irisWriteCheckBoxLayout.addWidget(r) r.setChecked(True) r.toggled.connect(self.setWriteIrises) info = SoapySDR.ArgInfo() info.type = info.STRING info.options.push_back("") info.options.push_back("LTS") info.optionNames.push_back("Off") info.optionNames.push_back("LTS") edit = ArbitrarySettingsWidget(info, self) formLayout.addRow("TX Replay Waveform", edit) self.loadEditWidget(edit, self.setupTxReplay, lambda: self._txReplayWaveform, ['Tx Waveform']) loadConfigButton = QPushButton("Load Config", groupBox) formLayout.addRow(loadConfigButton) loadConfigButton.pressed.connect(self._handleLoadDialog) saveConfigButton = QPushButton("Save Config", groupBox) formLayout.addRow(saveConfigButton) saveConfigButton.pressed.connect(self._handleSaveDialog) #per channel configuration parameters for ch in chans: for direction in (SOAPY_SDR_RX, SOAPY_SDR_TX): groupBox = QGroupBox(("Rx" if direction == SOAPY_SDR_RX else "Tx") + " Ch"+"AB"[ch], self) layout.addWidget(groupBox, 0 if direction == SOAPY_SDR_RX else 1, ch+1, 1, 1) self.loadChannelSettings(groupBox, direction, ch)