forked from 0xha0/df_datalink
Compare commits
25
Commits
c468bd9ca1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b42316dd84 | ||
|
|
3caea65695 | ||
|
|
b3fa034558 | ||
|
|
75cf7feedc | ||
|
|
1ae8360ae8 | ||
|
|
9e4fb6ffb5 | ||
|
|
7d3624e946 | ||
|
|
75d6651258 | ||
|
|
cb9dc0d934 | ||
|
|
e56afc4a78 | ||
|
|
3a90bc329b | ||
|
|
76b49097c1 | ||
|
|
9c24f66aae | ||
|
|
044345f597 | ||
|
|
6b9a2c8cc4 | ||
|
|
d3d45fbfb0 | ||
|
|
f9591a8c95 | ||
|
|
c0b239e028 | ||
|
|
5679de641c | ||
|
|
58a909673a | ||
|
|
5a91eaad72 | ||
|
|
74219c3cbe | ||
|
|
d138381578 | ||
|
|
8a273739c3 | ||
|
|
4932c9c6c7 |
@@ -6,10 +6,10 @@ TARGET_PROJ ?= node
|
|||||||
ifeq ($(TARGET_PROJ), node)
|
ifeq ($(TARGET_PROJ), node)
|
||||||
BUILD_DIR := $(PROJECT)/build/node
|
BUILD_DIR := $(PROJECT)/build/node
|
||||||
CONFIG_FILE := $(PROJECT)/config/node.json
|
CONFIG_FILE := $(PROJECT)/config/node.json
|
||||||
else ifeq ($(TARGET_PROJ), ge)
|
else ifeq ($(TARGET_PROJ), ground)
|
||||||
XILINX_VITIS_CLASSIC := y
|
XILINX_VITIS_CLASSIC := y
|
||||||
BUILD_DIR := $(PROJECT)/build/ge
|
BUILD_DIR := $(PROJECT)/build/ground
|
||||||
CONFIG_FILE := $(PROJECT)/config/ge.json
|
CONFIG_FILE := $(PROJECT)/config/ground.json
|
||||||
else
|
else
|
||||||
$(error Unsupported target PROJECT: $(TARGET_PROJ))
|
$(error Unsupported target PROJECT: $(TARGET_PROJ))
|
||||||
endif
|
endif
|
||||||
|
|||||||
+7
-6
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"project_name": "hsjl_ground",
|
"project_name": "hsjl_ground",
|
||||||
"version": "0.0.0",
|
"version": "0.1.0",
|
||||||
"hw_design": "hw/hsjl_ground_v0.0.1.xsa",
|
"hw_design": "hw/hsjl_ground_v0.1.0.xsa",
|
||||||
"apps": {
|
"apps": {
|
||||||
"datalink": {
|
"datalink": {
|
||||||
"sources": ["src/*"],
|
"sources": ["src/*"],
|
||||||
@@ -13,13 +13,14 @@
|
|||||||
"stack_size": "0x20000"
|
"stack_size": "0x20000"
|
||||||
},
|
},
|
||||||
"build_config": {
|
"build_config": {
|
||||||
"debug": {
|
|
||||||
"include-path": ["src/include"],
|
|
||||||
"libraries": ["m"]
|
|
||||||
},
|
|
||||||
"release": {
|
"release": {
|
||||||
"include-path": ["src/include"],
|
"include-path": ["src/include"],
|
||||||
"libraries": ["m"]
|
"libraries": ["m"]
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"include-path": ["src/include"],
|
||||||
|
"libraries": ["m"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"project_name": "hsjl_node",
|
"project_name": "hsjl_node",
|
||||||
"version": "0.0.0",
|
"version": "0.1.0",
|
||||||
"hw_design": "hw/hsjl_node_v0.0.1.hdf",
|
"hw_design": "hw/hsjl_node_v0.1.0.hdf",
|
||||||
"apps": {
|
"apps": {
|
||||||
"datalink": {
|
"datalink": {
|
||||||
"sources": ["src/*"],
|
"sources": ["src/*"],
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
"stack_size": "0x20000"
|
"stack_size": "0x20000"
|
||||||
},
|
},
|
||||||
"build_config": {
|
"build_config": {
|
||||||
"debug": {
|
|
||||||
"include-path": ["src/include"],
|
|
||||||
"libraries": ["m"]
|
|
||||||
},
|
|
||||||
"release": {
|
"release": {
|
||||||
"include-path": ["src/include"],
|
"include-path": ["src/include"],
|
||||||
"libraries": ["m"]
|
"libraries": ["m"]
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"include-path": ["src/include"],
|
||||||
|
"libraries": ["m"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+217
@@ -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
|
||||||
+15
-12
@@ -1,7 +1,7 @@
|
|||||||
# HSJL 上位机串口通信协议
|
# HSJL 上位机串口通信协议
|
||||||
|
|
||||||
> 版本:v1.2
|
> 版本:v1.2
|
||||||
> 日期:2025 年 6 月 12 日
|
> 日期:2025 年 6 月 16 日
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -46,19 +46,19 @@ block-beta
|
|||||||
|
|
||||||
| 字段名 | 字节数 (Byte) | 说明 |
|
| 字段名 | 字节数 (Byte) | 说明 |
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| 帧头 | 2 | 固定值:`0x54 0x5A` |
|
| 帧头 | 2 | 固定值:`0x5A 0x54` |
|
||||||
| 数据段 | ≤950 | 业务数据内容 |
|
| 数据段 | ≤950 | 业务数据内容 |
|
||||||
| Dummy Byte | 1 | 固定填充:`0x00` |
|
| Dummy Byte | 1 | 固定填充:`0x00` |
|
||||||
| 校验和 | 1 | 所有**数据段**字节累加和(无符号累加) |
|
| 校验和 | 1 | 所有**数据段**字节累加和(无符号累加) |
|
||||||
| 数据段长度 | 2 | 数据段字节数(不含 Dummy/校验/帧尾) |
|
| 数据段长度 | 2 | 数据段字节数(不含 Dummy/校验/帧尾) |
|
||||||
| 帧尾 | 2 | 固定值:`0xFE 0x5A` |
|
| 帧尾 | 2 | 固定值:`0x5A 0xFE` |
|
||||||
|
|
||||||
### 帧内冲突规避规则
|
### 帧内冲突规避规则
|
||||||
|
|
||||||
为防止数据段中出现帧尾 `0xFE 0x5A`:
|
为防止数据段中出现帧尾 `0x5A 0xFE`:
|
||||||
|
|
||||||
- 若数据段中出现 `0xFE 0x5A`,需插入 `0x00` 变成 `0x00 0xFE 0x5A`
|
- 若数据段中出现 `0x5A 0xFE`,需插入 `0x00` 变成 `0x00 0x5A 0xFE`
|
||||||
- 接收端收到 `0x00 0xFE 0x5A` 还原为 `0xFE 0x5A`
|
- 接收端收到 `0x00 0x5A 0xFE` 还原为 `0x5A 0xFE`
|
||||||
|
|
||||||
### 帧长说明
|
### 帧长说明
|
||||||
|
|
||||||
@@ -192,13 +192,13 @@ block-beta
|
|||||||
|
|
||||||
### (可选)遥测指令
|
### (可选)遥测指令
|
||||||
|
|
||||||
遥测指令上传的 Payload 由 5 部分组成,顺序存储,共 188 字节:
|
遥测指令上传的 Payload 由 5 部分组成,顺序存储,共 200 字节:
|
||||||
|
|
||||||
| 字段名 | 字节数 (Byte) |
|
| 字段名 | 字节数 (Byte) |
|
||||||
| ------------ | ------------- |
|
| ------------ | ------------- |
|
||||||
| 时间戳 | 8 |
|
| 时间戳 | 8 |
|
||||||
| 总线日志 | 16 |
|
| 总线日志 | 16 |
|
||||||
| 链路层日志 | 88 |
|
| 链路层日志 | 100 |
|
||||||
| 物理层日志 | 56 |
|
| 物理层日志 | 56 |
|
||||||
| 硬件状态日志 | 20 |
|
| 硬件状态日志 | 20 |
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ block-beta
|
|||||||
|
|
||||||
#### 链路层日志
|
#### 链路层日志
|
||||||
|
|
||||||
链路层日志顺序存储,共 88字节:
|
链路层日志顺序存储,共 100 字节:
|
||||||
|
|
||||||
| 字段名 | 字节数 (Byte) | 说明 |
|
| 字段名 | 字节数 (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 |
|
| 网管帧接收计数器 | 4 | 每配置接收一次网管帧,计数器+1 |
|
||||||
| 网关帧接收正确计数器 | 4 | 每正确接收一次网关帧,计数器+1 |
|
| 网管帧接收正确计数器 | 4 | 每正确接收一次网管帧,计数器+1 |
|
||||||
| RTT帧发送计数器 | 4 | 每发送一次 RTT 帧,计数器+1 |
|
| RTT帧发送计数器 | 4 | 每发送一次 RTT 帧,计数器+1 |
|
||||||
| RTT帧接收计数器 | 4 | 每配置接收一次 RTT 帧,计数器+1 |
|
| RTT帧接收计数器 | 4 | 每配置接收一次 RTT 帧,计数器+1 |
|
||||||
| RTT帧接收正确计数器 | 4 | 每正确接收一次 RTT 帧,计数器+1 |
|
| RTT帧接收正确计数器 | 4 | 每正确接收一次 RTT 帧,计数器+1 |
|
||||||
|
| 业务帧发送计数器 | 4 | 每发送一次业务帧,计数器+1 |
|
||||||
|
| 业务帧接收计数器 | 4 | 每配置接收一次业务帧,计数器+1 |
|
||||||
|
| 业务帧接收正确计数器 | 4 | 每正确接收一次业务帧,计数器+1 |
|
||||||
| 时间偏移量记录 | 4, int32 | 记录上一次节点时间和帧同步时间的偏差 |
|
| 时间偏移量记录 | 4, int32 | 记录上一次节点时间和帧同步时间的偏差 |
|
||||||
| 发送数据ID记录 | 4 | 记录上一次发送数据的ID |
|
| 发送数据ID记录 | 4 | 记录上一次发送数据的ID |
|
||||||
| 接收数据ID记录 | 4 | 记录上一次接收数据的ID |
|
| 接收数据ID记录 | 4 | 记录上一次接收数据的ID |
|
||||||
|
|||||||
@@ -0,0 +1,476 @@
|
|||||||
|
'''
|
||||||
|
@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": "数据发送测试(节点01)",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": (
|
||||||
|
"5A 54 E4 EE 01 00 00 00 01 28 00 "
|
||||||
|
"00 01 02 03 04 05 06 07 "
|
||||||
|
"08 09 0A 0B 0C 0D 0E 0F "
|
||||||
|
"10 11 12 13 14 15 16 17 "
|
||||||
|
"18 19 1A 1B 1C 1D 1E 1F "
|
||||||
|
"20 21 22 23 24 25 26 27 "
|
||||||
|
"00 08 31 5A FE"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "数据发送测试(节点02)",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": (
|
||||||
|
"5A 54 E4 EE 02 00 00 00 02 28 00 "
|
||||||
|
"00 01 02 03 04 05 06 07 "
|
||||||
|
"08 09 0A 0B 0C 0D 0E 0F "
|
||||||
|
"10 11 12 13 14 15 16 17 "
|
||||||
|
"18 19 1A 1B 1C 1D 1E 1F "
|
||||||
|
"20 21 22 23 24 25 26 27 "
|
||||||
|
"00 0A 31 5A FE"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "数据发送测试(节点03)",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": (
|
||||||
|
"5A 54 E4 EE 03 00 00 00 03 28 00 "
|
||||||
|
"00 01 02 03 04 05 06 07 "
|
||||||
|
"08 09 0A 0B 0C 0D 0E 0F "
|
||||||
|
"10 11 12 13 14 15 16 17 "
|
||||||
|
"18 19 1A 1B 1C 1D 1E 1F "
|
||||||
|
"20 21 22 23 24 25 26 27 "
|
||||||
|
"00 0C 31 5A FE"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【主 - 0x01】128 kbps,时隙表 1",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 01 22 01 00 9F 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【主 - 0x01】512 kbps,时隙表 2",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 01 33 02 00 B1 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【主 - 0x01】2 Mbps,时隙表 3",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 01 44 03 00 C3 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,时隙表 1",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 02 22 01 00 A0 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x02】512 kbps,时隙表 2",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 02 33 02 00 B2 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x02】2M bps,时隙表 3",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 02 44 03 00 C4 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x02】静默",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE 55 02 22 00 00 4A 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x03】128 kbps,时隙表 1",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 03 22 01 00 A1 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x03】512 kbps,时隙表 2",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 03 33 02 00 B3 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x03】2 Mbps,时隙表 3",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 03 44 03 00 C5 06 5A FE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "装订 - 【从 - 0x03】静默",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE 55 03 22 00 00 4B 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 III i II 3s IIII d Q dBB dB H B 2s BBBbbb HHHBBbB B 3s")
|
||||||
|
self.structData = Struct("<BB IBH 40s")
|
||||||
|
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:
|
||||||
|
self.showReceiveDataSignal.emit(self.evalStatusCheckRsp(data) + "\n")
|
||||||
|
elif data[0] == 0xE5:
|
||||||
|
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 = 50
|
||||||
|
|
||||||
|
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 + 12])[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)
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -0,0 +1,898 @@
|
|||||||
|
'''
|
||||||
|
@brief This is an example plugin, can receive and send data
|
||||||
|
@author
|
||||||
|
@date
|
||||||
|
@license LGPL-3.0
|
||||||
|
'''
|
||||||
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGridLayout,QHBoxLayout, QTextEdit, QPushButton, QLabel, QScrollArea, QSplitter
|
||||||
|
from PyQt5.QtCore import Qt, pyqtSignal
|
||||||
|
from PyQt5.QtGui import QFont, QTextCursor
|
||||||
|
from struct import Struct
|
||||||
|
try:
|
||||||
|
from PyQt5.QtWidgets import QFrame
|
||||||
|
import utils_ui
|
||||||
|
from plugins.base import Plugin_Base
|
||||||
|
from conn import ConnectionStatus
|
||||||
|
from i18n import _
|
||||||
|
from widgets import statusBar
|
||||||
|
from plugins.graph_widgets import graphWidgets
|
||||||
|
from PyQt5.QtWidgets import QPushButton, QMenu
|
||||||
|
from PyQt5.QtWidgets import QComboBox
|
||||||
|
from PyQt5 import QtCore
|
||||||
|
|
||||||
|
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
|
||||||
|
from COMTool.plugins.graph_widgets import graphWidgets
|
||||||
|
|
||||||
|
class Plugin(Plugin_Base):
|
||||||
|
|
||||||
|
id = "hsjl_timer"
|
||||||
|
name = _("hsjl_timer")
|
||||||
|
showReceiveDataSignal = pyqtSignal(str)
|
||||||
|
# 图片1的字节数据(已存在,提取为常量)
|
||||||
|
IMAGE1_DATA = [
|
||||||
|
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
|
||||||
|
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1F, 0xF3, 0xFF,
|
||||||
|
0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00,
|
||||||
|
0x00, 0x75, 0x49, 0x44, 0x41, 0x54, 0x38, 0x4F, 0x63, 0x64, 0xA0, 0x10, 0x30, 0x52, 0xA8, 0x9F,
|
||||||
|
0x61, 0xD4, 0x00, 0x06, 0xEC, 0x61, 0x20, 0xD0, 0xFE, 0xDA, 0x81, 0x91, 0x85, 0xF9, 0xCD, 0xFB,
|
||||||
|
0x52, 0xA1, 0x2B, 0xA0, 0x40, 0x06, 0xF1, 0x41, 0xF4, 0x87, 0x4A, 0xD1, 0x03, 0xE8, 0x81, 0x8E,
|
||||||
|
0x35, 0x10, 0xF9, 0x3A, 0x5F, 0xD7, 0x33, 0xFE, 0xFF, 0x1F, 0xFF, 0x9F, 0xE1, 0x7F, 0x26, 0xE3,
|
||||||
|
0x7F, 0x46, 0x3E, 0x06, 0x46, 0xC6, 0x55, 0x8C, 0xFF, 0x19, 0x1C, 0x89, 0x36, 0x00, 0x64, 0x0B,
|
||||||
|
0xC4, 0x10, 0x86, 0x52, 0x06, 0x06, 0x06, 0x6E, 0x86, 0xFF, 0xFF, 0xC3, 0x3E, 0x56, 0x8A, 0xAD,
|
||||||
|
0xC6, 0x16, 0xE5, 0x78, 0xA3, 0x11, 0x6C, 0xC8, 0xBF, 0xFF, 0xD7, 0x70, 0x69, 0x06, 0x19, 0x38,
|
||||||
|
0x9A, 0x0E, 0x06, 0x43, 0x18, 0x00, 0x00, 0x4E, 0x62, 0x24, 0x11, 0xDE, 0x82, 0x35, 0xD8, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
|
||||||
|
]
|
||||||
|
|
||||||
|
# 图片2的字节数据(新添加)
|
||||||
|
IMAGE2_DATA = [
|
||||||
|
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
|
||||||
|
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方法中)
|
||||||
|
def onInit(self, config):
|
||||||
|
self.image_index = 0 # 图片索引:0-图片1,1-图片2
|
||||||
|
self.cycle_count = 0 # 循环次数计数
|
||||||
|
self.send_timer = QtCore.QTimer() # 新增:定时器
|
||||||
|
self.send_timer.setInterval(1000) # 间隔1秒
|
||||||
|
self.send_timer.timeout.connect(self.send_next_image) # 绑定定时发送函数
|
||||||
|
default = {
|
||||||
|
"version": 1,
|
||||||
|
"customSendItems": [
|
||||||
|
{
|
||||||
|
"caption": "自检项",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"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": "图片传输",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E4 EE 00 00 00 01 02 00 BB 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 10 00 00 \n\
|
||||||
|
00 10 08 06 00 00 00 1F F3 FF 61 00 00 00 01 73 52 47 42 00 AE CE 1C E9 00 00 00 75 49 \n\
|
||||||
|
44 41 54 38 4F 63 64 A0 10 30 52 A8 9F 61 D4 00 06 EC 61 20 D0 FE DA 81 91 85 F9 CD FB \n\
|
||||||
|
52 A1 2B A0 40 06 F1 41 F4 87 4A D1 03 E8 81 8E 35 10 F9 3A 5F D7 33 FE FF 1F FF 9F E1 \n\
|
||||||
|
7F 26 E3 7F 46 3E 06 46 C6 55 8C FF 19 1C 89 36 00 64 0B C4 10 86 52 06 06 06 6E 86 FF \n\
|
||||||
|
FF C3 3E 56 8A AD C6 16 E5 78 A3 11 6C C8 BF FF D7 70 69 06 19 38 9A 0E 06 43 18 00 00 \n\
|
||||||
|
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": "配置发送",
|
||||||
|
"icon": "fa5.play-circle",
|
||||||
|
"data": "5A 54 E3 EE AA 03 22 00 00 A0 06 5A FE"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
self.config = config
|
||||||
|
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")
|
||||||
|
menu = QMenu(toggleBtn)
|
||||||
|
actionOn = menu.addAction("On")
|
||||||
|
actionOff = menu.addAction("Off")
|
||||||
|
|
||||||
|
def setOn():
|
||||||
|
toggleBtn.setText("开关: On")
|
||||||
|
print("开关设为 On")
|
||||||
|
|
||||||
|
def setOff():
|
||||||
|
toggleBtn.setText("开关: Off")
|
||||||
|
print("开关设为 Off")
|
||||||
|
|
||||||
|
actionOn.triggered.connect(setOn)
|
||||||
|
actionOff.triggered.connect(setOff)
|
||||||
|
toggleBtn.setMenu(menu)
|
||||||
|
return toggleBtn
|
||||||
|
|
||||||
|
def createIdButton(self):
|
||||||
|
# 定义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)
|
||||||
|
|
||||||
|
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正确
|
||||||
|
|
||||||
|
# 菜单显示带标识的文本,但传递原始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
|
||||||
|
|
||||||
|
def createSlotButton(self):
|
||||||
|
slotBtn = QPushButton("时隙表: 01") # 默认选中01
|
||||||
|
menu = QMenu(slotBtn)
|
||||||
|
slotOptions = ["01", "02", "03"]
|
||||||
|
|
||||||
|
def setSlot(text):
|
||||||
|
slotBtn.setText(f"时隙表: {text}")
|
||||||
|
print(f"时隙表设为 {text}")
|
||||||
|
|
||||||
|
for opt in slotOptions:
|
||||||
|
menu.addAction(opt).triggered.connect(lambda checked, t=opt: setSlot(t))
|
||||||
|
|
||||||
|
slotBtn.setMenu(menu)
|
||||||
|
return slotBtn
|
||||||
|
|
||||||
|
def createRateButton(self):
|
||||||
|
rateBtn = QPushButton("速率: 128kpbs") # 默认选中01
|
||||||
|
menu = QMenu(rateBtn)
|
||||||
|
rateOptions = ["128kpbs", "512kpbs", "2Mbps"]
|
||||||
|
|
||||||
|
def setRate(text):
|
||||||
|
rateBtn.setText(f"速率: {text}")
|
||||||
|
print(f"速率设为 {text}")
|
||||||
|
|
||||||
|
for opt in rateOptions:
|
||||||
|
menu.addAction(opt).triggered.connect(lambda checked, t=opt: setRate(t))
|
||||||
|
|
||||||
|
rateBtn.setMenu(menu)
|
||||||
|
return rateBtn
|
||||||
|
|
||||||
|
def buildBindCommand(self, switch_text, id_text, rate_text, slot_text):
|
||||||
|
"""
|
||||||
|
switch_text: "开关: On" 或 "开关: Off"
|
||||||
|
id_text: 形如 "id: 00", 只取后两位字符串
|
||||||
|
rate_text: "速率: 01" 对应 1/2/3
|
||||||
|
slot_text: "时隙表: 01" 对应 1/2/3
|
||||||
|
返回拼接好的指令字符串,如 "5A 54 E3 EE AA 01 22 01 00 ?? ?? 5A FE"
|
||||||
|
"""
|
||||||
|
# 头部固定
|
||||||
|
frame = [0x5A, 0x54, 0xE3, 0xEE]
|
||||||
|
|
||||||
|
# 开关字段:On -> 0xAA,Off -> 0x55
|
||||||
|
if switch_text.endswith("On"):
|
||||||
|
frame.append(0xAA)
|
||||||
|
else:
|
||||||
|
frame.append(0x55)
|
||||||
|
|
||||||
|
# ID字段,转为整数
|
||||||
|
try:
|
||||||
|
# 直接获取存储的原始ID(如"01")
|
||||||
|
original_id = self.idButton.property("originalId")
|
||||||
|
id_val = int(original_id, 16) # 转为16进制整数
|
||||||
|
except:
|
||||||
|
id_val = 0x00 # 异常时默认值
|
||||||
|
frame.append(id_val)
|
||||||
|
|
||||||
|
# 速率字段对应映射(参考原来速率的0x22等)
|
||||||
|
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)
|
||||||
|
|
||||||
|
# 时隙表,直接转为整数
|
||||||
|
try:
|
||||||
|
slot_val = int(slot_text.split(":")[1].strip())
|
||||||
|
except:
|
||||||
|
slot_val = 0x00
|
||||||
|
frame.append(slot_val)
|
||||||
|
|
||||||
|
# 后续固定填充和校验(填充字节+校验和+06 5A FE)
|
||||||
|
frame.append(0x00) # 填充字节
|
||||||
|
|
||||||
|
# 校验和计算(从第3字节开始到最后填充前)
|
||||||
|
checksum = sum(frame[2:]) & 0xFF
|
||||||
|
frame.append(checksum)
|
||||||
|
|
||||||
|
# 结尾
|
||||||
|
frame.extend([0x06, 0x5A, 0xFE])
|
||||||
|
|
||||||
|
# 转成空格分隔的大写16进制字符串
|
||||||
|
return " ".join(f"{b:02X}" for b in frame)
|
||||||
|
|
||||||
|
def buildimageCommand(self, switch_text, toid_text, rate_text, slot_text, image_index=0):
|
||||||
|
# 头部固定
|
||||||
|
frame = [0x5A, 0x54, 0xE4, 0xEE]
|
||||||
|
|
||||||
|
if image_index == 0:#两个图片的序号不同
|
||||||
|
frame.append(0x01)
|
||||||
|
else:
|
||||||
|
frame.append(0x02)
|
||||||
|
frame.extend([0x00, 0x00, 0x00])
|
||||||
|
|
||||||
|
# ID字段,转为整数
|
||||||
|
try:
|
||||||
|
original_toid = self.toidButton.property("originalId")
|
||||||
|
id_val = int(original_toid, 16)
|
||||||
|
except:
|
||||||
|
id_val = 0x01 # 异常时默认值
|
||||||
|
frame.append(id_val)
|
||||||
|
|
||||||
|
# 根据索引选择图片数据
|
||||||
|
if image_index == 0:
|
||||||
|
image_data = self.IMAGE1_DATA
|
||||||
|
else:
|
||||||
|
image_data = self.IMAGE2_DATA
|
||||||
|
|
||||||
|
# 计算图片数据长度(2字节表示,这里使用小端模式)
|
||||||
|
data_length = len(image_data)
|
||||||
|
# 拆分长度为高8位和低8位
|
||||||
|
high_byte = (data_length >> 8) & 0xFF # 高8位
|
||||||
|
low_byte = data_length & 0xFF # 低8位
|
||||||
|
|
||||||
|
frame.extend([low_byte, high_byte]) # 小端模式:低位字节在前,高位字节在后
|
||||||
|
# 根据索引选择图片数据
|
||||||
|
if image_index == 0:
|
||||||
|
frame.extend(self.IMAGE1_DATA)
|
||||||
|
else:
|
||||||
|
frame.extend(self.IMAGE2_DATA)
|
||||||
|
|
||||||
|
frame.append(0x00) # 填充字节
|
||||||
|
|
||||||
|
# 校验和计算(从第3字节开始到最后填充前)
|
||||||
|
checksum = sum(frame[2:]) & 0xFF
|
||||||
|
frame.append(checksum)
|
||||||
|
|
||||||
|
# 计算数据段长度:从第三个字节(索引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)
|
||||||
|
|
||||||
|
def send_next_image(self):
|
||||||
|
if self.cycle_count < 5: # 循环5次
|
||||||
|
# 读取按钮状态
|
||||||
|
switch_text = self.toggleButton.text()
|
||||||
|
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, toid_text, rate_text, slot_text,
|
||||||
|
self.image_index # 传入当前图片索引
|
||||||
|
)
|
||||||
|
print(f"第{self.cycle_count + 1}次发送,图片{self.image_index + 1}: {cmd_str}")
|
||||||
|
|
||||||
|
# 实际发送数据
|
||||||
|
data_bytes = self.parseSendData(
|
||||||
|
cmd_str,
|
||||||
|
encoding=self.configGlobal["encoding"],
|
||||||
|
isHexStr=True
|
||||||
|
)
|
||||||
|
if data_bytes:
|
||||||
|
self.send(data_bytes, callback=self.onSent)
|
||||||
|
|
||||||
|
# 切换图片索引(0<->1)
|
||||||
|
self.image_index = 1 - self.image_index
|
||||||
|
self.cycle_count += 1
|
||||||
|
else:
|
||||||
|
# 循环结束,重置状态
|
||||||
|
self.send_timer.stop()
|
||||||
|
self.cycle_count = 0
|
||||||
|
self.image_index = 0
|
||||||
|
# 重新启用按钮
|
||||||
|
self.image_send_btn.setEnabled(True)
|
||||||
|
print("循环发送完成")
|
||||||
|
|
||||||
|
def onWidgetMain(self, parent):
|
||||||
|
self.mainWidget = QSplitter(Qt.Vertical)
|
||||||
|
|
||||||
|
imageContainer = QSplitter(Qt.Horizontal)
|
||||||
|
self.widgets = []
|
||||||
|
|
||||||
|
for i in range(2):
|
||||||
|
if "image" in graphWidgets:
|
||||||
|
imageWidgetClass = graphWidgets["image"]
|
||||||
|
imageWidget = imageWidgetClass(
|
||||||
|
hintSignal=self.hintSignal,
|
||||||
|
rmCallback=lambda widget: None,
|
||||||
|
send=self.sendData,
|
||||||
|
config={}
|
||||||
|
)
|
||||||
|
self.widgets.append(imageWidget)
|
||||||
|
|
||||||
|
frame = QFrame()
|
||||||
|
frame.setFrameShape(QFrame.StyledPanel)
|
||||||
|
frame.setFrameShadow(QFrame.Raised)
|
||||||
|
frame.setStyleSheet("QFrame { border: 1px solid #999; border-radius: 6px; margin: 4px; }")
|
||||||
|
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
layout.setContentsMargins(6, 6, 6, 6)
|
||||||
|
layout.addWidget(imageWidget)
|
||||||
|
frame.setLayout(layout)
|
||||||
|
|
||||||
|
imageContainer.addWidget(frame)
|
||||||
|
else:
|
||||||
|
placeholder = QLabel("No graph widget configured")
|
||||||
|
placeholder.setAlignment(Qt.AlignCenter)
|
||||||
|
imageContainer.addWidget(placeholder)
|
||||||
|
|
||||||
|
self.mainWidget.addWidget(imageContainer)
|
||||||
|
|
||||||
|
self.customSendScroll = QScrollArea()
|
||||||
|
self.customSendScroll.setMinimumHeight(20)
|
||||||
|
self.customSendScroll.setWidgetResizable(True)
|
||||||
|
self.customSendScroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
self.customSendScroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
|
||||||
|
sendItemsWrapper = QWidget()
|
||||||
|
self.customSendScroll.setWidget(sendItemsWrapper)
|
||||||
|
|
||||||
|
sendItemsOuterWrapper = QWidget()
|
||||||
|
sendItemsOuterWrapper.setProperty("class", "scrollbar2")
|
||||||
|
layout0 = QVBoxLayout()
|
||||||
|
layout0.setContentsMargins(0, 8, 0, 0)
|
||||||
|
sendItemsOuterWrapper.setLayout(layout0)
|
||||||
|
layout0.addWidget(self.customSendScroll)
|
||||||
|
|
||||||
|
sendItemsLayoutWrapper = QVBoxLayout()
|
||||||
|
sendItemsLayoutWrapper.setContentsMargins(0, 0, 0, 0)
|
||||||
|
sendItemsWrapper.setLayout(sendItemsLayoutWrapper)
|
||||||
|
|
||||||
|
self.customItems = QWidget()
|
||||||
|
self.customSendItemsLayout = QGridLayout()
|
||||||
|
self.customSendItemsLayout.setContentsMargins(8, 4, 8, 4)
|
||||||
|
self.customItems.setLayout(self.customSendItemsLayout)
|
||||||
|
|
||||||
|
sendItemsLayoutWrapper.addWidget(self.customItems)
|
||||||
|
sendItemsLayoutWrapper.addStretch(0)
|
||||||
|
|
||||||
|
self.mainWidget.addWidget(sendItemsOuterWrapper)
|
||||||
|
|
||||||
|
# 网络状态标签初始化
|
||||||
|
self.networkStatusLabel = QLabel("节点状态: 未知")
|
||||||
|
self.networkStatusLabel.setAlignment(Qt.AlignLeft)
|
||||||
|
self.networkStatusLabel.setFont(QFont("Arial", 10))
|
||||||
|
|
||||||
|
self.networkPhaseLabel = QLabel("天线温度: 未知")
|
||||||
|
self.networkPhaseLabel.setAlignment(Qt.AlignLeft)
|
||||||
|
self.networkPhaseLabel.setFont(QFont("Arial", 10))
|
||||||
|
|
||||||
|
self.networktemLabel = QLabel("电压状态: 未知")
|
||||||
|
self.networktemLabel.setAlignment(Qt.AlignLeft)
|
||||||
|
self.networktemLabel.setFont(QFont("Arial", 10))
|
||||||
|
|
||||||
|
self.networkvoltageLabel = QLabel("fgpa温度: 未知")
|
||||||
|
self.networkvoltageLabel.setAlignment(Qt.AlignLeft)
|
||||||
|
self.networkvoltageLabel.setFont(QFont("Arial", 10))
|
||||||
|
|
||||||
|
# 设置主窗口比例
|
||||||
|
self.mainWidget.setStretchFactor(0, 6) # 图像区域
|
||||||
|
self.mainWidget.setStretchFactor(1, 4) # 自定义发送区域
|
||||||
|
|
||||||
|
return self.mainWidget
|
||||||
|
|
||||||
|
def clearLayout(self, layout):
|
||||||
|
while layout.count():
|
||||||
|
item = layout.takeAt(0)
|
||||||
|
widget = item.widget()
|
||||||
|
if widget:
|
||||||
|
widget.setParent(None)
|
||||||
|
|
||||||
|
def createSendItemWidget(self, item):
|
||||||
|
caption = item["caption"]
|
||||||
|
itemWidget = QWidget()
|
||||||
|
layout = QHBoxLayout()
|
||||||
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
itemWidget.setLayout(layout)
|
||||||
|
|
||||||
|
send = QPushButton("")
|
||||||
|
label = QLabel(caption)
|
||||||
|
icon = item.get("icon", "fa.send")
|
||||||
|
utils_ui.setButtonIcon(send, icon)
|
||||||
|
send.setProperty("class", "smallBtn")
|
||||||
|
|
||||||
|
def sendCustomData():
|
||||||
|
self.sendCustomItem(item)
|
||||||
|
|
||||||
|
send.clicked.connect(sendCustomData)
|
||||||
|
|
||||||
|
layout.addWidget(label)
|
||||||
|
layout.addWidget(send)
|
||||||
|
|
||||||
|
return itemWidget
|
||||||
|
|
||||||
|
def onUiInitDone(self):
|
||||||
|
|
||||||
|
# 清空旧布局
|
||||||
|
self.clearLayout(self.customSendItemsLayout)
|
||||||
|
|
||||||
|
# 创建“开关”、“ID”、“时隙表”、“速率”按钮,供“总控”使用
|
||||||
|
self.toggleButton = self.createToggleButton()
|
||||||
|
self.customSendItemsLayout.addWidget(self.toggleButton, 1, 0, 1, 2)
|
||||||
|
|
||||||
|
self.idButton = self.createIdButton()
|
||||||
|
self.customSendItemsLayout.addWidget(self.idButton, 0, 1)
|
||||||
|
|
||||||
|
self.slotButton = self.createSlotButton()
|
||||||
|
self.customSendItemsLayout.addWidget(self.slotButton, 0, 2)
|
||||||
|
|
||||||
|
self.rateButton = self.createRateButton()
|
||||||
|
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"] == "自检项":
|
||||||
|
print("找到自检项,准备添加到(0,0)") # 新增
|
||||||
|
w = self.createSendItemWidget(item)
|
||||||
|
self.customSendItemsLayout.addWidget(w, 3, 0, 1, 2)
|
||||||
|
elif item["caption"] == "图片传输":
|
||||||
|
totalControlWidget = QWidget()
|
||||||
|
layout = QHBoxLayout()
|
||||||
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
totalControlWidget.setLayout(layout)
|
||||||
|
|
||||||
|
sendBtn = QPushButton("")
|
||||||
|
self.image_send_btn = sendBtn
|
||||||
|
label = QLabel("图片传输")
|
||||||
|
|
||||||
|
utils_ui.setButtonIcon(sendBtn, item.get("icon", "fa.send"))
|
||||||
|
sendBtn.setProperty("class", "smallBtn")
|
||||||
|
|
||||||
|
# 初始化定时器(确保只初始化一次)
|
||||||
|
self.send_timer = QtCore.QTimer()
|
||||||
|
|
||||||
|
def start_image_cycle():
|
||||||
|
# 禁用按钮防止重复触发
|
||||||
|
sendBtn.setEnabled(False)
|
||||||
|
# 重置计数和索引
|
||||||
|
self.cycle_count = 0 # 总循环次数(每次循环包含图片1+图片2)
|
||||||
|
self.image_index = 0 # 当前图片索引(0:图片1,1:图片2)
|
||||||
|
|
||||||
|
# 新增:根据当前速率设置定时器间隔
|
||||||
|
# 1. 定义速率与间隔的映射关系(单位:毫秒)
|
||||||
|
rate_interval_map = {
|
||||||
|
"128kpbs": 1500, # 128kpbs对应1.5秒
|
||||||
|
"512kpbs": 1000, # 256kpbs对应1秒
|
||||||
|
"2Mbps": 500 # 2Mbps对应0.5秒
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. 获取当前选中的速率
|
||||||
|
rate_text = self.rateButton.text() # 格式为"速率: xxx"
|
||||||
|
rate_key = rate_text.split(":")[1].strip() # 提取"128kpbs"等关键部分
|
||||||
|
|
||||||
|
# 3. 获取对应的间隔时间(默认1秒)
|
||||||
|
interval = rate_interval_map.get(rate_key, 1000)
|
||||||
|
|
||||||
|
# 4. 启动定时器(使用动态计算的间隔)
|
||||||
|
self.send_timer.start(interval)
|
||||||
|
|
||||||
|
# 定义循环发送逻辑
|
||||||
|
def send_image_cycle():
|
||||||
|
# 读取按钮状态
|
||||||
|
switch_text = self.toggleButton.text()
|
||||||
|
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, toid_text, rate_text, slot_text, self.image_index
|
||||||
|
)
|
||||||
|
print(f"第{self.cycle_count + 1}次循环,图片{self.image_index + 1}: {cmd_str}")
|
||||||
|
|
||||||
|
# 发送数据
|
||||||
|
data_bytes = self.parseSendData(
|
||||||
|
cmd_str,
|
||||||
|
encoding=self.configGlobal["encoding"],
|
||||||
|
isHexStr=True
|
||||||
|
)
|
||||||
|
if data_bytes:
|
||||||
|
self.send(data_bytes, callback=self.onSent)
|
||||||
|
|
||||||
|
# 切换图片索引(0<->1)
|
||||||
|
self.image_index = 1 - self.image_index
|
||||||
|
|
||||||
|
# 当图片索引回到0时,代表完成一次完整循环(图片1+图片2)
|
||||||
|
if self.image_index == 0:
|
||||||
|
self.cycle_count += 1
|
||||||
|
# 达到5次循环则停止
|
||||||
|
if self.cycle_count >= 5:
|
||||||
|
self.send_timer.stop()
|
||||||
|
sendBtn.setEnabled(True) # 恢复按钮可用
|
||||||
|
print("循环发送完成")
|
||||||
|
|
||||||
|
# 绑定定时器触发事件
|
||||||
|
self.send_timer.timeout.connect(send_image_cycle)
|
||||||
|
# 绑定按钮点击事件(启动循环)
|
||||||
|
sendBtn.clicked.connect(start_image_cycle)
|
||||||
|
|
||||||
|
layout.addWidget(label)
|
||||||
|
layout.addWidget(sendBtn)
|
||||||
|
self.customSendItemsLayout.addWidget(totalControlWidget, 3, 2, 1, 2 )
|
||||||
|
|
||||||
|
elif item["caption"] == "配置发送":
|
||||||
|
totalControlWidget = QWidget()
|
||||||
|
layout = QHBoxLayout()
|
||||||
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
totalControlWidget.setLayout(layout)
|
||||||
|
|
||||||
|
sendBtn = QPushButton("")
|
||||||
|
label = QLabel("配置发送")
|
||||||
|
utils_ui.setButtonIcon(sendBtn, item.get("icon", "fa.send"))
|
||||||
|
sendBtn.setProperty("class", "smallBtn")
|
||||||
|
|
||||||
|
def sendTotalControl():
|
||||||
|
# 读取4个按钮当前文本
|
||||||
|
switch_text = self.toggleButton.text()
|
||||||
|
id_text = self.idButton.text()
|
||||||
|
slot_text = self.slotButton.text()
|
||||||
|
rate_text = self.rateButton.text()
|
||||||
|
|
||||||
|
# 动态构造指令字符串S
|
||||||
|
|
||||||
|
cmd_str = self.buildBindCommand(switch_text, id_text, rate_text, slot_text)
|
||||||
|
print(f"配置发送: {cmd_str}")
|
||||||
|
|
||||||
|
data_bytes = self.parseSendData(cmd_str,
|
||||||
|
encoding=self.configGlobal["encoding"],
|
||||||
|
isHexStr=True)
|
||||||
|
if data_bytes:
|
||||||
|
self.send(data_bytes, callback=self.onSent)
|
||||||
|
sendBtn.clicked.connect(sendTotalControl)
|
||||||
|
|
||||||
|
layout.addWidget(label)
|
||||||
|
layout.addWidget(sendBtn)
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
count = self.customSendItemsLayout.count()
|
||||||
|
row = count // 4 # 每 4 个换行
|
||||||
|
col = count % 4
|
||||||
|
|
||||||
|
self.customSendItemsLayout.addWidget(itemWidget,row,col)
|
||||||
|
if not load:
|
||||||
|
self.config["customSendItems"].append(item)
|
||||||
|
return item
|
||||||
|
|
||||||
|
def onReceived(self, data: bytes):
|
||||||
|
print('>')
|
||||||
|
print(data)
|
||||||
|
self.statusBar.addRx(len(data)) # 确保self在此处有定义(类成员)
|
||||||
|
|
||||||
|
# 新增:判断数据类型并获取二进制帧数据
|
||||||
|
binary_data = None
|
||||||
|
try:
|
||||||
|
# 尝试解码为十六进制字符串(处理第一种格式)
|
||||||
|
hex_str = data.decode('utf-8')
|
||||||
|
# 清理空格和换行
|
||||||
|
cleaned_hex = hex_str.replace(' ', '').replace('\n', '').replace('\r', '')
|
||||||
|
# 验证是否为有效的十六进制字符
|
||||||
|
if all(c in '0123456789ABCDEFabcdef' for c in cleaned_hex):
|
||||||
|
binary_data = bytes.fromhex(cleaned_hex)
|
||||||
|
print(f"转换后的二进制数据长度: {len(binary_data)} 字节")
|
||||||
|
else:
|
||||||
|
# 不是纯十六进制字符串,视为原始二进制数据
|
||||||
|
binary_data = data
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
# 解码失败,说明是原始二进制数据(处理第二种格式)
|
||||||
|
binary_data = data
|
||||||
|
print(f"直接使用原始二进制数据,长度: {len(binary_data)} 字节")
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"十六进制转换失败: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not binary_data:
|
||||||
|
print("无有效二进制数据")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 第二步:对二进制帧数据解析指令
|
||||||
|
try:
|
||||||
|
# 帧头为0x5A54(即b'ZT'),前2字节为帧头,第3字节为cmd_id
|
||||||
|
if len(binary_data) >= 3 and binary_data[:2] == b'\x5A\x54':
|
||||||
|
cmd_id = binary_data[2]
|
||||||
|
print(f"收到指令: cmd_id=0x{cmd_id:02X}")
|
||||||
|
|
||||||
|
if cmd_id == 0xE5: # 图像测试回令
|
||||||
|
result = self.evalimageTestRsp(binary_data)
|
||||||
|
self.showReceiveDataSignal.emit(result)
|
||||||
|
return
|
||||||
|
elif cmd_id == 0xE1: # 自检回令
|
||||||
|
result = self.evalSelfTestRsp(binary_data)
|
||||||
|
self.showReceiveDataSignal.emit(result)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print("未匹配帧头(5A54),进入PNG解析逻辑")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"指令解析失败: {e}")
|
||||||
|
|
||||||
|
# 第三步:PNG解析逻辑
|
||||||
|
if not hasattr(self, "png_buffer"):
|
||||||
|
self.png_buffer = bytearray()
|
||||||
|
self.png_buffer.extend(binary_data) # 使用处理后的二进制数据累积
|
||||||
|
|
||||||
|
png_start = self.png_buffer.find(b'\x89PNG\r\n\x1a\n')
|
||||||
|
print(f"png_start: {png_start}")
|
||||||
|
if png_start != -1:
|
||||||
|
png_candidate = self.png_buffer[png_start:]
|
||||||
|
iend_pos = png_candidate.rfind(b'IEND\xae\x42\x60\x82')
|
||||||
|
if iend_pos != -1:
|
||||||
|
complete_png = png_candidate[:iend_pos + 8]
|
||||||
|
for widget in self.widgets:
|
||||||
|
widget.onData(complete_png)
|
||||||
|
self.png_buffer.clear()
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# 超过一定长度仍未找到PNG头则清空,避免内存溢出
|
||||||
|
if len(self.png_buffer) > 1024 * 1024: # 1MB阈值
|
||||||
|
self.png_buffer.clear()
|
||||||
|
|
||||||
|
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 evalSelfTestRsp(self, data: bytes):
|
||||||
|
|
||||||
|
print('“”“”“”“”“”“”“”“”“”“”“”“')
|
||||||
|
try:
|
||||||
|
# 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 += f"节点编号: 0x{payload[-2]: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[3]:02X})\n"
|
||||||
|
network_status='未知错误'
|
||||||
|
|
||||||
|
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"
|
||||||
|
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(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_data = header_struct.unpack(data[:11])
|
||||||
|
frame_head, cmd_id, node_type, data_id, from_id, data_len = header_data
|
||||||
|
print(data)
|
||||||
|
print(header_data)
|
||||||
|
print(data_len)
|
||||||
|
# 2. 获取第八个字节的图片类型标识(01/02)
|
||||||
|
img_flag = data[7:8] # 第八个字节
|
||||||
|
print('m')
|
||||||
|
# 3. 动态构建完整结构体
|
||||||
|
struct_format = f"<2s B B I B H {data_len}s B B B 2s"
|
||||||
|
full_struct = Struct(struct_format)
|
||||||
|
print('km')
|
||||||
|
# 计算结构体要求的总长度
|
||||||
|
required_len = 11 + data_len + 5 # 头部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### evalimageTestRsp:: Failed to unpack data (data length {len(data)} byte).\n错误信息: {str(e)}"
|
||||||
|
|
||||||
|
ret = "----------- 图像测试回令 -----------\n"
|
||||||
|
|
||||||
|
# 字段索引对应(保留原始变量名)
|
||||||
|
frame_head = payload[0] # bytes: 2 字节帧头
|
||||||
|
cmd_id = payload[1] # int: 1 字节指令
|
||||||
|
node_type = payload[2] # int: 1 字节节点类型
|
||||||
|
data_id = payload[3] # int: 4 字节数据 ID
|
||||||
|
from_id = payload[4] # int: 1 字节源节点 ID
|
||||||
|
data_len = payload[5] # int: 2 字节数据长度
|
||||||
|
image_data = payload[6] # bytes: 动态长度
|
||||||
|
padding = payload[7] # int: 1 字节填充
|
||||||
|
checksum = payload[8] # int: 1 字节校验和
|
||||||
|
data_len2 = payload[9] # int: 1 字节数据段长度
|
||||||
|
frame_tail = payload[10] # bytes: 2 字节帧尾
|
||||||
|
|
||||||
|
# 格式化输出(保留原始输出格式)
|
||||||
|
ret += f"帧头: {frame_head.hex().upper()} (ascii: {frame_head.decode(errors='ignore')})\n"
|
||||||
|
ret += f"指令: 0x{cmd_id:02X}\n"
|
||||||
|
ret += f"节点类型: 0x{node_type:02X}\n"
|
||||||
|
ret += f"数据 ID: 0x{data_id:08X}\n"
|
||||||
|
ret += f"源节点 ID: {from_id}\n"
|
||||||
|
ret += f"数据长度字段: {data_len} 字节\n"
|
||||||
|
ret += f"数据段实际长度: {len(image_data)} 字节\n"
|
||||||
|
ret += f"填充字节: 0x{padding:02X}\n"
|
||||||
|
ret += f"校验和: 0x{checksum:02X}\n"
|
||||||
|
ret += f"数据段长度: {data_len2} (十六进制: 0x{data_len2:02X})\n"
|
||||||
|
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"]):
|
||||||
|
# 仅传递图像数据,缩放倍数已在控件初始化时通过config设置
|
||||||
|
self.widgets[0].onData(image_data)
|
||||||
|
else:
|
||||||
|
self.showReceiveDataSignal.emit("\n### No valid image widget found (A1)\n")
|
||||||
|
elif from_id == 0x03:
|
||||||
|
# 图像通道 B → 右侧图像控件
|
||||||
|
if len(self.widgets) >= 2 and isinstance(self.widgets[1], graphWidgets["image"]):
|
||||||
|
# 仅传递图像数据
|
||||||
|
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"
|
||||||
|
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)
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
+1
-1
Submodule scripts updated: 00960b6b8f...d13f6cb8b3
@@ -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, 0x0105, 0x3A); // ADC Large Overload Threshold
|
||||||
status = ad9361_reg_write(dev, 0x0107, 0x2B); // Small LMT 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, 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, 0x010A, 0x58); // Rx1 LPF Gain Index
|
||||||
status = ad9361_reg_write(dev, 0x010B, 0x00); // Rx1 Digital 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, 0x010D, 0x18); // Rx2 LPF Gain Index
|
||||||
status = ad9361_reg_write(dev, 0x010E, 0x00); // Rx2 Digital Gain Index
|
status = ad9361_reg_write(dev, 0x010E, 0x00); // Rx2 Digital Gain Index
|
||||||
status = ad9361_reg_write(dev, 0x0114, 0x30); // Low Power Threshold
|
status = ad9361_reg_write(dev, 0x0114, 0x30); // Low Power Threshold
|
||||||
|
|||||||
@@ -103,13 +103,13 @@ static ad9528outputSettings_t clockOutputSettings = {
|
|||||||
},
|
},
|
||||||
.outChannelDiv = {
|
.outChannelDiv = {
|
||||||
5,25,25,5,5,
|
5,25,25,5,5,
|
||||||
5,5,8,5,5,
|
5,5,5,5,5,
|
||||||
5,5,10,5
|
5,5,8,5
|
||||||
},
|
},
|
||||||
.outFrequency_Hz = {
|
.outFrequency_Hz = {
|
||||||
200e6, 40e6, 40e6, 200e6, 200e6,
|
200e6, 40e6, 40e6, 200e6, 200e6,
|
||||||
200e6, 200e6, 125e6, 200e6, 200e6,
|
200e6, 200e6, 200e6, 200e6, 200e6,
|
||||||
200e6, 200e6, 100e6, 200e6
|
200e6, 200e6, 125e6, 200e6
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -25,10 +25,10 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "delay.h"
|
#include "delay.h"
|
||||||
#include "system_monitor.h"
|
|
||||||
#include "hwconfig.h"
|
#include "hwconfig.h"
|
||||||
#include "config/app_config.h"
|
#include "config/app_config.h"
|
||||||
#include "dev_profile/dev_profile.h"
|
#include "dev_profile/dev_profile.h"
|
||||||
|
#include "systembus/systembus.h"
|
||||||
#ifdef RFSOC
|
#ifdef RFSOC
|
||||||
#include "xrfdc.h"
|
#include "xrfdc.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -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_1_reg_inst, 0x0002, &rd_back);
|
||||||
// Status = ad9361_reg_read(ad9361_2_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, 0x0109, 0x00); // Rx Gain
|
||||||
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 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, 0x0109, 0x00); // Rx Gain
|
||||||
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
|
// Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AD9653
|
#ifdef AD9653
|
||||||
|
|||||||
+40
-17
@@ -28,7 +28,6 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "hwconfig.h"
|
#include "hwconfig.h"
|
||||||
#include "system_monitor.h"
|
|
||||||
#include "config/app_config.h"
|
#include "config/app_config.h"
|
||||||
#include "dev_profile/dev_profile.h"
|
#include "dev_profile/dev_profile.h"
|
||||||
#include "systembus/systembus.h"
|
#include "systembus/systembus.h"
|
||||||
@@ -78,8 +77,10 @@ struct callback_desc apptimer_callback_desc = {
|
|||||||
// .myType = L2_NODE_HEAD,
|
// .myType = L2_NODE_HEAD,
|
||||||
// .clustId = 1U,
|
// .clustId = 1U,
|
||||||
// .myId = 1U,
|
// .myId = 1U,
|
||||||
// .headId = 1U,
|
// .headId = L2_HEAD_ID,
|
||||||
// .netScale = 10U,
|
// .netScale = L2_NET_SCALE,
|
||||||
|
// .initTable = initRoutTable,
|
||||||
|
// .normalTable = normalRoutTable1,
|
||||||
// .serviceRate = L2_SVC_512K,
|
// .serviceRate = L2_SVC_512K,
|
||||||
// .phyInstPtr = NULL, // physical layer reference
|
// .phyInstPtr = NULL, // physical layer reference
|
||||||
// .tmcInstPtr = NULL
|
// .tmcInstPtr = NULL
|
||||||
@@ -89,8 +90,10 @@ L2_CONFIG linkConfig = {
|
|||||||
.myType = L2_NODE_MEMBER,
|
.myType = L2_NODE_MEMBER,
|
||||||
.clustId = 1U,
|
.clustId = 1U,
|
||||||
.myId = 2U,
|
.myId = 2U,
|
||||||
.headId = 1U,
|
.headId = L2_HEAD_ID,
|
||||||
.netScale = 10U,
|
.netScale = L2_NET_SCALE,
|
||||||
|
.initTable = initRoutTable,
|
||||||
|
.normalTable = normalRoutTable1,
|
||||||
.serviceRate = L2_SVC_512K,
|
.serviceRate = L2_SVC_512K,
|
||||||
.phyInstPtr = NULL, // physical layer reference
|
.phyInstPtr = NULL, // physical layer reference
|
||||||
.tmcInstPtr = NULL
|
.tmcInstPtr = NULL
|
||||||
@@ -129,8 +132,8 @@ static SYSBUS_CONFIG sysbusConfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static SYSMON_CONFIG sysmonConfig = {
|
static SYSMON_CONFIG sysmonConfig = {
|
||||||
.sendQueueMax = 32U,
|
.sendQueueMax = 16U,
|
||||||
.recvQueueMax = 32U
|
.recvQueueMax = 16U
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********************** Driver Instance Definitions **************************/
|
/*********************** Driver Instance Definitions **************************/
|
||||||
@@ -199,6 +202,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
XScuGic_CPUWriteReg((XScuGic *)(xil_dev->instance), XSCUGIC_EOI_OFFSET, intrState);
|
XScuGic_CPUWriteReg((XScuGic *)(xil_dev->instance), XSCUGIC_EOI_OFFSET, intrState);
|
||||||
|
|
||||||
/* Initialize physical layer interrupt. */
|
/* Initialize physical layer interrupt. */
|
||||||
|
// Set interrupt trigger level
|
||||||
Status = irq_trigger_level_set(descPtr, PHY_INTR_ID, IRQ_EDGE_RISING);
|
Status = irq_trigger_level_set(descPtr, PHY_INTR_ID, IRQ_EDGE_RISING);
|
||||||
if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -221,6 +225,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize linklayer layer interrupt. */
|
/* Initialize linklayer layer interrupt. */
|
||||||
|
// Set interrupt trigger level
|
||||||
Status = irq_trigger_level_set(descPtr, PERIODIC_5MS_INTR_ID, IRQ_EDGE_RISING);
|
Status = irq_trigger_level_set(descPtr, PERIODIC_5MS_INTR_ID, IRQ_EDGE_RISING);
|
||||||
if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -243,17 +248,18 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize system bus interrupt. */
|
/* Initialize system bus interrupt. */
|
||||||
|
// Set interrupt trigger level
|
||||||
Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING);
|
Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
// Set interrupt priority
|
// Set interrupt priority
|
||||||
Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x10);
|
Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x10);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,20 +267,22 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
Status = irq_register_callback(descPtr, SYSBUS_TX_INTR_ID, &sysbus_tx_callback_desc);
|
Status = irq_register_callback(descPtr, SYSBUS_TX_INTR_ID, &sysbus_tx_callback_desc);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set interrupt trigger level
|
||||||
Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING);
|
Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
// Set interrupt priority
|
// Set interrupt priority
|
||||||
Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x18);
|
Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x18);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +290,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
Status = irq_register_callback(descPtr, SYSBUS_RX_INTR_ID, &sysbus_rx_callback_desc);
|
Status = irq_register_callback(descPtr, SYSBUS_RX_INTR_ID, &sysbus_rx_callback_desc);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +299,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
Status = irq_register_callback(descPtr, APPTIMER_INTR_ID, &apptimer_callback_desc);
|
Status = irq_register_callback(descPtr, APPTIMER_INTR_ID, &apptimer_callback_desc);
|
||||||
if (Status != SUCCESS)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,9 +427,24 @@ void AppTimer_IntrHandler(void *context)
|
|||||||
{
|
{
|
||||||
Phy_UpdateLogging(phyInstPtr);
|
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,
|
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
|
#else
|
||||||
#error No timer implementation!
|
#error No timer implementation!
|
||||||
@@ -543,7 +566,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start System Monitor logging.
|
// Start System Monitor logging.
|
||||||
timer_start(logTmPtr);
|
Status = timer_start(logTmPtr);
|
||||||
|
|
||||||
DBG_PRINT("Physical started...\n");
|
DBG_PRINT("Physical started...\n");
|
||||||
Phy_Start(phyInstPtr);
|
Phy_Start(phyInstPtr);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "circ_queue.h"
|
#include "circ_queue.h"
|
||||||
#include "../time_ctrl/time_ctrl.h"
|
#include "../time_ctrl/time_ctrl.h"
|
||||||
#ifndef EMULATION
|
#ifndef EMULATION
|
||||||
#include "../config/app_config.h"
|
#include "../../config/app_config.h"
|
||||||
#endif
|
#endif
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
#define NET_START_TIME_INFTY UINT32_MAX
|
#define NET_START_TIME_INFTY UINT32_MAX
|
||||||
@@ -601,8 +601,8 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
|
|||||||
(*instPtr)->tor.last = L2_TOR_SUSPEND;
|
(*instPtr)->tor.last = L2_TOR_SUSPEND;
|
||||||
(*instPtr)->tor.curr = L2_TOR_SUSPEND;
|
(*instPtr)->tor.curr = L2_TOR_SUSPEND;
|
||||||
(*instPtr)->tor.next = L2_TOR_SUSPEND;
|
(*instPtr)->tor.next = L2_TOR_SUSPEND;
|
||||||
(*instPtr)->rtneConfig.rtneTable = initTable;
|
(*instPtr)->rtneConfig.rtneTable = (*instPtr)->config.initTable;
|
||||||
(*instPtr)->rtneConfig.rtnePrd = ARRAY_SIZE(initTable);
|
(*instPtr)->rtneConfig.rtnePrd = ARRAY_SIZE(initRoutTable);
|
||||||
(*instPtr)->mainState = L2_INIT_STATE;
|
(*instPtr)->mainState = L2_INIT_STATE;
|
||||||
(*instPtr)->nextState = L2_INIT_STATE;
|
(*instPtr)->nextState = L2_INIT_STATE;
|
||||||
(*instPtr)->myInfo.nodeId = config->myId;
|
(*instPtr)->myInfo.nodeId = config->myId;
|
||||||
@@ -698,8 +698,8 @@ int32_t Linklayer_Reconfig(L2_INST *instPtr, const L2_CONFIG *config)
|
|||||||
instPtr->tor.last = L2_TOR_SUSPEND;
|
instPtr->tor.last = L2_TOR_SUSPEND;
|
||||||
instPtr->tor.curr = L2_TOR_SUSPEND;
|
instPtr->tor.curr = L2_TOR_SUSPEND;
|
||||||
instPtr->tor.next = L2_TOR_SUSPEND;
|
instPtr->tor.next = L2_TOR_SUSPEND;
|
||||||
instPtr->rtneConfig.rtneTable = initTable;
|
instPtr->rtneConfig.rtneTable = instPtr->config.initTable;
|
||||||
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initTable);
|
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initRoutTable);
|
||||||
instPtr->mainState = L2_INIT_STATE;
|
instPtr->mainState = L2_INIT_STATE;
|
||||||
instPtr->nextState = L2_INIT_STATE;
|
instPtr->nextState = L2_INIT_STATE;
|
||||||
instPtr->myInfo.nodeId = config->myId;
|
instPtr->myInfo.nodeId = config->myId;
|
||||||
@@ -883,14 +883,14 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
|
|||||||
// Reset scan net FMS for next scan process.
|
// Reset scan net FMS for next scan process.
|
||||||
L2_Scan_Reset(instPtr->scanFSM);
|
L2_Scan_Reset(instPtr->scanFSM);
|
||||||
UpdateMainSate(instPtr, L2_INIT_STATE);
|
UpdateMainSate(instPtr, L2_INIT_STATE);
|
||||||
instPtr->rtneConfig.rtneTable = initTable;
|
instPtr->rtneConfig.rtneTable = instPtr->config.initTable;
|
||||||
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initTable);
|
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initRoutTable);
|
||||||
}
|
}
|
||||||
else if (instPtr->nextState == L2_NORMAL_STATE)
|
else if (instPtr->nextState == L2_NORMAL_STATE)
|
||||||
{
|
{
|
||||||
UpdateMainSate(instPtr, L2_NORMAL_STATE);
|
UpdateMainSate(instPtr, L2_NORMAL_STATE);
|
||||||
instPtr->rtneConfig.rtneTable = normalTable0;
|
instPtr->rtneConfig.rtneTable = instPtr->config.normalTable;
|
||||||
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable0);
|
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalRoutTable1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "msg_def.h"
|
#include "msg_def.h"
|
||||||
#include "circ_queue.h"
|
#include "circ_queue.h"
|
||||||
#include "../phy_layer/phy_layer.h"
|
#include "../phy_layer/phy_layer.h"
|
||||||
#include "../../system_monitor.h"
|
#include "../../systembus/systembus.h"
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
/***************** Macros (Inline Functions) Definitions *********************/
|
/***************** Macros (Inline Functions) Definitions *********************/
|
||||||
#define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event)))
|
#define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event)))
|
||||||
@@ -45,6 +45,8 @@ typedef struct
|
|||||||
uint8_t headId; ///< head node id
|
uint8_t headId; ///< head node id
|
||||||
uint8_t netScale; ///< net scale
|
uint8_t netScale; ///< net scale
|
||||||
L2_SVC_RATE serviceRate; ///< service data rate
|
L2_SVC_RATE serviceRate; ///< service data rate
|
||||||
|
L2_RTNE_TABLE_ENTRY **initTable;
|
||||||
|
L2_RTNE_TABLE_ENTRY **normalTable;
|
||||||
PHY_INST *phyInstPtr; ///< pointer to system physical layer instance
|
PHY_INST *phyInstPtr; ///< pointer to system physical layer instance
|
||||||
TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance
|
TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance
|
||||||
} L2_CONFIG;
|
} L2_CONFIG;
|
||||||
@@ -93,6 +95,8 @@ typedef struct
|
|||||||
int64_t timeDev; ///< last time deviation estimation result
|
int64_t timeDev; ///< last time deviation estimation result
|
||||||
uint32_t reconnectCnt; ///< reconnect trial count
|
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 rxLog;
|
||||||
L2_MSG_RECORD txLog;
|
L2_MSG_RECORD txLog;
|
||||||
} L2_LOG;
|
} L2_LOG;
|
||||||
@@ -129,10 +133,10 @@ typedef struct
|
|||||||
} L2_INST;
|
} L2_INST;
|
||||||
|
|
||||||
/************************** Variable Definitions *****************************/
|
/************************** Variable Definitions *****************************/
|
||||||
extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD];
|
extern L2_RTNE_TABLE_ENTRY *initRoutTable[L2_INIT_RTNE_PERIOD];
|
||||||
extern L2_RTNE_TABLE_ENTRY *normalTable0[L2_INIT_RTNE_PERIOD];
|
extern L2_RTNE_TABLE_ENTRY *normalRoutTable1[L2_INIT_RTNE_PERIOD];
|
||||||
extern L2_RTNE_TABLE_ENTRY *normalTable1[L2_INIT_RTNE_PERIOD];
|
extern L2_RTNE_TABLE_ENTRY *normalRoutTable2[L2_INIT_RTNE_PERIOD];
|
||||||
extern L2_RTNE_TABLE_ENTRY *normalTable2[L2_INIT_RTNE_PERIOD];
|
extern L2_RTNE_TABLE_ENTRY *normalRoutTable3[L2_INIT_RTNE_PERIOD];
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
/**
|
/**
|
||||||
* @defgroup LinkLayer_Main
|
* @defgroup LinkLayer_Main
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "geometry/quaternion.h"
|
#include "geometry/quaternion.h"
|
||||||
#include "../phy_layer/phy_layer.h"
|
#include "../phy_layer/phy_layer.h"
|
||||||
#ifndef EMULATION
|
#ifndef EMULATION
|
||||||
#include "../config/app_config.h"
|
#include "../../config/app_config.h"
|
||||||
#endif
|
#endif
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
/**
|
/**
|
||||||
@@ -37,8 +37,9 @@
|
|||||||
#define L2_BROADCAST_ID2 0xF2
|
#define L2_BROADCAST_ID2 0xF2
|
||||||
#define L2_BROADCAST_ID3 0xF4
|
#define L2_BROADCAST_ID3 0xF4
|
||||||
#define L2_UNICAST_ID 0xF0
|
#define L2_UNICAST_ID 0xF0
|
||||||
#define L2_NONE_ID 0
|
#define L2_NONE_ID 0U
|
||||||
#define L2_HEAD_ID 0x01
|
#define L2_HEAD_ID 1U
|
||||||
|
#define L2_NET_SCALE 10U
|
||||||
|
|
||||||
// Routine configure
|
// Routine configure
|
||||||
#define L2_INIT_RTNE_PERIOD 1
|
#define L2_INIT_RTNE_PERIOD 1
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -243,12 +243,21 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
|
|||||||
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
|
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
|
||||||
|
|
||||||
// Get data payload & upload
|
// Get data payload & upload
|
||||||
SYSMON_SVC_PAYLOAD recvPayload;
|
if (message->dataId != DATA_ID_NONE)
|
||||||
recvPayload.dataId = message->dataId;
|
{
|
||||||
recvPayload.nodeId = message->common.src;
|
if (message->dataLen > maxDataLen)
|
||||||
recvPayload.dataLen = message->dataLen;
|
{
|
||||||
memcpy(recvPayload.data, message->data, maxDataLen);
|
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
|
||||||
SysMonitor_GenRecvRsp(&recvPayload);
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
SYSBUS_SVC_PLD *recvPayload = calloc(1, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
recvPayload->dataId = message->dataId;
|
||||||
|
recvPayload->nodeId = message->common.src;
|
||||||
|
recvPayload->dataLen = message->dataLen;
|
||||||
|
memcpy(recvPayload->data, message->data, message->dataLen);
|
||||||
|
SysMonitor_GenRecvRsp(recvPayload);
|
||||||
|
free(recvPayload);
|
||||||
|
}
|
||||||
|
|
||||||
// Logging...
|
// Logging...
|
||||||
instPtr->log.rxLog.dataId = message->dataId;
|
instPtr->log.rxLog.dataId = message->dataId;
|
||||||
@@ -268,7 +277,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
|
|||||||
|
|
||||||
L2_MSG_ACK *message = (L2_MSG_ACK *)msg;
|
L2_MSG_ACK *message = (L2_MSG_ACK *)msg;
|
||||||
size_t msgLen = sizeof(L2_MSG_ACK);
|
size_t msgLen = sizeof(L2_MSG_ACK);
|
||||||
size_t dataLen = L2_PAYLOAD_LEN_ACK;
|
size_t maxDataLen = L2_PAYLOAD_LEN_ACK;
|
||||||
|
|
||||||
// Update node status.
|
// Update node status.
|
||||||
uint8_t nodeId = message->common.src;
|
uint8_t nodeId = message->common.src;
|
||||||
@@ -318,12 +327,21 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get data payload & upload
|
// Get data payload & upload
|
||||||
SYSMON_SVC_PAYLOAD recvPayload;
|
if (message->dataId != DATA_ID_NONE)
|
||||||
recvPayload.dataId = message->dataId;
|
{
|
||||||
recvPayload.nodeId = message->common.src;
|
if (message->dataLen > maxDataLen)
|
||||||
recvPayload.dataLen = message->dataLen;
|
{
|
||||||
memcpy(recvPayload.data, message->data, dataLen);
|
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
|
||||||
SysMonitor_GenRecvRsp(&recvPayload);
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
SYSBUS_SVC_PLD *recvPayload = calloc(1, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
recvPayload->dataId = message->dataId;
|
||||||
|
recvPayload->nodeId = message->common.src;
|
||||||
|
recvPayload->dataLen = message->dataLen;
|
||||||
|
memcpy(recvPayload->data, message->data, message->dataLen);
|
||||||
|
SysMonitor_GenRecvRsp(recvPayload);
|
||||||
|
free(recvPayload);
|
||||||
|
}
|
||||||
|
|
||||||
// Logging...
|
// Logging...
|
||||||
instPtr->log.rxLog.dataId = message->dataId;
|
instPtr->log.rxLog.dataId = message->dataId;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "circ_queue.h"
|
#include "circ_queue.h"
|
||||||
#ifndef EMULATION
|
#ifndef EMULATION
|
||||||
#include "../config/app_config.h"
|
#include "../../config/app_config.h"
|
||||||
#endif
|
#endif
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
/***************** Macros (Inline Functions) Definitions *********************/
|
/***************** Macros (Inline Functions) Definitions *********************/
|
||||||
@@ -196,16 +196,30 @@ static int32_t Service_Packing128K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
|
|||||||
message->srcSpeedY = instPtr->sysInfo.vY;
|
message->srcSpeedY = instPtr->sysInfo.vY;
|
||||||
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
||||||
|
|
||||||
// TODO: Packing extra payload
|
// Pack extra payload
|
||||||
if (type == L2_FRAME_SVC)
|
if (type == L2_FRAME_SVC)
|
||||||
{
|
{
|
||||||
SYSMON_SVC_PAYLOAD sendPayload;
|
// Packing extra payload
|
||||||
SysMonitor_GetSendPayload(&sendPayload);
|
SYSBUS_SVC_PLD *sendPayload;
|
||||||
message->common.dst = sendPayload.nodeId;
|
SysMonitor_GetSendPayload(&sendPayload, dstId);
|
||||||
message->dataId = sendPayload.dataId;
|
if(sendPayload == NULL)
|
||||||
message->dataLen = sendPayload.dataLen;;
|
{
|
||||||
|
message->common.dst = L2_NONE_ID;
|
||||||
|
message->dataId = DATA_ID_NONE;
|
||||||
|
message->dataLen = 0;
|
||||||
memset(message->data, 0xAA, maxDataLen);
|
memset(message->data, 0xAA, maxDataLen);
|
||||||
memcpy(message->data, sendPayload.data, sendPayload.dataLen);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -264,14 +278,27 @@ static int32_t Service_Packing512K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
|
|||||||
message->srcSpeedY = instPtr->sysInfo.vY;
|
message->srcSpeedY = instPtr->sysInfo.vY;
|
||||||
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
||||||
|
|
||||||
// TODO: Packing extra payload
|
// Pack extra payload
|
||||||
SYSMON_SVC_PAYLOAD sendPayload;
|
SYSBUS_SVC_PLD *sendPayload;
|
||||||
SysMonitor_GetSendPayload(&sendPayload);
|
SysMonitor_GetSendPayload(&sendPayload, dstId);
|
||||||
message->common.dst = sendPayload.nodeId;
|
if(sendPayload == NULL)
|
||||||
message->dataId = sendPayload.dataId;
|
{
|
||||||
message->dataLen = sendPayload.dataLen;
|
message->common.dst = L2_NONE_ID;
|
||||||
|
message->dataId = DATA_ID_NONE;
|
||||||
|
message->dataLen = 0;
|
||||||
memset(message->data, 0xAA, maxDataLen);
|
memset(message->data, 0xAA, maxDataLen);
|
||||||
memcpy(message->data, sendPayload.data, sendPayload.dataLen);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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
|
// Append CRC
|
||||||
uint32_t crcVal;
|
uint32_t crcVal;
|
||||||
@@ -322,14 +349,27 @@ static int32_t Service_Packing2M(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t d
|
|||||||
message->srcSpeedY = instPtr->sysInfo.vY;
|
message->srcSpeedY = instPtr->sysInfo.vY;
|
||||||
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
||||||
|
|
||||||
// TODO: Packing extra payload
|
// Packing extra payload
|
||||||
SYSMON_SVC_PAYLOAD sendPayload;
|
SYSBUS_SVC_PLD *sendPayload;
|
||||||
SysMonitor_GetSendPayload(&sendPayload);
|
SysMonitor_GetSendPayload(&sendPayload, dstId);
|
||||||
message->common.dst = sendPayload.nodeId;
|
if(sendPayload == NULL)
|
||||||
message->dataId = sendPayload.dataId;
|
{
|
||||||
message->dataLen = sendPayload.dataLen;;
|
message->common.dst = L2_NONE_ID;
|
||||||
|
message->dataId = DATA_ID_NONE;
|
||||||
|
message->dataLen = 0;
|
||||||
memset(message->data, 0xAA, maxDataLen);
|
memset(message->data, 0xAA, maxDataLen);
|
||||||
memcpy(message->data, sendPayload.data, sendPayload.dataLen);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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
|
// Append CRC
|
||||||
uint32_t crcVal;
|
uint32_t crcVal;
|
||||||
@@ -491,12 +531,23 @@ static int32_t Service_PktHandler128K(L2_INST *instPtr, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get data payload
|
// Get data payload
|
||||||
SYSMON_SVC_PAYLOAD recvPayload;
|
if (message->dataId != DATA_ID_NONE)
|
||||||
recvPayload.dataId = message->dataId;
|
{
|
||||||
recvPayload.nodeId = message->common.src;
|
if (message->dataLen > maxDataLen)
|
||||||
recvPayload.dataLen = message->dataLen;
|
{
|
||||||
memcpy(recvPayload.data, message->data, maxDataLen);
|
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
|
||||||
SysMonitor_GenRecvRsp(&recvPayload);
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
SYSBUS_SVC_PLD *recvPayload = calloc(1, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
recvPayload->dataId = message->dataId;
|
||||||
|
recvPayload->nodeId = message->common.src;
|
||||||
|
recvPayload->dataLen = message->dataLen;
|
||||||
|
memcpy(recvPayload->data, message->data, message->dataLen);
|
||||||
|
SysMonitor_GenRecvRsp(recvPayload);
|
||||||
|
free(recvPayload);
|
||||||
|
// logging
|
||||||
|
instPtr->log.rxValidMsgCnt++;
|
||||||
|
}
|
||||||
|
|
||||||
// Logging...
|
// Logging...
|
||||||
instPtr->log.rxLog.dataId = message->dataId;
|
instPtr->log.rxLog.dataId = message->dataId;
|
||||||
@@ -571,12 +622,23 @@ static int32_t Service_PktHandler512K(L2_INST *instPtr, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get data payload
|
// Get data payload
|
||||||
SYSMON_SVC_PAYLOAD recvPayload;
|
if (message->dataId != DATA_ID_NONE)
|
||||||
recvPayload.dataId = message->dataId;
|
{
|
||||||
recvPayload.nodeId = message->common.src;
|
if (message->dataLen > maxDataLen)
|
||||||
recvPayload.dataLen = message->dataLen;
|
{
|
||||||
memcpy(recvPayload.data, message->data, maxDataLen);
|
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
|
||||||
SysMonitor_GenRecvRsp(&recvPayload);
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
SYSBUS_SVC_PLD *recvPayload = calloc(1, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
recvPayload->dataId = message->dataId;
|
||||||
|
recvPayload->nodeId = message->common.src;
|
||||||
|
recvPayload->dataLen = message->dataLen;
|
||||||
|
memcpy(recvPayload->data, message->data, message->dataLen);
|
||||||
|
SysMonitor_GenRecvRsp(recvPayload);
|
||||||
|
free(recvPayload);
|
||||||
|
// logging
|
||||||
|
instPtr->log.rxValidMsgCnt++;
|
||||||
|
}
|
||||||
|
|
||||||
// Logging...
|
// Logging...
|
||||||
instPtr->log.rxLog.dataId = message->dataId;
|
instPtr->log.rxLog.dataId = message->dataId;
|
||||||
@@ -651,12 +713,23 @@ static int32_t Service_PktHandler2M(L2_INST *instPtr, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get data payload
|
// Get data payload
|
||||||
SYSMON_SVC_PAYLOAD recvPayload;
|
if (message->dataId != DATA_ID_NONE)
|
||||||
recvPayload.dataId = message->dataId;
|
{
|
||||||
recvPayload.nodeId = message->common.src;
|
if (message->dataLen > maxDataLen)
|
||||||
recvPayload.dataLen = message->dataLen;
|
{
|
||||||
memcpy(recvPayload.data, message->data, message->dataLen);
|
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
|
||||||
SysMonitor_GenRecvRsp(&recvPayload);
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
SYSBUS_SVC_PLD *recvPayload = calloc(1, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
recvPayload->dataId = message->dataId;
|
||||||
|
recvPayload->nodeId = message->common.src;
|
||||||
|
recvPayload->dataLen = message->dataLen;
|
||||||
|
memcpy(recvPayload->data, message->data, message->dataLen);
|
||||||
|
SysMonitor_GenRecvRsp(recvPayload);
|
||||||
|
free(recvPayload);
|
||||||
|
// logging
|
||||||
|
instPtr->log.rxValidMsgCnt++;
|
||||||
|
}
|
||||||
|
|
||||||
// Logging...
|
// Logging...
|
||||||
instPtr->log.rxLog.dataId = message->dataId;
|
instPtr->log.rxLog.dataId = message->dataId;
|
||||||
@@ -887,10 +960,9 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
|
|||||||
memcpy(instPtr->sendPktData, testData, msgLen);
|
memcpy(instPtr->sendPktData, testData, msgLen);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else if (rtneEntry->dst == L2_GetNodeId(instPtr))
|
||||||
{
|
{
|
||||||
// In services slots, rx mode is always enabled when other nodes are transmitting
|
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->src);
|
||||||
commNode = L2_GetNodeById(instPtr->nodeList, L2_HEAD_ID);
|
|
||||||
// antenna selection based on node list
|
// antenna selection based on node list
|
||||||
antIndex = commNode->nodeInfo.antIndex;
|
antIndex = commNode->nodeInfo.antIndex;
|
||||||
// member node receives message in advertise slot
|
// member node receives message in advertise slot
|
||||||
@@ -898,7 +970,13 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
|
|||||||
|
|
||||||
svcFSMPtr->rxCnt++;
|
svcFSMPtr->rxCnt++;
|
||||||
}
|
}
|
||||||
(void)Phy_SetAntIndex(phyRef, antIndex);
|
else
|
||||||
|
{
|
||||||
|
// otherwise suspend
|
||||||
|
antIndex = PHY_ANT_INDEX_NONE;
|
||||||
|
torState = L2_TOR_SUSPEND;
|
||||||
|
}
|
||||||
|
(void)Phy_SetAntIndex(instPtr->config.phyInstPtr, antIndex);
|
||||||
(void)L2_SetupNextSlot(instPtr, torState, L2_FRAME_SVC);
|
(void)L2_SetupNextSlot(instPtr, torState, L2_FRAME_SVC);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -202,41 +202,101 @@ const uint16_t freqTable[L1_FRAME_MAX_HOPS] =
|
|||||||
|
|
||||||
const uint8_t hopPattern_ADV_24MS[L1_FRAME_ADV_24MS_HOPS] =
|
const uint8_t hopPattern_ADV_24MS[L1_FRAME_ADV_24MS_HOPS] =
|
||||||
{
|
{
|
||||||
0U, 35U, 66U, 47U, 40U, 16U, 30U, 65U,
|
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
|
||||||
43U, 7U, 70U, 63U, 7U, 65U, 42U, 28U,
|
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
|
||||||
2U
|
16U,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t hopPattern_ACK_8MS[L1_FRAME_ACK_8MS_HOPS] =
|
const uint8_t hopPattern_ACK_8MS[L1_FRAME_ACK_8MS_HOPS] =
|
||||||
{
|
{
|
||||||
0U, 5U, 49U, 25U, 7U
|
10U, 11U, 12U, 13U, 14U,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_128KBPS_4MS[L1_FRAME_128KBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 80U, 16U, 17U, 65U, 60U, 54U, 31U, 15U,
|
||||||
|
// 6U, 19U, 79U, 52U, 29U, 42U, 23U, 59U,
|
||||||
|
// 60U, 58U, 76U, 67U, 31U, 76U, 77U, 79U,
|
||||||
|
// 79U, 14U, 61U, 5U, 71U, 50U, 32U, 77U,
|
||||||
|
// 60U,
|
||||||
|
//};
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_128KBPS_4MS[L1_FRAME_128KBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
|
||||||
|
// 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
|
||||||
|
// 16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U,
|
||||||
|
// 24U, 25U, 26U, 27U, 28U, 29U, 30U, 31U,
|
||||||
|
// 32U,
|
||||||
|
//};
|
||||||
|
|
||||||
const uint8_t hopPattern_128KBPS_4MS[L1_FRAME_128KBPS_4MS_HOPS] =
|
const uint8_t hopPattern_128KBPS_4MS[L1_FRAME_128KBPS_4MS_HOPS] =
|
||||||
{
|
{
|
||||||
80U, 16U, 17U, 65U, 60U, 54U, 31U, 15U,
|
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
|
||||||
6U, 19U, 79U, 52U, 29U, 42U, 23U, 59U,
|
10U, 11U, 10U, 11U, 10U, 11U, 10U, 11U,
|
||||||
60U, 58U, 76U, 67U, 31U, 76U, 77U, 79U,
|
10U, 12U, 10U, 12U, 10U, 12U, 10U, 12U,
|
||||||
79U, 14U, 61U, 5U, 71U, 50U, 32U, 77U,
|
10U, 13U, 10U, 13U, 10U, 13U, 10U, 13U,
|
||||||
60U,
|
10U,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_128KBPS_4MS[L1_FRAME_128KBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 0U, 1U, 2U, 3U, 4U, 5U, 6U,
|
||||||
|
//};
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_128KBPS_4MS[L1_FRAME_128KBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 0U, 16U, 17U, 65U, 60U, 54U, 31U, 15U,
|
||||||
|
// 6U, 19U, 39U, 52U, 29U, 42U, 23U, 49U,
|
||||||
|
// 33U, 58U, 24U, 67U, 31U, 13U, 17U, 10U,
|
||||||
|
// 59U, 14U, 61U, 5U, 41U, 44U, 32U, 35U,
|
||||||
|
// 60U,
|
||||||
|
//};
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_512KBPS_4MS[L1_FRAME_512KBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
|
||||||
|
// 16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U,
|
||||||
|
// 24U, 25U, 26U, 27U, 28U, 29U, 30U, 31U,
|
||||||
|
// 32U, 33U, 34U, 35U, 36U, 37U, 38U, 39U,
|
||||||
|
// 40U, 41U, 42U, 43U,
|
||||||
|
//};
|
||||||
|
|
||||||
const uint8_t hopPattern_512KBPS_4MS[L1_FRAME_512KBPS_4MS_HOPS] =
|
const uint8_t hopPattern_512KBPS_4MS[L1_FRAME_512KBPS_4MS_HOPS] =
|
||||||
{
|
{
|
||||||
80U, 62U, 40U, 66U, 65U, 33U, 55U, 33U,
|
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
|
||||||
57U, 11U, 37U, 45U, 5U, 69U, 77U, 54U,
|
16U, 17U, 16U, 17U, 16U, 17U, 16U, 17U,
|
||||||
37U, 63U, 14U, 64U, 76U, 31U, 45U, 52U,
|
16U, 18U, 16U, 18U, 16U, 18U, 16U, 18U,
|
||||||
40U, 20U, 20U, 32U, 0U, 60U, 23U, 19U,
|
16U, 19U, 16U, 19U, 16U, 19U, 16U, 19U,
|
||||||
15U, 38U, 62U, 18U,
|
16U, 20U, 16U, 20U,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_2MBPS_4MS[L1_FRAME_2MBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U,
|
||||||
|
// 24U, 25U, 26U, 27U, 28U, 29U, 30U, 31U,
|
||||||
|
// 32U, 33U, 34U, 35U, 36U, 37U, 38U, 39U,
|
||||||
|
// 40U, 41U, 42U, 43U, 44U, 45U, 46U, 47U,
|
||||||
|
// 48U, 49U, 50U, 51U, 52U, 53U,
|
||||||
|
//};
|
||||||
|
|
||||||
|
//const uint8_t hopPattern_2MBPS_4MS[L1_FRAME_2MBPS_4MS_HOPS] =
|
||||||
|
//{
|
||||||
|
// 16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U,
|
||||||
|
// 24U, 25U, 24U, 25U, 24U, 25U, 24U, 25U,
|
||||||
|
// 24U, 26U, 24U, 26U, 24U, 26U, 24U, 26U,
|
||||||
|
// 24U, 27U, 24U, 27U, 24U, 27U, 24U, 27U,
|
||||||
|
// 24U, 28U, 24U, 28U, 24U, 28U,
|
||||||
|
//};
|
||||||
|
|
||||||
const uint8_t hopPattern_2MBPS_4MS[L1_FRAME_2MBPS_4MS_HOPS] =
|
const uint8_t hopPattern_2MBPS_4MS[L1_FRAME_2MBPS_4MS_HOPS] =
|
||||||
{
|
{
|
||||||
0U, 13U, 37U, 44U, 16U, 0U, 59U, 50U,
|
16U, 17U, 18U, 19U, 20U, 21U, 10U, 10U,
|
||||||
69U, 70U, 58U, 14U, 9U, 72U, 27U, 25U,
|
10U, 10U, 10U, 10U, 10U, 10U, 10U, 10U,
|
||||||
21U, 76U, 20U, 35U, 30U, 58U, 22U, 59U,
|
10U, 10U, 10U, 10U, 10U, 10U, 10U, 10U,
|
||||||
48U, 33U, 8U, 7U, 41U, 12U, 44U, 79U,
|
10U, 10U, 10U, 10U, 10U, 10U, 10U, 10U,
|
||||||
77U, 38U, 76U, 75U, 48U, 56U,
|
10U, 10U, 10U, 10U, 10U, 10U,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @} PhysicalLayer_AntennaConfig_Constants*/
|
/** @} PhysicalLayer_AntennaConfig_Constants*/
|
||||||
@@ -402,7 +462,7 @@ int32_t Phy_SetAntIndex(PHY_INST *instPtr, PHY_ANT_INDEX antIndex)
|
|||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
|
|
||||||
if (antIndex < 0 || antIndex >= L1_ANT_NUM)
|
if (antIndex < PHY_ANT_INDEX_NONE || antIndex > PHY_ANT_INDEX_3)
|
||||||
{
|
{
|
||||||
DBG_ERROR("Antenna index out of range: %" PRIu8 ". \n", antIndex);
|
DBG_ERROR("Antenna index out of range: %" PRIu8 ". \n", antIndex);
|
||||||
return EPARAM;
|
return EPARAM;
|
||||||
|
|||||||
@@ -696,6 +696,7 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
|
|||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
int32_t Status;
|
int32_t Status;
|
||||||
uint32_t phyModeCtrl, hopNum;
|
uint32_t phyModeCtrl, hopNum;
|
||||||
|
uint16_t txMultifactor; // physical layer tx power digital attenuation
|
||||||
const uint8_t *hopPattern;
|
const uint8_t *hopPattern;
|
||||||
// Implement a ping-pong flow, offset always is 0 or half of buffer depth.
|
// Implement a ping-pong flow, offset always is 0 or half of buffer depth.
|
||||||
instPtr->antConfigOffset = (L1_ANTCONFIG_MAX_LEN >> 1) - instPtr->antConfigOffset;
|
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)
|
switch (frameType)
|
||||||
{
|
{
|
||||||
|
#ifdef HSJL_GE
|
||||||
case L1_FRAME_ADV_24MS:
|
case L1_FRAME_ADV_24MS:
|
||||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ADV_24MS;
|
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ADV_24MS;
|
||||||
hopNum = L1_FRAME_ADV_24MS_HOPS;
|
hopNum = L1_FRAME_ADV_24MS_HOPS;
|
||||||
hopPattern = hopPattern_ADV_24MS;
|
hopPattern = hopPattern_ADV_24MS;
|
||||||
|
txMultifactor = 0x1f00; // -12dB
|
||||||
break;
|
break;
|
||||||
case L1_FRAME_ACK_8MS:
|
case L1_FRAME_ACK_8MS:
|
||||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ACK_8MS;
|
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ACK_8MS;
|
||||||
hopNum = L1_FRAME_ACK_8MS_HOPS;
|
hopNum = L1_FRAME_ACK_8MS_HOPS;
|
||||||
hopPattern = hopPattern_ACK_8MS;
|
hopPattern = hopPattern_ACK_8MS;
|
||||||
|
txMultifactor = 0x1f00; // -12dB
|
||||||
break;
|
break;
|
||||||
case L1_FRAME_128KBPS_4MS:
|
case L1_FRAME_128KBPS_4MS:
|
||||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_128KBPS_4MS;
|
phyModeCtrl |= PHY_MODE_CTRL_FRAME_128KBPS_4MS;
|
||||||
hopNum = L1_FRAME_128KBPS_4MS_HOPS;
|
hopNum = L1_FRAME_128KBPS_4MS_HOPS;
|
||||||
hopPattern = hopPattern_128KBPS_4MS;
|
hopPattern = hopPattern_128KBPS_4MS;
|
||||||
|
txMultifactor = 0x2000; // -15dB
|
||||||
break;
|
break;
|
||||||
case L1_FRAME_512KBPS_4MS:
|
case L1_FRAME_512KBPS_4MS:
|
||||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_512KBPS_4MS;
|
phyModeCtrl |= PHY_MODE_CTRL_FRAME_512KBPS_4MS;
|
||||||
hopNum = L1_FRAME_512KBPS_4MS_HOPS;
|
hopNum = L1_FRAME_512KBPS_4MS_HOPS;
|
||||||
hopPattern = hopPattern_512KBPS_4MS;
|
hopPattern = hopPattern_512KBPS_4MS;
|
||||||
|
txMultifactor = 0x2000; // -12dB
|
||||||
break;
|
break;
|
||||||
case L1_FRAME_2MBPS_4MS:
|
case L1_FRAME_2MBPS_4MS:
|
||||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_2MBPS_4MS;
|
phyModeCtrl |= PHY_MODE_CTRL_FRAME_2MBPS_4MS;
|
||||||
hopNum = L1_FRAME_2MBPS_4MS_HOPS;
|
hopNum = L1_FRAME_2MBPS_4MS_HOPS;
|
||||||
hopPattern = hopPattern_2MBPS_4MS;
|
hopPattern = hopPattern_2MBPS_4MS;
|
||||||
|
txMultifactor = 0x7000; // -6dB, baseline
|
||||||
break;
|
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:
|
default:
|
||||||
return EPARAM;
|
return EPARAM;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set frame configs
|
// 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.
|
// Trigger physical configuration.
|
||||||
// Indicate physical layer that all the configurations were done.
|
// Indicate physical layer that all the configurations were done.
|
||||||
PhyWrite(instPtr, SLOT_CMD, SLOT_CMD_KEY);
|
PhyWrite(instPtr, SLOT_CMD, SLOT_CMD_KEY);
|
||||||
@@ -1026,9 +1067,10 @@ void Phy_RefreshHwSate(PHY_INST *instPtr)
|
|||||||
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
|
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
|
||||||
? INT8_MAX
|
? INT8_MAX
|
||||||
: ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
|
: ((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.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.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));
|
|
||||||
#else
|
#else
|
||||||
double evalData;
|
double evalData;
|
||||||
instPtr->hwSate.isSpOk = true;
|
instPtr->hwSate.isSpOk = true;
|
||||||
@@ -1106,9 +1148,12 @@ void Phy_RefreshHwSate(PHY_INST *instPtr)
|
|||||||
// -- Update FPGA Chip temperature, unit 1 deg
|
// -- Update FPGA Chip temperature, unit 1 deg
|
||||||
rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_TEMP);
|
rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_TEMP);
|
||||||
evalData = XAdcPs_RawToTemperature(rawData);
|
evalData = XAdcPs_RawToTemperature(rawData);
|
||||||
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
|
// instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
|
||||||
? INT8_MAX
|
// ? INT8_MAX
|
||||||
: ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
|
// : ((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.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.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.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK));
|
||||||
|
|||||||
@@ -24,14 +24,14 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#ifndef EMULATION
|
#ifndef EMULATION
|
||||||
#include "xbram.h"
|
#include "xbram.h"
|
||||||
#include "../config/app_config.h"
|
#include "../../config/app_config.h"
|
||||||
#ifdef HSJL_GE // Zynq MPSoC (Zynq UltraScale+)
|
#ifdef HSJL_GE // Zynq MPSoC (Zynq UltraScale+)
|
||||||
#include "xsysmon.h"
|
#include "xsysmon.h"
|
||||||
#else
|
#else
|
||||||
#include "xadcps.h"
|
#include "xadcps.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#include "../../system_monitor.h"
|
#include "../../systembus/systembus.h"
|
||||||
#include "../../time_ctrl/time_ctrl.h"
|
#include "../../time_ctrl/time_ctrl.h"
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -207,7 +207,7 @@
|
|||||||
/**
|
/**
|
||||||
* Register: TM_TARGET_L
|
* Register: TM_TARGET_L
|
||||||
*/
|
*/
|
||||||
#define TM_TARGET_L 0x00000064U
|
#define TM_TARGET_L 0x00000034U
|
||||||
#define TM_TARGET_L_SHIFT 0
|
#define TM_TARGET_L_SHIFT 0
|
||||||
#define TM_TARGET_L_WIDTH 32
|
#define TM_TARGET_L_WIDTH 32
|
||||||
#define TM_TARGET_L_MASK 0xFFFFFFFFU
|
#define TM_TARGET_L_MASK 0xFFFFFFFFU
|
||||||
@@ -260,6 +260,14 @@
|
|||||||
#define ANT_SELECT_INDEX_WIDTH 32
|
#define ANT_SELECT_INDEX_WIDTH 32
|
||||||
#define ANT_SELECT_INDEX_MASK 0xFFFFFFFFU
|
#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
|
* Register: ANT_STATUS_1
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,380 +0,0 @@
|
|||||||
/**
|
|
||||||
* @addtogroup SystemMonitor
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************** Include Files *********************************/
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "common.h"
|
|
||||||
#include "circ_queue.h"
|
|
||||||
#include "system_monitor.h"
|
|
||||||
#include "systembus/systembus.h"
|
|
||||||
/************************** Constant Definitions *****************************/
|
|
||||||
/**
|
|
||||||
* @name SystemMonitor_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define BUFF_A 0x00
|
|
||||||
#define BUFF_B 0x01
|
|
||||||
#define BUFF_NONE 0xFF
|
|
||||||
|
|
||||||
#define SYSINFO_PACK_LEN 54 // bytes
|
|
||||||
#define PAYLOAD_PACK_LEN 46 // bytes
|
|
||||||
#define SLOTLOG_PACK_LEN 88 // bytes
|
|
||||||
#define PRTCLLOG_PACK_ELN 24 // bytes
|
|
||||||
#define HWSTATE_PACK_ELN 12 // bytes
|
|
||||||
/** @} SystemMonitor_Private_Constants*/
|
|
||||||
/************************** Data Type Definitions ****************************/
|
|
||||||
/**
|
|
||||||
* @struct PINGPONG
|
|
||||||
* @brief PingPing Control
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t latest; ///< latest available index
|
|
||||||
uint8_t rBusy; ///< current read busy index
|
|
||||||
uint8_t wBusy; ///< current write busy index
|
|
||||||
} PINGPONG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct SYSMONITOR
|
|
||||||
* @brief System Monitor struct holds all the system log info
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SYSMON_CONFIG config; ///< system monitor initialization parameters
|
|
||||||
CIRC_QUEUE *sendQueue; ///< send queue
|
|
||||||
CIRC_QUEUE *recvQueue; ///< receive queue
|
|
||||||
PINGPONG sysInfoCtrl;
|
|
||||||
SYSINFO sysInfo[2];
|
|
||||||
PINGPONG linkLogCtrl;
|
|
||||||
LINKLOG linkLog[2];
|
|
||||||
PINGPONG phyLogCtrl;
|
|
||||||
PHYLOG phyLog[2];
|
|
||||||
PINGPONG hwStateCtrl;
|
|
||||||
HWSTATE hwState[2];
|
|
||||||
} SYSMONITOR;
|
|
||||||
|
|
||||||
/************************** Function Prototypes ******************************/
|
|
||||||
static uint8_t GetWritable(PINGPONG ctrllor);
|
|
||||||
static uint8_t GetReadable(PINGPONG ctrllor);
|
|
||||||
/************************** Variable Definitions *****************************/
|
|
||||||
static SYSMONITOR *sysMonitorInst;
|
|
||||||
extern SYSBUS *sysbusDescPtr;
|
|
||||||
|
|
||||||
/*********************** Function Implementations ***************************/
|
|
||||||
inline static uint8_t GetWritable(PINGPONG ctrllor)
|
|
||||||
{
|
|
||||||
// Allow only one write.
|
|
||||||
ASSERT(ctrllor.wBusy == BUFF_NONE);
|
|
||||||
if (ctrllor.rBusy == BUFF_NONE)
|
|
||||||
return ((ctrllor.latest == BUFF_B) ? BUFF_A : BUFF_B);
|
|
||||||
else
|
|
||||||
return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static uint8_t GetReadable(PINGPONG ctrllor)
|
|
||||||
{
|
|
||||||
if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest)
|
|
||||||
return ((ctrllor.latest == BUFF_NONE) ? BUFF_A : BUFF_B);
|
|
||||||
else
|
|
||||||
return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize System monitor
|
|
||||||
*
|
|
||||||
* @return SUCCESS
|
|
||||||
*/
|
|
||||||
int32_t SysMonitor_Init(SYSMON_CONFIG *config)
|
|
||||||
{
|
|
||||||
ASSERT(config != NULL);
|
|
||||||
|
|
||||||
sysMonitorInst = calloc(1, sizeof(SYSMONITOR));
|
|
||||||
if (sysMonitorInst == NULL)
|
|
||||||
{
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&(sysMonitorInst->config), config, sizeof(SYSMON_CONFIG));
|
|
||||||
sysMonitorInst->sendQueue = NULL;
|
|
||||||
sysMonitorInst->recvQueue = NULL;
|
|
||||||
memset(&(sysMonitorInst->sysInfoCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
||||||
memset(&(sysMonitorInst->linkLogCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
||||||
memset(&(sysMonitorInst->phyLogCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
||||||
memset(&(sysMonitorInst->hwStateCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
||||||
|
|
||||||
if (CircQueueCreate(&(sysMonitorInst->sendQueue),
|
|
||||||
sysMonitorInst->config.sendQueueMax) == false)
|
|
||||||
{
|
|
||||||
SysMonitor_Destroy();
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
if (CircQueueCreate(&(sysMonitorInst->recvQueue),
|
|
||||||
sysMonitorInst->config.recvQueueMax) == false)
|
|
||||||
{
|
|
||||||
SysMonitor_Destroy();
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Destroy system monitor release all allocated memory
|
|
||||||
*/
|
|
||||||
void SysMonitor_Destroy(void)
|
|
||||||
{
|
|
||||||
free(sysMonitorInst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name SystemInfo_API
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update system info.
|
|
||||||
*
|
|
||||||
* @param info
|
|
||||||
*/
|
|
||||||
void SysMonitor_UpdateSysinfo(const SYSINFO *info)
|
|
||||||
{
|
|
||||||
ASSERT(info != NULL);
|
|
||||||
uint8_t buffIndx;
|
|
||||||
buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl);
|
|
||||||
sysMonitorInst->sysInfoCtrl.wBusy = buffIndx;
|
|
||||||
memcpy(&(sysMonitorInst->sysInfo[buffIndx]), info, sizeof(SYSINFO));
|
|
||||||
sysMonitorInst->sysInfoCtrl.latest = buffIndx;
|
|
||||||
sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get system info.
|
|
||||||
*
|
|
||||||
* @param info
|
|
||||||
*/
|
|
||||||
void SysMonitor_GetSysinfo(SYSINFO *info)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(info != NULL);
|
|
||||||
uint8_t buffIndx, buffIndex_old;
|
|
||||||
buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy;
|
|
||||||
if (buffIndex_old != BUFF_NONE)
|
|
||||||
buffIndx = buffIndex_old; // Keep it busy
|
|
||||||
else
|
|
||||||
buffIndx = GetReadable(sysMonitorInst->sysInfoCtrl);
|
|
||||||
sysMonitorInst->sysInfoCtrl.rBusy = buffIndx;
|
|
||||||
memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO));
|
|
||||||
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
|
|
||||||
}
|
|
||||||
/** @} SystemInfo_API*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name ServicePayload_API
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update send payload by
|
|
||||||
*
|
|
||||||
* @param payload
|
|
||||||
*/
|
|
||||||
int32_t SysMonitor_UpdateSendPayload(SYSMON_SVC_PAYLOAD *payload)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(payload != NULL);
|
|
||||||
|
|
||||||
// validity check
|
|
||||||
if (payload->dataLen > PAYLOAD_LEN_MAX)
|
|
||||||
{
|
|
||||||
DBG_ERROR("Payload length %d exceeds valid range.", payload->dataLen);
|
|
||||||
return EPARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// push message into send queue
|
|
||||||
if (CircQueuePush(sysMonitorInst->sendQueue, (void *)payload) == false)
|
|
||||||
{
|
|
||||||
DBG_WARNING("SystemMonitor::SEND Queue overflowed!\n");
|
|
||||||
return EQUEUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the latest send payload.
|
|
||||||
*
|
|
||||||
* @param payload
|
|
||||||
*/
|
|
||||||
void SysMonitor_GetSendPayload(SYSMON_SVC_PAYLOAD *payload)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(payload != NULL);
|
|
||||||
|
|
||||||
if (CircQueuePop(sysMonitorInst->sendQueue, (void *)payload) == false)
|
|
||||||
{
|
|
||||||
payload->dataId = DATA_ID_NONE;
|
|
||||||
payload->nodeId = 0;
|
|
||||||
payload->dataLen = 0;
|
|
||||||
// set payload to be 0xAA to balanced average signal power
|
|
||||||
memset(payload->data, 0xAA, PAYLOAD_LEN_MAX);
|
|
||||||
DBG_WARNING("SystemMonitor::Nothing to be sent.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update receive payload.
|
|
||||||
*
|
|
||||||
* @param payload
|
|
||||||
*/
|
|
||||||
int32_t SysMonitor_GenRecvRsp(SYSMON_SVC_PAYLOAD *payload)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(sysbusDescPtr != NULL);
|
|
||||||
int32_t Status;
|
|
||||||
|
|
||||||
if (payload->dataId == DATA_ID_NONE || payload->dataLen > PAYLOAD_LEN_MAX)
|
|
||||||
{
|
|
||||||
return EIGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = SystemBus_GenRecvRsp(sysbusDescPtr, payload);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
/** @} ServicePayload_API*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Linklayer_Log_API
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update link layer log
|
|
||||||
*
|
|
||||||
* @param log
|
|
||||||
*/
|
|
||||||
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(log != NULL);
|
|
||||||
uint8_t buffIndx;
|
|
||||||
buffIndx = GetWritable(sysMonitorInst->linkLogCtrl);
|
|
||||||
sysMonitorInst->linkLogCtrl.wBusy = buffIndx;
|
|
||||||
memcpy(&(sysMonitorInst->linkLog[buffIndx]), log, sizeof(LINKLOG));
|
|
||||||
sysMonitorInst->linkLogCtrl.latest = buffIndx;
|
|
||||||
sysMonitorInst->linkLogCtrl.wBusy = BUFF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the latest link layer log
|
|
||||||
*
|
|
||||||
* @param log
|
|
||||||
*/
|
|
||||||
void SysMonitor_GetLinklayerLog(LINKLOG *log)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(log != NULL);
|
|
||||||
uint8_t buffIndx, buffIndex_old;
|
|
||||||
buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy;
|
|
||||||
if (buffIndex_old != BUFF_NONE)
|
|
||||||
buffIndx = buffIndex_old; // Keep it busy
|
|
||||||
else
|
|
||||||
buffIndx = GetReadable(sysMonitorInst->linkLogCtrl);
|
|
||||||
sysMonitorInst->linkLogCtrl.rBusy = buffIndx;
|
|
||||||
memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG));
|
|
||||||
sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old;
|
|
||||||
}
|
|
||||||
/** @} Linklayer_Log_API*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name PhysicalLayer_Log_API
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update physical layer log
|
|
||||||
*
|
|
||||||
* @param log
|
|
||||||
*/
|
|
||||||
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(log != NULL);
|
|
||||||
uint8_t buffIndx;
|
|
||||||
buffIndx = GetWritable(sysMonitorInst->phyLogCtrl);
|
|
||||||
sysMonitorInst->phyLogCtrl.wBusy = buffIndx;
|
|
||||||
memcpy(&(sysMonitorInst->phyLog[buffIndx]), log, sizeof(PHYLOG));
|
|
||||||
sysMonitorInst->phyLogCtrl.latest = buffIndx;
|
|
||||||
sysMonitorInst->phyLogCtrl.wBusy = BUFF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the latest physical layer log
|
|
||||||
*
|
|
||||||
* @param log
|
|
||||||
*/
|
|
||||||
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(log != NULL);
|
|
||||||
uint8_t buffIndx, buffIndex_old;
|
|
||||||
buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy;
|
|
||||||
if (buffIndex_old != BUFF_NONE)
|
|
||||||
buffIndx = buffIndex_old; // Keep it busy
|
|
||||||
else
|
|
||||||
buffIndx = GetReadable(sysMonitorInst->phyLogCtrl);
|
|
||||||
sysMonitorInst->phyLogCtrl.rBusy = buffIndx;
|
|
||||||
memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG));
|
|
||||||
sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old;
|
|
||||||
}
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name HardwareState_Log_API
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Log hardware running status.
|
|
||||||
*
|
|
||||||
* @param state
|
|
||||||
*/
|
|
||||||
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(state != NULL);
|
|
||||||
uint8_t buffIndx;
|
|
||||||
buffIndx = GetWritable(sysMonitorInst->hwStateCtrl);
|
|
||||||
sysMonitorInst->hwStateCtrl.wBusy = buffIndx;
|
|
||||||
memcpy(&(sysMonitorInst->hwState[buffIndx]), state, sizeof(HWSTATE));
|
|
||||||
sysMonitorInst->hwStateCtrl.latest = buffIndx;
|
|
||||||
sysMonitorInst->hwStateCtrl.wBusy = BUFF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the latest hardware running status.
|
|
||||||
*
|
|
||||||
* @param state
|
|
||||||
*/
|
|
||||||
void SysMonitor_GetHardwareStatus(HWSTATE *state)
|
|
||||||
{
|
|
||||||
ASSERT(sysMonitorInst != NULL);
|
|
||||||
ASSERT(state != NULL);
|
|
||||||
uint8_t buffIndx, buffIndex_old;
|
|
||||||
buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy;
|
|
||||||
if (buffIndex_old != BUFF_NONE)
|
|
||||||
buffIndx = buffIndex_old; // Keep it busy
|
|
||||||
else
|
|
||||||
buffIndx = GetReadable(sysMonitorInst->hwStateCtrl);
|
|
||||||
sysMonitorInst->hwStateCtrl.rBusy = buffIndx;
|
|
||||||
memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE));
|
|
||||||
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} HardwareState_Log_API */
|
|
||||||
|
|
||||||
/** @} SystemMonitor*/
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
/**
|
|
||||||
* @defgroup SystemMonitor
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SYSTEM_MONITOR_H_
|
|
||||||
#define __SYSTEM_MONITOR_H_
|
|
||||||
|
|
||||||
/***************************** Include Files *********************************/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/************************* Constant Definitions ******************************/
|
|
||||||
/**
|
|
||||||
* @name SystemMonitor_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define PAYLOAD_LEN_MAX 1000
|
|
||||||
|
|
||||||
#define DATA_ID_NONE UINT32_MAX
|
|
||||||
#define DATA_ID_TEST 0x02030203
|
|
||||||
|
|
||||||
#define VOLTAGE_LSB 0.01 // volt
|
|
||||||
#define VOLTAGE_MAX 2.55 // volt
|
|
||||||
|
|
||||||
#define VOLT_PS_STD 1.0
|
|
||||||
#define VOLT_PSAUX_STD 1.8
|
|
||||||
#define VOLT_DDR_STD 1.5
|
|
||||||
#define VOLT_PL_STD 1.0
|
|
||||||
#define VOLT_PLAUX_STD 1.8
|
|
||||||
#define VOLT_BRAM_STD 1.0
|
|
||||||
|
|
||||||
#define VOLT_PS_OK BIT(0)
|
|
||||||
#define VOLT_PSAUX_OK BIT(1)
|
|
||||||
#define VOLT_DDR_OK BIT(2)
|
|
||||||
#define VOLT_PL_OK BIT(3)
|
|
||||||
#define VOLT_PLAUX_OK BIT(4)
|
|
||||||
#define VOLT_BRAM_OK BIT(5)
|
|
||||||
|
|
||||||
#define VOLT_ANT_PROC_OK BIT(0)
|
|
||||||
#define VOLT_ANT_RF_OK BIT(2)
|
|
||||||
#define VOLT_ANT_NIL_OK BIT(4)
|
|
||||||
#define ANT_STATE_OK BIT(6)
|
|
||||||
|
|
||||||
// Xilinx Recommended
|
|
||||||
// #define IS_PS_VALID(x) (x <= 1.05 && x >= 0.95)
|
|
||||||
// #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 <= 1.03 && x >= 0.97)
|
|
||||||
// #define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71)
|
|
||||||
// #define IS_BRAM_VALID(x) (x <= 1.03 && x >= 0.97)
|
|
||||||
#define IS_PS_VALID(x) ((x) <= 1.1 && (x) >= 0.9)
|
|
||||||
#define IS_PSAUX_VALID(x) ((x) <= 2.0 && (x) >= 1.6)
|
|
||||||
#define IS_DDR_VALID(x) ((x) <= 1.7 && (x) >= 1.3)
|
|
||||||
#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)
|
|
||||||
|
|
||||||
#define CLK_SP_PLL1_LOCK BIT(0)
|
|
||||||
#define CLK_SP_PLL2_LOCK BIT(2)
|
|
||||||
|
|
||||||
#define CLK_AD0_BBPLL_LOCK BIT(0)
|
|
||||||
#define CLK_AD0_RFPLL_LOCK BIT(2)
|
|
||||||
#define CLK_AD1_BBPLL_LOCK BIT(4)
|
|
||||||
#define CLK_AD1_RFPLL_LOCK BIT(6)
|
|
||||||
|
|
||||||
#define CLK_ANT_BBPLL_LOCK BIT(0)
|
|
||||||
#define CLK_ANT_RFPLL1_LOCK BIT(2)
|
|
||||||
#define CLK_ANT_RFPLL2_LOCK BIT(4)
|
|
||||||
|
|
||||||
#define TEMPERATURE_LSB 1.0 // Celsius degree
|
|
||||||
#define TEMPERATURE_MAX 127.0 // Celsius degree
|
|
||||||
#define TEMPERATURE_MIN -128.0 // Celsius degree
|
|
||||||
/** @} SystemMonitor_Constants */
|
|
||||||
|
|
||||||
/************************* Data Type Definitions ****************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct SYSINFO
|
|
||||||
* @brief System Infomation log
|
|
||||||
*/
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
uint32_t psBDS; ///< -- unit: ms, 0~604799999
|
|
||||||
uint16_t pBDS; ///< -- unit: week, 0~0~8191
|
|
||||||
uint32_t psGPS; ///< -- unit: ms, 0~604799999
|
|
||||||
uint16_t pGPS; ///< -- unit: week, 0~0~8191
|
|
||||||
uint8_t tmInd; ///< Time validation indicator \n
|
|
||||||
// -- [0] GPS\n
|
|
||||||
// -- [1] reserve.\n
|
|
||||||
// -- [2] UTC\n
|
|
||||||
// -- [3] BDS\n
|
|
||||||
float tmFly; ///< Time of flying uint: s
|
|
||||||
uint8_t stFly; ///< Status of flying \n
|
|
||||||
// [7:6] departure status 11 - departed/00 - not departed \n
|
|
||||||
// [5:4] ready status 11 - ready/00 - not ready \n
|
|
||||||
// [3:2] attitude status 11 - attitude ok/00 - attitude not ok \n
|
|
||||||
// [1:0] attitude adjust status 11 - adjusted/00 - not adjusted
|
|
||||||
float posX; ///< coord X Position in launch coordinate system
|
|
||||||
float posY; ///< coord Y Position in launch coordinate system
|
|
||||||
float posZ; ///< coord Z Position in launch coordinate system
|
|
||||||
float vX; ///< Speed X in launch coordinate system
|
|
||||||
float vY; ///< Speed Y in launch coordinate system
|
|
||||||
float vZ; ///< Speed Z in launch coordinate system
|
|
||||||
float pitch; ///< Pitch Attitude in launch inertia coordinate system
|
|
||||||
float yaw; ///< Yaw Attitude in launch inertia coordinate system
|
|
||||||
float roll; ///< Roll Attitude in launch inertia coordinate system
|
|
||||||
} SYSINFO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct SYSBUSLOG
|
|
||||||
* @brief System Info holds the system bus log
|
|
||||||
*/
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
// SystemBus log
|
|
||||||
|
|
||||||
uint8_t lastConfig[4]; ///< Last valid config \n
|
|
||||||
// byte 0: Enable control, 0xAA - enable, 0x55 - disable \n
|
|
||||||
// byte 1: Node ID \n
|
|
||||||
// byte 2: Service rate \n
|
|
||||||
// byte 3: routing table number
|
|
||||||
uint32_t recvCnt; ///< number of received data packet
|
|
||||||
uint32_t sendCnt; ///< number of send data packet
|
|
||||||
uint32_t remoteCnt; ///< number of remote check commands
|
|
||||||
} SYSBUSLOG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct LINKLOG
|
|
||||||
* @brief Linklayer Log struct holds the Linklayer log
|
|
||||||
*/
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
// Network log
|
|
||||||
uint32_t tuNum; ///< current time unite number
|
|
||||||
uint8_t slotNum; ///< current slot number
|
|
||||||
uint8_t nodeType; ///< current node type
|
|
||||||
uint8_t cxnStatus; ///< current connection status
|
|
||||||
uint8_t linkStage; ///< current linklayer working stage
|
|
||||||
uint32_t recxnCnt; ///< reconnect trial count
|
|
||||||
uint8_t antIndex; ///< current working antenna index
|
|
||||||
uint32_t advTxCnt; ///< adv frame send count
|
|
||||||
uint32_t advRecvCnt; ///< adv frame received count
|
|
||||||
uint32_t advCorrectCnt; ///< adv frame received correctly count
|
|
||||||
uint32_t ackTxCnt; ///< ack frame send count
|
|
||||||
uint32_t ackRecvCnt; ///< ack frame received count
|
|
||||||
uint32_t ackCorrectCnt; ///< ack frame received correctly count
|
|
||||||
uint32_t disTxCnt; ///< dist frame send count
|
|
||||||
uint32_t disRecvCnt; ///< dist frame received count
|
|
||||||
uint32_t disCorrectCnt;///< dist frame received correctly count
|
|
||||||
uint32_t mngTxCnt; ///< mng frame send count
|
|
||||||
uint32_t mngRecvCnt; ///< mng frame received count
|
|
||||||
uint32_t mngCorrectCnt; ///< mng frame received correctly count
|
|
||||||
uint32_t rttTxCnt; ///< rtt frame send count
|
|
||||||
uint32_t rttRecvCnt; ///< rtt frame received count
|
|
||||||
uint32_t rttCorrectCnt; ///< rtt frame received correctly count
|
|
||||||
uint32_t svcTxCnt; ///< svc frame send count
|
|
||||||
uint32_t svcRecvCnt; ///< svc frame received count
|
|
||||||
uint32_t svcCorrectCnt; ///< svc frame received correctly count
|
|
||||||
int32_t timeDev; ///< last time deviation result
|
|
||||||
uint32_t sendId; ///< last send data id
|
|
||||||
uint32_t recvId; ///< last received data id
|
|
||||||
uint8_t reserve[3]; ///< reserved data
|
|
||||||
} LINKLOG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct PHYLOG
|
|
||||||
* @brief Physical Layer Log struct holds the Linklayer log
|
|
||||||
*/
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
uint32_t acqCnt; ///< acquisition count
|
|
||||||
uint32_t fsyncCnt; ///< frame sync count
|
|
||||||
uint32_t decodeCnt; ///< decode count
|
|
||||||
uint32_t crcCnt; ///< crc valid count
|
|
||||||
double doppler; ///< last doppler estimation result
|
|
||||||
uint64_t recvStamp; ///< last frame arrival time
|
|
||||||
double acqPAPR; ///< last acquisition peak-average ration
|
|
||||||
uint8_t acqPhase; ///< last acquisition phase estimation
|
|
||||||
uint8_t acqFreqCh; ///< last acquisition frequency deviation estimation
|
|
||||||
double fsyncPAPR; ///< last frame sync peak-average ration
|
|
||||||
uint8_t fsyncFreqCh; ///< last frame sync frequency estimation
|
|
||||||
uint16_t deintlvAmpEst; ///< de-interleave amplitude estimation
|
|
||||||
uint8_t antControl; ///< current antenna rf mode
|
|
||||||
uint8_t reserve[2]; ///< reserved data
|
|
||||||
} PHYLOG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct HWSTATE
|
|
||||||
* @brief Hardware Status Log struct holds all hardware status
|
|
||||||
*/
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
bool isSpOk; ///< signal processor state
|
|
||||||
bool isAntOk; ///< antenna state
|
|
||||||
// -- Signal processor status
|
|
||||||
uint8_t spFpgaVolt; ///< Signal processor voltage state indicator
|
|
||||||
uint8_t spClkState; ///< Signal processor clock state indicator
|
|
||||||
uint8_t spAdLockState; ///< Signal processor adc lock state indicator
|
|
||||||
int8_t spAdTemp_0; ///< Signal processor adc0 temperature
|
|
||||||
int8_t spAdTemp_1; ///< Signal processor adc1 temperature
|
|
||||||
int8_t spFpgaTemp; ///< Signal processor FPGA temperature
|
|
||||||
// -- Antenna status
|
|
||||||
uint16_t ant1Freq; ///< Antenna 1 frequency
|
|
||||||
uint16_t ant2Freq; ///< Antenna 2 frequency
|
|
||||||
uint16_t ant3Freq; ///< Antenna 3 frequency
|
|
||||||
uint8_t antPll; ///< Antenna pll lock state indicator
|
|
||||||
uint8_t antMode; ///< Antenna mode indicator
|
|
||||||
int8_t antTemp; ///< Antenna rf temperature
|
|
||||||
uint8_t antRsvd; ///< Antenna reserved status register
|
|
||||||
uint8_t phyId;
|
|
||||||
uint8_t reserve[3];
|
|
||||||
} HWSTATE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct SYSMON_CONFIG
|
|
||||||
* @brief System monitor config struct holds system monitor initialization parameters
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t sendQueueMax; ///< maximum send queue length
|
|
||||||
uint32_t recvQueueMax; ///< maximum receive queue length
|
|
||||||
} SYSMON_CONFIG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct SYSMON_SVC_PAYLOAD
|
|
||||||
* @brief Payload struct that holds the service payload
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t dataId; ///< data identifier
|
|
||||||
uint8_t nodeId; ///< destination ID for tx, source ID for rx
|
|
||||||
uint16_t dataLen; ///< data length
|
|
||||||
uint8_t data[PAYLOAD_LEN_MAX];
|
|
||||||
} SYSMON_SVC_PAYLOAD;
|
|
||||||
|
|
||||||
/************************** Function Prototypes ******************************/
|
|
||||||
int32_t SysMonitor_Init(SYSMON_CONFIG *config);
|
|
||||||
void SysMonitor_Destroy(void);
|
|
||||||
|
|
||||||
void SysMonitor_UpdateSysinfo(const SYSINFO *info);
|
|
||||||
void SysMonitor_GetSysinfo(SYSINFO *info);
|
|
||||||
|
|
||||||
int32_t SysMonitor_UpdateSendPayload(SYSMON_SVC_PAYLOAD *payload);
|
|
||||||
void SysMonitor_GetSendPayload(SYSMON_SVC_PAYLOAD *payload);
|
|
||||||
int32_t SysMonitor_GenRecvRsp(SYSMON_SVC_PAYLOAD *payload);
|
|
||||||
|
|
||||||
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log);
|
|
||||||
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log);
|
|
||||||
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state);
|
|
||||||
void SysMonitor_GetLinklayerLog(LINKLOG *log);
|
|
||||||
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log);
|
|
||||||
void SysMonitor_GetHardwareStatus(HWSTATE *state);
|
|
||||||
|
|
||||||
#endif //__SYSTEM_MONITOR_H_
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
+422
-66
@@ -27,7 +27,9 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "circ_queue.h"
|
#include "circ_queue.h"
|
||||||
#include "../system_monitor.h"
|
// TODO: better approach?
|
||||||
|
#include "../networking/link_layer/link_layer.h"
|
||||||
|
#include "../networking/phy_layer/phy_layer.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup SystemBus_Protocol_Routine
|
* @addtogroup SystemBus_Protocol_Routine
|
||||||
@@ -71,8 +73,8 @@
|
|||||||
// -- Request
|
// -- Request
|
||||||
// -- -- Enable control
|
// -- -- Enable control
|
||||||
#define WD_EN_CMD 0x02
|
#define WD_EN_CMD 0x02
|
||||||
#define EN_CMD_ENABLE 0x66
|
#define EN_CMD_ENABLE 0xAA
|
||||||
#define EN_CMD_SILENT 0x88
|
#define EN_CMD_SILENT 0x55
|
||||||
// -- -- Node mode control
|
// -- -- Node mode control
|
||||||
#define WD_ID_CMD 0x03
|
#define WD_ID_CMD 0x03
|
||||||
// -- -- Service Rate control
|
// -- -- Service Rate control
|
||||||
@@ -128,7 +130,7 @@
|
|||||||
// -- Request
|
// -- Request
|
||||||
// -- -- --
|
// -- -- --
|
||||||
// -- Response
|
// -- Response
|
||||||
#define RM_TEST_RSP_LEN 190
|
#define RM_TEST_RSP_LEN 202
|
||||||
// -- -- 8 byte time stamp
|
// -- -- 8 byte time stamp
|
||||||
#define RT_TIME_STAMP_OFFSET 0x02
|
#define RT_TIME_STAMP_OFFSET 0x02
|
||||||
#define RT_TIME_STAMP_LEN 8
|
#define RT_TIME_STAMP_LEN 8
|
||||||
@@ -137,18 +139,59 @@
|
|||||||
#define RT_SYSBUS_LOG_LEN 16
|
#define RT_SYSBUS_LOG_LEN 16
|
||||||
// -- -- 88 byte link layer log
|
// -- -- 88 byte link layer log
|
||||||
#define RT_LINK_LOG_OFFSET 0x1A
|
#define RT_LINK_LOG_OFFSET 0x1A
|
||||||
#define RT_LINK_LOG_LEN 88
|
#define RT_LINK_LOG_LEN 100
|
||||||
// -- -- 56 byte physical layer log
|
// -- -- 56 byte physical layer log
|
||||||
#define RT_PHY_LOG_OFFSET 0x72
|
#define RT_PHY_LOG_OFFSET 0x7E
|
||||||
#define RT_PHY_LOG_LEN 56
|
#define RT_PHY_LOG_LEN 56
|
||||||
// -- -- 20 byte hardware log
|
// -- -- 20 byte hardware log
|
||||||
#define RT_HARDWARE_ST_OFFSET 0xAA
|
#define RT_HARDWARE_ST_OFFSET 0xB6
|
||||||
#define RT_HARDWARE_ST_LEN 20
|
#define RT_HARDWARE_ST_LEN 20
|
||||||
|
|
||||||
// My Production Type
|
// My Production Type
|
||||||
#define MY_PRD_ID PRD_DL_C
|
#define MY_PRD_ID PRD_DL_C
|
||||||
/** @} SystemBus_MSG_Constants*/
|
/** @} SystemBus_MSG_Constants*/
|
||||||
|
#define BUFF_A 0x00
|
||||||
|
#define BUFF_B 0x01
|
||||||
|
#define BUFF_NONE 0xFF
|
||||||
|
|
||||||
|
#define SYSINFO_PACK_LEN 54 // bytes
|
||||||
|
#define PAYLOAD_PACK_LEN 46 // bytes
|
||||||
|
#define SLOTLOG_PACK_LEN 88 // bytes
|
||||||
|
#define PRTCLLOG_PACK_ELN 24 // bytes
|
||||||
|
#define HWSTATE_PACK_ELN 12 // bytes
|
||||||
|
/************************** Data Type Definitions ****************************/
|
||||||
|
/**
|
||||||
|
* @struct PINGPONG
|
||||||
|
* @brief PingPing Control
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t latest; ///< latest available index
|
||||||
|
uint8_t rBusy; ///< current read busy index
|
||||||
|
uint8_t wBusy; ///< current write busy index
|
||||||
|
} PINGPONG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct SYSMONITOR
|
||||||
|
* @brief System Monitor struct holds all the system log info
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SYSMON_CONFIG config; ///< system monitor initialization parameters
|
||||||
|
CIRC_QUEUE *sendQueue[L2_NET_SCALE]; ///< send queue
|
||||||
|
CIRC_QUEUE *recvQueue[L2_NET_SCALE]; ///< receive queue
|
||||||
|
PINGPONG sysInfoCtrl;
|
||||||
|
SYSINFO sysInfo[2];
|
||||||
|
PINGPONG linkLogCtrl;
|
||||||
|
LINKLOG linkLog[2];
|
||||||
|
PINGPONG phyLogCtrl;
|
||||||
|
PHYLOG phyLog[2];
|
||||||
|
PINGPONG hwStateCtrl;
|
||||||
|
HWSTATE hwState[2];
|
||||||
|
} SYSMONITOR;
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
|
static uint8_t GetWritable(PINGPONG ctrllor);
|
||||||
|
static uint8_t GetReadable(PINGPONG ctrllor);
|
||||||
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr);
|
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr);
|
||||||
static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg);
|
static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg);
|
||||||
static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame);
|
static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame);
|
||||||
@@ -156,10 +199,28 @@ static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg);
|
|||||||
/**************************** Type Definitions *******************************/
|
/**************************** Type Definitions *******************************/
|
||||||
/************************** Variable Definitions *****************************/
|
/************************** Variable Definitions *****************************/
|
||||||
// TODO: better approach?
|
// TODO: better approach?
|
||||||
#include "../networking/link_layer/link_layer.h"
|
|
||||||
#include "../networking/phy_layer/phy_layer.h"
|
|
||||||
extern L2_INST *linkInstPtr;
|
extern L2_INST *linkInstPtr;
|
||||||
extern L2_CONFIG linkConfig;
|
extern L2_CONFIG linkConfig;
|
||||||
|
extern SYSBUS *sysbusDescPtr;
|
||||||
|
static SYSMONITOR *sysMonitorInst;
|
||||||
|
|
||||||
|
inline static uint8_t GetWritable(PINGPONG ctrllor)
|
||||||
|
{
|
||||||
|
// Allow only one write.
|
||||||
|
ASSERT(ctrllor.wBusy == BUFF_NONE);
|
||||||
|
if (ctrllor.rBusy == BUFF_NONE)
|
||||||
|
return ((ctrllor.latest == BUFF_B) ? BUFF_A : BUFF_B);
|
||||||
|
else
|
||||||
|
return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static uint8_t GetReadable(PINGPONG ctrllor)
|
||||||
|
{
|
||||||
|
if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest)
|
||||||
|
return ((ctrllor.latest == BUFF_NONE) ? BUFF_A : BUFF_B);
|
||||||
|
else
|
||||||
|
return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool SystemBus_IsReqPending(SYSBUS *instPtr)
|
inline bool SystemBus_IsReqPending(SYSBUS *instPtr)
|
||||||
{
|
{
|
||||||
@@ -178,6 +239,7 @@ inline bool SystemBus_IsTxBusy(SYSBUS *instPtr)
|
|||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
return (!instPtr->isTxDone);
|
return (!instPtr->isTxDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SystemBus_IsRxBusy(SYSBUS *instPtr)
|
inline bool SystemBus_IsRxBusy(SYSBUS *instPtr)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
@@ -237,7 +299,7 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
|
|||||||
if (msg[WD_ID_CMD] >= 0 && msg[WD_ID_CMD] < linkConfig.netScale)
|
if (msg[WD_ID_CMD] >= 0 && msg[WD_ID_CMD] < linkConfig.netScale)
|
||||||
{
|
{
|
||||||
reconfig |= (msg[WD_ID_CMD] != linkConfig.myId);
|
reconfig |= (msg[WD_ID_CMD] != linkConfig.myId);
|
||||||
linkConfig.myType = (msg[WD_ID_CMD] == 0) ? L2_NODE_HEAD : L2_NODE_MEMBER;
|
linkConfig.myType = (msg[WD_ID_CMD] == L2_HEAD_ID) ? L2_NODE_HEAD : L2_NODE_MEMBER;
|
||||||
linkConfig.myId = msg[WD_ID_CMD];
|
linkConfig.myId = msg[WD_ID_CMD];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -278,6 +340,45 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Routing table selection
|
||||||
|
if (msg[WD_RTNE_CMD] != instPtr->sysbusLog.lastConfig[3])
|
||||||
|
{
|
||||||
|
switch (msg[WD_RTNE_CMD])
|
||||||
|
{
|
||||||
|
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
|
||||||
|
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
|
||||||
|
WD_RTNE_CMD, msg[WD_RTNE_CMD]);
|
||||||
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Enable control
|
// Enable control
|
||||||
if (msg[WD_EN_CMD] == EN_CMD_ENABLE)
|
if (msg[WD_EN_CMD] == EN_CMD_ENABLE)
|
||||||
{
|
{
|
||||||
@@ -307,58 +408,6 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
|
|||||||
return EIGNORE;
|
return EIGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routing table selection
|
|
||||||
if (msg[WD_RTNE_CMD] != instPtr->sysbusLog.lastConfig[3])
|
|
||||||
{
|
|
||||||
L2_RTNE_CONFIG newRtneConfig;
|
|
||||||
switch (msg[WD_RTNE_CMD])
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
newRtneConfig.rtneTable = normalTable0;
|
|
||||||
newRtneConfig.rtnePrd = ARRAY_SIZE(normalTable0);
|
|
||||||
L2_EVENT l2Event =
|
|
||||||
{
|
|
||||||
.event = L2_ROUTINE_UPDATE,
|
|
||||||
.msg = &newRtneConfig
|
|
||||||
};
|
|
||||||
AssertL2Event(instPtr, &l2Event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
newRtneConfig.rtneTable = normalTable1;
|
|
||||||
newRtneConfig.rtnePrd = ARRAY_SIZE(normalTable1);
|
|
||||||
L2_EVENT l2Event =
|
|
||||||
{
|
|
||||||
.event = L2_ROUTINE_UPDATE,
|
|
||||||
.msg = &newRtneConfig
|
|
||||||
};
|
|
||||||
AssertL2Event(instPtr, &l2Event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
newRtneConfig.rtneTable = normalTable2;
|
|
||||||
newRtneConfig.rtnePrd = ARRAY_SIZE(normalTable2);
|
|
||||||
L2_EVENT l2Event =
|
|
||||||
{
|
|
||||||
.event = L2_ROUTINE_UPDATE,
|
|
||||||
.msg = &newRtneConfig
|
|
||||||
};
|
|
||||||
AssertL2Event(instPtr, &l2Event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
// Ignore current command
|
|
||||||
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
|
|
||||||
WD_RTNE_CMD, msg[WD_RTNE_CMD]);
|
|
||||||
return EIGNORE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
instPtr->sysbusLog.lastConfig[0] = msg[WD_EN_CMD];
|
instPtr->sysbusLog.lastConfig[0] = msg[WD_EN_CMD];
|
||||||
instPtr->sysbusLog.lastConfig[1] = msg[WD_ID_CMD];
|
instPtr->sysbusLog.lastConfig[1] = msg[WD_ID_CMD];
|
||||||
instPtr->sysbusLog.lastConfig[2] = msg[WD_RATE_CMD];
|
instPtr->sysbusLog.lastConfig[2] = msg[WD_RATE_CMD];
|
||||||
@@ -394,7 +443,7 @@ static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame)
|
|||||||
/**
|
/**
|
||||||
* @brief Generate System Bus receive call command response
|
* @brief Generate System Bus receive call command response
|
||||||
*/
|
*/
|
||||||
int32_t SystemBus_GenRecvRsp(SYSBUS *instPtr, SYSMON_SVC_PAYLOAD *payload)
|
int32_t SystemBus_GenRecvRsp(SYSBUS *instPtr, SYSBUS_SVC_PLD *payload)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
ASSERT(payload != NULL);
|
ASSERT(payload != NULL);
|
||||||
@@ -406,11 +455,11 @@ int32_t SystemBus_GenRecvRsp(SYSBUS *instPtr, SYSMON_SVC_PAYLOAD *payload)
|
|||||||
return ENOMEM;
|
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_CMD] = CMD_RECV_DATA;
|
||||||
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
||||||
memcpy(sysbusRsp->data + RECV_DATA_ID_OFFSET, payload, sizeof(SYSMON_SVC_PAYLOAD));
|
memcpy(sysbusRsp->data + RECV_DATA_ID_OFFSET, payload, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
|
||||||
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
||||||
{
|
{
|
||||||
@@ -527,7 +576,7 @@ int32_t SystemBus_HandleCmd(SYSBUS *instPtr)
|
|||||||
}
|
}
|
||||||
case CMD_SEND_DATA:
|
case CMD_SEND_DATA:
|
||||||
{
|
{
|
||||||
Status = SysMonitor_UpdateSendPayload((SYSMON_SVC_PAYLOAD *)(msg + SEND_DATA_ID_OFFSET));
|
Status = SysMonitor_UpdateSendPayload((SYSBUS_SVC_PLD *)(msg + SEND_DATA_ID_OFFSET));
|
||||||
if (Status == SUCCESS)
|
if (Status == SUCCESS)
|
||||||
{
|
{
|
||||||
instPtr->sysbusLog.sendCnt++;
|
instPtr->sysbusLog.sendCnt++;
|
||||||
@@ -703,4 +752,311 @@ int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize System monitor
|
||||||
|
*
|
||||||
|
* @return SUCCESS
|
||||||
|
*/
|
||||||
|
int32_t SysMonitor_Init(SYSMON_CONFIG *config)
|
||||||
|
{
|
||||||
|
ASSERT(config != NULL);
|
||||||
|
|
||||||
|
sysMonitorInst = calloc(1, sizeof(SYSMONITOR));
|
||||||
|
if (sysMonitorInst == NULL)
|
||||||
|
{
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&(sysMonitorInst->config), config, sizeof(SYSMON_CONFIG));
|
||||||
|
memset(&(sysMonitorInst->sysInfoCtrl), BUFF_NONE, sizeof(PINGPONG));
|
||||||
|
memset(&(sysMonitorInst->linkLogCtrl), BUFF_NONE, sizeof(PINGPONG));
|
||||||
|
memset(&(sysMonitorInst->phyLogCtrl), BUFF_NONE, sizeof(PINGPONG));
|
||||||
|
memset(&(sysMonitorInst->hwStateCtrl), BUFF_NONE, sizeof(PINGPONG));
|
||||||
|
|
||||||
|
for (uint8_t ii = 0; ii < L2_NET_SCALE; ii++)
|
||||||
|
{
|
||||||
|
sysMonitorInst->sendQueue[ii] = NULL;
|
||||||
|
sysMonitorInst->recvQueue[ii] = NULL;
|
||||||
|
if (CircQueueCreate(&(sysMonitorInst->sendQueue[ii]),
|
||||||
|
sysMonitorInst->config.sendQueueMax) == false)
|
||||||
|
{
|
||||||
|
SysMonitor_Destroy();
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
if (CircQueueCreate(&(sysMonitorInst->recvQueue[ii]),
|
||||||
|
sysMonitorInst->config.recvQueueMax) == false)
|
||||||
|
{
|
||||||
|
SysMonitor_Destroy();
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroy system monitor release all allocated memory
|
||||||
|
*/
|
||||||
|
void SysMonitor_Destroy(void)
|
||||||
|
{
|
||||||
|
free(sysMonitorInst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SystemInfo_API
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update system info.
|
||||||
|
*
|
||||||
|
* @param info
|
||||||
|
*/
|
||||||
|
void SysMonitor_UpdateSysinfo(const SYSINFO *info)
|
||||||
|
{
|
||||||
|
ASSERT(info != NULL);
|
||||||
|
uint8_t buffIndx;
|
||||||
|
buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl);
|
||||||
|
sysMonitorInst->sysInfoCtrl.wBusy = buffIndx;
|
||||||
|
memcpy(&(sysMonitorInst->sysInfo[buffIndx]), info, sizeof(SYSINFO));
|
||||||
|
sysMonitorInst->sysInfoCtrl.latest = buffIndx;
|
||||||
|
sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get system info.
|
||||||
|
*
|
||||||
|
* @param info
|
||||||
|
*/
|
||||||
|
void SysMonitor_GetSysinfo(SYSINFO *info)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(info != NULL);
|
||||||
|
uint8_t buffIndx, buffIndex_old;
|
||||||
|
buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy;
|
||||||
|
if (buffIndex_old != BUFF_NONE)
|
||||||
|
buffIndx = buffIndex_old; // Keep it busy
|
||||||
|
else
|
||||||
|
buffIndx = GetReadable(sysMonitorInst->sysInfoCtrl);
|
||||||
|
sysMonitorInst->sysInfoCtrl.rBusy = buffIndx;
|
||||||
|
memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO));
|
||||||
|
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
|
||||||
|
}
|
||||||
|
/** @} SystemInfo_API*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ServicePayload_API
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update send payload by
|
||||||
|
*
|
||||||
|
* @param payload
|
||||||
|
*/
|
||||||
|
int32_t SysMonitor_UpdateSendPayload(SYSBUS_SVC_PLD *payload)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(payload != NULL);
|
||||||
|
|
||||||
|
// validity check
|
||||||
|
if (payload->dataLen > SYSBUS_PLD_MAX)
|
||||||
|
{
|
||||||
|
DBG_ERROR("Payload length %d exceeds valid range.", payload->dataLen);
|
||||||
|
return EPARAM;
|
||||||
|
}
|
||||||
|
if (payload->nodeId < L2_NODE_NONE || payload->nodeId > L2_NET_SCALE)
|
||||||
|
{
|
||||||
|
DBG_ERROR("Node ID %d exceeds valid range.", payload->nodeId);
|
||||||
|
return EPARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push message into send queue
|
||||||
|
SYSBUS_SVC_PLD *payloadCopy = malloc(sizeof(SYSBUS_SVC_PLD));
|
||||||
|
if (payloadCopy == NULL)
|
||||||
|
{
|
||||||
|
DBG_ERROR("Allocate memory for send payload failed.\n");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(payloadCopy, payload, sizeof(SYSBUS_SVC_PLD));
|
||||||
|
// valid id starts from 0x01
|
||||||
|
if (CircQueuePush(sysMonitorInst->sendQueue[payload->nodeId-1], (void *)payloadCopy) == false)
|
||||||
|
{
|
||||||
|
DBG_WARNING("SystemMonitor::SEND Queue overflowed!\n");
|
||||||
|
free(payloadCopy);
|
||||||
|
return EQUEUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the latest send payload.
|
||||||
|
*
|
||||||
|
* @param payload
|
||||||
|
*/
|
||||||
|
void SysMonitor_GetSendPayload(SYSBUS_SVC_PLD **payload, uint8_t dstId)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(payload != NULL);
|
||||||
|
|
||||||
|
// valid id starts from 0x01
|
||||||
|
if (CircQueuePop(sysMonitorInst->sendQueue[dstId-1], (void **)payload) == false)
|
||||||
|
{
|
||||||
|
*payload = NULL;
|
||||||
|
DBG_INFO("SystemMonitor::Empty sendQueue, nothing need sent.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update receive payload.
|
||||||
|
*
|
||||||
|
* @param payload
|
||||||
|
*/
|
||||||
|
int32_t SysMonitor_GenRecvRsp(SYSBUS_SVC_PLD *payload)
|
||||||
|
{
|
||||||
|
ASSERT(payload != NULL);
|
||||||
|
int32_t Status;
|
||||||
|
|
||||||
|
if (payload->dataId == DATA_ID_NONE || payload->dataLen > SYSBUS_PLD_MAX)
|
||||||
|
{
|
||||||
|
DBG_INFO("SystemMonitor::Drop invalid message.\n");
|
||||||
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SystemBus_GenRecvRsp(sysbusDescPtr, payload);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/** @} ServicePayload_API*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Linklayer_Log_API
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update link layer log
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
*/
|
||||||
|
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(log != NULL);
|
||||||
|
uint8_t buffIndx;
|
||||||
|
buffIndx = GetWritable(sysMonitorInst->linkLogCtrl);
|
||||||
|
sysMonitorInst->linkLogCtrl.wBusy = buffIndx;
|
||||||
|
memcpy(&(sysMonitorInst->linkLog[buffIndx]), log, sizeof(LINKLOG));
|
||||||
|
sysMonitorInst->linkLogCtrl.latest = buffIndx;
|
||||||
|
sysMonitorInst->linkLogCtrl.wBusy = BUFF_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the latest link layer log
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
*/
|
||||||
|
void SysMonitor_GetLinklayerLog(LINKLOG *log)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(log != NULL);
|
||||||
|
uint8_t buffIndx, buffIndex_old;
|
||||||
|
buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy;
|
||||||
|
if (buffIndex_old != BUFF_NONE)
|
||||||
|
buffIndx = buffIndex_old; // Keep it busy
|
||||||
|
else
|
||||||
|
buffIndx = GetReadable(sysMonitorInst->linkLogCtrl);
|
||||||
|
sysMonitorInst->linkLogCtrl.rBusy = buffIndx;
|
||||||
|
memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG));
|
||||||
|
sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old;
|
||||||
|
}
|
||||||
|
/** @} Linklayer_Log_API*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PhysicalLayer_Log_API
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update physical layer log
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
*/
|
||||||
|
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(log != NULL);
|
||||||
|
uint8_t buffIndx;
|
||||||
|
buffIndx = GetWritable(sysMonitorInst->phyLogCtrl);
|
||||||
|
sysMonitorInst->phyLogCtrl.wBusy = buffIndx;
|
||||||
|
memcpy(&(sysMonitorInst->phyLog[buffIndx]), log, sizeof(PHYLOG));
|
||||||
|
sysMonitorInst->phyLogCtrl.latest = buffIndx;
|
||||||
|
sysMonitorInst->phyLogCtrl.wBusy = BUFF_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the latest physical layer log
|
||||||
|
*
|
||||||
|
* @param log
|
||||||
|
*/
|
||||||
|
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(log != NULL);
|
||||||
|
uint8_t buffIndx, buffIndex_old;
|
||||||
|
buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy;
|
||||||
|
if (buffIndex_old != BUFF_NONE)
|
||||||
|
buffIndx = buffIndex_old; // Keep it busy
|
||||||
|
else
|
||||||
|
buffIndx = GetReadable(sysMonitorInst->phyLogCtrl);
|
||||||
|
sysMonitorInst->phyLogCtrl.rBusy = buffIndx;
|
||||||
|
memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG));
|
||||||
|
sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old;
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name HardwareState_Log_API
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log hardware running status.
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(state != NULL);
|
||||||
|
uint8_t buffIndx;
|
||||||
|
buffIndx = GetWritable(sysMonitorInst->hwStateCtrl);
|
||||||
|
sysMonitorInst->hwStateCtrl.wBusy = buffIndx;
|
||||||
|
memcpy(&(sysMonitorInst->hwState[buffIndx]), state, sizeof(HWSTATE));
|
||||||
|
sysMonitorInst->hwStateCtrl.latest = buffIndx;
|
||||||
|
sysMonitorInst->hwStateCtrl.wBusy = BUFF_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the latest hardware running status.
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
void SysMonitor_GetHardwareStatus(HWSTATE *state)
|
||||||
|
{
|
||||||
|
ASSERT(sysMonitorInst != NULL);
|
||||||
|
ASSERT(state != NULL);
|
||||||
|
uint8_t buffIndx, buffIndex_old;
|
||||||
|
buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy;
|
||||||
|
if (buffIndex_old != BUFF_NONE)
|
||||||
|
buffIndx = buffIndex_old; // Keep it busy
|
||||||
|
else
|
||||||
|
buffIndx = GetReadable(sysMonitorInst->hwStateCtrl);
|
||||||
|
sysMonitorInst->hwStateCtrl.rBusy = buffIndx;
|
||||||
|
memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE));
|
||||||
|
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @} SystemBus*/
|
/** @} SystemBus*/
|
||||||
|
|||||||
+255
-2
@@ -23,9 +23,84 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "systembus_uart.h" // SystemBus UART driver
|
#include "systembus_uart.h" // SystemBus UART driver
|
||||||
#include "circ_queue.h"
|
#include "circ_queue.h"
|
||||||
#include "../system_monitor.h"
|
|
||||||
|
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
|
/**
|
||||||
|
* @name SystemMonitor_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SYSBUS_FRM_MAX UART_FRM_MAX
|
||||||
|
#define SYSBUS_DAT_MAX UART_DAT_MAX
|
||||||
|
#define SYSBUS_PRE_LEN 2 // length of preamble of data chunk (command + node type)
|
||||||
|
#define SYSBUS_PLD_MAX SYSBUS_DAT_MAX-SYSBUS_PRE_LEN // max length of payload chunk (part of data chunk)
|
||||||
|
#define SYSBUS_SVC_PRE_LEN 7 // length of service premable
|
||||||
|
#define SYSBUS_SVC_PLD_MAX SYSBUS_PLD_MAX-SYSBUS_SVC_PRE_LEN // max length of service payload
|
||||||
|
|
||||||
|
#define DATA_ID_NONE UINT32_MAX
|
||||||
|
#define DATA_ID_TEST 0x02030203
|
||||||
|
|
||||||
|
#define VOLTAGE_LSB 0.01 // volt
|
||||||
|
#define VOLTAGE_MAX 2.55 // volt
|
||||||
|
|
||||||
|
#define VOLT_PS_STD 1.0
|
||||||
|
#define VOLT_PSAUX_STD 1.8
|
||||||
|
#define VOLT_DDR_STD 1.5
|
||||||
|
#define VOLT_PL_STD 1.0
|
||||||
|
#define VOLT_PLAUX_STD 1.8
|
||||||
|
#define VOLT_BRAM_STD 1.0
|
||||||
|
|
||||||
|
#define VOLT_PS_OK BIT(0)
|
||||||
|
#define VOLT_PSAUX_OK BIT(1)
|
||||||
|
#define VOLT_DDR_OK BIT(2)
|
||||||
|
#define VOLT_PL_OK BIT(3)
|
||||||
|
#define VOLT_PLAUX_OK BIT(4)
|
||||||
|
#define VOLT_BRAM_OK BIT(5)
|
||||||
|
|
||||||
|
#define VOLT_ANT_PROC_OK BIT(0)
|
||||||
|
#define VOLT_ANT_RF_OK BIT(2)
|
||||||
|
#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)
|
||||||
|
// #define IS_DDR_VALID(x) (x <= 1.89 && x >= 1.14)
|
||||||
|
// #define IS_PL_VALID(x) (x <= 1.03 && x >= 0.97)
|
||||||
|
// #define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71)
|
||||||
|
// #define IS_BRAM_VALID(x) (x <= 1.03 && x >= 0.97)
|
||||||
|
#define IS_PS_VALID(x) ((x) <= 1.1 && (x) >= 0.9)
|
||||||
|
#define IS_PSAUX_VALID(x) ((x) <= 2.0 && (x) >= 1.6)
|
||||||
|
#define IS_DDR_VALID(x) ((x) <= 1.7 && (x) >= 1.3)
|
||||||
|
#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)
|
||||||
|
|
||||||
|
#define CLK_AD0_BBPLL_LOCK BIT(0)
|
||||||
|
#define CLK_AD0_RFPLL_LOCK BIT(2)
|
||||||
|
#define CLK_AD1_BBPLL_LOCK BIT(4)
|
||||||
|
#define CLK_AD1_RFPLL_LOCK BIT(6)
|
||||||
|
|
||||||
|
#define CLK_ANT_BBPLL_LOCK BIT(0)
|
||||||
|
#define CLK_ANT_RFPLL1_LOCK BIT(2)
|
||||||
|
#define CLK_ANT_RFPLL2_LOCK BIT(4)
|
||||||
|
|
||||||
|
#define TEMPERATURE_LSB 1.0 // Celsius degree
|
||||||
|
#define TEMPERATURE_MAX 127.0 // Celsius degree
|
||||||
|
#define TEMPERATURE_MIN -128.0 // Celsius degree
|
||||||
|
/** @} SystemMonitor_Constants */
|
||||||
/************************** Data Type Definitions ****************************/
|
/************************** Data Type Definitions ****************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +114,156 @@ typedef struct
|
|||||||
uint32_t rxQueueMax; ///< maximum rx queue length
|
uint32_t rxQueueMax; ///< maximum rx queue length
|
||||||
} SYSBUS_CONFIG;
|
} SYSBUS_CONFIG;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct SYSBUS_SVC_PLD
|
||||||
|
* @brief Payload struct that holds the service payload
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint32_t dataId; ///< data identifier
|
||||||
|
uint8_t nodeId; ///< destination ID for tx, source ID for rx
|
||||||
|
uint16_t dataLen; ///< data length
|
||||||
|
uint8_t data[SYSBUS_SVC_PLD_MAX];
|
||||||
|
} SYSBUS_SVC_PLD;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct SYSINFO
|
||||||
|
* @brief System Infomation log
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint32_t psBDS; ///< -- unit: ms, 0~604799999
|
||||||
|
uint16_t pBDS; ///< -- unit: week, 0~0~8191
|
||||||
|
uint32_t psGPS; ///< -- unit: ms, 0~604799999
|
||||||
|
uint16_t pGPS; ///< -- unit: week, 0~0~8191
|
||||||
|
uint8_t tmInd; ///< Time validation indicator \n
|
||||||
|
// -- [0] GPS\n
|
||||||
|
// -- [1] reserve.\n
|
||||||
|
// -- [2] UTC\n
|
||||||
|
// -- [3] BDS\n
|
||||||
|
float tmFly; ///< Time of flying uint: s
|
||||||
|
uint8_t stFly; ///< Status of flying \n
|
||||||
|
// [7:6] departure status 11 - departed/00 - not departed \n
|
||||||
|
// [5:4] ready status 11 - ready/00 - not ready \n
|
||||||
|
// [3:2] attitude status 11 - attitude ok/00 - attitude not ok \n
|
||||||
|
// [1:0] attitude adjust status 11 - adjusted/00 - not adjusted
|
||||||
|
float posX; ///< coord X Position in launch coordinate system
|
||||||
|
float posY; ///< coord Y Position in launch coordinate system
|
||||||
|
float posZ; ///< coord Z Position in launch coordinate system
|
||||||
|
float vX; ///< Speed X in launch coordinate system
|
||||||
|
float vY; ///< Speed Y in launch coordinate system
|
||||||
|
float vZ; ///< Speed Z in launch coordinate system
|
||||||
|
float pitch; ///< Pitch Attitude in launch inertia coordinate system
|
||||||
|
float yaw; ///< Yaw Attitude in launch inertia coordinate system
|
||||||
|
float roll; ///< Roll Attitude in launch inertia coordinate system
|
||||||
|
} SYSINFO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct SYSBUSLOG
|
||||||
|
* @brief System Info holds the system bus log
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
// SystemBus log
|
||||||
|
|
||||||
|
uint8_t lastConfig[4]; ///< Last valid config \n
|
||||||
|
// byte 0: Enable control, 0xAA - enable, 0x55 - disable \n
|
||||||
|
// byte 1: Node ID \n
|
||||||
|
// byte 2: Service rate \n
|
||||||
|
// byte 3: routing table number
|
||||||
|
uint32_t recvCnt; ///< number of received data packet
|
||||||
|
uint32_t sendCnt; ///< number of send data packet
|
||||||
|
uint32_t remoteCnt; ///< number of remote check commands
|
||||||
|
} SYSBUSLOG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct LINKLOG
|
||||||
|
* @brief Linklayer Log struct holds the Linklayer log
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
// Network log
|
||||||
|
uint32_t tuNum; ///< current time unite number
|
||||||
|
uint8_t slotNum; ///< current slot number
|
||||||
|
uint8_t nodeType; ///< current node type
|
||||||
|
uint8_t cxnStatus; ///< current connection status
|
||||||
|
uint8_t linkStage; ///< current linklayer working stage
|
||||||
|
uint32_t recxnCnt; ///< reconnect trial count
|
||||||
|
uint8_t antIndex; ///< current working antenna index
|
||||||
|
uint32_t advTxCnt; ///< adv frame send count
|
||||||
|
uint32_t advRecvCnt; ///< adv frame received count
|
||||||
|
uint32_t advCorrectCnt; ///< adv frame received correctly count
|
||||||
|
uint32_t ackTxCnt; ///< ack frame send count
|
||||||
|
uint32_t ackRecvCnt; ///< ack frame received count
|
||||||
|
uint32_t ackCorrectCnt; ///< ack frame received correctly count
|
||||||
|
uint32_t disTxCnt; ///< dist frame send count
|
||||||
|
uint32_t disRecvCnt; ///< dist frame received count
|
||||||
|
uint32_t disCorrectCnt;///< dist frame received correctly count
|
||||||
|
uint32_t mngTxCnt; ///< mng frame send count
|
||||||
|
uint32_t mngRecvCnt; ///< mng frame received count
|
||||||
|
uint32_t mngCorrectCnt; ///< mng frame received correctly count
|
||||||
|
uint32_t rttTxCnt; ///< rtt frame send count
|
||||||
|
uint32_t rttRecvCnt; ///< rtt frame received count
|
||||||
|
uint32_t rttCorrectCnt; ///< rtt frame received correctly count
|
||||||
|
uint32_t svcTxCnt; ///< svc frame send count
|
||||||
|
uint32_t svcRecvCnt; ///< svc frame received count
|
||||||
|
uint32_t svcCorrectCnt; ///< svc frame received correctly count
|
||||||
|
int32_t timeDev; ///< last time deviation result
|
||||||
|
uint32_t sendId; ///< last send data id
|
||||||
|
uint32_t recvId; ///< last received data id
|
||||||
|
uint8_t reserve[3]; ///< reserved data
|
||||||
|
} LINKLOG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct PHYLOG
|
||||||
|
* @brief Physical Layer Log struct holds the Linklayer log
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint32_t acqCnt; ///< acquisition count
|
||||||
|
uint32_t fsyncCnt; ///< frame sync count
|
||||||
|
uint32_t decodeCnt; ///< decode count
|
||||||
|
uint32_t crcCnt; ///< crc valid count
|
||||||
|
double doppler; ///< last doppler estimation result
|
||||||
|
uint64_t recvStamp; ///< last frame arrival time
|
||||||
|
double acqPAPR; ///< last acquisition peak-average ration
|
||||||
|
uint8_t acqPhase; ///< last acquisition phase estimation
|
||||||
|
uint8_t acqFreqCh; ///< last acquisition frequency deviation estimation
|
||||||
|
double fsyncPAPR; ///< last frame sync peak-average ration
|
||||||
|
uint8_t fsyncFreqCh; ///< last frame sync frequency estimation
|
||||||
|
uint16_t deintlvAmpEst; ///< de-interleave amplitude estimation
|
||||||
|
uint8_t antControl; ///< current antenna rf mode
|
||||||
|
uint8_t reserve[2]; ///< reserved data
|
||||||
|
} PHYLOG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct HWSTATE
|
||||||
|
* @brief Hardware Status Log struct holds all hardware status
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
bool isSpOk; ///< signal processor state
|
||||||
|
bool isAntOk; ///< antenna state
|
||||||
|
// -- Signal processor status
|
||||||
|
uint8_t spFpgaVolt; ///< Signal processor voltage state indicator
|
||||||
|
uint8_t spClkState; ///< Signal processor clock state indicator
|
||||||
|
uint8_t spAdLockState; ///< Signal processor adc lock state indicator
|
||||||
|
int8_t spAdTemp_0; ///< Signal processor adc0 temperature
|
||||||
|
int8_t spAdTemp_1; ///< Signal processor adc1 temperature
|
||||||
|
int8_t spFpgaTemp; ///< Signal processor FPGA temperature
|
||||||
|
// -- Antenna status
|
||||||
|
uint16_t ant1Freq; ///< Antenna 1 frequency
|
||||||
|
uint16_t ant2Freq; ///< Antenna 2 frequency
|
||||||
|
uint16_t ant3Freq; ///< Antenna 3 frequency
|
||||||
|
uint8_t antPll; ///< Antenna pll lock state indicator
|
||||||
|
uint8_t antMode; ///< Antenna mode indicator
|
||||||
|
int8_t antTemp; ///< Antenna rf temperature
|
||||||
|
uint8_t antRsvd; ///< Antenna reserved status register
|
||||||
|
uint8_t phyId;
|
||||||
|
uint8_t reserve[3];
|
||||||
|
} HWSTATE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct SYSBUS
|
* @struct SYSBUS
|
||||||
* @brief SystemBus Instance struct
|
* @brief SystemBus Instance struct
|
||||||
@@ -57,9 +282,19 @@ typedef struct
|
|||||||
bool isRxDone; ///< rx done indicator
|
bool isRxDone; ///< rx done indicator
|
||||||
} SYSBUS;
|
} SYSBUS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct SYSMON_CONFIG
|
||||||
|
* @brief System monitor config struct holds system monitor initialization parameters
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t sendQueueMax; ///< maximum send queue length
|
||||||
|
uint32_t recvQueueMax; ///< maximum receive queue length
|
||||||
|
} SYSMON_CONFIG;
|
||||||
|
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
|
|
||||||
int32_t SystemBus_GenRecvRsp(SYSBUS *instPtr, SYSMON_SVC_PAYLOAD *payload);
|
int32_t SystemBus_GenRecvRsp(SYSBUS *instPtr, SYSBUS_SVC_PLD *payload);
|
||||||
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config);
|
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config);
|
||||||
void SystemBus_Destroy(SYSBUS *instPtr);
|
void SystemBus_Destroy(SYSBUS *instPtr);
|
||||||
|
|
||||||
@@ -80,6 +315,24 @@ bool SystemBus_IsRespPending(SYSBUS *instPtr);
|
|||||||
bool SystemBus_IsTxBusy(SYSBUS *instPtr);
|
bool SystemBus_IsTxBusy(SYSBUS *instPtr);
|
||||||
bool SystemBus_IsRxBusy(SYSBUS *instPtr);
|
bool SystemBus_IsRxBusy(SYSBUS *instPtr);
|
||||||
|
|
||||||
|
|
||||||
|
int32_t SysMonitor_Init(SYSMON_CONFIG *config);
|
||||||
|
void SysMonitor_Destroy(void);
|
||||||
|
|
||||||
|
void SysMonitor_UpdateSysinfo(const SYSINFO *info);
|
||||||
|
void SysMonitor_GetSysinfo(SYSINFO *info);
|
||||||
|
|
||||||
|
int32_t SysMonitor_UpdateSendPayload(SYSBUS_SVC_PLD *payload);
|
||||||
|
void SysMonitor_GetSendPayload(SYSBUS_SVC_PLD **payload, uint8_t dstId);
|
||||||
|
int32_t SysMonitor_GenRecvRsp(SYSBUS_SVC_PLD *payload);
|
||||||
|
|
||||||
|
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log);
|
||||||
|
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log);
|
||||||
|
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state);
|
||||||
|
void SysMonitor_GetLinklayerLog(LINKLOG *log);
|
||||||
|
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log);
|
||||||
|
void SysMonitor_GetHardwareStatus(HWSTATE *state);
|
||||||
|
|
||||||
#endif //__SYSTEMBUS_H_
|
#endif //__SYSTEMBUS_H_
|
||||||
|
|
||||||
/** @} SystemBus*/
|
/** @} SystemBus*/
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -34,10 +33,10 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
// Control and status register
|
// Control and status register
|
||||||
#define MODULE_VERSION 0
|
#define MODULE_VERSION 0x00000000U
|
||||||
#define UART_STATUS 4
|
#define UART_STATUS 0x0000004U
|
||||||
#define UART_SEND_CMD 8
|
#define UART_SEND_CMD 0x00000008U
|
||||||
#define UART_RECV_CNT 12
|
#define UART_RECV_CNT 0x0000000CU
|
||||||
|
|
||||||
// Status code
|
// Status code
|
||||||
#define UART_STATUS_TX_BUSY 0x00010000
|
#define UART_STATUS_TX_BUSY 0x00010000
|
||||||
@@ -48,6 +47,10 @@
|
|||||||
#define UART_RXBUFF_OFFSET 2048
|
#define UART_RXBUFF_OFFSET 2048
|
||||||
#define UART_RXBUFF_MAX 1024
|
#define UART_RXBUFF_MAX 1024
|
||||||
|
|
||||||
|
#if (UART_TXBUFF_MAX < UART_FRM_MAX || UART_RXBUFF_MAX < UART_FRM_MAX)
|
||||||
|
#error "UART_FRM_MAX exceeds the maximum value."
|
||||||
|
#endif
|
||||||
|
|
||||||
// Frame Data offsets
|
// Frame Data offsets
|
||||||
#define FRAME_HEAD_LOW 0x5A
|
#define FRAME_HEAD_LOW 0x5A
|
||||||
#define FRAME_HEAD_HIGH 0x54
|
#define FRAME_HEAD_HIGH 0x54
|
||||||
@@ -62,16 +65,6 @@
|
|||||||
#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen
|
#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen
|
||||||
/** @} SystemBus_UART_Driver_Constants*/
|
/** @} SystemBus_UART_Driver_Constants*/
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/**
|
|
||||||
* @brief Instance initial
|
|
||||||
*
|
|
||||||
* @param instPtr A pointer to frame uart instance structure.
|
|
||||||
* @param config Base address of frame uart, refer to "xparameters.h"
|
|
||||||
*
|
|
||||||
* @return None.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config)
|
int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
@@ -85,17 +78,6 @@ int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/**
|
|
||||||
* @brief Send a system bus frame.
|
|
||||||
*
|
|
||||||
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
|
||||||
* @param buff A pointer to send data buffer
|
|
||||||
* @param dLen A integer indicate the send data buffer length in byte.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
@@ -146,23 +128,14 @@ int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
|||||||
free(sendBuff);
|
free(sendBuff);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
memcpy((void *)(instPtr->config.baseAddr + UART_TXBUFF_OFFSET), sendBuff, (sendLen + sizeof(uint32_t) - 1) / sizeof(uint32_t) * sizeof(uint32_t));
|
memcpy((void *)(instPtr->config.baseAddr + UART_TXBUFF_OFFSET), sendBuff,
|
||||||
|
NORMALIZE_SIZE((sendLen + sizeof(uint32_t) - 1) / sizeof(uint32_t) * sizeof(uint32_t)));
|
||||||
free(sendBuff);
|
free(sendBuff);
|
||||||
// Start Sending
|
// Start Sending
|
||||||
SYSTEMBUS_UART_mWriteReg(instPtr->config.baseAddr, UART_SEND_CMD, sendLen);
|
SYSTEMBUS_UART_mWriteReg(instPtr->config.baseAddr, UART_SEND_CMD, sendLen);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/**
|
|
||||||
* @brief Get last system bus frame.
|
|
||||||
*
|
|
||||||
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
|
||||||
* @param buff A pointer to receive data buffer.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
@@ -183,7 +156,8 @@ int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
|||||||
{
|
{
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
memcpy(dBuff, (void *)(instPtr->config.baseAddr + UART_RXBUFF_OFFSET), sizeof(uint32_t) * dWLen);
|
memcpy(dBuff, (void *)(instPtr->config.baseAddr + UART_RXBUFF_OFFSET),
|
||||||
|
NORMALIZE_SIZE(sizeof(uint32_t) * dWLen));
|
||||||
plBuff = dBuff + FRAME_HEAD_LEN;
|
plBuff = dBuff + FRAME_HEAD_LEN;
|
||||||
checkSumCal = 0;
|
checkSumCal = 0;
|
||||||
checkSum = plBuff[dLen + FRAME_DUMMY_LEN];
|
checkSum = plBuff[dLen + FRAME_DUMMY_LEN];
|
||||||
@@ -210,16 +184,6 @@ int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/**
|
|
||||||
* @brief Get rx channel status.
|
|
||||||
*
|
|
||||||
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
|
||||||
*
|
|
||||||
* @return true - SYSBUS_UART rx channel is busy.
|
|
||||||
* false - SYSBUS_UART rx channel is idle.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr)
|
bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
@@ -236,16 +200,6 @@ bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/**
|
|
||||||
* @brief Get tx channel status.
|
|
||||||
*
|
|
||||||
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
|
||||||
*
|
|
||||||
* @return true - SYSBUS_UART tx channel is busy.
|
|
||||||
* false - SYSBUS_UART tx channel is idle.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr)
|
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr)
|
||||||
{
|
{
|
||||||
ASSERT(instPtr != NULL);
|
ASSERT(instPtr != NULL);
|
||||||
|
|||||||
@@ -27,6 +27,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
/************************** Constant Definitions *****************************/
|
||||||
|
#define UART_FRM_MAX 1024 // max length of uart frame
|
||||||
|
#define UART_DAT_MAX 1000 // max length of data chunk (part of uart frame)
|
||||||
/**************************** Type Definitions *****************************/
|
/**************************** Type Definitions *****************************/
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -96,23 +99,71 @@ typedef struct
|
|||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t checkSum;
|
uint8_t checkSum;
|
||||||
uint8_t isValid;
|
uint8_t isValid;
|
||||||
uint8_t data[1024];
|
uint8_t data[UART_FRM_MAX];
|
||||||
} SYSBUS_UART_FRAME;
|
} SYSBUS_UART_FRAME;
|
||||||
|
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
// Instance initial
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Instance initial
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to frame uart instance structure.
|
||||||
|
* @param config Base address of frame uart, refer to "xparameters.h"
|
||||||
|
*
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config);
|
int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config);
|
||||||
|
|
||||||
// Send a system bus frame.
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Send a system bus frame.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
||||||
|
* @param buff A pointer to send data buffer
|
||||||
|
* @param dLen A integer indicate the send data buffer length in byte.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame);
|
int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame);
|
||||||
|
|
||||||
// Get last system bus frame.
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Get last system bus frame.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
||||||
|
* @param buff A pointer to receive data buffer.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame);
|
int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame);
|
||||||
|
|
||||||
// Get system bus rx channel status.
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Get rx channel status.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
||||||
|
*
|
||||||
|
* @return true - SYSBUS_UART rx channel is busy.
|
||||||
|
* false - SYSBUS_UART rx channel is idle.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr);
|
bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr);
|
||||||
|
|
||||||
// Get system bus tx channel status.
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Get tx channel status.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to SYSBUS_UART instance structure.
|
||||||
|
*
|
||||||
|
* @return true - SYSBUS_UART tx channel is busy.
|
||||||
|
* false - SYSBUS_UART tx channel is idle.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr);
|
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr);
|
||||||
|
|
||||||
#endif // SYSTEMBUS_UART_H
|
#endif // SYSTEMBUS_UART_H
|
||||||
|
|||||||
Reference in New Issue
Block a user