def InitBscope(self, int_size, endian, clock, length): # Bandscope initialization; accept raw samples from the ADC # You may call this once from your hardware __init__() after calling InitSamples(). The bandscope format can not be changed. # int_size is the number of bytes in each sample: 1, 2, 3, or 4 # endian is the order of bytes in the sample: 0 == little endian; 1 == big endian # clock is the integer ADC sample rate in Hertz # length is the number of samples in each block of ADC samples, and equals the FFT size. QS.set_params(bscope_bytes=int_size, bscope_endian=endian, bscope_size=length) self.application.bandscope_clock = clock
def InitSamples( self, int_size, endian ): # Rx sample initialization; you must call this from your hardware __init__(). # int_size is the number of bytes in each I or Q sample: 1, 2, 3, or 4 # endian is the order of bytes in the sample: 0 == little endian; 1 == big endian # This can be called again to change the format. For example, a different number of bytes for different sample rates. QS.set_params(rx_bytes=int_size, rx_endian=endian) self.application.samples_from_python = True
def GotReadError(self, print_msg, msg): # Call this to indicate an error in receiving the Rx samples. if print_msg: print(msg) QS.set_params(read_error=1)
def GotClip(self): # Call this to indicate that samples were received with the clip (overrange) indicator true. QS.set_params(clip=1)
def ProgramGateware( self, event): # Program the Gateware (FPGA firmware) over Ethernet title = "Program the Gateware" main_frame = self.application.main_frame dlg = wx.FileDialog( main_frame, message='Choose an RBF file for programming the Gateware', style=wx.FD_OPEN, wildcard="RBF files (*.rbf)|*.rbf") if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() dlg.Destroy() else: dlg.Destroy() return timeout = 0.2 # socket timeout in seconds erase_time = 50 # in units of timeout hermes_ip = self.hermes_ip hermes_mac = self.hermes_mac if not hermes_ip: msg = wx.MessageDialog(main_frame, "No Hermes hardware was found.", title, wx.OK | wx.ICON_ERROR) msg.ShowModal() msg.Destroy() return try: fp = open(path, "rb") size = os.stat(path).st_size except: msg = wx.MessageDialog(main_frame, "Can not read the RBF file specified.", title, wx.OK | wx.ICON_ERROR) msg.ShowModal() msg.Destroy() return for i in range(10): state = QS.set_params(hermes_pause=1) #print ("state", state) if state == 23: break else: time.sleep(0.05) else: msg = wx.MessageDialog( main_frame, "Failure to find a running Hermes and stop the samples.", title, wx.OK | wx.ICON_ERROR) msg.ShowModal() msg.Destroy() fp.close() return blocks = (size + 255) // 256 dlg = wx.ProgressDialog(title, "Erase old program...", blocks + 1, main_frame, wx.PD_APP_MODAL) program_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) program_socket.settimeout(timeout) port = self.conf.rx_udp_port program_socket.connect((hermes_ip, port)) cmd = bytearray(64) # Erase command cmd[0] = 0xEF cmd[1] = 0xFE cmd[2] = 0x03 cmd[3] = 0x02 program_socket.send(cmd) success = False for i in range(erase_time): dlg.Update(i * blocks // erase_time) try: reply = program_socket.recv(1500) except socket.timeout: pass else: reply = bytearray(reply) if reply[0:3] == bytearray( b"\xEF\xFE\03") and reply[3:9] == hermes_mac: success = True break if not success: dlg.Destroy() self.application.Yield() fp.close() msg = wx.MessageDialog( main_frame, "Failure to erase the old program. Please push the Program button again.", title, wx.OK | wx.ICON_ERROR) msg.ShowModal() msg.Destroy() program_socket.close() return dlg.Update(0, "Programming...") cmd = bytearray(8) cmd[0] = 0xEF cmd[1] = 0xFE cmd[2] = 0x03 cmd[3] = 0x01 cmd[4] = (blocks >> 24) & 0xFF cmd[5] = (blocks >> 16) & 0xFF cmd[6] = (blocks >> 8) & 0xFF cmd[7] = (blocks) & 0xFF for block in range(blocks): dlg.Update(block) prog = fp.read(256) if block == blocks - 1: # last block may have an odd number of bytes prog = prog + bytearray(b"\xFF" * (256 - len(prog))) if len(prog) != 256: print("read wrong number of bytes for block", block) success = False break try: program_socket.send(cmd + prog) reply = program_socket.recv(1500) except socket.timeout: print("Socket timeout while programming block", block) success = False break else: reply = bytearray(reply) if reply[0:3] != bytearray( b"\xEF\xFE\04") or reply[3:9] != hermes_mac: print("Program failed at block", block) success = False break fp.close() for i in range(10): # throw away extra packets try: program_socket.recv(1500) except socket.timeout: break if success: dlg.Update(0, "Waiting for Hermes to start...") wait_secs = 15 # number of seconds to wait for restart cmd = bytearray(63) # Discover cmd[0] = 0xEF cmd[1] = 0xFE cmd[2] = 0x02 program_socket.settimeout(1.0) for i in range(wait_secs): dlg.Update(i * blocks // wait_secs) if i < 5: time.sleep(1.0) continue program_socket.send(cmd) try: reply = program_socket.recv(1500) except socket.timeout: pass else: reply = bytearray(reply) #print ("0x%X 0x%X %d 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X %d %d" % tuple(reply[0:11])) if reply[0] == 0xEF and reply[1] == 0xFE and reply[10] == 6: self.hermes_mac = reply[3:9] self.hermes_code_version = reply[9] st = 'Capture from Hermes device: Mac %2x:%2x:%2x:%2x:%2x:%2x, Code version %d, ID %d' % tuple( reply[3:11]) st += ', IP %s' % self.hermes_ip self.config_text = st #print (st) self.application.config_text = st self.application.main_frame.SetConfigText(st) QS.set_params(hermes_pause=0) break dlg.Destroy() self.application.Yield() else: dlg.Destroy() self.application.Yield() msg = wx.MessageDialog( main_frame, "Programming failed. Please push the Program button again.", title, wx.OK | wx.ICON_ERROR) msg.ShowModal() msg.Destroy() program_socket.close()
def pre_open(self): # This socket is used for the Metis Discover protocol self.discover_request = b"\xEF\xFE\x02" + b"\x00" * 60 self.socket_discover = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socket_discover.setblocking(0) self.socket_discover.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) found = False st = "No capture device found." port = self.conf.rx_udp_port for i in range(5): if found: break if DEBUG: print('Send discover') try: for broadcast_addr in self.broadcast_addrs: self.socket_discover.sendto(self.discover_request, (broadcast_addr, port)) if DEBUG: print('discover_request', (broadcast_addr, port)) time.sleep(0.01) except: if DEBUG > 1: traceback.print_exc() for j in range(5): try: data, addr = self.socket_discover.recvfrom(1500) except: if DEBUG > 1: traceback.print_exc() time.sleep(0.02) continue else: if DEBUG: print('recvfrom', addr, 'length', len(data), "type", type(data)) data = bytearray(data) if len(data) > 32 and data[0] == 0xEF and data[1] == 0xFE: if DEBUG: print('data', data) ver = self.conf.hermes_code_version bid = self.conf.hermes_board_id if ver >= 0 and data[9] != ver: pass elif bid >= 0 and data[10] != bid: pass else: st = 'Capture from Hermes device: Mac %2x:%2x:%2x:%2x:%2x:%2x, Code version %d, ID %d' % tuple( data[3:11]) self.hermes_mac = data[3:9] self.hermes_ip = addr[0] self.hermes_code_version = data[9] self.hermes_board_id = data[10] QS.set_hermes_id(data[9], data[10]) if data[0x16] >> 6 == 0: QS.set_params(bandscopeScale=2048) if DEBUG: print(st) adr = self.conf.rx_udp_ip found = True if adr and adr != addr[0]: # Change the IP address if DEBUG: print("Change IP address from %s to %s" % (addr[0], adr)) ip = adr.split('.') ip = list(map(int, ip)) cmd = bytearray(73) cmd[0] = 0xEF cmd[1] = 0xFE cmd[2] = 0x03 cmd[3] = data[3] cmd[4] = data[4] cmd[5] = data[5] cmd[6] = data[6] cmd[7] = data[7] cmd[8] = data[8] cmd[9] = ip[0] cmd[10] = ip[1] cmd[11] = ip[2] cmd[12] = ip[3] for broadcast_addr in self.broadcast_addrs: self.socket_discover.sendto( cmd, (broadcast_addr, port)) time.sleep(0.01) # Note: There is no response, contrary to the documentation self.hermes_ip = adr if False: try: data, addr = self.socket_discover.recvfrom( 1500) except: if DEBUG: traceback.print_exc() else: print(repr(data), addr) ##self.hermes_ip = adr time.sleep(1.0) st += ', IP %s' % self.hermes_ip break if not found and self.conf.udp_rx_ip: self.hermes_ip = self.conf.udp_rx_ip code = 62 bid = 6 self.hermes_code_version = code self.hermes_board_id = bid QS.set_hermes_id(code, bid) st = 'Capture from Hermes device at specified IP %s' % self.hermes_ip found = True if found: # Open a socket for communication with the hardware msg = QS.open_rx_udp(self.hermes_ip, port) if msg[0:8] != "Capture ": st = msg # Error self.socket_discover.close() self.config_text = st self.ChangeLNA( 2 ) # Initialize the LNA using the correct LNA code from the FPGA code version