trx-client-new.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. # This script is a client for controlling a TRX device over TCP/IP.
  2. # It allows the user to set various parameters such as RX frequency, TX frequency,
  3. # RX rate, TX level, and more. The script uses a socket connection to communicate with the TRX device.
  4. import socket
  5. import sys
  6. import time
  7. import struct
  8. import numpy as np
  9. default_port = 1001
  10. default_host = '192.168.1.100'
  11. class TrxClient:
  12. def __init__(self, host='localhost', port=1001):
  13. self.host = host
  14. self.port = port
  15. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  16. self.size = 0
  17. self.sock.settimeout(5)
  18. self.connect()
  19. self.tx_rate = 2
  20. def connect(self):
  21. try:
  22. self.sock.connect((self.host, self.port))
  23. print(f"Connected to {self.host}:{self.port}")
  24. except socket.error as e:
  25. print(f"Connection error: {e}")
  26. sys.exit(1)
  27. def set_rx_freq(self, freq):
  28. try:
  29. data = struct.pack('<Q', 0 << 60 | np.uint64(1e6 * freq))
  30. self.sock.send(data)
  31. #rdata = self.sock.recv(8)
  32. print(f"Set RX frequency to {freq} MHz")
  33. # no response expected for RX frequency
  34. except socket.error as e:
  35. print(f"Socket error: {e}")
  36. def set_tx_freq(self, freq):
  37. try:
  38. data = struct.pack('<Q', 1 << 60 | np.uint64(1e6 * freq))
  39. self.sock.send(data)
  40. #rdata = self.sock.recv(8)
  41. print(f"Set TX frequency to {freq} MHz")
  42. # no response expected for TX frequency
  43. except socket.error as e:
  44. print(f"Socket error: {e}")
  45. def set_rx_rate(self, rate):
  46. try:
  47. data = struct.pack('<Q', 2 << 60 | np.uint64(round(122.88e6 / rate / 2)))
  48. self.sock.send(data)
  49. #rdata = self.sock.recv(8)
  50. print(f"Set RX rate to {rate} kSPS")
  51. # no response expected for RX rate
  52. except socket.error as e:
  53. print(f"Socket error: {e}")
  54. def set_tx_rate(self, rate):
  55. self.tx_rate = rate
  56. def set_tx_level(self, level):
  57. try:
  58. data = struct.pack('<Q', 3 << 60 | np.uint64(level))
  59. self.sock.send(data)
  60. #rdata = self.sock.recv(8)
  61. print(f"Set TX level to {level}")
  62. # no response expected for TX level
  63. except socket.error as e:
  64. print(f"Socket error: {e}")
  65. def set_pin(self, pin):
  66. try:
  67. data = struct.pack('<Q', 4 << 60 | np.uint64(pin))
  68. self.sock.send(data)
  69. #rdata = self.sock.recv(8)
  70. print(f"Set pin to {pin}")
  71. # no response expected for pin
  72. except socket.error as e:
  73. print(f"Socket error: {e}")
  74. def clear_pin(self, pin):
  75. try:
  76. data = struct.pack('<Q', 5 << 60 | np.uint64(pin))
  77. self.sock.send(data)
  78. data = self.sock.recv(8)
  79. print(f"Cleared pin {pin}")
  80. # no response expected for clear pin
  81. except socket.error as e:
  82. print(f"Socket error: {e}")
  83. def set_dac(self, dac):
  84. try:
  85. data = struct.pack('<Q', 6 << 60 | np.uint64(dac))
  86. self.sock.send(data)
  87. #rdata = self.sock.recv(8)
  88. print(f"Set DAC to {dac}")
  89. # no response expected for DAC
  90. except socket.error as e:
  91. print(f"Socket error: {e}")
  92. def clear_pulses(self):
  93. try:
  94. data = struct.pack('<Q', 7 << 60)
  95. self.sock.send(data)
  96. #rdata = self.sock.recv(8)
  97. self.size = 0
  98. print("Cleared pulses")
  99. # no response expected for clear pulses
  100. except socket.error as e:
  101. print(f"Socket error: {e}")
  102. def add_pulse(self, level, phase, width):
  103. try:
  104. self.size += 1
  105. data = struct.pack('<Q', 8 << 60 | np.uint64(width-1))
  106. self.sock.send(data)
  107. #rdata = self.sock.recv(8)
  108. print(f"Set width {width}")
  109. phase = np.int64(np.floor(phase / 360.0 * (1 << 30) + 0.5))
  110. data = struct.pack('<Q', 9 << 60 | np.uint64((phase) | (level << 32) | (1 << 48)))
  111. self.sock.send(data)
  112. ##rdata = self.sock.recv(8)
  113. print(f"Set phase {phase} and level {level}")
  114. # no response expected for add pulse
  115. except socket.error as e:
  116. print(f"Socket error: {e}")
  117. def add_pulses(self, level, phase, width, num):
  118. for i in range(num):
  119. self.add_pulse(level, phase, width)
  120. def add_delay(self, gate, width):
  121. try:
  122. self.size += 1
  123. data = struct.pack('<Q', 8 << 60 | np.uint64(width-1))
  124. self.sock.send(data)
  125. #rdata = self.sock.recv(8)
  126. print(f"Set delay width {width}")
  127. data = struct.pack('<Q', 9 << 60 | np.uint64(gate << 48))
  128. self.sock.send(data)
  129. ##rdata = self.sock.recv(8)
  130. print(f"Set delay gate {gate}")
  131. # no response expected for add delay
  132. except socket.error as e:
  133. print(f"Socket error: {e}")
  134. def load_file(self, filename):
  135. with open(filename, 'rb') as file:
  136. self.size += 1
  137. sin_amp = file.read(1)
  138. #print(sin_amp) # dbg
  139. sin_data = np.floor(0.5 + 32767 * np.int64(np.frombuffer(sin_amp, dtype=np.int8)[0]) / 128)
  140. #print(sin_data) #dbg
  141. #input() #dbg
  142. quad_amp = file.read(1)
  143. quad_data = np.floor(0.5 + 32767 * np.int64(np.frombuffer(quad_amp, dtype=np.int8)[0]) / 128)
  144. level = int(np.floor(0.5 + np.sqrt(quad_data**2 / 2 + sin_data**2 / 2)))
  145. phase_enter = np.floor(0.5 + np.atan2(quad_data, sin_data) * 180 / np.pi)
  146. phase = 0.0
  147. print(level) #dbg
  148. print(phase_enter) #dbg
  149. #print(np.floor(124.88 / self.tx_rate + 0.5))
  150. #input() #dbg
  151. self.add_pulse(level, phase, 125)
  152. # repeat this while data is not empty
  153. while quad_amp:
  154. self.size += 1
  155. sin_amp = file.read(1)
  156. if not sin_amp:
  157. break
  158. sin_data = np.floor(0.5 + 32767 * np.int64(np.frombuffer(sin_amp, dtype=np.int8)[0]) / 128)
  159. quad_amp = file.read(1)
  160. if not quad_amp:
  161. break
  162. quad_data = 0.0
  163. level = int(np.floor(0.5 + np.sqrt(quad_data**2 / 2 + sin_data**2 / 2)))
  164. phase_enter = 0.0
  165. phase = 0.0
  166. with open('log.txt', 'a') as f:
  167. f.write(f'lev: {level}\n')
  168. f.write(f'phs: {phase_enter}\n\n')
  169. #print(np.floor(124.88 / self.tx_rate + 0.5))
  170. self.add_pulse(level, phase, 125)
  171. print(f"Size: {self.size}")
  172. def start_sequence(self):
  173. try:
  174. size = self.size
  175. data = struct.pack('<Q', 10 << 60 | np.uint64(size))
  176. self.sock.send(data)
  177. print("Started sequence")
  178. n = 2048
  179. counter = 0
  180. while counter < size:
  181. if n > (size - counter):
  182. n = size - counter
  183. rcv_data = self.sock.recv(4096)
  184. counter += n
  185. if not rcv_data:
  186. print("No data received")
  187. break
  188. except socket.error as e:
  189. print(f"Socket error: {e}")
  190. def close(self):
  191. try:
  192. self.sock.close()
  193. print("Connection closed")
  194. except socket.error as e:
  195. print(f"Socket error: {e}")
  196. client = TrxClient(default_host, default_port)
  197. end_of_cmd = False
  198. while not end_of_cmd:
  199. cmd = str(input('Enter command: '))
  200. if cmd == 'set_rx_freq':
  201. freq = float(input('Enter RX frequency (MHz): '))
  202. client.set_rx_freq(freq)
  203. elif cmd == 'set_tx_freq':
  204. freq = float(input('Enter TX frequency (MHz): '))
  205. client.set_tx_freq(freq)
  206. elif cmd == 'set_rx_rate':
  207. rate = int(input('Enter RX rate (kSPS): '))
  208. client.set_rx_rate(rate)
  209. elif cmd == 'set_tx_level':
  210. level = int(input('Enter TX level: '))
  211. client.set_tx_level(level)
  212. elif cmd == 'set_pin':
  213. pin = int(input('Enter pin number: '))
  214. client.set_pin(pin)
  215. elif cmd == 'clear_pin':
  216. pin = int(input('Enter pin number: '))
  217. client.clear_pin(pin)
  218. elif cmd == 'set_dac':
  219. dac = int(input('Enter DAC value: '))
  220. client.set_dac(dac)
  221. elif cmd == 'clear_pulses':
  222. client.clear_pulses()
  223. elif cmd == 'add_pulse':
  224. level = int(input('Enter pulse level: '))
  225. phase = float(input('Enter pulse phase (degrees): '))
  226. width = int(input('Enter pulse width (ticks): '))
  227. client.add_pulse(level, phase, width)
  228. elif cmd == 'add_pulses':
  229. level = int(input('Enter pulse level: '))
  230. phase = float(input('Enter pulse phase (degrees): '))
  231. width = int(input('Enter pulse width (ticks): '))
  232. num = int(input('Enter num: '))
  233. client.add_pulses(level, phase, width, num)
  234. elif cmd == 'add_delay':
  235. gate = int(input('Enter delay gate: '))
  236. width = int(input('Enter delay width (ticks): '))
  237. client.add_delay(gate, width)
  238. elif cmd == 'load_file':
  239. filename = str(input('Enter filename: '))
  240. client.load_file(filename)
  241. elif cmd == 'start_sequence':
  242. client.start_sequence()
  243. elif cmd == 'exit':
  244. client.close()
  245. end_of_cmd = True
  246. else:
  247. print("Invalid command")