10 Commits
20 changed files with 1818 additions and 857 deletions
+48 -27
View File
@@ -39,10 +39,10 @@ class Plugin(Plugin_Base):
"data": "5A 54 E1 EE 00 CF 02 5A FE"
},
{
"caption": "数据发送测试 - 40 Byte",
"caption": "数据发送测试(节点01)",
"icon": "fa5.play-circle",
"data": (
"5A 54 E4 EE 00 00 00 00 02 00 28 "
"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 "
@@ -51,25 +51,46 @@ class Plugin(Plugin_Base):
"00 08 31 5A FE"
)
},
# {
# "caption": "数据发送测试 - 2",
# "icon": "fa5.play-circle",
# "data": ""
# },
{
"caption": "装订 - 【主 - 0x01】128 kbps,时隙表 0",
"caption": "数据发送测试(节点02)",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 01 22 00 00 9E 06 5A FE"
"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": "装订 - 【主 - 0x01】512 kbps,时隙表 1",
"caption": "数据发送测试(节点03)",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 01 33 01 00 B0 06 5A FE"
"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】2 Mbps,时隙表 2",
"caption": "装订 - 【主 - 0x01】128 kbps,时隙表 1",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 01 44 02 00 C2 06 5A FE"
"data": "5A 54 E3 EE AA 01 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】静默",
@@ -77,44 +98,44 @@ class Plugin(Plugin_Base):
"data": "5A 54 E3 EE 55 01 22 00 00 49 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】128 kbps,时隙表 0",
"caption": "装订 - 【从 - 0x02】128 kbps,时隙表 1",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 02 22 00 00 9F 06 5A FE"
"data": "5A 54 E3 EE AA 02 22 01 00 A0 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】512 kbps,时隙表 1",
"caption": "装订 - 【从 - 0x02】512 kbps,时隙表 2",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 02 33 01 00 B1 06 5A FE"
"data": "5A 54 E3 EE AA 02 33 02 00 B2 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】2M bps,时隙表 2",
"caption": "装订 - 【从 - 0x02】2M bps,时隙表 3",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 02 44 02 00 C3 06 5A FE"
"data": "5A 54 E3 EE AA 02 44 03 00 C4 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x02】静默",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE 55 02 22 00 00 0C 06 5A FE"
"data": "5A 54 E3 EE 55 02 22 00 00 4A 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】128 kbps,时隙表 0",
"caption": "装订 - 【从 - 0x03】128 kbps,时隙表 1",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 22 00 00 A0 06 5A FE"
"data": "5A 54 E3 EE AA 03 22 01 00 A1 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】512 kbps,时隙表 1",
"caption": "装订 - 【从 - 0x03】512 kbps,时隙表 2",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 33 02 00 B2 06 5A FE"
"data": "5A 54 E3 EE AA 03 33 02 00 B3 06 5A FE"
},
{
"caption": "装订 - 【从 - 0x03】2 Mbps,时隙表 2",
"caption": "装订 - 【从 - 0x03】2 Mbps,时隙表 3",
"icon": "fa5.play-circle",
"data": "5A 54 E3 EE AA 03 44 01 00 C4 06 5A FE"
"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 0D 06 5A FE"
"data": "5A 54 E3 EE 55 03 22 00 00 4B 06 5A FE"
},
{
"caption": "遥测",
+913
View File
@@ -0,0 +1,913 @@
'''
@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_time"
name = _("hsjl_time")
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 E6 EE 00 D4 02 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]
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):
toggleBtn = QPushButton("id: 01")
menu = QMenu(toggleBtn)
ids = ["01", "02", "03"]
def setId(text):
toggleBtn.setText(f"id: {text}")
print(f"id设为 {text}")
for id_text in ids:
menu.addAction(id_text).triggered.connect(lambda checked, t=id_text: setId(t))
toggleBtn.setMenu(menu)
return toggleBtn
def createtoIdButton(self):
toggleBtn = QPushButton("目的节点id: 01")
menu = QMenu(toggleBtn)
ids = ["01", "02", "03"]
def setId(text):
toggleBtn.setText(f"目的节点id: {text}")
print(f"目的节点id设为 {text}")
for id_text in ids:
menu.addAction(id_text).triggered.connect(lambda checked, t=id_text: setId(t))
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_val = int(id_text.split(":")[1].strip(), 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:
id_val = int(toid_text.split(":")[1].strip(), 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("fpga温度: 未知")
self.networktemLabel.setAlignment(Qt.AlignLeft)
self.networktemLabel.setFont(QFont("Arial", 10))
self.networkvoltageLabel = QLabel("电压监测: 未知")
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.config["customSendItems"] = [item for item in self.config["customSendItems"] if item["caption"] != "自检"]
# 清空旧布局
self.clearLayout(self.customSendItemsLayout)
# 创建“开关”、“ID”、“时隙表”、“速率”按钮,供“总控”使用
self.toggleButton = self.createToggleButton()
self.customSendItemsLayout.addWidget(self.toggleButton, 1, 0)
self.idButton = self.createIdButton()
self.customSendItemsLayout.addWidget(self.idButton, 1, 1)
self.slotButton = self.createSlotButton()
self.customSendItemsLayout.addWidget(self.slotButton, 1, 2)
self.rateButton = self.createRateButton()
self.customSendItemsLayout.addWidget(self.rateButton, 1, 3)
self.toidButton = self.createtoIdButton()
self.customSendItemsLayout.addWidget(self.toidButton, 0, 3)
# 第一行固定插入“遥测”、“图片传输”、“总控”
for item in self.config["customSendItems"]:
if item["caption"] == "遥测":
w = self.createSendItemWidget(item)
self.customSendItemsLayout.addWidget(w, 0, 0)
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, 0, 1)
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, 0, 2)
# 第三行放4个状态标签
self.customSendItemsLayout.addWidget(self.networkStatusLabel, 2, 0)
self.customSendItemsLayout.addWidget(self.networkPhaseLabel, 2, 1)
self.customSendItemsLayout.addWidget(self.networkvoltageLabel, 2, 2)
self.customSendItemsLayout.addWidget(self.networktemLabel, 2, 3)
# 初始化结构体
self.structStatusCheckRsp = Struct(
"<BB Q IIII IBBBBIB III III III III III i II 3s IIII d Q dBB dB H B 2s BBBbbb HHHBBbB B 3s")
def insertSendItem(self, item = None, load = False):
caption = item["caption"]
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 == 0xE6: # 遥测回令
result = self.evalStatusCheckRsp(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 evalStatusCheckRsp(self, data: bytes):
try:
payload = self.structStatusCheckRsp.unpack(data)
except :
return f"\n### evalStatusCheckRsp:: Failed to unpack data (data length {len(data)} byte).\n"
ret = "----------- 遥测回令 -----------\n"
ret += "节点类型: "
if payload[1] == 0xEE:
ret += f"C频段 (0x{payload[1]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[1]:02X})\n"
ret += f"时间戳: {payload[2]/1e5:.2f} ms\n"
sysbusOffset = 3
linkOffset = 7
phyOffset = 36
hwOffset = 47
ret += "\n -- 总线状态\n"
ret += f"配置装订: {payload[sysbusOffset + 0]:08X}\n"
ret += f"接收数据计数: {payload[sysbusOffset + 1]:>6d}\n"
ret += f"发送数据计数: {payload[sysbusOffset + 2]:>6d}\n"
ret += f"遥测请求计数: {payload[sysbusOffset + 3]:>6d}\n"
ret += "\n -- 链路层状态\n"
ret += f"时元号: {payload[linkOffset + 0]:>6d}\n"
ret += f"时隙号: {payload[linkOffset + 1]:>3d}\n"
ret += "当前角色: "
if payload[linkOffset + 2] == 0xAA:
ret += f"簇首 (0x{payload[linkOffset + 2]:02X})\n"
elif payload[linkOffset + 2] == 0xCC:
ret += f"成员 (0x{payload[linkOffset + 2]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[linkOffset + 2]:02X})\n"
# 网络连接状态更新
network_status = "未连接"
if payload[linkOffset + 3] == 0x11:
network_status = "已连接"
elif payload[linkOffset + 3] == 0x00:
network_status = "未连接"
else:
network_status = f"未知状态 (0x{payload[linkOffset + 3]:02X})"
# 网络运行阶段更新
phase = "未知"
if payload[linkOffset + 4] == 0x11:
phase = "建网阶段"
elif payload[linkOffset + 4] == 0x22:
phase = "业务通信"
else:
phase = f"未知阶段 (0x{payload[linkOffset + 4]:02X})"
self.networkStatusLabel.setText(f"网络连接状态: {network_status}")
self.networkPhaseLabel.setText(f"网络运行阶段: {phase}")
ret += f"重建/入网计数: {payload[linkOffset + 5]:>6d}\n"
ret += f"通信天线位号: {payload[linkOffset + 6]:>1d}\n"
ret += f"建网帧发送计数: {payload[linkOffset + 7]:>6d}\n"
ret += f"建网帧接收计数: {payload[linkOffset + 8]:>6d}\n"
ret += f"建网帧正确计数: {payload[linkOffset + 9]:>6d}\n"
ret += f"应答帧发送计数: {payload[linkOffset + 10]:>6d}\n"
ret += f"应答帧接收计数: {payload[linkOffset + 11]:>6d}\n"
ret += f"应答帧正确计数: {payload[linkOffset + 12]:>6d}\n"
ret += f"分发帧发送计数: {payload[linkOffset + 13]:>6d}\n"
ret += f"分发帧接收计数: {payload[linkOffset + 14]:>6d}\n"
ret += f"分发帧正确计数: {payload[linkOffset + 15]:>6d}\n"
ret += f"网管帧发送计数: {payload[linkOffset + 16]:>6d}\n"
ret += f"网管帧接收计数: {payload[linkOffset + 17]:>6d}\n"
ret += f"网管帧正确计数: {payload[linkOffset + 18]:>6d}\n"
ret += f"RTT 帧发送计数: {payload[linkOffset + 19]:>6d}\n"
ret += f"RTT 帧接收计数: {payload[linkOffset + 20]:>6d}\n"
ret += f"RTT 帧正确计数: {payload[linkOffset + 21]:>6d}\n"
ret += f"业务帧发送计数: {payload[linkOffset + 22]:>6d}\n"
ret += f"业务帧接收计数: {payload[linkOffset + 23]:>6d}\n"
ret += f"业务帧正确计数: {payload[linkOffset + 24]:>6d}\n"
ret += f"时间偏差记录: {payload[linkOffset + 25]/1e2:.2f} us\n"
ret += f"发送数据 ID: {payload[linkOffset + 26]:>6d}\n"
ret += f"接收数据 ID: {payload[linkOffset + 27]:>6d}\n"
ret += "\n -- 物理层状态\n"
ret += f"捕获计数: {payload[phyOffset + 0]:>6d}\n"
ret += f"帧同步计数: {payload[phyOffset + 1]:>6d}\n"
ret += f"译码计数: {payload[phyOffset + 2]:>6d}\n"
ret += f"CRC 正确计数:{payload[phyOffset + 3]:>6d}\n"
ret += f"多普勒估计: {payload[phyOffset + 4]:.2f} Hz\n"
ret += f"正确接收时刻: {payload[phyOffset + 5]/1e2:.2f} us\n"
ret += f"捕获峰均比: {payload[phyOffset + 6]:.2f}\n"
ret += f"捕获相位值: {payload[phyOffset + 7]:>3d}\n"
ret += f"捕获频偏通道: {payload[phyOffset + 8]:>3d}\n"
ret += f"帧同步峰均比: {payload[phyOffset + 9]:.2f}\n"
ret += f"帧同步频偏通道: {payload[phyOffset + 10]:>3d}\n"
ret += f"交织输入数据幅度统计:\t0x{payload[phyOffset + 11]:04X}\n"
ret += f"天线控制模式: {bin(payload[phyOffset + 10])[2:].zfill(8)}\n"
ret += "\n -- 硬件状态\n"
voltage = f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
ret += f"时钟锁定状态: {bin(payload[hwOffset+1])[2:].zfill(8)}\n"
ret += f"AD 锁定状态: {bin(payload[hwOffset+2])[2:].zfill(8)}\n"
ret += f"AD 温度 1: {payload[hwOffset+3]:>4d}\n"
ret += f"AD 温度 2: {payload[hwOffset+4]:>4d}\n"
temp = f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
ret += f"天线-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"
print('+')
print(voltage)
print('_')
self.networkvoltageLabel.setText(f"电压监测: {voltage}")
self.networktemLabel.setText(f"fgpa温度: {temp}")
ret += "--------------------------------\n"
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('&&&&&')
# 图像显示逻辑(保留原始控件调用方式)
# 截取有效图像数据
if from_id == 0x01 or from_id == 0x02:
# 图像通道 A → 左侧图像控件
if len(self.widgets) >= 1 and isinstance(self.widgets[0], graphWidgets["image"]):
self.widgets[0].onData(image_data) # 发送有效数据
else:
self.showReceiveDataSignal.emit("\n### No valid image widget found (A1)\n")
print(from_id)
elif from_id == 0x03:
# 图像通道 B → 右侧图像控件
if len(self.widgets) >= 2 and isinstance(self.widgets[1], graphWidgets["image"]):
self.widgets[1].onData(image_data) # 发送有效数据
else:
self.showReceiveDataSignal.emit("\n### No valid image widget found (A2)\n")
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)
+2 -2
View File
@@ -1535,10 +1535,10 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){
status = ad9361_reg_write(dev, 0x0105, 0x3A); // ADC Large Overload Threshold
status = ad9361_reg_write(dev, 0x0107, 0x2B); // Small LMT Overload Threshold
status = ad9361_reg_write(dev, 0x0108, 0x31); // Large LMT Overload Threshold
status = ad9361_reg_write(dev, 0x0109, 0x00); // Rx1 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x0109, 0x20); // Rx1 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x010A, 0x58); // Rx1 LPF Gain Index
status = ad9361_reg_write(dev, 0x010B, 0x00); // Rx1 Digital Gain Index
status = ad9361_reg_write(dev, 0x010C, 0x00); // Rx2 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x010C, 0x20); // Rx2 Full/LMT Gain Index
status = ad9361_reg_write(dev, 0x010D, 0x18); // Rx2 LPF Gain Index
status = ad9361_reg_write(dev, 0x010E, 0x00); // Rx2 Digital Gain Index
status = ad9361_reg_write(dev, 0x0114, 0x30); // Low Power Threshold
+5 -5
View File
@@ -25,10 +25,10 @@
#include "common.h"
#include "error.h"
#include "delay.h"
#include "system_monitor.h"
#include "hwconfig.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
#include "systembus/systembus.h"
#ifdef RFSOC
#include "xrfdc.h"
#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_2_reg_inst, 0x0002, &rd_back);
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
#endif
#ifdef AD9653
+22 -14
View File
@@ -28,7 +28,6 @@
#include "error.h"
#include "timer.h"
#include "hwconfig.h"
#include "system_monitor.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
#include "systembus/systembus.h"
@@ -78,8 +77,10 @@ struct callback_desc apptimer_callback_desc = {
// .myType = L2_NODE_HEAD,
// .clustId = 1U,
// .myId = 1U,
// .headId = 1U,
// .netScale = 10U,
// .headId = L2_HEAD_ID,
// .netScale = L2_NET_SCALE,
// .initTable = initRoutTable,
// .normalTable = normalRoutTable1,
// .serviceRate = L2_SVC_512K,
// .phyInstPtr = NULL, // physical layer reference
// .tmcInstPtr = NULL
@@ -89,8 +90,10 @@ L2_CONFIG linkConfig = {
.myType = L2_NODE_MEMBER,
.clustId = 1U,
.myId = 2U,
.headId = 1U,
.netScale = 10U,
.headId = L2_HEAD_ID,
.netScale = L2_NET_SCALE,
.initTable = initRoutTable,
.normalTable = normalRoutTable1,
.serviceRate = L2_SVC_512K,
.phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL
@@ -129,8 +132,8 @@ static SYSBUS_CONFIG sysbusConfig = {
};
static SYSMON_CONFIG sysmonConfig = {
.sendQueueMax = 32U,
.recvQueueMax = 32U
.sendQueueMax = 16U,
.recvQueueMax = 16U
};
/*********************** 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);
/* Initialize physical layer interrupt. */
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, PHY_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
@@ -221,6 +225,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
/* Initialize linklayer layer interrupt. */
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, PERIODIC_5MS_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
@@ -243,17 +248,18 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
/* Initialize system bus interrupt. */
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_TX_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x10);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_TX_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
@@ -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);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_TX_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt trigger level
Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_RX_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x18);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("SYSBUS_RX_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
@@ -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);
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;
}
@@ -291,7 +299,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
Status = irq_register_callback(descPtr, APPTIMER_INTR_ID, &apptimer_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
DBG_ERROR("APPTIMER_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
+8 -8
View File
@@ -601,8 +601,8 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
(*instPtr)->tor.last = L2_TOR_SUSPEND;
(*instPtr)->tor.curr = L2_TOR_SUSPEND;
(*instPtr)->tor.next = L2_TOR_SUSPEND;
(*instPtr)->rtneConfig.rtneTable = initTable;
(*instPtr)->rtneConfig.rtnePrd = ARRAY_SIZE(initTable);
(*instPtr)->rtneConfig.rtneTable = (*instPtr)->config.initTable;
(*instPtr)->rtneConfig.rtnePrd = ARRAY_SIZE(initRoutTable);
(*instPtr)->mainState = L2_INIT_STATE;
(*instPtr)->nextState = L2_INIT_STATE;
(*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.curr = L2_TOR_SUSPEND;
instPtr->tor.next = L2_TOR_SUSPEND;
instPtr->rtneConfig.rtneTable = initTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initTable);
instPtr->rtneConfig.rtneTable = instPtr->config.initTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initRoutTable);
instPtr->mainState = L2_INIT_STATE;
instPtr->nextState = L2_INIT_STATE;
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.
L2_Scan_Reset(instPtr->scanFSM);
UpdateMainSate(instPtr, L2_INIT_STATE);
instPtr->rtneConfig.rtneTable = initTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initTable);
instPtr->rtneConfig.rtneTable = instPtr->config.initTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(initRoutTable);
}
else if (instPtr->nextState == L2_NORMAL_STATE)
{
UpdateMainSate(instPtr, L2_NORMAL_STATE);
instPtr->rtneConfig.rtneTable = normalTable0;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable0);
instPtr->rtneConfig.rtneTable = instPtr->config.normalTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalRoutTable1);
}
else
{
+9 -5
View File
@@ -27,7 +27,7 @@
#include "msg_def.h"
#include "circ_queue.h"
#include "../phy_layer/phy_layer.h"
#include "../../system_monitor.h"
#include "../../systembus/systembus.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event)))
@@ -45,6 +45,8 @@ typedef struct
uint8_t headId; ///< head node id
uint8_t netScale; ///< net scale
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
TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance
} L2_CONFIG;
@@ -93,6 +95,8 @@ typedef struct
int64_t timeDev; ///< last time deviation estimation result
uint32_t reconnectCnt; ///< reconnect trial count
uint32_t txValidMsgCnt; ///< non-default tx message count
uint32_t rxValidMsgCnt; ///< non-default rx message count
L2_MSG_RECORD rxLog;
L2_MSG_RECORD txLog;
} L2_LOG;
@@ -129,10 +133,10 @@ typedef struct
} L2_INST;
/************************** Variable Definitions *****************************/
extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable0[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable1[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable2[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *initRoutTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable1[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable2[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalRoutTable3[L2_INIT_RTNE_PERIOD];
/************************** Function Prototypes ******************************/
/**
* @defgroup LinkLayer_Main
+3 -2
View File
@@ -37,8 +37,9 @@
#define L2_BROADCAST_ID2 0xF2
#define L2_BROADCAST_ID3 0xF4
#define L2_UNICAST_ID 0xF0
#define L2_NONE_ID 0
#define L2_HEAD_ID 0x01
#define L2_NONE_ID 0U
#define L2_HEAD_ID 1U
#define L2_NET_SCALE 10U
// Routine configure
#define L2_INIT_RTNE_PERIOD 1
+4 -4
View File
@@ -853,22 +853,22 @@ L2_RTNE_TABLE_ENTRY tab3Mng3Svc[L2_SLOTS_PER_FRAME] =
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}
};
L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *initRoutTable[L2_INIT_RTNE_PERIOD] =
{
tab10Mng10Svc
};
L2_RTNE_TABLE_ENTRY *normalTable0[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *normalRoutTable1[L2_INIT_RTNE_PERIOD] =
{
tab10Mng10Svc
};
L2_RTNE_TABLE_ENTRY *normalTable1[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *normalRoutTable2[L2_INIT_RTNE_PERIOD] =
{
tab10Mng3Svc
};
L2_RTNE_TABLE_ENTRY *normalTable2[L2_INIT_RTNE_PERIOD] =
L2_RTNE_TABLE_ENTRY *normalRoutTable3[L2_INIT_RTNE_PERIOD] =
{
tab3Mng3Svc
};
+18 -8
View File
@@ -250,12 +250,13 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
return EIGNORE;
}
SYSMON_SVC_PAYLOAD *recvPayload = calloc(1, NORMALIZE_SIZE(sizeof(SYSMON_SVC_PAYLOAD)));
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...
@@ -276,7 +277,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
L2_MSG_ACK *message = (L2_MSG_ACK *)msg;
size_t msgLen = sizeof(L2_MSG_ACK);
size_t dataLen = L2_PAYLOAD_LEN_ACK;
size_t maxDataLen = L2_PAYLOAD_LEN_ACK;
// Update node status.
uint8_t nodeId = message->common.src;
@@ -326,12 +327,21 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
}
// Get data payload & upload
SYSMON_SVC_PAYLOAD recvPayload;
recvPayload.dataId = message->dataId;
recvPayload.nodeId = message->common.src;
recvPayload.dataLen = message->dataLen;
memcpy(recvPayload.data, message->data, dataLen);
SysMonitor_GenRecvRsp(&recvPayload);
if (message->dataId != DATA_ID_NONE)
{
if (message->dataLen > maxDataLen)
{
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
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.rxLog.dataId = message->dataId;
+24 -12
View File
@@ -200,8 +200,8 @@ static int32_t Service_Packing128K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
if (type == L2_FRAME_SVC)
{
// Packing extra payload
SYSMON_SVC_PAYLOAD *sendPayload;
SysMonitor_GetSendPayload(&sendPayload);
SYSBUS_SVC_PLD *sendPayload;
SysMonitor_GetSendPayload(&sendPayload, dstId);
if(sendPayload == NULL)
{
message->common.dst = L2_NONE_ID;
@@ -211,13 +211,14 @@ static int32_t Service_Packing128K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
}
else
{
message->common.dst = sendPayload->nodeId;
message->dataId = sendPayload->dataId;
message->dataLen = sendPayload->dataLen;
memset(message->data, 0xAA, maxDataLen);
memcpy(message->data, sendPayload->data, (sendPayload->dataLen > maxDataLen) ?
maxDataLen : sendPayload->dataLen);
free(sendPayload);
// logging
instPtr->log.txValidMsgCnt++;
}
}
else
@@ -278,8 +279,8 @@ static int32_t Service_Packing512K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
message->srcSpeedZ = instPtr->sysInfo.vZ;
// Pack extra payload
SYSMON_SVC_PAYLOAD *sendPayload;
SysMonitor_GetSendPayload(&sendPayload);
SYSBUS_SVC_PLD *sendPayload;
SysMonitor_GetSendPayload(&sendPayload, dstId);
if(sendPayload == NULL)
{
message->common.dst = L2_NONE_ID;
@@ -289,13 +290,14 @@ static int32_t Service_Packing512K(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t
}
else
{
message->common.dst = sendPayload->nodeId;
message->dataId = sendPayload->dataId;
message->dataLen = sendPayload->dataLen;
memset(message->data, 0xAA, maxDataLen);
memcpy(message->data, sendPayload->data, (sendPayload->dataLen > maxDataLen) ?
maxDataLen : sendPayload->dataLen);
free(sendPayload);
// logging
instPtr->log.txValidMsgCnt++;
}
// Append CRC
@@ -348,8 +350,8 @@ static int32_t Service_Packing2M(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t d
message->srcSpeedZ = instPtr->sysInfo.vZ;
// Packing extra payload
SYSMON_SVC_PAYLOAD *sendPayload;
SysMonitor_GetSendPayload(&sendPayload);
SYSBUS_SVC_PLD *sendPayload;
SysMonitor_GetSendPayload(&sendPayload, dstId);
if(sendPayload == NULL)
{
message->common.dst = L2_NONE_ID;
@@ -359,13 +361,14 @@ static int32_t Service_Packing2M(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t d
}
else
{
message->common.dst = sendPayload->nodeId;
message->dataId = sendPayload->dataId;
message->dataLen = sendPayload->dataLen;
memset(message->data, 0xAA, maxDataLen);
memcpy(message->data, sendPayload->data, (sendPayload->dataLen > maxDataLen) ?
maxDataLen : sendPayload->dataLen);
free(sendPayload);
// logging
instPtr->log.txValidMsgCnt++;
}
// Append CRC
@@ -535,12 +538,15 @@ static int32_t Service_PktHandler128K(L2_INST *instPtr, uint8_t *msg)
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
return EIGNORE;
}
SYSMON_SVC_PAYLOAD *recvPayload = calloc(1, NORMALIZE_SIZE(sizeof(SYSMON_SVC_PAYLOAD)));
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...
@@ -623,12 +629,15 @@ static int32_t Service_PktHandler512K(L2_INST *instPtr, uint8_t *msg)
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
return EIGNORE;
}
SYSMON_SVC_PAYLOAD *recvPayload = calloc(1, NORMALIZE_SIZE(sizeof(SYSMON_SVC_PAYLOAD)));
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...
@@ -711,12 +720,15 @@ static int32_t Service_PktHandler2M(L2_INST *instPtr, uint8_t *msg)
DBG_ERROR("Payload length" PRIu16 " out of range.\n", message->dataLen);
return EIGNORE;
}
SYSMON_SVC_PAYLOAD *recvPayload = calloc(1, NORMALIZE_SIZE(sizeof(SYSMON_SVC_PAYLOAD)));
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...
+15 -2
View File
@@ -696,6 +696,7 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
ASSERT(instPtr != NULL);
int32_t Status;
uint32_t phyModeCtrl, hopNum;
uint16_t txMultifactor; // physical layer tx power digital attenuation
const uint8_t *hopPattern;
// Implement a ping-pong flow, offset always is 0 or half of buffer depth.
instPtr->antConfigOffset = (L1_ANTCONFIG_MAX_LEN >> 1) - instPtr->antConfigOffset;
@@ -721,26 +722,31 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
phyModeCtrl |= PHY_MODE_CTRL_FRAME_ADV_24MS;
hopNum = L1_FRAME_ADV_24MS_HOPS;
hopPattern = hopPattern_ADV_24MS;
txMultifactor = 0x4023; // -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 = 0x4023; // -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 = 0x2D84; // -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 = 0x4023; // -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 = 0x8000; // -6dB, baseline
break;
default:
return EPARAM;
@@ -794,6 +800,9 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode,
}
}
// Set tx multifactor
PhyWrite(instPtr, TX_MULFAC, txMultifactor);
// Trigger physical configuration.
// Indicate physical layer that all the configurations were done.
PhyWrite(instPtr, SLOT_CMD, SLOT_CMD_KEY);
@@ -1026,9 +1035,11 @@ void Phy_RefreshHwSate(PHY_INST *instPtr)
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
? INT8_MAX
: ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
// FIXME: XADC range needs further refine
instPtr->hwSate.spFpgaVolt = (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK);
instPtr->hwSate.spClkState = (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK);
instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK))
&& (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK))
&& (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK));
&& (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK));
#else
double evalData;
instPtr->hwSate.isSpOk = true;
@@ -1109,6 +1120,8 @@ void Phy_RefreshHwSate(PHY_INST *instPtr)
instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX)
? INT8_MAX
: ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB));
// FIXME: XADC readback is required
instPtr->hwSate.spFpgaVolt = (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK);
instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK))
&& (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK))
&& (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK));
+1 -1
View File
@@ -31,7 +31,7 @@
#include "xadcps.h"
#endif
#endif
#include "../../system_monitor.h"
#include "../../systembus/systembus.h"
#include "../../time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/
/**
+10 -2
View File
@@ -207,7 +207,7 @@
/**
* Register: TM_TARGET_L
*/
#define TM_TARGET_L 0x00000064U
#define TM_TARGET_L 0x00000034U
#define TM_TARGET_L_SHIFT 0
#define TM_TARGET_L_WIDTH 32
#define TM_TARGET_L_MASK 0xFFFFFFFFU
@@ -260,6 +260,14 @@
#define ANT_SELECT_INDEX_WIDTH 32
#define ANT_SELECT_INDEX_MASK 0xFFFFFFFFU
/**
* Register: TX_MULFAC
*/
#define TX_MULFAC 0x00000048U
#define TX_MULFAC_SHIFT 0
#define TX_MULFAC_WIDTH 16
#define TX_MULFAC_MASK 0x0000FFFFU
/**
* Register: ANT_STATUS_1
*/
@@ -500,4 +508,4 @@
/** @} PhysicalLayer_REG_Constants*/
/** @} PhysicalLayer*/
/** @} PhysicalLayer*/
-383
View File
@@ -1,383 +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
SYSMON_SVC_PAYLOAD *payloadCopy = malloc(sizeof(SYSMON_SVC_PAYLOAD));
if (payloadCopy == NULL)
{
DBG_ERROR("Allocate memory for send payload failed.\n");
return ENOMEM;
}
memcpy(payloadCopy, payload, sizeof(SYSMON_SVC_PAYLOAD));
if (CircQueuePush(sysMonitorInst->sendQueue, (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(SYSMON_SVC_PAYLOAD **payload)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(payload != NULL);
if (CircQueuePop(sysMonitorInst->sendQueue, (void **)payload) == false)
{
*payload = NULL;
}
}
/**
* @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*/
-258
View File
@@ -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[1000];
} 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_
/** @} */
+416 -60
View File
@@ -27,7 +27,9 @@
#include "common.h"
#include "error.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
@@ -148,7 +150,48 @@
// My Production Type
#define MY_PRD_ID PRD_DL_C
/** @} 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 ******************************/
static uint8_t GetWritable(PINGPONG ctrllor);
static uint8_t GetReadable(PINGPONG ctrllor);
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr);
static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg);
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 *******************************/
/************************** Variable Definitions *****************************/
// TODO: better approach?
#include "../networking/link_layer/link_layer.h"
#include "../networking/phy_layer/phy_layer.h"
extern L2_INST *linkInstPtr;
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)
{
@@ -178,6 +239,7 @@ inline bool SystemBus_IsTxBusy(SYSBUS *instPtr)
ASSERT(instPtr != NULL);
return (!instPtr->isTxDone);
}
inline bool SystemBus_IsRxBusy(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
@@ -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
if (msg[WD_EN_CMD] == EN_CMD_ENABLE)
{
@@ -307,58 +408,6 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
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(linkInstPtr, &l2Event);
break;
}
case 1:
{
newRtneConfig.rtneTable = normalTable1;
newRtneConfig.rtnePrd = ARRAY_SIZE(normalTable1);
L2_EVENT l2Event =
{
.event = L2_ROUTINE_UPDATE,
.msg = &newRtneConfig
};
AssertL2Event(linkInstPtr, &l2Event);
break;
}
case 2:
{
newRtneConfig.rtneTable = normalTable2;
newRtneConfig.rtnePrd = ARRAY_SIZE(normalTable2);
L2_EVENT l2Event =
{
.event = L2_ROUTINE_UPDATE,
.msg = &newRtneConfig
};
AssertL2Event(linkInstPtr, &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[1] = msg[WD_ID_CMD];
instPtr->sysbusLog.lastConfig[2] = msg[WD_RATE_CMD];
@@ -394,23 +443,23 @@ static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame)
/**
* @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(payload != NULL);
SYSBUS_UART_FRAME *sysbusRsp = malloc(NORMALIZE_SIZE(sizeof(SYSBUS_UART_FRAME)));
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for Receive Response!\n");
return ENOMEM;
}
sysbusRsp->len = payload->dataLen + RECV_DATA_LEN_OFFSET;
sysbusRsp->len = payload->dataLen + RECV_DATA_OFFSET;
sysbusRsp->data[WD_CMD] = CMD_RECV_DATA;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
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)
{
@@ -527,7 +576,7 @@ int32_t SystemBus_HandleCmd(SYSBUS *instPtr)
}
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)
{
instPtr->sysbusLog.sendCnt++;
@@ -703,4 +752,311 @@ int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr)
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*/
+255 -2
View File
@@ -23,9 +23,84 @@
#include <stdbool.h>
#include "systembus_uart.h" // SystemBus UART driver
#include "circ_queue.h"
#include "../system_monitor.h"
/************************** 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 ****************************/
/**
@@ -39,6 +114,156 @@ typedef struct
uint32_t rxQueueMax; ///< maximum rx queue length
} 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
* @brief SystemBus Instance struct
@@ -57,9 +282,19 @@ typedef struct
bool isRxDone; ///< rx done indicator
} 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 ******************************/
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);
void SystemBus_Destroy(SYSBUS *instPtr);
@@ -80,6 +315,24 @@ bool SystemBus_IsRespPending(SYSBUS *instPtr);
bool SystemBus_IsTxBusy(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_
/** @} SystemBus*/
+8 -56
View File
@@ -21,7 +21,6 @@
* @{
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
@@ -34,10 +33,10 @@
* @{
*/
// Control and status register
#define MODULE_VERSION 0
#define UART_STATUS 4
#define UART_SEND_CMD 8
#define UART_RECV_CNT 12
#define MODULE_VERSION 0x00000000U
#define UART_STATUS 0x0000004U
#define UART_SEND_CMD 0x00000008U
#define UART_RECV_CNT 0x0000000CU
// Status code
#define UART_STATUS_TX_BUSY 0x00010000
@@ -48,6 +47,10 @@
#define UART_RXBUFF_OFFSET 2048
#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
#define FRAME_HEAD_LOW 0x5A
#define FRAME_HEAD_HIGH 0x54
@@ -62,16 +65,6 @@
#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen
/** @} 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)
{
ASSERT(instPtr != NULL);
@@ -85,17 +78,6 @@ int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config)
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)
{
ASSERT(instPtr != NULL);
@@ -154,16 +136,6 @@ int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
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)
{
ASSERT(instPtr != NULL);
@@ -212,16 +184,6 @@ int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
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)
{
ASSERT(instPtr != NULL);
@@ -238,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)
{
ASSERT(instPtr != NULL);
+57 -6
View File
@@ -27,6 +27,9 @@
#include <stdint.h>
#include <stdbool.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 *****************************/
/**
*
@@ -96,23 +99,71 @@ typedef struct
uint16_t len;
uint8_t checkSum;
uint8_t isValid;
uint8_t data[1024];
uint8_t data[UART_FRM_MAX];
} SYSBUS_UART_FRAME;
/************************** 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);
// 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);
// 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);
// 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);
// 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);
#endif // SYSTEMBUS_UART_H