forked from gatsby/df_datalink
doc & fix: 增加comtool plugin, 修改上传遥测长度问题
This commit is contained in:
+15
-12
@@ -1,7 +1,7 @@
|
||||
# HSJL 上位机串口通信协议
|
||||
|
||||
> 版本:v1.2
|
||||
> 日期:2025 年 6 月 12 日
|
||||
> 日期:2025 年 6 月 16 日
|
||||
|
||||
---
|
||||
|
||||
@@ -46,19 +46,19 @@ block-beta
|
||||
|
||||
| 字段名 | 字节数 (Byte) | 说明 |
|
||||
|--|--|--|
|
||||
| 帧头 | 2 | 固定值:`0x54 0x5A` |
|
||||
| 帧头 | 2 | 固定值:`0x5A 0x54` |
|
||||
| 数据段 | ≤950 | 业务数据内容 |
|
||||
| Dummy Byte | 1 | 固定填充:`0x00` |
|
||||
| 校验和 | 1 | 所有**数据段**字节累加和(无符号累加) |
|
||||
| 数据段长度 | 2 | 数据段字节数(不含 Dummy/校验/帧尾) |
|
||||
| 帧尾 | 2 | 固定值:`0xFE 0x5A` |
|
||||
| 帧尾 | 2 | 固定值:`0x5A 0xFE` |
|
||||
|
||||
### 帧内冲突规避规则
|
||||
|
||||
为防止数据段中出现帧尾 `0xFE 0x5A`:
|
||||
为防止数据段中出现帧尾 `0x5A 0xFE`:
|
||||
|
||||
- 若数据段中出现 `0xFE 0x5A`,需插入 `0x00` 变成 `0x00 0xFE 0x5A`
|
||||
- 接收端收到 `0x00 0xFE 0x5A` 还原为 `0xFE 0x5A`
|
||||
- 若数据段中出现 `0x5A 0xFE`,需插入 `0x00` 变成 `0x00 0x5A 0xFE`
|
||||
- 接收端收到 `0x00 0x5A 0xFE` 还原为 `0x5A 0xFE`
|
||||
|
||||
### 帧长说明
|
||||
|
||||
@@ -192,13 +192,13 @@ block-beta
|
||||
|
||||
### (可选)遥测指令
|
||||
|
||||
遥测指令上传的 Payload 由 5 部分组成,顺序存储,共 188 字节:
|
||||
遥测指令上传的 Payload 由 5 部分组成,顺序存储,共 200 字节:
|
||||
|
||||
| 字段名 | 字节数 (Byte) |
|
||||
| ------------ | ------------- |
|
||||
| 时间戳 | 8 |
|
||||
| 总线日志 | 16 |
|
||||
| 链路层日志 | 88 |
|
||||
| 链路层日志 | 100 |
|
||||
| 物理层日志 | 56 |
|
||||
| 硬件状态日志 | 20 |
|
||||
|
||||
@@ -219,7 +219,7 @@ block-beta
|
||||
|
||||
#### 链路层日志
|
||||
|
||||
链路层日志顺序存储,共 88字节:
|
||||
链路层日志顺序存储,共 100 字节:
|
||||
|
||||
| 字段名 | 字节数 (Byte) | 说明 |
|
||||
| -------------------- | ------------- | ---------------------------------------- |
|
||||
@@ -239,12 +239,15 @@ block-beta
|
||||
| 分发帧发送计数器 | 4 | 每发送一次分发帧,计数器+1(仅簇首) |
|
||||
| 分发帧接收计数器 | 4 | 每配置接收一次分发帧,计数器+1(仅成员) |
|
||||
| 分发帧接收正确计数器 | 4 | 每正确接收一次分发帧,计数器+1(仅成员) |
|
||||
| 网关帧发送计数器 | 4 | 每发送一次网关帧,计数器+1 |
|
||||
| 网关帧接收计数器 | 4 | 每配置接收一次网关帧,计数器+1 |
|
||||
| 网关帧接收正确计数器 | 4 | 每正确接收一次网关帧,计数器+1 |
|
||||
| 网管帧发送计数器 | 4 | 每发送一次网管帧,计数器+1 |
|
||||
| 网管帧接收计数器 | 4 | 每配置接收一次网管帧,计数器+1 |
|
||||
| 网管帧接收正确计数器 | 4 | 每正确接收一次网管帧,计数器+1 |
|
||||
| RTT帧发送计数器 | 4 | 每发送一次 RTT 帧,计数器+1 |
|
||||
| RTT帧接收计数器 | 4 | 每配置接收一次 RTT 帧,计数器+1 |
|
||||
| RTT帧接收正确计数器 | 4 | 每正确接收一次 RTT 帧,计数器+1 |
|
||||
| 业务帧发送计数器 | 4 | 每发送一次业务帧,计数器+1 |
|
||||
| 业务帧接收计数器 | 4 | 每配置接收一次业务帧,计数器+1 |
|
||||
| 业务帧接收正确计数器 | 4 | 每正确接收一次业务帧,计数器+1 |
|
||||
| 时间偏移量记录 | 4, int32 | 记录上一次节点时间和帧同步时间的偏差 |
|
||||
| 发送数据ID记录 | 4 | 记录上一次发送数据的ID |
|
||||
| 接收数据ID记录 | 4 | 记录上一次接收数据的ID |
|
||||
|
||||
@@ -0,0 +1,433 @@
|
||||
'''
|
||||
@brief This is an example plugin, can receive and send data
|
||||
@author
|
||||
@date
|
||||
@license LGPL-3.0
|
||||
'''
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QPushButton, QLabel, QScrollArea, QSplitter
|
||||
from PyQt5.QtCore import Qt, pyqtSignal
|
||||
from PyQt5.QtGui import QFont, QTextCursor
|
||||
from struct import Struct
|
||||
try:
|
||||
import utils_ui
|
||||
from plugins.base import Plugin_Base
|
||||
from conn import ConnectionStatus
|
||||
from i18n import _
|
||||
from widgets import statusBar
|
||||
except ImportError:
|
||||
from COMTool import utils_ui
|
||||
from COMTool.plugins.base import Plugin_Base
|
||||
from COMTool.i18n import _
|
||||
from COMTool.conn import ConnectionStatus
|
||||
from COMTool.widgets import statusBar
|
||||
|
||||
class Plugin(Plugin_Base):
|
||||
id = "HJ DATALINK"
|
||||
name = _("HJ DATALINK")
|
||||
showReceiveDataSignal = pyqtSignal(str)
|
||||
|
||||
def onInit(self, config):
|
||||
'''
|
||||
init params
|
||||
'''
|
||||
default = {
|
||||
"version": 1,
|
||||
"customSendItems": [
|
||||
{
|
||||
"caption": "自检",
|
||||
"icon": "fa5.question-circle",
|
||||
"data": "5A 54 E1 EE 00 CF 02 5A FE"
|
||||
},
|
||||
# {
|
||||
# "caption": "数据发送测试 - 1",
|
||||
# "icon": "fa5.play-circle",
|
||||
# "data": ""
|
||||
# },
|
||||
# {
|
||||
# "caption": "数据发送测试 - 2",
|
||||
# "icon": "fa5.play-circle",
|
||||
# "data": ""
|
||||
# },
|
||||
{
|
||||
"caption": "装订 - 【主 - 0x01】128 kbps,时隙表 0",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE AA 01 22 00 00 7B 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【主 - 0x01】2 Mbps,时隙表 1",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE AA 01 44 01 00 C1 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【主 - 0x01】静默",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE 55 01 22 00 00 49 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从 - 0x02】128 kbps,时隙表 0",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE AA 02 22 00 00 9F 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从 - 0x02】2 Mbps,时隙表 1",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE AA 02 44 01 00 C2 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从 - 0x02】静默",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE 55 02 22 00 00 0C 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从 - 0x03】128 kbps,时隙表 0",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE AA 03 22 00 00 A0 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从 - 0x03】2 Mbps,时隙表 1",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE AA 03 44 01 00 C3 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从 - 0x03】静默",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 EE 55 03 22 00 00 0D 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "遥测",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E6 EE 00 D4 02 5A FE"
|
||||
},
|
||||
]
|
||||
}
|
||||
self.config = config
|
||||
for k in default:
|
||||
if not k in self.config:
|
||||
self.config[k] = default[k]
|
||||
|
||||
def onConnChanged(self, status:ConnectionStatus, msg:str):
|
||||
print("-- connection changed: {}, msg: {}".format(status, msg))
|
||||
|
||||
def onWidgetMain(self, parent):
|
||||
'''
|
||||
main widget, just return a QWidget object
|
||||
'''
|
||||
self.mainWidget = QSplitter(Qt.Vertical)
|
||||
# receive widget
|
||||
self.receiveWidget = QTextEdit("")
|
||||
font = QFont('Consolas, DejaVu Sans Mono, Courier New, monospace, Microsoft YaHei', 10)
|
||||
self.receiveWidget.setFont(font)
|
||||
self.receiveWidget.setLineWrapMode(QTextEdit.NoWrap)
|
||||
# clear button
|
||||
self.clearBtn = QPushButton("")
|
||||
utils_ui.setButtonIcon(self.clearBtn, "mdi6.broom")
|
||||
# send scroll
|
||||
self.customSendScroll = QScrollArea()
|
||||
self.customSendScroll.setMinimumHeight(20)
|
||||
self.customSendScroll.setWidgetResizable(True)
|
||||
self.customSendScroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||
self.customSendScroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
cutomSendItemsWraper = QWidget()
|
||||
self.customSendScroll.setWidget(cutomSendItemsWraper)
|
||||
|
||||
# -- wrapper widget
|
||||
cutomSendItemsWraper0 = QWidget()
|
||||
cutomSendItemsWraper0.setProperty("class", "scrollbar2")
|
||||
layout0 = QVBoxLayout()
|
||||
layout0.setContentsMargins(0,8,0,0)
|
||||
cutomSendItemsWraper0.setLayout(layout0)
|
||||
layout0.addWidget(self.customSendScroll)
|
||||
customSendItemsLayoutWrapper = QVBoxLayout()
|
||||
customSendItemsLayoutWrapper.setContentsMargins(0,0,0,0)
|
||||
cutomSendItemsWraper.setLayout(customSendItemsLayoutWrapper)
|
||||
|
||||
# -- items container
|
||||
self.customItems = QWidget()
|
||||
self.customSendItemsLayout = QVBoxLayout()
|
||||
self.customSendItemsLayout.setContentsMargins(0,0,0,0)
|
||||
self.customItems.setLayout(self.customSendItemsLayout)
|
||||
customSendItemsLayoutWrapper.addWidget(self.customItems)
|
||||
customSendItemsLayoutWrapper.addStretch(0)
|
||||
|
||||
# add widgets
|
||||
self.mainWidget.addWidget(self.receiveWidget)
|
||||
self.mainWidget.addWidget(self.clearBtn)
|
||||
self.mainWidget.addWidget(cutomSendItemsWraper0)
|
||||
self.mainWidget.setStretchFactor(0, 2)
|
||||
self.mainWidget.setStretchFactor(1, 1)
|
||||
self.mainWidget.setStretchFactor(2, 11)
|
||||
|
||||
# event
|
||||
def clearReceived():
|
||||
self.receiveWidget.clear();self.statusBar.clear()
|
||||
self.clearBtn.clicked.connect(clearReceived)
|
||||
return self.mainWidget
|
||||
|
||||
def onWidgetStatusBar(self, parent):
|
||||
self.statusBar = statusBar(rxTxCount=True)
|
||||
return self.statusBar
|
||||
|
||||
def onUiInitDone(self):
|
||||
'''
|
||||
UI init done, you can update your widget here
|
||||
this method runs in UI thread, do not block too long
|
||||
'''
|
||||
newItems = []
|
||||
print(self.config["customSendItems"])
|
||||
for item in self.config["customSendItems"]:
|
||||
print(item)
|
||||
item = self.insertSendItem(item, load=True)
|
||||
newItems.append(item)
|
||||
self.config["customSendItems"] = newItems
|
||||
self.showReceiveDataSignal.connect(self.showReceivedData)
|
||||
# frame struct
|
||||
self.structSelfTestRsp = Struct("<BB B BBBbbb HHHBBbB B 3s")
|
||||
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")
|
||||
self.structFljData = Struct("<dddd IHI fff fff")
|
||||
self.structLjData = Struct("<IHI ffff IHI fff fff fff IHI fff fff fff IHI fff fff fff I")
|
||||
self.structSysInfo = Struct("<IHI H B I B fff fff fff")
|
||||
|
||||
def insertSendItem(self, item = None, load = False):
|
||||
caption = item["caption"]
|
||||
itemWidget = QWidget()
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0,0,0,0)
|
||||
itemWidget.setLayout(layout)
|
||||
send = QPushButton("")
|
||||
label = QLabel(caption)
|
||||
if (not "icon" in item) or not item["icon"]:
|
||||
item["icon"] = "fa.send"
|
||||
utils_ui.setButtonIcon(send, item["icon"])
|
||||
send.setProperty("class", "smallBtn")
|
||||
def sendCustomData(idx):
|
||||
self.sendCustomItem(self.config["customSendItems"][idx])
|
||||
send.clicked.connect(lambda: sendCustomData(self.customSendItemsLayout.indexOf(itemWidget)))
|
||||
layout.addWidget(label)
|
||||
layout.addWidget(send)
|
||||
self.customSendItemsLayout.addWidget(itemWidget)
|
||||
if not load:
|
||||
self.config["customSendItems"].append(item)
|
||||
return item
|
||||
|
||||
def showReceivedData(self, text: str):
|
||||
curScrollValue = self.receiveWidget.verticalScrollBar().value()
|
||||
self.receiveWidget.moveCursor(QTextCursor.End)
|
||||
endScrollValue = self.receiveWidget.verticalScrollBar().value()
|
||||
self.receiveWidget.insertPlainText(text)
|
||||
if curScrollValue < endScrollValue:
|
||||
self.receiveWidget.verticalScrollBar().setValue(curScrollValue)
|
||||
else:
|
||||
self.receiveWidget.moveCursor(QTextCursor.End)
|
||||
|
||||
def onReceived(self, data : bytes):
|
||||
'''
|
||||
call in receive thread, not UI thread
|
||||
'''
|
||||
self.statusBar.addRx(len(data))
|
||||
## Apply data validation check
|
||||
if len(data) < 7:
|
||||
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong frame header/tail\n")
|
||||
return
|
||||
|
||||
dataLen = data[-3]
|
||||
if data[0] != 0x5A or data[1] != 0x54 or data[-1] != 0xFE or data[-2] != 0x5A:
|
||||
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong length\n")
|
||||
|
||||
checkSum = 0
|
||||
for i in data[2:-4]:
|
||||
checkSum += i
|
||||
if checkSum & 0xFF != data[-4]:
|
||||
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong check sum\n")
|
||||
|
||||
## Eval data
|
||||
data = data[2:-5].replace(b'\x00\x54\xFE', b'\x54\xFE')
|
||||
# self.printFrame(data)
|
||||
if data[0] == 0xE1:
|
||||
# eval self test
|
||||
self.showReceiveDataSignal.emit(self.evalSelfTestRsp(data) + "\n")
|
||||
elif data[0] == 0xE6 or data[0] == 0xF6:
|
||||
self.showReceiveDataSignal.emit(self.evalStatusCheckRsp(data) + "\n")
|
||||
elif data[0] == 0xE5 or data[0] == 0xF5:
|
||||
self.showReceiveDataSignal.emit('Retrieved Data Frame:\n' + self.printFrame(data) + "\n")
|
||||
else:
|
||||
self.showReceiveDataSignal.emit(f"\n### Unexpected response code 0x{data[0]:02x}.\n")
|
||||
|
||||
def evalSelfTestRsp(self, data: bytes):
|
||||
try:
|
||||
payload = self.structSelfTestRsp.unpack(data)
|
||||
except :
|
||||
return f"\n### evalSelfTestRsp:: Failed to unpack data (data length {len(data)} byte).\n"
|
||||
|
||||
ret = "----------- 自检回令 -----------\n"
|
||||
|
||||
ret += f"节点编号: 0x{payload[-2]:02X}\n"
|
||||
|
||||
ret += "节点类型: "
|
||||
if payload[1] == 0xEE:
|
||||
ret += f"C频段 (0x{payload[1]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[1]:02X})\n"
|
||||
|
||||
ret += "自检结果: "
|
||||
if payload[2] == 0xAA:
|
||||
ret += f"正常 (0x{payload[2]:02X})\n"
|
||||
elif payload[2] == 0x55:
|
||||
ret += f"异常 (0x{payload[2]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[2]:02X})\n"
|
||||
|
||||
hwOffset = 3
|
||||
|
||||
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"
|
||||
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"
|
||||
ret += f"天线-2 工作 PLL: {(payload[hwOffset+7] >> 15) & 0x01:>1d}\n"
|
||||
ret += f"天线-2 工作频率: {(payload[hwOffset+7] & 0x7FFF)+3700:>4d}\n"
|
||||
ret += f"天线-3 工作 PLL: {(payload[hwOffset+8] >> 15) & 0x01:>1d}\n"
|
||||
ret += f"天线-3 工作频率: {(payload[hwOffset+8] & 0x7FFF)+3700:>4d}\n"
|
||||
ret += f"天线 PLL 锁定状态: {bin(payload[hwOffset+9])[2:].zfill(8)}\n"
|
||||
ret += f"天线工作模式: {bin(payload[hwOffset+10])[2:].zfill(8)}\n"
|
||||
ret += f"天线温度: {payload[hwOffset+11]:>4d}\n"
|
||||
ret += "--------------------------------\n"
|
||||
|
||||
return ret + '\n' + self.printFrame(data)
|
||||
|
||||
def printFrame(self, data: bytes):
|
||||
ret = ''
|
||||
for i in range(len(data)):
|
||||
ret += f'{data[i]:02X}'
|
||||
ret += '\n' if i%16 == 15 else ' '
|
||||
ret += '\n'
|
||||
return ret
|
||||
|
||||
def evalStatusCheckRsp(self, data: bytes):
|
||||
try:
|
||||
payload = self.structStatusCheckRsp.unpack(data)
|
||||
except :
|
||||
return f"\n### evalStatusCheckRsp:: Failed to unpack data (data length {len(data)} byte).\n"
|
||||
|
||||
ret = "----------- 遥测回令 -----------\n"
|
||||
|
||||
ret += "节点类型: "
|
||||
if payload[1] == 0xEE:
|
||||
ret += f"C频段 (0x{payload[1]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[1]:02X})\n"
|
||||
|
||||
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"
|
||||
|
||||
ret += "网络连接状态: "
|
||||
if payload[linkOffset + 3] == 0x11:
|
||||
ret += f"已连接 (0x{payload[linkOffset + 3]:02X})\n"
|
||||
elif payload[linkOffset + 3] == 0x00:
|
||||
ret += f"未连接 (0x{payload[linkOffset + 3]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[linkOffset + 3]:02X})\n"
|
||||
|
||||
ret += "网络运行阶段: "
|
||||
if payload[linkOffset + 4] == 0x11:
|
||||
ret += f"建网阶段 (0x{payload[linkOffset + 4]:02X})\n"
|
||||
elif payload[linkOffset + 4] == 0x22:
|
||||
ret += f"业务通信 (0x{payload[linkOffset + 4]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[linkOffset + 4]:02X})\n"
|
||||
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
ret += f"天线-2 工作 PLL: {(payload[hwOffset+7] >> 15) & 0x01:>1d}\n"
|
||||
ret += f"天线-2 工作频率: {(payload[hwOffset+7] & 0x7FFF)+3700:>4d}\n"
|
||||
ret += f"天线-3 工作 PLL: {(payload[hwOffset+8] >> 15) & 0x01:>1d}\n"
|
||||
ret += f"天线-3 工作频率: {(payload[hwOffset+8] & 0x7FFF)+3700:>4d}\n"
|
||||
ret += f"天线 PLL 锁定状态: {bin(payload[hwOffset+9])[2:].zfill(8)}\n"
|
||||
ret += f"天线工作模式: {bin(payload[hwOffset+10])[2:].zfill(8)}\n"
|
||||
ret += f"天线温度: {payload[hwOffset+11]:>4d}\n"
|
||||
|
||||
ret += "--------------------------------\n"
|
||||
return ret + '\n' + self.printFrame(data)
|
||||
|
||||
def onSent(self, ok, msg, length, path):
|
||||
if ok:
|
||||
self.statusBar.addTx(length)
|
||||
else:
|
||||
self.hintSignal.emit("error", _("Error"), _("Send data failed!") + " " + msg)
|
||||
|
||||
def sendCustomItem(self, item):
|
||||
data = item["data"]
|
||||
dateBytes = self.parseSendData(data, encoding = self.configGlobal["encoding"], isHexStr = True)
|
||||
if dateBytes:
|
||||
self.send(dateBytes, callback=self.onSent)
|
||||
@@ -128,7 +128,7 @@
|
||||
// -- Request
|
||||
// -- -- --
|
||||
// -- Response
|
||||
#define RM_TEST_RSP_LEN 190
|
||||
#define RM_TEST_RSP_LEN 202
|
||||
// -- -- 8 byte time stamp
|
||||
#define RT_TIME_STAMP_OFFSET 0x02
|
||||
#define RT_TIME_STAMP_LEN 8
|
||||
@@ -137,12 +137,12 @@
|
||||
#define RT_SYSBUS_LOG_LEN 16
|
||||
// -- -- 88 byte link layer log
|
||||
#define RT_LINK_LOG_OFFSET 0x1A
|
||||
#define RT_LINK_LOG_LEN 88
|
||||
#define RT_LINK_LOG_LEN 100
|
||||
// -- -- 56 byte physical layer log
|
||||
#define RT_PHY_LOG_OFFSET 0x72
|
||||
#define RT_PHY_LOG_OFFSET 0x7E
|
||||
#define RT_PHY_LOG_LEN 56
|
||||
// -- -- 20 byte hardware log
|
||||
#define RT_HARDWARE_ST_OFFSET 0xAA
|
||||
#define RT_HARDWARE_ST_OFFSET 0xB6
|
||||
#define RT_HARDWARE_ST_LEN 20
|
||||
|
||||
// My Production Type
|
||||
|
||||
Reference in New Issue
Block a user