8 Commits
23 changed files with 1650 additions and 756 deletions
+217
View File
@@ -0,0 +1,217 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
#poetry.toml
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
#pdm.lock
#pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
#pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# Redis
*.rdb
*.aof
*.pid
# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/
# ActiveMQ
activemq-data/
# SageMath parsed files
*.sage.py
# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/
# Streamlit
.streamlit/secrets.toml
+18 -18
View File
@@ -78,19 +78,19 @@ class Plugin(Plugin_Base):
)
},
{
"caption": "装订 - 【主 - 0x01】128 kbps,时隙表 0",
"caption": "装订 - 【主 - 0x01】128 kbps,时隙表 1",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 01 22 00 00 9E 06 5A FE"
"data": "5A 54 E3 EE AA 01 22 01 00 9F 06 5A FE"
},
{
"caption": "装订 - 【主 - 0x01】512 kbps,时隙表 1",
"caption": "装订 - 【主 - 0x01】512 kbps,时隙表 2",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 01 33 01 00 B0 06 5A FE"
"data": "5A 54 E3 EE AA 01 33 02 00 B1 06 5A FE"
},
{
"caption": "装订 - 【主 - 0x01】2 Mbps,时隙表 2",
"caption": "装订 - 【主 - 0x01】2 Mbps,时隙表 3",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 01 44 02 00 C2 06 5A FE"
"data": "5A 54 E3 EE AA 01 44 03 00 C3 06 5A FE"
},
{
"caption": "装订 - 【主 - 0x01】静默",
@@ -98,19 +98,19 @@ class Plugin(Plugin_Base):
"data": "5A 54 E3 EE 55 01 22 00 00 49 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】128 kbps,时隙表 0",
"caption": "装订 - 【从 - 0x02】128 kbps,时隙表 1",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 02 22 00 00 9F 06 5A FE"
"data": "5A 54 E3 EE AA 02 22 01 00 A0 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】512 kbps,时隙表 1",
"caption": "装订 - 【从 - 0x02】512 kbps,时隙表 2",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 02 33 01 00 B1 06 5A FE"
"data": "5A 54 E3 EE AA 02 33 02 00 B2 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】2M bps,时隙表 2",
"caption": "装订 - 【从 - 0x02】2M bps,时隙表 3",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 02 44 02 00 C3 06 5A FE"
"data": "5A 54 E3 EE AA 02 44 03 00 C4 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】静默",
@@ -118,19 +118,19 @@ class Plugin(Plugin_Base):
"data": "5A 54 E3 EE 55 02 22 00 00 4A 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】128 kbps,时隙表 0",
"caption": "装订 - 【从 - 0x03】128 kbps,时隙表 1",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 22 00 00 A0 06 5A FE"
"data": "5A 54 E3 EE AA 03 22 01 00 A1 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】512 kbps,时隙表 1",
"caption": "装订 - 【从 - 0x03】512 kbps,时隙表 2",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 33 01 00 B2 06 5A FE"
"data": "5A 54 E3 EE AA 03 33 02 00 B3 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】2 Mbps,时隙表 2",
"caption": "装订 - 【从 - 0x03】2 Mbps,时隙表 3",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 44 02 00 C4 06 5A FE"
"data": "5A 54 E3 EE AA 03 44 03 00 C5 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】静默",
+562
View File
@@ -0,0 +1,562 @@
# from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QLabel, QSlider, QLineEdit, QGridLayout, QPushButton, QCheckBox, QHBoxLayout, QInputDialog)
# from PyQt5.QtCore import pyqtSignal
# from PyQt5.QtGui import QDoubleValidator
import os
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QLabel, QSlider, QLineEdit,
QGridLayout, QPushButton, QCheckBox, QHBoxLayout, QInputDialog, QComboBox, QFileDialog)
from PyQt5.QtCore import pyqtSignal, Qt, QTimer
from PyQt5.QtGui import QDoubleValidator, QPixmap
try:
from i18n import _
import utils_ui
import utils
from widgets import EditRemarDialog
except Exception:
from COMTool.i18n import _
from COMTool import utils_ui
from COMTool import utils
from COMTool.widgets import EditRemarDialog
# from .graph_widget_metasenselite import Graph_MetaSenseLite
from .graph_widgets_base import Graph_Widget_Base
import pyqtgraph as pg
from struct import unpack, pack
import time
class Graph_Image(Graph_Widget_Base):
id = "image"
updateSignal = pyqtSignal(bytes)
startTimeoutSignal = pyqtSignal()
stopTimeoutSignal = pyqtSignal()
def __init__(self, parent=None, hintSignal=lambda type, title, msg: None,
rmCallback=lambda widget: None, send=lambda x: None, config=None):
# 初始化配置,默认缩放倍数为10
default = {"scale_factor": 10}
if config:
default.update(config)
super().__init__(parent, hintSignal, rmCallback, send, default, default)
self.image_data = bytearray()
# 从配置获取缩放倍数
self.scale_factor = self.config.get("scale_factor", 10)
layout = QVBoxLayout()
self.setLayout(layout)
self.imageLabel = QLabel("[ Waiting for image... ]")
self.imageLabel.setAlignment(Qt.AlignCenter)
layout.addWidget(self.imageLabel)
self.clearBtn = QPushButton("Clear Image")
self.clearBtn.clicked.connect(self.clear)
layout.addWidget(self.clearBtn)
self.updateSignal.connect(self.update_image)
self.timeoutTimer = QTimer(self)
self.timeoutTimer.setInterval(2000) # 2 seconds timeout
self.timeoutTimer.timeout.connect(self.clear_buffer)
self.startTimeoutSignal.connect(lambda: self.timeoutTimer.start())
self.stopTimeoutSignal.emit()
def clear(self):
self.image_data.clear()
self.imageLabel.clear()
self.imageLabel.setText("[ Cleared ]")
self.stopTimeoutSignal.emit()
def clear_buffer(self):
self.image_data.clear()
self.imageLabel.setText("[ Timeout: buffer cleared ]")
self.stopTimeoutSignal.emit()
def onData(self, data: bytes):
self.stopTimeoutSignal.emit() # Stop any running timer when data is received
self.image_data.extend(data)
# Check for common image signatures
if self._is_complete_jpeg(self.image_data) or \
self._is_complete_png(self.image_data) or \
self._is_complete_bmp(self.image_data):
self.updateSignal.emit(bytes(self.image_data))
self.image_data.clear()
else:
self.startTimeoutSignal.emit() # Restart timer only if not complete
def _is_complete_jpeg(self, data):
return data[:2] == b'\xFF\xD8' and data[-2:] == b'\xFF\xD9'
def _is_complete_png(self, data):
return data[:8] == b'\x89PNG\r\n\x1a\n' and b'IEND' in data[-20:]
def _is_complete_bmp(self, data):
return data[:2] == b'BM' and len(data) >= int.from_bytes(data[2:6], 'little')
def update_image(self, img_bytes: bytes):
pixmap = QPixmap()
if pixmap.loadFromData(img_bytes):
# 使用配置的缩放倍数进行缩放
scaled_width = pixmap.width() * self.scale_factor
scaled_height = pixmap.height() * self.scale_factor
scaled = pixmap.scaled(
scaled_width,
scaled_height,
Qt.KeepAspectRatio,
Qt.SmoothTransformation
)
self.imageLabel.setPixmap(scaled)
else:
self.imageLabel.setText("[ Failed to decode image ]")
class Graph_Plot(Graph_Widget_Base):
updateSignal = pyqtSignal(dict)
id = "plot"
def __init__(self, parent=None, hintSignal=lambda type, title, msg: None, rmCallback=lambda widget: None, send=lambda x: None, config=None):
default = {
"xRange": 10,
"xRangeEnable": True,
"header": "\\xAA\\xCC\\xEE\\xBB",
"binary_protocol": False,
}
super().__init__(parent, hintSignal=hintSignal, rmCallback=rmCallback,
send=send, config=config, defaultConfig=default)
self.headerBytes = utils.str_to_bytes(
self.config["header"], escape=True, encoding="utf-8")
self.layout = QGridLayout()
self.setLayout(self.layout)
self.plotWin = pg.GraphicsLayoutWidget()
self.plotWin.setMinimumHeight(200)
self.default_x = 0;
pg.setConfigOptions(antialias=True)
rmBtn = QPushButton(_("Remove"))
clearBtn = QPushButton(_("Clear"))
rangeLabel = QLabel(_("Range:"))
rangeConf = QLineEdit(str(self.config["xRange"]))
rangeEnable = QCheckBox(_("Enable"))
rangeEnable.setChecked(self.config["xRangeEnable"])
self.binary_protocol = QCheckBox(_("Binary Protocol"))
headerLabel = QLabel(_("Header:"))
headerConf = QLineEdit(self.config["header"])
self.headerBtn = QPushButton(_("Set"))
hint = _("Protocol: header + 1Byte name length + name + 8Bytes x(double) + 8Bytes y(double) + 1Byte sum\n"
"Protocol example code see help")
headerConf.setToolTip(hint)
self.binary_widgets = [headerLabel, headerConf, self.headerBtn]
self.binary_protocol.setToolTip(_('Check this if you want to use binary protocol, or use ASCII protocol(e.g. "$data1,10.0,200.0\\n"), more see help button on the top of window'))
self.show_binary_protocol_widgets(self.config["binary_protocol"])
headerLabel.setToolTip(hint)
self.headerBtn.setToolTip(hint)
validator = QDoubleValidator()
rangeConf.setValidator(validator)
self.layout.addWidget(self.plotWin, 0, 0, 1, 3)
self.layout.addWidget(rmBtn, 1, 0, 1, 1)
self.layout.addWidget(clearBtn, 1, 2, 1, 1)
self.layout.addWidget(rangeLabel, 2, 0, 1, 1)
self.layout.addWidget(rangeConf, 2, 1, 1, 1)
self.layout.addWidget(rangeEnable, 2, 2, 1, 1)
self.layout.addWidget(self.binary_protocol, 3, 0, 1, 1)
self.layout.addWidget(headerLabel, 4, 0, 1, 1)
self.layout.addWidget(headerConf, 4, 1, 1, 1)
self.layout.addWidget(self.headerBtn, 4, 2, 1, 1)
self.resize(600, 400)
self.p = self.plotWin.addPlot(colspan=2)
# self.p.setLabel('bottom', 'x', '')
self.p.addLegend()
self.p.setXRange(0, self.config["xRange"])
self.updateSignal.connect(self.update)
self.curves = {}
self.rawData = b''
self.data = {}
self.builtinColors = [
"#BD4B4B",
"#3BB273",
"#FFFFFA",
"#307473",
"#3C6997",
"#746D75",
"#228CDB",
"#824C71",
"#7768AE",
"#DC6BAD",
"#607d8b",
"#F18701",
"#912F40",
"#414288",
"#ED4D6E",
"#FFD29D",
"#B56576",
"#503B31",
"#93E1D8",
"#596157",
]
self.notUsedColors = self.builtinColors.copy()
self.colors = {
}
rangeConf.textChanged.connect(self.setRange)
rangeEnable.clicked.connect(
lambda: self.setEnableRange(rangeEnable.isChecked()))
self.headerBtn.clicked.connect(
lambda: self.setHeader(headerConf.text()))
rmBtn.clicked.connect(self.remove)
headerConf.textChanged.connect(self.headerChanged)
clearBtn.clicked.connect(self.clear)
self.binary_protocol.clicked.connect(self.en_binary_protocol)
def remove(self):
self.rmCallback(self)
def en_binary_protocol(self):
self.rawData = b''
self.config["binary_protocol"] = self.binary_protocol.isChecked()
self.show_binary_protocol_widgets(self.config["binary_protocol"])
def show_binary_protocol_widgets(self, show=True):
for w in self.binary_widgets:
w.setVisible(show)
def clear(self):
self.data = {}
self.curves = {}
self.notUsedColors = self.builtinColors.copy()
self.colors = {}
self.p.clear()
def setRange(self, text):
if text:
self.config["xRange"] = float(text)
def setEnableRange(self, en):
self.config["xRangeEnable"] = en
def headerChanged(self, text):
if self.config["header"] != text:
self.headerBtn.setText(_("Set") + " *")
else:
self.headerBtn.setText(_("Set"))
def setHeader(self, text):
if text:
try:
textBytes = utils.str_to_bytes(
text, escape=True, encoding="utf-8")
self.config["header"] = text
self.headerBytes = textBytes
self.headerBtn.setText(_("Set"))
except Exception:
self.hintSignal.emit("error", _("Error"), _("Format error"))
def decodeData(self, data: bytes):
'''
@data bytes, protocol:
| header(4B) | line name len(1B) | line name | x(8B) | y(8B) | sum(1B) |
| AA CC EE BB | 1~255 | roll | double | double | uint8 |
@return haveFrame, dict {
"name": {
"x": [],
"y": []
}
}
'''
# append data
self.rawData += data
# find header
header = self.headerBytes
idx = self.rawData.find(header)
if idx < 0:
return False, self.data
self.rawData = self.rawData[idx:]
# check data length
nameLen = unpack("B", self.rawData[len(header): len(header) + 1])[0]
frameLen = len(header) + nameLen + 18 # 5 + nameLen + 16 + 1
if len(self.rawData) < frameLen:
return False, self.data
# get data
frame = self.rawData[:frameLen]
self.rawData = self.rawData[frameLen:]
_sum = frame[-1]
# check sum
if _sum != sum(frame[:frameLen - 1]) % 256:
return True, self.data
name = frame[len(header) + 1: len(header) +
1 + nameLen].decode("utf-8")
x = unpack("d", frame[-17:-9])[0]
y = unpack("d", frame[-9:-1])[0]
if not name in self.data:
self.data[name] = {
"x": [x],
"y": [y]
}
else:
self.data[name]["x"].append(x)
self.data[name]["y"].append(y)
return True, self.data
def decodeDataAscii(self, data: bytes):
'''
@data bytes, protocol:
$[line name],[x],[y]<,checksum>\n
or $[line name],[y]
"$" means start of frame, "," means separator,
checksum is optional, checksum is sum of all bytes in frame except ",checksum".
e.g.
"$roll,2.0\n"
"$roll,1.0,2.0\n"
"$pitch,1.0,2.0\r\n"
"$pitch,1.0,2.0,179\n" , the 179 = sum(ord(c) for c in "$pitch,1.0,2.0") % 256
@return haveFrame, dict {
"name": {
"x": [],
"y": []
}
}
'''
# append data
self.rawData += data
# find header
header = b"$"
end = b"\n"
idx = self.rawData.find(header)
if idx < 0:
return False, self.data
self.rawData = self.rawData[idx:]
# find \n
idx = self.rawData.find(end)
if idx < 0:
return False, self.data
# get data
frame = self.rawData[1:idx] # pitch,1.0,2.0 pitch,1.0,2.0,179
self.rawData = self.rawData[idx + 1:]
items = frame.split(b",")
if len(items) != 2 and len(items) != 3 and len(items) != 4:
print("-- format error, frame item len(%s, should 3 or 4) error: %s" % (len(items), frame))
return False, self.data
try:
if len(items) == 2:
x = float(self.default_x)
y = float(items[1])
self.default_x += 1
else:
x = float(items[1])
y = float(items[2])
except Exception:
print("-- x or y format error, frame: %s" % frame)
return False, self.data
# checksum
if len(items) == 4:
try:
_sum = int(items[3])
except Exception:
print("-- checksum format error({} not int), frame: {}".format(items[3], frame))
return False, self.data
# get last , index
idx = frame.rfind(b",")
if sum(header + frame[:idx]) % 256 != _sum:
print("-- checksum error")
return False, self.data
name = items[0].decode("utf-8")
if not name in self.data:
self.data[name] = {
"x": [x],
"y": [y]
}
else:
self.data[name]["x"].append(x)
self.data[name]["y"].append(y)
return True, self.data
def pickColor(self, name: str):
if name in self.colors:
return self.colors[name]
else:
if not self.notUsedColors:
self.notUsedColors = self.builtinColors.copy()
color = self.notUsedColors.pop(0)
self.colors[name] = color
return color
def update(self, data: dict):
for k, v in data.items():
if not k in self.curves:
print("add curve:", k)
color = self.pickColor(k)
self.colors[k] = color
self.curves[k] = self.p.plot(pen=pg.mkPen(color=color, width=2),
name=k,)
# symbolBrush=color, symbolPen='w', symbol='o', symbolSize=1)
if self.config["xRangeEnable"] and self.config["xRange"] > 0:
self.p.setXRange(
v["x"][-1] - self.config["xRange"], v["x"][-1])
self.curves[k].setData(x=v["x"], y=v["y"])
def onData(self, data: bytes):
while 1:
haveFrame, allData = self.decodeData(data) if self.config["binary_protocol"] else self.decodeDataAscii(data)
if not haveFrame:
break
data = b''
self.updateSignal.emit(allData)
class Graph_Button(Graph_Widget_Base):
class Button(QWidget):
def __init__(self, rmCallback, addCallback, clickCallback, changeCallback,
value=("", "hello", "hello", "fa.circle", [])):
super().__init__()
if not value[0]:
self.id = str(int(time.time() * 1000))
else:
self.id = value[0]
self.rmCallback = rmCallback
self.changeCallback = changeCallback
self.setProperty("class", "graphBtn")
layout = QHBoxLayout()
layoutSetting = QVBoxLayout()
self.setLayout(layout)
self.button = QPushButton(value[2])
self.button.setProperty("class", "bigBtn")
self.value = value[2]
self.icon = value[3]
self.shortcut = value[4]
layout.addLayout(layoutSetting)
layout.addWidget(self.button)
self.addBtn = QPushButton()
self.rmBtn = QPushButton()
self.editBtn = QPushButton()
self.addBtn.setProperty("class", "smallBtn3")
self.rmBtn.setProperty("class", "smallBtn3")
self.editBtn.setProperty("class", "smallBtn3")
utils_ui.setButtonIcon(self.addBtn, "fa.plus")
utils_ui.setButtonIcon(self.rmBtn, "fa.minus")
utils_ui.setButtonIcon(self.editBtn, "fa.edit")
if self.icon:
utils_ui.setButtonIcon(self.button, self.icon)
if self.shortcut:
tip = self.getShortcutTip()
self.button.setToolTip(tip)
layoutSetting.addStretch()
layoutSetting.addWidget(self.rmBtn)
layoutSetting.addWidget(self.addBtn)
layoutSetting.addWidget(self.editBtn)
self.rmBtn.clicked.connect(self.onRm)
self.addBtn.clicked.connect(lambda: addCallback(self))
self.editBtn.clicked.connect(self.editButton)
self.button.clicked.connect(lambda: clickCallback(
self, utils.str_to_bytes(self.value, escape=True, encoding="utf-8")))
def getInfo(self):
return [self.id, self.button.text(), self.value, self.icon, self.shortcut]
def onRm(self):
utils_ui.clearButtonIcon(self.addBtn)
utils_ui.clearButtonIcon(self.rmBtn)
utils_ui.clearButtonIcon(self.editBtn)
utils_ui.clearButtonIcon(self.button)
self.rmCallback(self)
def editButton(self):
ok, remark, value, icon, shortcut = EditRemarDialog(
self.button.text(), self.icon, shortcut=self.shortcut, value=self.value).exec()
if ok:
self.value = value
self.icon = icon
self.shortcut = shortcut
self.button.setText(remark)
if self.shortcut:
tip = self.getShortcutTip()
self.button.setToolTip(tip)
utils_ui.setButtonIcon(self.button, icon)
self.changeCallback(self)
def getShortcutTip(self):
return _("Shortcut") + ": " + "+".join((name for v, name in self.shortcut))
id = "button"
def __init__(self, parent=None, hintSignal=lambda type, title, msg: None, rmCallback=lambda widget: None, send=lambda x: None, config=None):
default = {
"items": []
}
super().__init__(parent, hintSignal, rmCallback, send, config, default)
self.layout = QHBoxLayout()
self.setLayout(self.layout)
if not self.config["items"]:
button = Graph_Button.Button(
self.onRm, self.onAdd, self.onClick, self.onChange)
self.layout.addWidget(button)
self.buttons = [button]
self.config["items"] = [button.getInfo()]
else:
self.buttons = []
for item in self.config["items"]:
button = Graph_Button.Button(
self.onRm, self.onAdd, self.onClick, self.onChange, value=item)
self.layout.addWidget(button)
self.buttons.append(button)
self.pressedKeys = []
def onRm(self, widget):
'''
@widget Graph_Button.Button
'''
item = widget.getInfo()
for item_ in self.config["items"]:
if item_[0] == item[0]: # id
self.config["items"].remove(item_)
break
self.buttons.remove(widget)
widget.setParent(None)
if not self.buttons:
self.rmCallback(self)
def onAdd(self, widget):
'''
@widget Graph_Button.Button
'''
button = Graph_Button.Button(
self.onRm, self.onAdd, self.onClick, self.onChange)
self.layout.addWidget(button)
self.buttons.append(button)
self.config["items"].append(button.getInfo())
def onClick(self, widget, data: bytes):
self.send(data)
def onChange(self, widget):
self.config["items"][self.buttons.index(widget)] = widget.getInfo()
def onKeyPressEvent(self, event):
key = event.key()
self.pressedKeys.append(key)
for uid, name, value, icon, shortcut in self.config["items"]:
if not shortcut:
continue
if len(shortcut) == len(self.pressedKeys):
same = True
for i in range(len(shortcut)):
if shortcut[i][0] != self.pressedKeys[i]:
same = False
break
if same:
value = utils.str_to_bytes(
value, escape=True, encoding="utf-8")
self.send(value)
def onKeyReleaseEvent(self, event):
key = event.key()
if key in self.pressedKeys:
self.pressedKeys.remove(key)
graphWidgets = {
Graph_Plot.id: Graph_Plot,
Graph_Button.id: Graph_Button,
Graph_Image.id: Graph_Image
# Graph_DragTof.id: Graph_DragTof,
# Graph_MetaSenseLite.id: Graph_MetaSenseLite,
}
+180 -197
View File
@@ -30,8 +30,8 @@ except ImportError:
class Plugin(Plugin_Base):
id = "hsjl_time"
name = _("hsjl_time")
id = "hsjl_timer"
name = _("hsjl_timer")
showReceiveDataSignal = pyqtSignal(str)
# 图片1的字节数据(已存在,提取为常量)
IMAGE1_DATA = [
@@ -52,37 +52,13 @@ class Plugin(Plugin_Base):
# 图片2的字节数据(新添加)
IMAGE2_DATA = [
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x22, 0x04, 0x03, 0x00, 0x00, 0x00, 0x9D, 0x24, 0x37,
0xEA, 0x00, 0x00, 0x00, 0x2D, 0x50, 0x4C, 0x54, 0x45, 0xFF, 0xFF, 0xFF, 0x27, 0x26, 0x36, 0x27,
0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26,
0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x27, 0x26, 0x36,
0x27, 0x26, 0x36, 0x27, 0x26, 0x36, 0x99, 0xBB, 0x2D, 0xFF, 0x00, 0x00, 0x00, 0x0E, 0x74, 0x52,
0x4E, 0x53, 0x00, 0x11, 0x44, 0x99, 0xEE, 0xAA, 0xBB, 0x22, 0xCC, 0x33, 0x66, 0x88, 0xDD, 0x77,
0x52, 0x6E, 0x24, 0x11, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4B, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1D,
0x48, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x48, 0x00, 0x46, 0xC9, 0x6B, 0x3E, 0x00, 0x00, 0x00, 0x94, 0x49, 0x44, 0x41, 0x54, 0x48, 0xC7,
0x63, 0x60, 0x00, 0x02, 0x21, 0x25, 0x0A, 0x80, 0x00, 0x03, 0x04, 0x30, 0x99, 0xBC, 0xA3, 0x04,
0x3C, 0x09, 0x02, 0x9B, 0xC2, 0x68, 0x47, 0x91, 0x29, 0x40, 0x90, 0x0E, 0x32, 0xA6, 0x82, 0x52,
0x53, 0xDE, 0x3D, 0x99, 0x00, 0x74, 0x4C, 0x1F, 0xC5, 0xC6, 0xBC, 0xF3, 0x64, 0x60, 0x60, 0xA6,
0xDC, 0x94, 0x77, 0xCF, 0x18, 0x18, 0xEA, 0xA8, 0x60, 0xCC, 0xBB, 0x05, 0x0C, 0xFB, 0xA8, 0x61,
0x4C, 0x00, 0xC3, 0x39, 0x6A, 0x18, 0xF3, 0x80, 0x81, 0x1A, 0xA6, 0x8C, 0x1A, 0x33, 0x6A, 0xCC,
0xA8, 0x31, 0xA3, 0xC6, 0xD0, 0xD1, 0x98, 0x3E, 0x6A, 0x18, 0xE3, 0xC0, 0x70, 0x8F, 0x1A, 0xC6,
0x04, 0x30, 0x94, 0x50, 0xC3, 0x18, 0x05, 0x06, 0x6E, 0x2A, 0x98, 0x02, 0xAC, 0xA7, 0x18, 0xF2,
0x28, 0x37, 0xE6, 0x20, 0xD0, 0x18, 0x31, 0x8A, 0x4D, 0x79, 0x31, 0x01, 0xD4, 0x16, 0xD8, 0x42,
0xA9, 0x31, 0x86, 0x90, 0x96, 0xC9, 0x0D, 0xCA, 0xDC, 0xB2, 0x1D, 0x68, 0x06, 0x00, 0x45, 0x8D,
0x41, 0x11, 0x72, 0x0F, 0xD2, 0x4E, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61,
0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2D, 0x30,
0x35, 0x2D, 0x31, 0x38, 0x54, 0x31, 0x34, 0x3A, 0x33, 0x37, 0x3A, 0x35, 0x34, 0x2B, 0x30, 0x38,
0x3A, 0x30, 0x30, 0x9D, 0x24, 0x28, 0xF9, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64,
0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2D,
0x30, 0x35, 0x2D, 0x31, 0x38, 0x54, 0x31, 0x34, 0x3A, 0x33, 0x37, 0x3A, 0x35, 0x34, 0x2B, 0x30,
0x38, 0x3A, 0x30, 0x30, 0xEC, 0x79, 0x90, 0x45, 0x00, 0x00, 0x00, 0x1E, 0x74, 0x45, 0x58, 0x74,
0x70, 0x73, 0x3A, 0x48, 0x69, 0x52, 0x65, 0x73, 0x42, 0x6F, 0x75, 0x6E, 0x64, 0x69, 0x6E, 0x67,
0x42, 0x6F, 0x78, 0x00, 0x31, 0x33, 0x39, 0x78, 0x33, 0x34, 0x2B, 0x30, 0x2B, 0x30, 0x87, 0x35,
0x32, 0x1E, 0x00, 0x00, 0x00, 0x1C, 0x74, 0x45, 0x58, 0x74, 0x70, 0x73, 0x3A, 0x4C, 0x65, 0x76,
0x65, 0x6C, 0x00, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x2D, 0x33, 0x2E, 0x30, 0x20, 0x45, 0x50, 0x53,
0x46, 0x2D, 0x33, 0x2E, 0x30, 0x0A, 0x9B, 0x70, 0xBB, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x05, 0x08, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x64, 0x7D,
0x68, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00,
0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00,
0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x12, 0x74, 0x00, 0x00, 0x12, 0x74, 0x01, 0xDE,
0x66, 0x1F, 0x78, 0x00, 0x00, 0x00, 0x14, 0x49, 0x44, 0x41, 0x54, 0x18, 0x57, 0x63, 0x50, 0x54,
0x54, 0xF9, 0x4F, 0x0C, 0x1E, 0xFC, 0x0A, 0x55, 0xFE, 0x03, 0x00, 0xAC, 0x06, 0x45, 0xBB, 0xD3,
0x7A, 0x66, 0x86, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
]
# 在类初始化时添加定时器相关变量(onInit方法中)
@@ -96,9 +72,11 @@ class Plugin(Plugin_Base):
"version": 1,
"customSendItems": [
{
"caption": "遥测",
"caption": "自检项",
"icon": "fa5.play-circle",
"data": "5A 54 E6 EE 00 D4 02 5A FE"
"data": "5A 54 E1 EE 00 CF 02 5A FE"
#"data": "5A 54 E1 EE 01 00 00 00 01 15 00 55 00 05 55 57 58 80 00 00 00 00 00 00 00\n\
#00 00 00 01 00 00 00 00 75 17 5A FE "
},
{
"caption": "图片传输",
@@ -112,7 +90,7 @@ class Plugin(Plugin_Base):
4E 62 24 11 DE 82 35 D8 00 00 00 00 49 45 4E 44 AE 42 60 82 00 76 C4 5A FE"
},
{
"caption": "总控",
"caption": "配置发送",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 22 00 00 A0 06 5A FE"
},
@@ -122,6 +100,8 @@ class Plugin(Plugin_Base):
for k in default:
if k not in self.config:
self.config[k] = default[k]
self.config["customSendItems"] = default["customSendItems"]
print("初始化的customSendItems:", self.config["customSendItems"])
def createToggleButton(self):
toggleBtn = QPushButton("开关: Off")
@@ -143,16 +123,58 @@ class Plugin(Plugin_Base):
return toggleBtn
def createIdButton(self):
toggleBtn = QPushButton("id: 01")
# 定义ID映射:原始ID -> 显示文本(带标识)
id_display_map = {
"01": "01(主)",
"02": "02(从)",
"03": "03(从)"
}
default_id = "01" # 原始ID默认值
# 按钮显示带标识的文本
toggleBtn = QPushButton(f"id: {id_display_map[default_id]}")
# 存储原始ID(关键:组帧时用这个值)
toggleBtn.setProperty("originalId", default_id)
menu = QMenu(toggleBtn)
ids = ["01", "02", "03"]
def setId(text):
toggleBtn.setText(f"id: {text}")
print(f"id设为 {text}")
def setId(original_id):
# 更新显示文本(带标识)
toggleBtn.setText(f"id: {id_display_map[original_id]}")
# 更新存储的原始ID
toggleBtn.setProperty("originalId", original_id)
print(f"id设为 {original_id}") # 确认原始ID正确
for id_text in ids:
menu.addAction(id_text).triggered.connect(lambda checked, t=id_text: setId(t))
# 菜单显示带标识的文本,但传递原始ID
for original_id, display_text in id_display_map.items():
menu.addAction(display_text).triggered.connect(
lambda checked, id=original_id: setId(id)
)
toggleBtn.setMenu(menu)
return toggleBtn
def createtoIdButton(self):
# 目的节点ID同理处理
id_display_map = {
"01": "01(主)",
"02": "02(从)",
"03": "03(从)"
}
default_id = "01"
toggleBtn = QPushButton(f"目的节点id: {id_display_map[default_id]}")
toggleBtn.setProperty("originalId", default_id) # 存储原始ID
menu = QMenu(toggleBtn)
def setId(original_id):
toggleBtn.setText(f"目的节点id: {id_display_map[original_id]}")
toggleBtn.setProperty("originalId", original_id)
print(f"目的节点id设为 {original_id}")
for original_id, display_text in id_display_map.items():
menu.addAction(display_text).triggered.connect(
lambda checked, id=original_id: setId(id)
)
toggleBtn.setMenu(menu)
return toggleBtn
@@ -175,7 +197,7 @@ class Plugin(Plugin_Base):
def createRateButton(self):
rateBtn = QPushButton("速率: 128kpbs") # 默认选中01
menu = QMenu(rateBtn)
rateOptions = ["128kpbs", "256kpbs", "2Mbps"]
rateOptions = ["128kpbs", "512kpbs", "2Mbps"]
def setRate(text):
rateBtn.setText(f"速率: {text}")
@@ -206,13 +228,15 @@ class Plugin(Plugin_Base):
# ID字段,转为整数
try:
id_val = int(id_text.split(":")[1].strip(), 16)
# 直接获取存储的原始ID(如"01")
original_id = self.idButton.property("originalId")
id_val = int(original_id, 16) # 转为16进制整数
except:
id_val = 0x00
id_val = 0x00 # 异常时默认值
frame.append(id_val)
# 速率字段对应映射(参考原来速率的0x22等)
rate_map = {"128kpbs": 0x22, "256kpbs": 0x33, "2Mbps": 0x44}
rate_map = {"128kpbs": 0x22, "512kpbs": 0x33, "2Mbps": 0x44}
rate_key = rate_text.split(":")[1].strip()
rate_val = rate_map.get(rate_key, 0x22)
frame.append(rate_val)
@@ -237,20 +261,22 @@ class Plugin(Plugin_Base):
# 转成空格分隔的大写16进制字符串
return " ".join(f"{b:02X}" for b in frame)
def buildimageCommand(self, switch_text, id_text, rate_text, slot_text, image_index=0):
def buildimageCommand(self, switch_text, toid_text, rate_text, slot_text, image_index=0):
# 头部固定
frame = [0x5A, 0x54, 0xE4, 0xEE, 0x00, 0x00, 0x00]
frame = [0x5A, 0x54, 0xE4, 0xEE]
if image_index == 0:#两个图片的序号不同
frame.append(0x01)
else:
frame.append(0x02)
frame.extend([0x00, 0x00, 0x00])
# ID字段,转为整数
try:
id_val = int(id_text.split(":")[1].strip(), 16)
original_toid = self.toidButton.property("originalId")
id_val = int(original_toid, 16)
except:
id_val = 0x01
id_val = 0x01 # 异常时默认值
frame.append(id_val)
# 根据索引选择图片数据
@@ -259,13 +285,13 @@ class Plugin(Plugin_Base):
else:
image_data = self.IMAGE2_DATA
# 计算图片数据长度(2字节表示,这里使用大端模式)
# 计算图片数据长度(2字节表示,这里使用小端模式)
data_length = len(image_data)
# 拆分长度为高8位和低8位
high_byte = (data_length >> 8) & 0xFF
low_byte = data_length & 0xFF
high_byte = (data_length >> 8) & 0xFF # 高8位
low_byte = data_length & 0xFF # 低8位
frame.extend([high_byte, low_byte]) # 替换固定字段为动态长度
frame.extend([low_byte, high_byte]) # 小端模式:低位字节在前,高位字节在后
# 根据索引选择图片数据
if image_index == 0:
frame.extend(self.IMAGE1_DATA)
@@ -278,8 +304,12 @@ class Plugin(Plugin_Base):
checksum = sum(frame[2:]) & 0xFF
frame.append(checksum)
# 结尾
frame.extend([0xC4, 0x5A, 0xFE])
# 计算数据段长度:从第三个字节(索引2)到dummy byte(当前frame的最后一个字节)
# 长度 = 总字节数 - 前两个字节(因为前两个是帧头,不算数据段)
data_segment_length = len(frame) -4 # len(frame)此时是:2(头) + 数据段内容长度 + 1(dummy)
# 替换固定值0xC4为计算出的长度,再添加后续固定字节
frame.extend([data_segment_length, 0x5A, 0xFE])
# 转成空格分隔的大写16进制字符串
return " ".join(f"{b:02X}" for b in frame)
@@ -291,10 +321,9 @@ class Plugin(Plugin_Base):
id_text = self.idButton.text()
slot_text = self.slotButton.text()
rate_text = self.rateButton.text()
# 发送当前索引对应的图片
toid_text = self.toidButton.text()
cmd_str = self.buildimageCommand(
switch_text, id_text, rate_text, slot_text,
switch_text, toid_text, rate_text, slot_text,
self.image_index # 传入当前图片索引
)
print(f"第{self.cycle_count + 1}次发送,图片{self.image_index + 1}: {cmd_str}")
@@ -386,19 +415,19 @@ class Plugin(Plugin_Base):
self.mainWidget.addWidget(sendItemsOuterWrapper)
# 网络状态标签初始化
self.networkStatusLabel = QLabel("网络连接状态: 未连接")
self.networkStatusLabel = QLabel("节点状态: 未知")
self.networkStatusLabel.setAlignment(Qt.AlignLeft)
self.networkStatusLabel.setFont(QFont("Arial", 10))
self.networkPhaseLabel = QLabel("网络运行阶段: 未知")
self.networkPhaseLabel = QLabel("天线温度: 未知")
self.networkPhaseLabel.setAlignment(Qt.AlignLeft)
self.networkPhaseLabel.setFont(QFont("Arial", 10))
self.networktemLabel = QLabel("fpga温度: 未知")
self.networktemLabel = QLabel("电压状态: 未知")
self.networktemLabel.setAlignment(Qt.AlignLeft)
self.networktemLabel.setFont(QFont("Arial", 10))
self.networkvoltageLabel = QLabel("电压监测: 未知")
self.networkvoltageLabel = QLabel("fgpa温度: 未知")
self.networkvoltageLabel.setAlignment(Qt.AlignLeft)
self.networkvoltageLabel.setFont(QFont("Arial", 10))
@@ -439,31 +468,32 @@ class Plugin(Plugin_Base):
return itemWidget
def onUiInitDone(self):
# 去掉自检项
self.config["customSendItems"] = [item for item in self.config["customSendItems"] if item["caption"] != "自检"]
# 清空旧布局
self.clearLayout(self.customSendItemsLayout)
# 创建“开关”、“ID”、“时隙表”、“速率”按钮,供“总控”使用
self.toggleButton = self.createToggleButton()
self.customSendItemsLayout.addWidget(self.toggleButton, 1, 0)
self.customSendItemsLayout.addWidget(self.toggleButton, 1, 0, 1, 2)
self.idButton = self.createIdButton()
self.customSendItemsLayout.addWidget(self.idButton, 1, 1)
self.customSendItemsLayout.addWidget(self.idButton, 0, 1)
self.slotButton = self.createSlotButton()
self.customSendItemsLayout.addWidget(self.slotButton, 1, 2)
self.customSendItemsLayout.addWidget(self.slotButton, 0, 2)
self.rateButton = self.createRateButton()
self.customSendItemsLayout.addWidget(self.rateButton, 1, 3)
self.customSendItemsLayout.addWidget(self.rateButton, 0, 0)
# 第一行固定插入“遥测”、“图片传输”、“总控”
self.toidButton = self.createtoIdButton()
self.customSendItemsLayout.addWidget(self.toidButton, 0, 3)
# 第一行固定插入“自检”、“图片传输”、“总控”
for item in self.config["customSendItems"]:
if item["caption"] == "遥测":
if item["caption"] == "自检项":
print("找到自检项,准备添加到(0,0)") # 新增
w = self.createSendItemWidget(item)
self.customSendItemsLayout.addWidget(w, 0, 0)
self.customSendItemsLayout.addWidget(w, 3, 0, 1, 2)
elif item["caption"] == "图片传输":
totalControlWidget = QWidget()
layout = QHBoxLayout()
@@ -491,7 +521,7 @@ class Plugin(Plugin_Base):
# 1. 定义速率与间隔的映射关系(单位:毫秒)
rate_interval_map = {
"128kpbs": 1500, # 128kpbs对应1.5秒
"256kpbs": 1000, # 256kpbs对应1秒
"512kpbs": 1000, # 256kpbs对应1秒
"2Mbps": 500 # 2Mbps对应0.5秒
}
@@ -512,10 +542,10 @@ class Plugin(Plugin_Base):
id_text = self.idButton.text()
slot_text = self.slotButton.text()
rate_text = self.rateButton.text()
toid_text = self.toidButton.text()
# 构建当前图片指令
cmd_str = self.buildimageCommand(
switch_text, id_text, rate_text, slot_text, self.image_index
switch_text, toid_text, rate_text, slot_text, self.image_index
)
print(f"第{self.cycle_count + 1}次循环,图片{self.image_index + 1}: {cmd_str}")
@@ -547,16 +577,16 @@ class Plugin(Plugin_Base):
layout.addWidget(label)
layout.addWidget(sendBtn)
self.customSendItemsLayout.addWidget(totalControlWidget, 0, 1)
self.customSendItemsLayout.addWidget(totalControlWidget, 3, 2, 1, 2 )
elif item["caption"] == "总控":
elif item["caption"] == "配置发送":
totalControlWidget = QWidget()
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
totalControlWidget.setLayout(layout)
sendBtn = QPushButton("")
label = QLabel("总控")
label = QLabel("配置发送")
utils_ui.setButtonIcon(sendBtn, item.get("icon", "fa.send"))
sendBtn.setProperty("class", "smallBtn")
@@ -570,7 +600,7 @@ class Plugin(Plugin_Base):
# 动态构造指令字符串S
cmd_str = self.buildBindCommand(switch_text, id_text, rate_text, slot_text)
print(f"总控: {cmd_str}")
print(f"配置发送: {cmd_str}")
data_bytes = self.parseSendData(cmd_str,
encoding=self.configGlobal["encoding"],
@@ -581,16 +611,13 @@ class Plugin(Plugin_Base):
layout.addWidget(label)
layout.addWidget(sendBtn)
self.customSendItemsLayout.addWidget(totalControlWidget, 0, 2)
self.customSendItemsLayout.addWidget(totalControlWidget, 1, 2, 1, 2)
# 第三行放4个状态标签
self.customSendItemsLayout.addWidget(self.networkStatusLabel, 2, 0)
self.customSendItemsLayout.addWidget(self.networkPhaseLabel, 2, 1)
self.customSendItemsLayout.addWidget(self.networkvoltageLabel, 2, 2)
self.customSendItemsLayout.addWidget(self.networktemLabel, 2, 3)
# 初始化结构体
self.structStatusCheckRsp = Struct(
"<BB Q IIII IBBBBIB III III III III III i II 3s IIII d Q dBB dB H B 2s BBBbbb HHHBBbB B 3s")
def insertSendItem(self, item = None, load = False):
caption = item["caption"]
@@ -659,12 +686,12 @@ class Plugin(Plugin_Base):
cmd_id = binary_data[2]
print(f"收到指令: cmd_id=0x{cmd_id:02X}")
if cmd_id == 0xE4: # 图像测试回令
if cmd_id == 0xE5: # 图像测试回令
result = self.evalimageTestRsp(binary_data)
self.showReceiveDataSignal.emit(result)
return
elif cmd_id == 0xE6: # 遥测回令
result = self.evalStatusCheckRsp(binary_data)
elif cmd_id == 0xE1: # 自检回令
result = self.evalSelfTestRsp(binary_data)
self.showReceiveDataSignal.emit(result)
return
else:
@@ -702,135 +729,85 @@ class Plugin(Plugin_Base):
ret += '\n'
return ret
def evalStatusCheckRsp(self, data: bytes):
def evalSelfTestRsp(self, data: bytes):
print('“”“”“”“”“”“”“”“”“”“”“”“')
try:
payload = self.structStatusCheckRsp.unpack(data)
except :
return f"\n### evalStatusCheckRsp:: Failed to unpack data (data length {len(data)} byte).\n"
# 1. 先解析头部获取数据长度和图片类型标识
header_struct = Struct("<2s B B") # 前11字节结构
header_data = header_struct.unpack(data[:4])
frame_head, cmd_id, node_type= header_data
print(data)
print(header_data)
img_flag = data[7:8] # 第八个字节
print('m')
# 3. 动态构建完整结构体
struct_format = f"<2s B B BBBBbbb 2B 2B 2B BBbBB 3s B B B 2s"
full_struct = Struct(struct_format)
print('km')
# 计算结构体要求的总长度
required_len = 30 # 头部11 + 数据段data_len + 尾部5
print(f"预期长度: {required_len}, 实际数据长度: {len(data)}")
payload = full_struct.unpack(data)
print('lm')
except Exception as e:
print('x')
return f"\n### evalselfTestRsp:: Failed to unpack data (data length {len(data)} byte).\n错误信息: {str(e)}"
ret = "----------- 自检回令 -----------\n"
ret = "----------- 遥测回令 -----------\n"
ret += f"节点编号: 0x{payload[-2]:02X}\n"
ret += "节点类型: "
if payload[1] == 0xEE:
ret += f"C频段 (0x{payload[1]:02X})\n"
ret += "节点状态: "
if payload[3] == 0xAA:
ret += f"正常 (0x{payload[3]:02X})\n"
network_status='正常'
elif payload[6] == 0x55:
ret += f"异常 (0x{payload[3]:02X})\n"
network_status='异常'
else:
ret += f"【未知错误】(0x{payload[1]:02X})\n"
ret += f"【未知错误】(0x{payload[3]:02X})\n"
network_status='未知错误'
ret += f"时间戳: {payload[2]/1e5:.2f} ms\n"
sysbusOffset = 3
linkOffset = 7
phyOffset = 36
hwOffset = 47
ret += "\n -- 总线状态\n"
ret += f"配置装订: {payload[sysbusOffset + 0]:08X}\n"
ret += f"接收数据计数: {payload[sysbusOffset + 1]:>6d}\n"
ret += f"发送数据计数: {payload[sysbusOffset + 2]:>6d}\n"
ret += f"遥测请求计数: {payload[sysbusOffset + 3]:>6d}\n"
ret += "\n -- 链路层状态\n"
ret += f"时元号: {payload[linkOffset + 0]:>6d}\n"
ret += f"时隙号: {payload[linkOffset + 1]:>3d}\n"
ret += "当前角色: "
if payload[linkOffset + 2] == 0xAA:
ret += f"簇首 (0x{payload[linkOffset + 2]:02X})\n"
elif payload[linkOffset + 2] == 0xCC:
ret += f"成员 (0x{payload[linkOffset + 2]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[linkOffset + 2]:02X})\n"
# 网络连接状态更新
network_status = "未连接"
if payload[linkOffset + 3] == 0x11:
network_status = "已连接"
elif payload[linkOffset + 3] == 0x00:
network_status = "未连接"
else:
network_status = f"未知状态 (0x{payload[linkOffset + 3]:02X})"
# 网络运行阶段更新
phase = "未知"
if payload[linkOffset + 4] == 0x11:
phase = "建网阶段"
elif payload[linkOffset + 4] == 0x22:
phase = "业务通信"
else:
phase = f"未知阶段 (0x{payload[linkOffset + 4]:02X})"
self.networkStatusLabel.setText(f"网络连接状态: {network_status}")
self.networkPhaseLabel.setText(f"网络运行阶段: {phase}")
ret += f"重建/入网计数: {payload[linkOffset + 5]:>6d}\n"
ret += f"通信天线位号: {payload[linkOffset + 6]:>1d}\n"
ret += f"建网帧发送计数: {payload[linkOffset + 7]:>6d}\n"
ret += f"建网帧接收计数: {payload[linkOffset + 8]:>6d}\n"
ret += f"建网帧正确计数: {payload[linkOffset + 9]:>6d}\n"
ret += f"应答帧发送计数: {payload[linkOffset + 10]:>6d}\n"
ret += f"应答帧接收计数: {payload[linkOffset + 11]:>6d}\n"
ret += f"应答帧正确计数: {payload[linkOffset + 12]:>6d}\n"
ret += f"分发帧发送计数: {payload[linkOffset + 13]:>6d}\n"
ret += f"分发帧接收计数: {payload[linkOffset + 14]:>6d}\n"
ret += f"分发帧正确计数: {payload[linkOffset + 15]:>6d}\n"
ret += f"网管帧发送计数: {payload[linkOffset + 16]:>6d}\n"
ret += f"网管帧接收计数: {payload[linkOffset + 17]:>6d}\n"
ret += f"网管帧正确计数: {payload[linkOffset + 18]:>6d}\n"
ret += f"RTT 帧发送计数: {payload[linkOffset + 19]:>6d}\n"
ret += f"RTT 帧接收计数: {payload[linkOffset + 20]:>6d}\n"
ret += f"RTT 帧正确计数: {payload[linkOffset + 21]:>6d}\n"
ret += f"业务帧发送计数: {payload[linkOffset + 22]:>6d}\n"
ret += f"业务帧接收计数: {payload[linkOffset + 23]:>6d}\n"
ret += f"业务帧正确计数: {payload[linkOffset + 24]:>6d}\n"
ret += f"时间偏差记录: {payload[linkOffset + 25]/1e2:.2f} us\n"
ret += f"发送数据 ID: {payload[linkOffset + 26]:>6d}\n"
ret += f"接收数据 ID: {payload[linkOffset + 27]:>6d}\n"
ret += "\n -- 物理层状态\n"
ret += f"捕获计数: {payload[phyOffset + 0]:>6d}\n"
ret += f"帧同步计数: {payload[phyOffset + 1]:>6d}\n"
ret += f"译码计数: {payload[phyOffset + 2]:>6d}\n"
ret += f"CRC 正确计数:{payload[phyOffset + 3]:>6d}\n"
ret += f"多普勒估计: {payload[phyOffset + 4]:.2f} Hz\n"
ret += f"正确接收时刻: {payload[phyOffset + 5]/1e2:.2f} us\n"
ret += f"捕获峰均比: {payload[phyOffset + 6]:.2f}\n"
ret += f"捕获相位值: {payload[phyOffset + 7]:>3d}\n"
ret += f"捕获频偏通道: {payload[phyOffset + 8]:>3d}\n"
ret += f"帧同步峰均比: {payload[phyOffset + 9]:.2f}\n"
ret += f"帧同步频偏通道: {payload[phyOffset + 10]:>3d}\n"
ret += f"交织输入数据幅度统计:\t0x{payload[phyOffset + 11]:04X}\n"
ret += f"天线控制模式: {bin(payload[phyOffset + 10])[2:].zfill(8)}\n"
ret += "\n -- 硬件状态\n"
voltage = f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
hwOffset = 4
ret += f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
ret += f"时钟锁定状态: {bin(payload[hwOffset+1])[2:].zfill(8)}\n"
ret += f"AD 锁定状态: {bin(payload[hwOffset+2])[2:].zfill(8)}\n"
ret += f"AD 温度 1: {payload[hwOffset+3]:>4d}\n"
ret += f"AD 温度 2: {payload[hwOffset+4]:>4d}\n"
temp = f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
ret += f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
ret += f"天线-1 工作 PLL: {(payload[hwOffset+6] >> 15) & 0x01:>1d}\n"
ret += f"天线-1 工作频率: {(payload[hwOffset+6] & 0x7FFF)+3700:>4d}\n"
print(payload[3])
ret += f"天线-2 工作 PLL: {(payload[hwOffset+7] >> 15) & 0x01:>1d}\n"
ret += f"天线-2 工作频率: {(payload[hwOffset+7] & 0x7FFF)+3700:>4d}\n"
print(payload[3])
ret += f"天线-3 工作 PLL: {(payload[hwOffset+8] >> 15) & 0x01:>1d}\n"
ret += f"天线-3 工作频率: {(payload[hwOffset+8] & 0x7FFF)+3700:>4d}\n"
print(payload[3])
ret += f"天线 PLL 锁定状态: {bin(payload[hwOffset+9])[2:].zfill(8)}\n"
print(payload[3])
ret += f"天线工作模式: {bin(payload[hwOffset+10])[2:].zfill(8)}\n"
ret += f"天线温度: {payload[hwOffset+11]:>4d}\n"
print('+')
print(voltage)
print('_')
self.networkvoltageLabel.setText(f"电压监测: {voltage}")
self.networktemLabel.setText(f"fgpa温度: {temp}")
print(payload[3])
ret += "--------------------------------\n"
print(payload[3])
print(network_status)
phase=payload[14]
temp=payload[9]
voltage=payload[4]
self.networkStatusLabel.setText(f"节点状态: {network_status}")
self.networkPhaseLabel.setText(f"天线温度: {phase}")
self.networkvoltageLabel.setText(f"电压状态: {voltage}")
self.networktemLabel.setText(f"fgpa温度: {temp}")
return ret + '\n' + self.printFrame(data)
def evalimageTestRsp(self, data: bytes):
print('“”“”“”“”“”“”“”“”“”“”“”“')
try:
# 1. 先解析头部获取数据长度和图片类型标识
header_struct = Struct(">2s B B I B H") # 前11字节结构
header_struct = Struct("<2s B B I B H") # 前11字节结构
header_data = header_struct.unpack(data[:11])
frame_head, cmd_id, node_type, data_id, from_id, data_len = header_data
print(data)
@@ -881,22 +858,28 @@ class Plugin(Plugin_Base):
ret += f"帧尾: {frame_tail.hex().upper()}\n"
print('&&&&&')
# 图像显示逻辑(保留原始控件调用方式)
# 截取有效图像数据
# 图像显示逻辑(添加缩放倍数控制)
# 1. 手动设置缩放倍数(可根据需要修改,例如放大2倍)
# 图像显示逻辑(修正后)
if from_id == 0x01 or from_id == 0x02:
# 图像通道 A → 左侧图像控件
if len(self.widgets) >= 1 and isinstance(self.widgets[0], graphWidgets["image"]):
self.widgets[0].onData(image_data) # 发送有效数据
# 仅传递图像数据,缩放倍数已在控件初始化时通过config设置
self.widgets[0].onData(image_data)
else:
self.showReceiveDataSignal.emit("\n### No valid image widget found (A1)\n")
print(from_id)
elif from_id == 0x03:
# 图像通道 B → 右侧图像控件
if len(self.widgets) >= 2 and isinstance(self.widgets[1], graphWidgets["image"]):
self.widgets[1].onData(image_data) # 发送有效数据
# 仅传递图像数据
self.widgets[1].onData(image_data)
else:
self.showReceiveDataSignal.emit("\n### No valid image widget found (A2)\n")
print(from_id)
print('+')
ret += "------------------------------------\n"
return ret + '\n' + self.printFrame(data)
print(from_id)
print('+')
ret += "------------------------------------\n"
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1535,10 +1535,10 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){
status = ad9361_reg_write(dev, 0x0105, 0x3A); // ADC Large Overload Threshold
status = ad9361_reg_write(dev, 0x0107, 0x2B); // Small LMT Overload Threshold
status = ad9361_reg_write(dev, 0x0108, 0x31); // Large LMT Overload Threshold
status = ad9361_reg_write(dev, 0x0109, 0x00); // Rx1 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x0109, 0x28); // Rx1 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x010A, 0x58); // Rx1 LPF Gain Index
status = ad9361_reg_write(dev, 0x010B, 0x00); // Rx1 Digital Gain Index
status = ad9361_reg_write(dev, 0x010C, 0x00); // Rx2 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x010C, 0x28); // Rx2 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x010D, 0x18); // Rx2 LPF Gain Index
status = ad9361_reg_write(dev, 0x010E, 0x00); // Rx2 Digital Gain Index
status = ad9361_reg_write(dev, 0x0114, 0x30); // Low Power Threshold
+4 -4
View File
@@ -259,10 +259,10 @@ int32_t Hardware_Init(void)
// Status = ad9361_reg_read(ad9361_1_reg_inst, 0x0002, &rd_back);
// Status = ad9361_reg_read(ad9361_2_reg_inst, 0x0002, &rd_back);
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
#endif
#ifdef AD9653
+32 -12
View File
@@ -80,7 +80,7 @@ struct callback_desc apptimer_callback_desc = {
// .headId = L2_HEAD_ID,
// .netScale = L2_NET_SCALE,
// .initTable = initRoutTable,
// .normalTable = normalRoutTable0,
// .normalTable = normalRoutTable1,
// .serviceRate = L2_SVC_512K,
// .phyInstPtr = NULL, // physical layer reference
// .tmcInstPtr = NULL
@@ -93,7 +93,7 @@ L2_CONFIG linkConfig = {
.headId = L2_HEAD_ID,
.netScale = L2_NET_SCALE,
.initTable = initRoutTable,
.normalTable = normalRoutTable0,
.normalTable = normalRoutTable1,
.serviceRate = L2_SVC_512K,
.phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL
@@ -202,6 +202,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
XScuGic_CPUWriteReg((XScuGic *)(xil_dev->instance), XSCUGIC_EOI_OFFSET, intrState);
/* Initialize physical layer interrupt. */
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, PHY_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
@@ -224,6 +225,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
/* Initialize linklayer layer interrupt. */
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, PERIODIC_5MS_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
@@ -246,17 +248,18 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
/* Initialize system bus interrupt. */
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_TX_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x10);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_TX_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
@@ -264,20 +267,22 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
Status = irq_register_callback(descPtr, SYSBUS_TX_INTR_ID, &sysbus_tx_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_TX_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_RX_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x18);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_RX_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
@@ -285,7 +290,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
Status = irq_register_callback(descPtr, SYSBUS_RX_INTR_ID, &sysbus_rx_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_RX_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
@@ -294,7 +299,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
Status = irq_register_callback(descPtr, APPTIMER_INTR_ID, &apptimer_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("APPTIMER_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
@@ -422,9 +427,24 @@ void AppTimer_IntrHandler(void *context)
{
Phy_UpdateLogging(phyInstPtr);
}
/*
* Read the new Control/Status Register content.
*/
uint32_t ControlStatusReg;
ControlStatusReg = XTmrCtr_ReadReg(((XTmrCtr *)xdesc->instance)->BaseAddress,
0, XTC_TCSR_OFFSET);
/*
* Acknowledge the interrupt by clearing the
* interrupt bit in the timer control status
* register, this is done after calling the
* handler so the application could call
* IsExpired, the interrupt is cleared by
* writing a 1 to the interrupt bit of the
* register without changing any of the other
* bits
*/
XTmrCtr_WriteReg(((XTmrCtr *)xdesc->instance)->BaseAddress, 0,
XTC_TCSR_OFFSET, XTC_CSR_INT_OCCURED_MASK);
XTC_TCSR_OFFSET, ControlStatusReg | XTC_CSR_INT_OCCURED_MASK);
}
#else
#error No timer implementation!
@@ -546,7 +566,7 @@ int main(void)
}
// Start System Monitor logging.
timer_start(logTmPtr);
Status = timer_start(logTmPtr);
DBG_PRINT("Physical started...\n");
Phy_Start(phyInstPtr);
+2 -2
View File
@@ -28,7 +28,7 @@
#include "circ_queue.h"
#include "../time_ctrl/time_ctrl.h"
#ifndef EMULATION
#include "../config/app_config.h"
#include "../../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/
#define NET_START_TIME_INFTY UINT32_MAX
@@ -890,7 +890,7 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
{
UpdateMainSate(instPtr, L2_NORMAL_STATE);
instPtr->rtneConfig.rtneTable = instPtr->config.normalTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalRoutTable0);
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalRoutTable1);
}
else
{
+3 -1
View File
@@ -95,6 +95,8 @@ typedef struct
int64_t timeDev; ///< last time deviation estimation result
uint32_t reconnectCnt; ///< reconnect trial count
uint32_t txValidMsgCnt; ///< non-default tx message count
uint32_t rxValidMsgCnt; ///< non-default rx message count
L2_MSG_RECORD rxLog;
L2_MSG_RECORD txLog;
} L2_LOG;
@@ -132,9 +134,9 @@ typedef struct
/************************** Variable Definitions *****************************/
extern L2_RTNE_TABLE_ENTRY *initRoutTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable0[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable1[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable2[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable3[L2_INIT_RTNE_PERIOD];
/************************** Function Prototypes ******************************/
/**
* @defgroup LinkLayer_Main
+1 -1
View File
@@ -25,7 +25,7 @@
#include "geometry/quaternion.h"
#include "../phy_layer/phy_layer.h"
#ifndef EMULATION
#include "../config/app_config.h"
#include "../../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/
/**
+3 -3
View File
@@ -858,17 +858,17 @@ L2_RTNE_TABLE_ENTRY *initRoutTable[L2_INIT_RTNE_PERIOD] =
tab10Mng10Svc
};
L2_RTNE_TABLE_ENTRY *normalRoutTable0[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *normalRoutTable1[L2_INIT_RTNE_PERIOD] =
{
tab10Mng10Svc
};
L2_RTNE_TABLE_ENTRY *normalRoutTable1[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *normalRoutTable2[L2_INIT_RTNE_PERIOD] =
{
tab10Mng3Svc
};
L2_RTNE_TABLE_ENTRY *normalRoutTable2[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *normalRoutTable3[L2_INIT_RTNE_PERIOD] =
{
tab3Mng3Svc
};
+13 -4
View File
@@ -29,7 +29,7 @@
#include "common.h"
#include "circ_queue.h"
#ifndef EMULATION
#include "../config/app_config.h"
#include "../../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
@@ -211,13 +211,14 @@ static int32_t Service_Packing128K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
}
else
{
// message->common.dst = sendPayload->nodeId;
message->dataId = sendPayload->dataId;
message->dataLen = sendPayload->dataLen;
memset(message->data, 0xAA, maxDataLen);
memcpy(message->data, sendPayload->data, (sendPayload->dataLen > maxDataLen) ?
maxDataLen : sendPayload->dataLen);
free(sendPayload);
// logging
instPtr->log.txValidMsgCnt++;
}
}
else
@@ -289,13 +290,14 @@ static int32_t Service_Packing512K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
}
else
{
// message->common.dst = sendPayload->nodeId;
message->dataId = sendPayload->dataId;
message->dataLen = sendPayload->dataLen;
memset(message->data, 0xAA, maxDataLen);
memcpy(message->data, sendPayload->data, (sendPayload->dataLen > maxDataLen) ?
maxDataLen : sendPayload->dataLen);
free(sendPayload);
// logging
instPtr->log.txValidMsgCnt++;
}
// Append CRC
@@ -359,13 +361,14 @@ static int32_t Service_Packing2M(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t d
}
else
{
// message->common.dst = sendPayload->nodeId;
message->dataId = sendPayload->dataId;
message->dataLen = sendPayload->dataLen;
memset(message->data, 0xAA, maxDataLen);
memcpy(message->data, sendPayload->data, (sendPayload->dataLen > maxDataLen) ?
maxDataLen : sendPayload->dataLen);
free(sendPayload);
// logging
instPtr->log.txValidMsgCnt++;
}
// Append CRC
@@ -542,6 +545,8 @@ static int32_t Service_PktHandler128K(L2_INST *instPtr, uint8_t *msg)
memcpy(recvPayload->data, message->data, message->dataLen);
SysMonitor_GenRecvRsp(recvPayload);
free(recvPayload);
// logging
instPtr->log.rxValidMsgCnt++;
}
// Logging...
@@ -631,6 +636,8 @@ static int32_t Service_PktHandler512K(L2_INST *instPtr, uint8_t *msg)
memcpy(recvPayload->data, message->data, message->dataLen);
SysMonitor_GenRecvRsp(recvPayload);
free(recvPayload);
// logging
instPtr->log.rxValidMsgCnt++;
}
// Logging...
@@ -720,6 +727,8 @@ static int32_t Service_PktHandler2M(L2_INST *instPtr, uint8_t *msg)
memcpy(recvPayload->data, message->data, message->dataLen);
SysMonitor_GenRecvRsp(recvPayload);
free(recvPayload);
// logging
instPtr->log.rxValidMsgCnt++;
}
// Logging...
+5 -5
View File
@@ -292,11 +292,11 @@ const uint8_t hopPattern_512KBPS_4MS[L1_FRAME_512KBPS_4MS_HOPS] =
const uint8_t hopPattern_2MBPS_4MS[L1_FRAME_2MBPS_4MS_HOPS] =
{
16U, 17U, 18U, 19U, 20U, 21U, 20U, 20U,
20U, 20U, 20U, 20U, 20U, 20U, 20U, 20U,
20U, 20U, 20U, 20U, 20U, 20U, 20U, 20U,
20U, 20U, 20U, 20U, 20U, 20U, 20U, 20U,
20U, 20U, 20U, 20U, 20U, 20U,
16U, 17U, 18U, 19U, 20U, 21U, 10U, 10U,
10U, 10U, 10U, 10U, 10U, 10U, 10U, 10U,
10U, 10U, 10U, 10U, 10U, 10U, 10U, 10U,
10U, 10U, 10U, 10U, 10U, 10U, 10U, 10U,
10U, 10U, 10U, 10U, 10U, 10U,
};
/** @} PhysicalLayer_AntennaConfig_Constants*/
+51 -6
View File
@@ -696,6 +696,7 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
ASSERT(instPtr != NULL);
int32_t Status;
uint32_t phyModeCtrl, hopNum;
uint16_t txMultifactor; // physical layer tx power digital attenuation
const uint8_t *hopPattern;
// Implement a ping-pong flow, offset always is 0 or half of buffer depth.
instPtr->antConfigOffset = (L1_ANTCONFIG_MAX_LEN >> 1) - instPtr->antConfigOffset;
@@ -717,34 +718,71 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
}
switch (frameType)
{
#ifdef HSJL_GE
case L1_FRAME_ADV_24MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ADV_24MS;
hopNum = L1_FRAME_ADV_24MS_HOPS;
hopPattern = hopPattern_ADV_24MS;
txMultifactor = 0x1f00; // -12dB
break;
case L1_FRAME_ACK_8MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ACK_8MS;
hopNum = L1_FRAME_ACK_8MS_HOPS;
hopPattern = hopPattern_ACK_8MS;
txMultifactor = 0x1f00; // -12dB
break;
case L1_FRAME_128KBPS_4MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_128KBPS_4MS;
hopNum = L1_FRAME_128KBPS_4MS_HOPS;
hopPattern = hopPattern_128KBPS_4MS;
txMultifactor = 0x2000; // -15dB
break;
case L1_FRAME_512KBPS_4MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_512KBPS_4MS;
hopNum = L1_FRAME_512KBPS_4MS_HOPS;
hopPattern = hopPattern_512KBPS_4MS;
txMultifactor = 0x2000; // -12dB
break;
case L1_FRAME_2MBPS_4MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_2MBPS_4MS;
hopNum = L1_FRAME_2MBPS_4MS_HOPS;
hopPattern = hopPattern_2MBPS_4MS;
txMultifactor = 0x7000; // -6dB, baseline
break;
#else
case L1_FRAME_ADV_24MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ADV_24MS;
hopNum = L1_FRAME_ADV_24MS_HOPS;
hopPattern = hopPattern_ADV_24MS;
txMultifactor = 0x0A00; // -12dB
break;
case L1_FRAME_ACK_8MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ACK_8MS;
hopNum = L1_FRAME_ACK_8MS_HOPS;
hopPattern = hopPattern_ACK_8MS;
txMultifactor = 0x0A00; // -12dB
break;
case L1_FRAME_128KBPS_4MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_128KBPS_4MS;
hopNum = L1_FRAME_128KBPS_4MS_HOPS;
hopPattern = hopPattern_128KBPS_4MS;
txMultifactor = 0x0F00; // -15dB
break;
case L1_FRAME_512KBPS_4MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_512KBPS_4MS;
hopNum = L1_FRAME_512KBPS_4MS_HOPS;
hopPattern = hopPattern_512KBPS_4MS;
txMultifactor = 0x1000; // -12dB
break;
case L1_FRAME_2MBPS_4MS:
phyModeCtrl |= PHY_MODE_CTRL_FRAME_2MBPS_4MS;
hopNum = L1_FRAME_2MBPS_4MS_HOPS;
hopPattern = hopPattern_2MBPS_4MS;
txMultifactor = 0x2000; // -6dB, baseline
break;
#endif
default:
return EPARAM;
break;
}
// Set frame configs
@@ -794,6 +832,9 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
}
}
// Set tx multifactor
PhyWrite(instPtr, TX_MULFAC, txMultifactor);
// Trigger physical configuration.
// Indicate physical layer that all the configurations were done.
PhyWrite(instPtr, SLOT_CMD, SLOT_CMD_KEY);
@@ -1026,9 +1067,10 @@ void Phy_RefreshHwSate(PHY_INST *instPtr)
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
? INT8_MAX
: ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
// FIXME: XADC range needs further refine
instPtr->hwSate.spFpgaVolt = (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK);
instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK))
&& (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK))
&& (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK));
&& (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK));
#else
double evalData;
instPtr->hwSate.isSpOk = true;
@@ -1106,9 +1148,12 @@ void Phy_RefreshHwSate(PHY_INST *instPtr)
// -- Update FPGA Chip temperature, unit 1 deg
rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_TEMP);
evalData = XAdcPs_RawToTemperature(rawData);
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
? INT8_MAX
: ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
// instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
// ? INT8_MAX
// : ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
// FIXME: XADC readback is required
instPtr->hwSate.spFpgaTemp = ((instPtr->hwSate.spAdTemp_0 - 5) + (instPtr->hwSate.spAdTemp_1 - 7)) / 2;
instPtr->hwSate.spFpgaVolt = (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK);
instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK))
&& (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK))
&& (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK));
+1 -1
View File
@@ -24,7 +24,7 @@
#include "common.h"
#ifndef EMULATION
#include "xbram.h"
#include "../config/app_config.h"
#include "../../config/app_config.h"
#ifdef HSJL_GE // Zynq MPSoC (Zynq UltraScale+)
#include "xsysmon.h"
#else
+9 -1
View File
@@ -207,7 +207,7 @@
/**
* Register: TM_TARGET_L
*/
#define TM_TARGET_L 0x00000064U
#define TM_TARGET_L 0x00000034U
#define TM_TARGET_L_SHIFT 0
#define TM_TARGET_L_WIDTH 32
#define TM_TARGET_L_MASK 0xFFFFFFFFU
@@ -260,6 +260,14 @@
#define ANT_SELECT_INDEX_WIDTH 32
#define ANT_SELECT_INDEX_MASK 0xFFFFFFFFU
/**
* Register: TX_MULFAC
*/
#define TX_MULFAC 0x00000048U
#define TX_MULFAC_SHIFT 0
#define TX_MULFAC_WIDTH 16
#define TX_MULFAC_MASK 0x0000FFFFU
/**
* Register: ANT_STATUS_1
*/
+13 -7
View File
@@ -345,24 +345,30 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
{
switch (msg[WD_RTNE_CMD])
{
case 0:
{
reconfig |= (linkConfig.normalTable != normalRoutTable0);
linkConfig.normalTable = normalRoutTable0;
break;
}
case 1:
{
reconfig |= (linkConfig.initTable != normalRoutTable1);
reconfig |= (linkConfig.normalTable != normalRoutTable1);
linkConfig.initTable = normalRoutTable1;
linkConfig.normalTable = normalRoutTable1;
break;
}
case 2:
{
reconfig |= (linkConfig.initTable != normalRoutTable2);
reconfig |= (linkConfig.normalTable != normalRoutTable2);
linkConfig.initTable = normalRoutTable2;
linkConfig.normalTable = normalRoutTable2;
break;
}
case 3:
{
reconfig |= (linkConfig.initTable != normalRoutTable3);
reconfig |= (linkConfig.normalTable != normalRoutTable3);
linkConfig.initTable = normalRoutTable3;
linkConfig.normalTable = normalRoutTable3;
break;
}
default:
{
// Ignore current command
@@ -449,7 +455,7 @@ int32_t SystemBus_GenRecvRsp(SYSBUS *instPtr, SYSBUS_SVC_PLD *payload)
return ENOMEM;
}
sysbusRsp->len = payload->dataLen + RECV_DATA_LEN_OFFSET;
sysbusRsp->len = payload->dataLen + RECV_DATA_OFFSET;
sysbusRsp->data[WD_CMD] = CMD_RECV_DATA;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
+10
View File
@@ -61,6 +61,15 @@
#define VOLT_ANT_NIL_OK BIT(4)
#define ANT_STATE_OK BIT(6)
#ifdef HSJL_GE
// Xilinx Recommended
#define IS_PS_VALID(x) (x <= 0.892 && x >= 0.808)
#define IS_PSAUX_VALID(x) (x <= 1.89 && x >= 1.71)
#define IS_DDR_VALID(x) (x <= 1.89 && x >= 1.14)
#define IS_PL_VALID(x) (x <= 0.892 && x >= 0.808)
#define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71)
#define IS_BRAM_VALID(x) (x <= 0.892 && x >= 0.808)
#else
// Xilinx Recommended
// #define IS_PS_VALID(x) (x <= 1.05 && x >= 0.95)
// #define IS_PSAUX_VALID(x) (x <= 1.89 && x >= 1.71)
@@ -74,6 +83,7 @@
#define IS_PL_VALID(x) (x <= 1.1 && (x) >= 0.9)
#define IS_PLAUX_VALID(x) ((x) <= 2.0 && (x) >= 1.6)
#define IS_BRAM_VALID(x) ((x) <= 1.1 && (x) >= 0.9)
#endif
#define CLK_SP_PLL1_LOCK BIT(0)
#define CLK_SP_PLL2_LOCK BIT(2)