summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authordmlunar <root@lunar.sh>2025-01-22 16:47:21 +0200
committerdmlunar <root@lunar.sh>2025-10-15 23:42:50 +0200
commit729f2a2c3ebfb2612d873caf453a1d7ca02180d9 (patch)
tree7bab2fcc0c7f50eab3013348697bc06ddd71d551 /scripts
downloadvarpa-729f2a2c3ebfb2612d873caf453a1d7ca02180d9.tar.gz
varpa-729f2a2c3ebfb2612d873caf453a1d7ca02180d9.zip
varpa: initial public commit
Diffstat (limited to 'scripts')
-rw-r--r--scripts/README.txt20
-rw-r--r--scripts/cli.py289
-rw-r--r--scripts/cli.tui.json1838
-rw-r--r--scripts/device.py87
-rw-r--r--scripts/launcher.py23
-rw-r--r--scripts/reset.py50
-rw-r--r--scripts/rms.py118
-rw-r--r--scripts/setup.py139
8 files changed, 2564 insertions, 0 deletions
diff --git a/scripts/README.txt b/scripts/README.txt
new file mode 100644
index 0000000..5465119
--- /dev/null
+++ b/scripts/README.txt
@@ -0,0 +1,20 @@
+Dependencies
+------------
+
+pip3 install pyserial
+pip3 install pyTermTk
+
+Usage
+-----
+
+python3 cli.py
+
+Calibration
+-----------
+
+python3 rms.py
+
+Note:
+
+Generation of calibration data for the LTC5582 RMS power
+detector requires a Rigol DSA815 spectrum analyzer.
diff --git a/scripts/cli.py b/scripts/cli.py
new file mode 100644
index 0000000..e401239
--- /dev/null
+++ b/scripts/cli.py
@@ -0,0 +1,289 @@
+# Author: Dylan Muller
+# Copyright (c) 2025
+# All rights reserved.
+#
+# - Commercial/IP use prohibited.
+# - Attribution required.
+# See License.txt
+
+import TermTk as ttk
+import os
+import sys
+import msvcrt
+import ctypes
+import time
+import serial
+import serial.tools.list_ports
+from threading import Thread, Lock
+import signal
+
+from setup import *
+from device import *
+
+GWL_STYLE = -16
+WS_SIZEBOX = 0x00040000
+WS_MAXIMIZEBOX = 0x00010000
+CLI_TITLE = "RFCLI"
+CLI_VER = "1.00.01"
+
+class gate_status:
+ status = ""
+ q_volt = 0
+ q_amp = 0
+ q_time = 0
+ v_set = 0
+ q_drain = 0
+
+class drain_status:
+ status = ""
+ v_adc = 0
+ v_set = 0
+ amp = 0
+
+class system_status:
+ status = ""
+ v_fwd = 0
+ p_fwd = 0
+ p_set = 0
+ t_delta = 0
+
+class global_status:
+ gate = gate_status()
+ drain = drain_status()
+ system = system_status()
+
+status = global_status()
+root = ttk.TTk(title= CLI_TITLE + " " + CLI_VER,
+ sigmask=())
+serial_port = None
+update_thread = None
+lock = Lock()
+
+def cli_inputs_focused():
+ if (cli_LEDrainOverride.hasFocus() or
+ cli_LEGateQDrain.hasFocus() or
+ cli_LESystemPSet.hasFocus() or
+ cli_LESystemSWRLim.hasFocus()):
+ return True
+ return False
+
+def cli_update_thread():
+ global serial_port
+
+ while(True):
+ with lock:
+ if(serial_port.is_open):
+ reply = sys_reply(serial_port)
+ if (SETUP_CMD_BUSY_RESPONSE in reply):
+ serial_port.close()
+ continue
+ if (cli_inputs_focused() == False):
+ rv = cli_update_status(serial_port)
+ if(rv == 0):
+ serial_port.close()
+ if(cli_FSystemStatus.color() != le_green):
+ cli_FSystemStatus.setColor(le_green)
+ else:
+ if(cli_FSystemStatus.color() != le_red):
+ cli_FSystemStatus.setText("USER INPUT")
+ cli_FSystemStatus.setColor(le_red)
+
+ if (cli_BSystemConnect.text() != "Disconnect"):
+ cli_BSystemConnect.setText("Disconnect")
+ else:
+ if (cli_inputs_focused() == False):
+ cli_FSystemStatus.setText("NO-LINK")
+ cli_BSystemConnect.setText("Connect")
+ time.sleep(SETUP_CLI_UPDATE_RATE)
+
+def cli_BSystemConnect_clicked():
+ global serial_port
+ global update_thread
+ with lock:
+ if (serial_port is None or serial_port.is_open == False):
+ target = cli_CBSystemPort.currentText()
+ if (target == SETUP_STR_EMPTY):
+ display_message("No valid COM port")
+ return
+ else:
+ init_uart_link(target)
+ if (serial_port and serial_port.is_open):
+ reply = sys_reply(serial_port)
+ if (SETUP_CMD_BUSY_RESPONSE in reply):
+ display_message("Target is busy")
+ serial_port.close()
+ return
+ elif (SETUP_CMD_REPLY_RESPONSE not in reply):
+ display_message("Target does not respond")
+ serial_port.close()
+ return
+ else:
+ display_message("Failed establishing link")
+ serial_port.close()
+ return
+
+ if (update_thread == None):
+ update_thread = Thread(target=cli_update_thread)
+ update_thread.start()
+ else:
+ serial_port.close()
+
+def cli_update_gate_frame(line, param):
+ global status
+ if (SETUP_REPORT_STATUS in line):
+ status.gate.status = param
+ cli_FGateStatus.setText(param)
+ elif (SETUP_REPORT_Q_VOLT in line):
+ status.gate.q_volt = int(param)
+ cli_FGateQV.setText(param)
+ elif (SETUP_REPORT_Q_AMP in line):
+ status.gate.q_amp = int(param)
+ cli_FGateQA.setText(param)
+ elif (SETUP_REPORT_Q_TIME in line):
+ status.gate.q_time = int(param)
+ cli_FGateQTime.setText(param)
+ elif (SETUP_REPORT_V_SET in line):
+ status.gate.v_set = int(param)
+ cli_FGateVSet.setText(param)
+ elif (SETUP_REPORT_Q_DRAIN in line):
+ status.gate.q_drain = int(param)
+
+def cli_update_drain_frame(line, param):
+ global status
+ if (SETUP_REPORT_STATUS in line):
+ status.drain.status = param
+ cli_FDrainStatus.setText(param)
+ elif (SETUP_REPORT_V_ADC in line):
+ status.drain.v_adc = int(param)
+ cli_FDrainVADC.setText(param)
+ elif (SETUP_REPORT_V_SET in line):
+ status.drain.amp = int(param)
+ cli_FDrainVSet.setText(param)
+
+def cli_update_system_frame(line, param):
+ global status
+ if (SETUP_REPORT_STATUS in line):
+ status.system.status = param
+ cli_FSystemStatus.setText(param)
+ elif (SETUP_REPORT_V_FWD in line):
+ status.system.v_fwd = int(param)
+ cli_FSystemVFwd.setText(param)
+ elif (SETUP_REPORT_P_FWD in line):
+ status.system.p_fwd = int(param)
+ cli_FSystemPFwd.setText(param)
+ elif (SETUP_REPORT_P_SET in line):
+ status.system.p_set = int(param)
+ elif (SETUP_REPORT_T_DELTA in line):
+ status.system.t_delta = int(param)
+ cli_FSystemTSet.setText(param)
+
+def cli_update_status(serial):
+ serial.flush()
+ report = sys_report(serial)
+ if (report == SETUP_STR_EMPTY or
+ SETUP_CMD_BUSY_RESPONSE in report):
+ return 0
+ current_frame = 0
+ fields_updated = 0
+ for line in report:
+ if (SETUP_REPORT_FRAME_GATE in line):
+ current_frame = SETUP_REPORT_FRAME_GATE
+ continue
+ elif (SETUP_REPORT_FRAME_DRAIN in line):
+ current_frame = SETUP_REPORT_FRAME_DRAIN
+ continue
+ elif (SETUP_REPORT_FRAME_SYSTEM in line):
+ current_frame = SETUP_REPORT_FRAME_SYSTEM
+ continue
+ if (current_frame != 0 and serial_port):
+ param = extract_param(line)
+ if (param == False):
+ return 0
+ fields_updated += 1
+ if (current_frame == SETUP_REPORT_FRAME_GATE):
+ cli_update_gate_frame(line, param)
+ elif (current_frame == SETUP_REPORT_FRAME_DRAIN):
+ cli_update_drain_frame(line, param)
+ elif (current_frame == SETUP_REPORT_FRAME_SYSTEM):
+ cli_update_system_frame(line, param)
+ return fields_updated
+
+def signal_handler(sig, frame):
+ display_message("test")
+ exit_terminal()
+
+def extract_param(line):
+ split = line.split(':')
+ if (len(split) != 2):
+ return False
+ return split[1].strip()
+
+def uart_established(serial):
+ if (serial and serial.is_open):
+ return True
+ return False
+
+def init_uart_link(port):
+ global serial_port
+ try:
+ if (serial_port is None):
+ serial_port = serial.Serial(
+ port=port,
+ baudrate=SETUP_SERIAL_BAUD,
+ timeout=SETUP_SERIAL_TIMEOUT)
+ serial_port.open()
+ else:
+ serial_port.open()
+ except serial.SerialException as e:
+ return None
+
+def list_com_ports():
+ com = []
+ ports = list(serial.tools.list_ports.comports())
+ for port in ports:
+ com.append(port.device)
+ return com
+
+def set_win_attributes():
+ hwnd = ctypes.windll.kernel32.GetConsoleWindow()
+ current_style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_STYLE)
+ ctypes.windll.user32.SetWindowLongW(hwnd, GWL_STYLE, current_style &
+ ~WS_SIZEBOX & ~WS_MAXIMIZEBOX)
+
+def cleanup_terminal():
+ os.system('cls')
+ os.system('echo \x1b[?25h')
+
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+ while msvcrt.kbhit():
+ msvcrt.getch()
+ os._exit(0)
+
+def exit_terminal():
+ root.quit()
+ cleanup_terminal()
+
+def display_message(text):
+ messageBox = ttk.TTkMessageBox(text=text)
+ ttk.TTkHelper.overlay(None, messageBox, 25, 10, True)
+
+cli_ctrl_c = ttk.TTkK.CTRL | ttk.TTkK.Key_C
+root.layout().addWidget(main_window)
+ttk.TTkShortcut(cli_ctrl_c).activated.connect(exit_terminal)
+cli_BSystemConnect.clicked.connect(cli_BSystemConnect_clicked)
+cli_CBSystemPort.addItems(list_com_ports())
+
+cli_LEGateQDrain.setInputType(ttk.TTkK.Input_Number)
+cli_LESystemSWRLim.setInputType(ttk.TTkK.Input_Number)
+cli_LEDrainOverride.setInputType(ttk.TTkK.Input_Number)
+cli_LESystemPSet.setInputType(ttk.TTkK.Input_Number)
+
+cli_FSystemStatus.setColor(le_green)
+
+#BSystemExit.clicked.connect(exit_terminal)
+#set_win_attributes()
+root.mainloop()
+
+#currentIndexChanged
diff --git a/scripts/cli.tui.json b/scripts/cli.tui.json
new file mode 100644
index 0000000..73fc2da
--- /dev/null
+++ b/scripts/cli.tui.json
@@ -0,0 +1,1838 @@
+{
+ "type": "TTkUi/Document",
+ "version": "2.0.2",
+ "tui": {
+ "class": "TTkContainer",
+ "params": {
+ "Name": "MainWindow",
+ "Position": [
+ 2,
+ 1
+ ],
+ "Size": [
+ 77,
+ 29
+ ],
+ "Min Width": 0,
+ "Min Height": 0,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "Layout": "TTkLayout"
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 77,
+ 29
+ ]
+ },
+ "children": [
+ {
+ "class": "TTkFrame",
+ "params": {
+ "Name": "FSystem",
+ "Position": [
+ 39,
+ 0
+ ],
+ "Size": [
+ 37,
+ 28
+ ],
+ "Min Width": 0,
+ "Min Height": 0,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "Layout": "TTkLayout",
+ "Border": true,
+ "Title": "\u001b[0;48;2;0;0;255mSYSTEM"
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 35,
+ 26
+ ]
+ },
+ "children": [
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemPort",
+ "Position": [
+ 3,
+ 1
+ ],
+ "Size": [
+ 10,
+ 1
+ ],
+ "Min Width": 4,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "PORT",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemStatus",
+ "Position": [
+ 3,
+ 5
+ ],
+ "Size": [
+ 7,
+ 1
+ ],
+ "Min Width": 6,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "STATUS",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemVFwd",
+ "Position": [
+ 18,
+ 6
+ ],
+ "Size": [
+ 7,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemAtt",
+ "Position": [
+ 18,
+ 12
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemSWRLim",
+ "Position": [
+ 3,
+ 11
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 9,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "SWR LIMIT",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkComboBox",
+ "params": {
+ "Name": "CBSystemPort",
+ "Position": [
+ 17,
+ 1
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 5,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "Layout": "TTkLayout",
+ "Editable": false,
+ "Text Align.": 4,
+ "Insert Policy": 3
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 16,
+ 1
+ ]
+ },
+ "children": []
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLineEdit",
+ "params": {
+ "Name": "LESystemPSet",
+ "Position": [
+ 18,
+ 16
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Input Type": 1,
+ "Echo Mode": 0,
+ "Text": ""
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BSystemConnect",
+ "Position": [
+ 17,
+ 3
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 9,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Connect",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemPStrat",
+ "Position": [
+ 3,
+ 15
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 7,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "P-STRAT",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLineEdit",
+ "params": {
+ "Name": "LESystemSWRLim",
+ "Position": [
+ 18,
+ 11
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Input Type": 1,
+ "Echo Mode": 0,
+ "Text": ""
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemSWR",
+ "Position": [
+ 18,
+ 10
+ ],
+ "Size": [
+ 7,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemPFwd",
+ "Position": [
+ 3,
+ 7
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "P-FW (cdBm)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemPRev",
+ "Position": [
+ 3,
+ 9
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "P-REV (cdBm)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemVFwd",
+ "Position": [
+ 3,
+ 6
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 10,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "V-FW (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemPRev",
+ "Position": [
+ 18,
+ 9
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BSystemDefaults",
+ "Position": [
+ 17,
+ 22
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 10,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Defaults",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BSystemSetPower",
+ "Position": [
+ 17,
+ 18
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 11,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Set Power",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemVRev",
+ "Position": [
+ 18,
+ 8
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BSystemSave",
+ "Position": [
+ 17,
+ 20
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 6,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Save",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemTSet",
+ "Position": [
+ 3,
+ 13
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 10,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "T-SET (ms)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemTSet",
+ "Position": [
+ 18,
+ 13
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkComboBox",
+ "params": {
+ "Name": "CBSystemPStrat",
+ "Position": [
+ 17,
+ 15
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 5,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "Layout": "TTkLayout",
+ "Editable": false,
+ "Text Align.": 4,
+ "Insert Policy": 3
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 16,
+ 1
+ ]
+ },
+ "children": []
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemPSet",
+ "Position": [
+ 3,
+ 16
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "P-SET (cdBm)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemVRev",
+ "Position": [
+ 3,
+ 8
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 10,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "V-REV (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BSystemReboot",
+ "Position": [
+ 17,
+ 24
+ ],
+ "Size": [
+ 16,
+ 1
+ ],
+ "Min Width": 8,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Reboot",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemAtt",
+ "Position": [
+ 3,
+ 12
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "ATTEN (cdBm)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LSystemSWR",
+ "Position": [
+ 3,
+ 10
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 3,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "SWR",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemPFwd",
+ "Position": [
+ 18,
+ 7
+ ],
+ "Size": [
+ 13,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FSystemStatus",
+ "Position": [
+ 18,
+ 5
+ ],
+ "Size": [
+ 15,
+ 1
+ ],
+ "Min Width": 7,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "NO-LINK",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ }
+ ]
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkFrame",
+ "params": {
+ "Name": "FGate",
+ "Position": [
+ 1,
+ 0
+ ],
+ "Size": [
+ 37,
+ 14
+ ],
+ "Min Width": 0,
+ "Min Height": 0,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "Layout": "TTkLayout",
+ "Border": true,
+ "Title": "\u001b[0;48;2;0;0;255mGATE"
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 35,
+ 12
+ ]
+ },
+ "children": [
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateStatus",
+ "Position": [
+ 2,
+ 1
+ ],
+ "Size": [
+ 8,
+ 1
+ ],
+ "Min Width": 6,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "STATUS",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateVSet",
+ "Position": [
+ 2,
+ 5
+ ],
+ "Size": [
+ 18,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "V-SET (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateQTime",
+ "Position": [
+ 2,
+ 4
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Q-TIME (ms)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FGateStatus",
+ "Position": [
+ 21,
+ 1
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 8,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "INACTIVE",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FGateQV",
+ "Position": [
+ 21,
+ 2
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FGateQA",
+ "Position": [
+ 21,
+ 3
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FGateQTime",
+ "Position": [
+ 21,
+ 4
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FGateVSet",
+ "Position": [
+ 21,
+ 5
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkComboBox",
+ "params": {
+ "Name": "CBGateFunc",
+ "Position": [
+ 20,
+ 8
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 5,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "Layout": "TTkLayout",
+ "Editable": false,
+ "Text Align.": 4,
+ "Insert Policy": 3
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 14,
+ 1
+ ]
+ },
+ "children": []
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateQV",
+ "Position": [
+ 2,
+ 2
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Q-VOLT (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateQDrain",
+ "Position": [
+ 2,
+ 7
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Q-DRAIN (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLineEdit",
+ "params": {
+ "Name": "LEGateQDrain",
+ "Position": [
+ 21,
+ 7
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Input Type": 1,
+ "Echo Mode": 0,
+ "Text": ""
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateQA",
+ "Position": [
+ 2,
+ 3
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Q-AMP (mA)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BGateProbe",
+ "Position": [
+ 20,
+ 10
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 7,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Probe",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LGateFunc",
+ "Position": [
+ 2,
+ 8
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 4,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "FUNC",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ }
+ ]
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkFrame",
+ "params": {
+ "Name": "FDrain",
+ "Position": [
+ 1,
+ 14
+ ],
+ "Size": [
+ 37,
+ 14
+ ],
+ "Min Width": 0,
+ "Min Height": 0,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "Layout": "TTkLayout",
+ "Border": true,
+ "Title": "\u001b[0;48;2;0;0;255mDRAIN"
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 35,
+ 12
+ ]
+ },
+ "children": [
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LDrainStatus",
+ "Position": [
+ 2,
+ 1
+ ],
+ "Size": [
+ 9,
+ 1
+ ],
+ "Min Width": 6,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "STATUS",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FDrainStatus",
+ "Position": [
+ 21,
+ 1
+ ],
+ "Size": [
+ 9,
+ 1
+ ],
+ "Min Width": 8,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "INACTIVE",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FDrainVSet",
+ "Position": [
+ 21,
+ 2
+ ],
+ "Size": [
+ 8,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LDrainVADC",
+ "Position": [
+ 2,
+ 7
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "V-ADC (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FDrainVADC",
+ "Position": [
+ 21,
+ 7
+ ],
+ "Size": [
+ 5,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LDrainVSet",
+ "Position": [
+ 2,
+ 2
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "V-SET (mV)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LDrainA",
+ "Position": [
+ 2,
+ 8
+ ],
+ "Size": [
+ 12,
+ 1
+ ],
+ "Min Width": 12,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "AMP (mA)",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "LDrainFunc",
+ "Position": [
+ 2,
+ 9
+ ],
+ "Size": [
+ 8,
+ 1
+ ],
+ "Min Width": 4,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "FUNC",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkComboBox",
+ "params": {
+ "Name": "CBDrainFunc",
+ "Position": [
+ 20,
+ 9
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 5,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Padding": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "Layout": "TTkLayout",
+ "Editable": false,
+ "Text Align.": 4,
+ "Insert Policy": 3
+ },
+ "layout": {
+ "class": "TTkLayout",
+ "params": {
+ "Geometry": [
+ 0,
+ 0,
+ 14,
+ 1
+ ]
+ },
+ "children": []
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLineEdit",
+ "params": {
+ "Name": "LEDrainOverride",
+ "Position": [
+ 21,
+ 3
+ ],
+ "Size": [
+ 11,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Input Type": 1,
+ "Echo Mode": 0,
+ "Text": ""
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkButton",
+ "params": {
+ "Name": "BDrainOverride",
+ "Position": [
+ 20,
+ 5
+ ],
+ "Size": [
+ 14,
+ 1
+ ],
+ "Min Width": 10,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 1,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "Override",
+ "Border": false,
+ "Checkable": false,
+ "Checked": false
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ },
+ {
+ "class": "TTkLabel",
+ "params": {
+ "Name": "FDrainA",
+ "Position": [
+ 21,
+ 8
+ ],
+ "Size": [
+ 6,
+ 1
+ ],
+ "Min Width": 1,
+ "Min Height": 1,
+ "Max Width": 65536,
+ "Max Height": 65536,
+ "Visible": true,
+ "Enabled": true,
+ "ToolTip": "",
+ "Text": "0",
+ "Color": "\u001b[0m",
+ "Alignment": 0
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ }
+ ]
+ },
+ "row": 0,
+ "col": 0,
+ "rowspan": 1,
+ "colspan": 1
+ }
+ ]
+ }
+ },
+ "connections": []
+} \ No newline at end of file
diff --git a/scripts/device.py b/scripts/device.py
new file mode 100644
index 0000000..fc17786
--- /dev/null
+++ b/scripts/device.py
@@ -0,0 +1,87 @@
+# Author: Dylan Muller
+# Copyright (c) 2025
+# All rights reserved.
+#
+# - Commercial/IP use prohibited.
+# - Attribution required.
+# See License.txt
+
+from setup import *
+import time
+
+def serial_send(serial, data):
+ try:
+ if (serial and serial.is_open):
+ serial.write(data.encode('utf-8'))
+ except:
+ return 0
+
+def serial_receive_line(serial):
+ try:
+ if (serial and serial.is_open):
+ serial_data = serial.readline().decode('utf-8').rstrip()
+ else:
+ return ""
+ except:
+ return ""
+ return serial_data
+
+def serial_receive_lines(serial, n):
+ lines = []
+ for i in range(n):
+ line = serial_receive_line(serial)
+ if (line == ""):
+ return line
+ if (SETUP_CMD_BUSY_RESPONSE in line):
+ return SETUP_CMD_BUSY_RESPONSE
+ lines.append(line)
+ return lines
+
+def sys_reset(serial):
+ serial_send(serial, SETUP_CMD_RESET)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_line(serial)
+ return response
+
+def sys_gate_probe(serial):
+ serial_send(serial, SETUP_CMD_PROBE)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_lines(serial, SETUP_CMD_PROBE_N)
+ return response
+
+def sys_drain_set(serial, count):
+ payload = SETUP_CMD_DRAIN_SET + ' ' + str(count) + SETUP_NEWLINE
+ serial_send(serial, payload)
+ time.sleep(SETUP_CMD_TIMEOUT)
+
+def sys_si4468_tx(serial):
+ serial_send(serial, SETUP_CMD_TX)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_line(serial)
+ return response
+
+def sys_si4468_rx(serial):
+ serial_send(serial, SETUP_CMD_RX)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_line(serial)
+ return response
+
+def sys_read_power(serial):
+ serial_send(serial, SETUP_CMD_POWER_GET)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ power_count = serial_receive_line(serial)
+ power_count = power_count.split(" ")[1]
+ power_count = int(power_count)
+ return power_count
+
+def sys_reply(serial):
+ serial_send(serial, SETUP_CMD_REPLY)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_line(serial)
+ return response
+
+def sys_report(serial):
+ serial_send(serial, SETUP_CMD_REPORT)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_lines(serial, SETUP_CMD_REPORT_N)
+ return response
diff --git a/scripts/launcher.py b/scripts/launcher.py
new file mode 100644
index 0000000..fa086a7
--- /dev/null
+++ b/scripts/launcher.py
@@ -0,0 +1,23 @@
+# Author: Dylan Muller
+# Copyright (c) 2025
+# All rights reserved.
+#
+# - Commercial/IP use prohibited.
+# - Attribution required.
+# See License.txt
+
+import subprocess
+import time
+import ctypes
+import os
+from setup import *
+
+def open_fixed_size_cmd(width, height, script_path):
+ command = f"mode con: cols={width} lines={height} && python.exe {script_path}"
+ subprocess.Popen(["cmd.exe", "/K", command], creationflags=subprocess.CREATE_NEW_CONSOLE)
+
+script_path = os.path.abspath(SETUP_STUB_NAME)
+print(SETUP_LAUNCHER_NAME + " " + SETUP_LAUNCHER_VER)
+open_fixed_size_cmd(width=SETUP_CONSOLE_COL,
+ height=SETUP_CONSOLE_ROW,
+ script_path=script_path)
diff --git a/scripts/reset.py b/scripts/reset.py
new file mode 100644
index 0000000..8c07a66
--- /dev/null
+++ b/scripts/reset.py
@@ -0,0 +1,50 @@
+# Author: Dylan Muller
+# Copyright (c) 2025
+# All rights reserved.
+#
+# - Commercial/IP use prohibited.
+# - Attribution required.
+# See License.txt
+
+import serial
+import socket
+import time
+import math
+import sys
+import os
+
+from setup import *
+
+RESET_DELAY = 2
+EXIT_ERROR = 1
+
+def serial_send(serial, data):
+ serial.write(data.encode('utf-8'))
+
+def serial_receive_line(serial):
+ serial_data = serial.readline().decode('utf-8').rstrip()
+ return serial_data
+
+def sys_reset(serial):
+ serial_send(serial, SETUP_CMD_RESET)
+ time.sleep(SETUP_CMD_TIMEOUT)
+ response = serial_receive_line(serial)
+ return response
+
+sys_serial = serial.Serial(port=SETUP_SERIAL_PORT, baudrate=SETUP_SERIAL_BAUD, timeout=SETUP_SERIAL_TIMEOUT)
+
+print("PRECOMPILE CONDITIONING")
+print("EXEC SOFT RESET")
+response = ""
+
+try:
+ response = sys_reset(sys_serial)
+except:
+ print("CRITICAL ERROR")
+
+if ("RESET" in response):
+ print("OK")
+ time.sleep(RESET_DELAY)
+ sys.exit(os.EX_OK)
+else:
+ sys.exit(EXIT_ERROR)
diff --git a/scripts/rms.py b/scripts/rms.py
new file mode 100644
index 0000000..9ae7c6a
--- /dev/null
+++ b/scripts/rms.py
@@ -0,0 +1,118 @@
+# Author: Dylan Muller
+# Copyright (c) 2025
+# All rights reserved.
+#
+# - Commercial/IP use prohibited.
+# - Attribution required.
+# See License.txt
+
+# Script for RMS power calibration
+# using the Rigol DSA815.
+
+import serial
+import socket
+import time
+import math
+
+from setup import *
+from device import *
+
+rms_power_count = []
+rms_power_dbm = []
+
+rms_power_gradient_count = []
+rms_power_threshold = []
+rms_power_intercept = []
+
+drain_increment = 0
+drain_counter = 0
+
+steps = int(2*SETUP_CAL_POINTS)
+
+def dsa815_get_power(sa_socket):
+ sa_socket.send(':CALCulate:MARKer1:Y?\r\n'.encode('utf-8'))
+ power_dbm = float(sa_socket.recv(1024).strip().decode('utf-8'))
+ return power_dbm
+
+def print_response(data):
+ for i in data:
+ print(i)
+
+# Initialize connections
+sa_socket = socket.create_connection((SETUP_DSA815_IP, SETUP_DSA815_PORT))
+sys_serial = serial.Serial(port=SETUP_SERIAL_PORT, baudrate=SETUP_SERIAL_BAUD, timeout=SETUP_SERIAL_TIMEOUT)
+
+print("BATCH START")
+
+print ("EXEC SYSTEM RESET")
+response = sys_reset(sys_serial)
+print(response)
+time.sleep(SETUP_RESET_TIMEOUT)
+sys_serial.flushInput()
+
+print("EXEC GATE PROBE")
+response = sys_gate_probe(sys_serial)
+print_response(response)
+
+print("EXEC TX MODE")
+response = sys_si4468_tx(sys_serial)
+print(response)
+
+print("DATA ACQUISITION START")
+
+for i in range(steps):
+
+ if (i > SETUP_CAL_POINTS ):
+ drain_increment = SETUP_DRAIN_INC_CORASE
+ else:
+ drain_increment = SETUP_DRAIN_INC_FINE
+
+ sys_drain_set(drain_counter)
+ fw_power_count = sys_read_power(sys_serial)
+
+ time.sleep(SETUP_LOOP_DELAY)
+
+ fw_power_dbm = dsa815_get_power(sa_socket)
+ print(drain_counter, fw_power_count, fw_power_dbm)
+
+ rms_power_count.append(float(fw_power_count))
+ rms_power_dbm.append(float(fw_power_dbm))
+
+ drain_counter += drain_increment
+
+print("EXEC RX MODE")
+response = sys_si4468_rx(sys_serial)
+print(response)
+
+print("DATA ACQUISITION END")
+
+for i in range(0, steps, 2):
+ num_power_gradient = float(rms_power_count[i + 1] - rms_power_count[i])
+ den_power_gradient = float(rms_power_dbm[i + 1] - rms_power_dbm[i])
+
+ power_gradient = num_power_gradient / den_power_gradient
+ power_gradient_count = int(math.ceil((power_gradient * 10)))
+
+ power_intercept = float(rms_power_dbm[i + 1] - (float(1/power_gradient)*rms_power_count[i + 1]))
+
+ power_intercept = int(float(round(power_intercept, 2) * 100))
+
+ rms_power_gradient_count.append(power_gradient_count)
+ rms_power_intercept.append(power_intercept)
+ rms_power_threshold.append(int(rms_power_count[i + 1]))
+
+
+c_power_gradient = "{ " + ", ".join(map(str, rms_power_gradient_count)) + " };"
+c_power_intercept = "{ " + ", ".join(map(str, rms_power_intercept)) + " };"
+c_power_threshold = "{ " + ", ".join(map(str, rms_power_threshold)) + " };"
+
+print("C DUMP START")
+
+print("const uint16_t fw_pwr_gradient[] = " + c_power_gradient)
+print("const int16_t fw_pwr_intercept[] = " + c_power_intercept)
+print("const uint16_t fw_pwr_threshold[] = " + c_power_threshold)
+
+print("C DUMP END")
+
+print("BATCH END")
+
diff --git a/scripts/setup.py b/scripts/setup.py
new file mode 100644
index 0000000..f0067e9
--- /dev/null
+++ b/scripts/setup.py
@@ -0,0 +1,139 @@
+# Author: Dylan Muller
+# Copyright (c) 2025
+# All rights reserved.
+#
+# - Commercial/IP use prohibited.
+# - Attribution required.
+# See License.txt
+
+from TermTk import TTkUtil, TTkUiLoader, TTk, TTkColor
+
+# DSA815 analyzer config
+SETUP_DSA815_IP = '169.254.0.3'
+SETUP_DSA815_PORT = 5555
+
+# Serial link config
+SETUP_SERIAL_PORT = 'COM4'
+SETUP_SERIAL_BAUD = 19200
+SETUP_SERIAL_TIMEOUT = 1
+
+SETUP_CLI_UPDATE_RATE = 0.1
+SETUP_CLI_BUSY_TIMEOUT = 5
+
+# Timer delay
+SETUP_LOOP_DELAY = 0.1
+
+# Misc
+SETUP_NEWLINE = "\n"
+SETUP_CMD_TIMEOUT = 0.25
+SETUP_RESET_TIMEOUT = 5
+
+# Commands
+SETUP_CMD_REPORT = "REPORT" + SETUP_NEWLINE
+SETUP_CMD_REPORT_N = 19
+SETUP_CMD_RESET = "RESET" + SETUP_NEWLINE
+SETUP_CMD_PROBE = "PROBE" + SETUP_NEWLINE
+SETUP_CMD_PROBE_N = 4
+SETUP_CMD_TX = "TX" + SETUP_NEWLINE
+SETUP_CMD_RX = "RX" + SETUP_NEWLINE
+SETUP_CMD_DRAIN_SET = "DRAIN"
+SETUP_CMD_POWER_GET = "POWER?" + SETUP_NEWLINE
+SETUP_CMD_REPLY = "REPLY" + SETUP_NEWLINE
+SETUP_CMD_REPLY_RESPONSE = "HELLO"
+SETUP_CMD_BUSY_RESPONSE = "BUSY"
+SETUP_STR_EMPTY = ""
+
+SETUP_REPORT_FRAME_GATE = "- GATE -"
+SETUP_REPORT_FRAME_DRAIN = "- DRAIN -"
+SETUP_REPORT_FRAME_SYSTEM = "- SYSTEM -"
+
+SETUP_REPORT_STATUS = "STATUS"
+SETUP_REPORT_Q_VOLT = "Q-VOLT"
+SETUP_REPORT_Q_AMP = "Q-AMP"
+SETUP_REPORT_Q_TIME = "Q-TIME"
+SETUP_REPORT_V_SET = "V-SET"
+SETUP_REPORT_Q_DRAIN = "Q-DRAIN"
+SETUP_REPORT_V_ADC = "V-ADC"
+SETUP_REPORT_AMP = "AMP"
+SETUP_REPORT_V_FWD = "V-FWD"
+SETUP_REPORT_P_FWD = "P-FWD"
+SETUP_REPORT_P_SET = "P-SET"
+SETUP_REPORT_T_DELTA = "T-DELTA"
+
+SETUP_CAL_POINTS = 10
+SETUP_DRAIN_INC_FINE = 50
+SETUP_DRAIN_INC_CORASE = 200
+
+SETUP_CONSOLE_COL = 79
+SETUP_CONSOLE_ROW = 27
+SETUP_STUB_NAME = "stub.py"
+
+SETUP_LAUNCHER_NAME = "RFCLI LAUNCHER"
+SETUP_LAUNCHER_VER = "1.00.00"
+
+main_window = TTkUiLoader.loadDict(TTkUtil.base64_deflate_2_obj(
+ "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" +
+ "qYaFE3H4P2ZwWfk="))
+
+bg_red = TTkColor.bg('#e86448')
+bg_green = TTkColor.bg('#8ce848')
+
+fg_white = TTkColor.fg('#ffffff')
+fg_black = TTkColor.fg('#000000')
+
+le_red = bg_red + fg_white
+le_green = bg_green + fg_black
+
+# Gate Widgets
+cli_FGateStatus = main_window.getWidgetByName("FGateStatus")
+cli_FGateQV = main_window.getWidgetByName("FGateQV")
+cli_FGateQA = main_window.getWidgetByName("FGateQA")
+cli_FGateQTime = main_window.getWidgetByName("FGateQTime")
+cli_FGateVSet = main_window.getWidgetByName("FGateVSet")
+cli_CBGateFunc = main_window.getWidgetByName("CBGateFunc")
+cli_LEGateQDrain = main_window.getWidgetByName("LEGateQDrain")
+cli_BGateProbe = main_window.getWidgetByName("BGateProbe")
+
+# Drain Widgets
+cli_FDrainStatus = main_window.getWidgetByName("FDrainStatus")
+cli_FDrainVSet = main_window.getWidgetByName("FDrainVSet")
+cli_FDrainVADC = main_window.getWidgetByName("FDrainVADC")
+cli_FDrainA = main_window.getWidgetByName("FDrainA")
+cli_CBDrainFunc = main_window.getWidgetByName("CBDrainFunc")
+cli_LEDrainOverride = main_window.getWidgetByName("LEDrainOverride")
+cli_BDrainOverride = main_window.getWidgetByName("BDrainOverride")
+
+# System Widgets
+cli_FSystemStatus = main_window.getWidgetByName("FSystemStatus")
+cli_FSystemVFwd = main_window.getWidgetByName("FSystemVFwd")
+cli_FSystemAtt = main_window.getWidgetByName("FSystemAtt")
+cli_CBSystemPStrat = main_window.getWidgetByName("CBSystemPStrat")
+cli_CBSystemPort = main_window.getWidgetByName("CBSystemPort")
+cli_LESystemPSet = main_window.getWidgetByName("LESystemPSet")
+cli_BSystemConnect = main_window.getWidgetByName("BSystemConnect")
+cli_LESystemSWRLim = main_window.getWidgetByName("LESystemSWRLim")
+cli_FSystemSWR = main_window.getWidgetByName("FSystemSWR")
+cli_FSystemPFwd = main_window.getWidgetByName("FSystemPFwd")
+cli_FSystemPRev = main_window.getWidgetByName("FSystemPRev")
+cli_BSystemReboot = main_window.getWidgetByName("BSystemReboot")
+cli_BSystemSave = main_window.getWidgetByName("BSystemSave")
+cli_FSystemTSet = main_window.getWidgetByName("FSystemTSet")
+cli_BSystemDefaults = main_window.getWidgetByName("BSystemDefaults")
+cli_BSystemSetPower = main_window.getWidgetByName("BSystemSetPower")
+cli_FSystemVRev = main_window.getWidgetByName("FSystemVRev")