nsqdriver 0.12.17__cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nsqdriver/NS_CST.py +260 -0
- nsqdriver/NS_DDS_v3.py +591 -0
- nsqdriver/NS_DDS_v4.py +778 -0
- nsqdriver/NS_MCI.py +597 -0
- nsqdriver/NS_QSYNC.py +812 -0
- nsqdriver/__init__.py +10 -0
- nsqdriver/common.py +20 -0
- nsqdriver/compiler/__init__.py +0 -0
- nsqdriver/compiler/assembler.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/compiler/ns_wave.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/compiler/ns_wave.pyi +151 -0
- nsqdriver/compiler/py_wave_asm.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/compiler/py_wave_asm.pyi +29 -0
- nsqdriver/nswave/__init__.py +9 -0
- nsqdriver/nswave/_asm.pyi +97 -0
- nsqdriver/nswave/_checkers.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_checkers.pyi +47 -0
- nsqdriver/nswave/_errors.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_errors.pyi +24 -0
- nsqdriver/nswave/_functions.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_functions.pyi +34 -0
- nsqdriver/nswave/_ir.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_ir.pyi +283 -0
- nsqdriver/nswave/_ir_pass.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_ir_pass.pyi +7 -0
- nsqdriver/nswave/_optimizations.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_optimizations.pyi +16 -0
- nsqdriver/nswave/_rules.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_rules.pyi +56 -0
- nsqdriver/nswave/_simulator.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_translate.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/_translate.pyi +12 -0
- nsqdriver/nswave/kernel.cpython-313-x86_64-linux-gnu.so +0 -0
- nsqdriver/nswave/kernel.pyi +57 -0
- nsqdriver/wrapper/AWG_ADC.py +534 -0
- nsqdriver/wrapper/ND_NSMCI.py +245 -0
- nsqdriver/wrapper/__init__.py +0 -0
- nsqdriver-0.12.17.dist-info/METADATA +117 -0
- nsqdriver-0.12.17.dist-info/RECORD +41 -0
- nsqdriver-0.12.17.dist-info/WHEEL +6 -0
- nsqdriver-0.12.17.dist-info/top_level.txt +1 -0
nsqdriver/NS_CST.py
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import struct
|
|
3
|
+
import time
|
|
4
|
+
from functools import lru_cache, wraps
|
|
5
|
+
from typing import Union, TYPE_CHECKING, Tuple, Iterable
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from .common import BaseDriver, Quantity
|
|
9
|
+
except ImportError as e:
|
|
10
|
+
class BaseDriver:
|
|
11
|
+
def __init__(self, addr, timeout, **kw):
|
|
12
|
+
self.addr = addr
|
|
13
|
+
self.timeout = timeout
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Quantity(object):
|
|
17
|
+
def __init__(self, name: str, value=None, ch: int = 1, unit: str = ''):
|
|
18
|
+
self.name = name
|
|
19
|
+
self.default = dict(value=value, ch=ch, unit=unit)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
DEBUG_PRINT = False
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def print_debug(*args, **kwargs):
|
|
26
|
+
if DEBUG_PRINT:
|
|
27
|
+
print(*args, **kwargs)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def retry(times):
|
|
31
|
+
def decorator(func):
|
|
32
|
+
@wraps(func)
|
|
33
|
+
def wrapper(*args, **kwargs):
|
|
34
|
+
_times = times - 1
|
|
35
|
+
while not func(*args, **kwargs) and _times > 0:
|
|
36
|
+
_times -= 1
|
|
37
|
+
return _times != 0
|
|
38
|
+
|
|
39
|
+
return wrapper
|
|
40
|
+
|
|
41
|
+
return decorator
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Driver(BaseDriver):
|
|
45
|
+
icd_head_mode = 0x51000009
|
|
46
|
+
icd_head_open = 0x5100000A
|
|
47
|
+
CHs = list(range(1, 17))
|
|
48
|
+
|
|
49
|
+
quants = [
|
|
50
|
+
Quantity('SAMode', value='manual'), # set/get, 运行模式manual为手动,根据指令切换开关
|
|
51
|
+
Quantity('Strobe', value=1, ch=1), # set/get, 选通开关通道,value为开关矩阵in口,ch为out口
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
SystemParameter = {
|
|
55
|
+
'SAMode': 'manual', # 运行模式manual为手动,根据指令切换开关
|
|
56
|
+
'StrobeList': [1, 9],
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
def __init__(self, addr: str = '', timeout: float = 10.0, **kw):
|
|
60
|
+
super().__init__(addr, timeout, **kw)
|
|
61
|
+
self.handle = None
|
|
62
|
+
self.model = 'NS_CST' # 默认为设备名字
|
|
63
|
+
self.srate = None
|
|
64
|
+
self.gen_trig_num = 0
|
|
65
|
+
self.addr = addr
|
|
66
|
+
|
|
67
|
+
self.param = {'SAMode': 'manual'}
|
|
68
|
+
print_debug(f'CST: 实例化成功{addr}')
|
|
69
|
+
|
|
70
|
+
def open(self, **kw):
|
|
71
|
+
"""!
|
|
72
|
+
输入IP打开设备,配置默认超时时间为5秒
|
|
73
|
+
打开设备时配置RFSoC采样时钟,采样时钟以参数定义
|
|
74
|
+
@param kw:
|
|
75
|
+
@return:
|
|
76
|
+
"""
|
|
77
|
+
# 配置系统初始值
|
|
78
|
+
system_parameter = kw.get('system_parameter', {})
|
|
79
|
+
values = self.SystemParameter.copy()
|
|
80
|
+
values.update(system_parameter)
|
|
81
|
+
for name, value in values.items():
|
|
82
|
+
if value is not None:
|
|
83
|
+
self.set(name, value, 1)
|
|
84
|
+
|
|
85
|
+
def close(self, **kw):
|
|
86
|
+
"""
|
|
87
|
+
关闭设备
|
|
88
|
+
"""
|
|
89
|
+
# self.handle.release_dma()
|
|
90
|
+
# self.handle.close()
|
|
91
|
+
...
|
|
92
|
+
|
|
93
|
+
def write(self, name: str, value, **kw):
|
|
94
|
+
channel = kw.get('ch', 1)
|
|
95
|
+
return self.set(name, value, channel)
|
|
96
|
+
|
|
97
|
+
def read(self, name: str, **kw):
|
|
98
|
+
channel = kw.get('ch', 1)
|
|
99
|
+
result = self.get(name, channel)
|
|
100
|
+
return result
|
|
101
|
+
|
|
102
|
+
def set(self, name, value=None, channel=1):
|
|
103
|
+
"""!
|
|
104
|
+
设置设备属性
|
|
105
|
+
@param name:
|
|
106
|
+
@param value:
|
|
107
|
+
@param channel:
|
|
108
|
+
@return:
|
|
109
|
+
"""
|
|
110
|
+
print_debug(f'CST: set操作被调用{name}')
|
|
111
|
+
if name == 'SAMode':
|
|
112
|
+
data = self.__fmt_cst_mode(
|
|
113
|
+
value
|
|
114
|
+
)
|
|
115
|
+
self._send_command(data, connect_timeout=2)
|
|
116
|
+
elif name == 'Strobe':
|
|
117
|
+
config = self.param['StrobeList']
|
|
118
|
+
if value not in [1, 2]:
|
|
119
|
+
raise ValueError(f'IN通道超界,不应为{value},需要为1或2')
|
|
120
|
+
config[value-1] = channel
|
|
121
|
+
data = self.__fmt_cst_strobe(
|
|
122
|
+
config
|
|
123
|
+
)
|
|
124
|
+
self._send_command(data, connect_timeout=2)
|
|
125
|
+
elif name == 'UpdateFirmware':
|
|
126
|
+
self.update_firmware(value)
|
|
127
|
+
|
|
128
|
+
else:
|
|
129
|
+
self.param[name] = value
|
|
130
|
+
|
|
131
|
+
def get(self, name, channel=1, value=0):
|
|
132
|
+
"""!
|
|
133
|
+
查询设备属性,获取数据
|
|
134
|
+
@param name:
|
|
135
|
+
@param channel:
|
|
136
|
+
@param value:
|
|
137
|
+
@return:
|
|
138
|
+
"""
|
|
139
|
+
print_debug(f'CST: get操作被调用{name}')
|
|
140
|
+
return self.param.get(name, None)
|
|
141
|
+
|
|
142
|
+
def update_firmware(self, file_path, boards=None):
|
|
143
|
+
"""!
|
|
144
|
+
固件更新
|
|
145
|
+
|
|
146
|
+
@param file_path: 固件路径
|
|
147
|
+
@param boards:
|
|
148
|
+
@return:
|
|
149
|
+
"""
|
|
150
|
+
import os
|
|
151
|
+
if not os.path.exists(file_path):
|
|
152
|
+
raise ValueError(f'文件路径: {file_path} 不存在')
|
|
153
|
+
with open(file_path, 'rb') as fp:
|
|
154
|
+
cmd_data = self.__fmt_update_firmware(fp.read())
|
|
155
|
+
if not self._send_command(cmd_data):
|
|
156
|
+
print(f'qsync: 固件更新 执行失败')
|
|
157
|
+
|
|
158
|
+
def _connect(self, addr=None, port=5001, timeout=None):
|
|
159
|
+
"""!
|
|
160
|
+
获取到指定ip的tcp连接
|
|
161
|
+
|
|
162
|
+
@param addr:
|
|
163
|
+
@param port:
|
|
164
|
+
@return:
|
|
165
|
+
"""
|
|
166
|
+
timeout = self.timeout if timeout is None else timeout
|
|
167
|
+
addr = self.addr if addr is None else addr
|
|
168
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
169
|
+
sock.settimeout(timeout)
|
|
170
|
+
sock.connect((addr, port))
|
|
171
|
+
return sock
|
|
172
|
+
|
|
173
|
+
@retry(3)
|
|
174
|
+
def _send_command(self, data: Union[str, bytes], wait=0, addr=None, port=5001,
|
|
175
|
+
check_feedback=True, return_fdk=False, connect_timeout=10):
|
|
176
|
+
"""!
|
|
177
|
+
发送指定内容到后端
|
|
178
|
+
|
|
179
|
+
@param data: 指令内容
|
|
180
|
+
@param wait: 指令发送完成后,等待一段时间再接收反馈,阻塞式等待
|
|
181
|
+
@param addr: 后端IP
|
|
182
|
+
@param port: 后端端口
|
|
183
|
+
@param check_feedback: 是否解析反馈
|
|
184
|
+
@param connect_timeout:
|
|
185
|
+
@return:
|
|
186
|
+
"""
|
|
187
|
+
command_bak = data
|
|
188
|
+
try:
|
|
189
|
+
sock = self._connect(addr=addr, port=port, timeout=connect_timeout)
|
|
190
|
+
except Exception as e:
|
|
191
|
+
print(f'device: {addr}无法连接 {e}')
|
|
192
|
+
return False
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
sock.sendall(memoryview(data))
|
|
196
|
+
|
|
197
|
+
time.sleep(wait)
|
|
198
|
+
_feedback = sock.recv(20)
|
|
199
|
+
if check_feedback:
|
|
200
|
+
if not _feedback.startswith(b'\xcf\xcf\xcf\xcf'):
|
|
201
|
+
print('返回指令包头错误')
|
|
202
|
+
return False
|
|
203
|
+
if command_bak[4:8] != _feedback[4:8]:
|
|
204
|
+
print(f'返回指令ID错误')
|
|
205
|
+
return False
|
|
206
|
+
_feedback = struct.unpack('=IIIII', _feedback)
|
|
207
|
+
if _feedback[4] != 0:
|
|
208
|
+
print('指令成功下发,但执行失败')
|
|
209
|
+
return False
|
|
210
|
+
except Exception as e:
|
|
211
|
+
print(f'device: {addr}指令{command_bak[:4]}发送失败 {e}')
|
|
212
|
+
return False
|
|
213
|
+
finally:
|
|
214
|
+
sock.close()
|
|
215
|
+
return True
|
|
216
|
+
|
|
217
|
+
@lru_cache(maxsize=32)
|
|
218
|
+
def __fmt_cst_mode(self, mode):
|
|
219
|
+
cmd_pack = (
|
|
220
|
+
0x5F5F5F5F,
|
|
221
|
+
self.icd_head_mode,
|
|
222
|
+
0x00000000,
|
|
223
|
+
20,
|
|
224
|
+
0 if mode == 'manual' else 1
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
return struct.pack('=' + 'I' * len(cmd_pack), *cmd_pack)
|
|
228
|
+
|
|
229
|
+
@lru_cache(maxsize=32)
|
|
230
|
+
def __fmt_cst_strobe(self, out_ch):
|
|
231
|
+
if out_ch[0] > 8:
|
|
232
|
+
raise ValueError(f'不能将IN1通道选通到OUT9~16')
|
|
233
|
+
if out_ch[1] <= 8:
|
|
234
|
+
raise ValueError(f'不能将IN2通道选通到OUT1~8')
|
|
235
|
+
cmd_pack = (
|
|
236
|
+
0x5F5F5F5F,
|
|
237
|
+
self.icd_head_open,
|
|
238
|
+
0x00000000,
|
|
239
|
+
20,
|
|
240
|
+
(1 << (out_ch[0] - 1)) + (1 << (out_ch[1]-1))
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
return struct.pack('=' + 'I' * len(cmd_pack), *cmd_pack)
|
|
244
|
+
|
|
245
|
+
@staticmethod
|
|
246
|
+
def __fmt_update_firmware(file_data):
|
|
247
|
+
cmd_pack = (
|
|
248
|
+
0x5F5F5F5F,
|
|
249
|
+
0x31000006,
|
|
250
|
+
0x00000000,
|
|
251
|
+
16 + len(file_data),
|
|
252
|
+
)
|
|
253
|
+
return struct.pack('=' + 'I' * len(cmd_pack), *cmd_pack) + file_data
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
if __name__ == '__main__':
|
|
257
|
+
driver = Driver('192.168.1.241')
|
|
258
|
+
driver.open()
|
|
259
|
+
driver.set('Strobe', 1, 3) # I1选通到OUT3,所有通道编号从1计数
|
|
260
|
+
driver.set('Strobe', 2, 9) # I2选通到OUT9,OUT9为第二个模块的OUT1
|