|  | #!/usr/bin/env python3 | 
|  | import argparse | 
|  | import serial | 
|  |  | 
|  | from rom_generator import generate_rom_data | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def generate_expected_pattern(length, dump=False): | 
|  |  | 
|  | # Use the same generator as for ROM | 
|  | input_data = generate_rom_data(length) | 
|  |  | 
|  | # Simulate processing of the data | 
|  | output_data = [] | 
|  | for data_word in input_data: | 
|  |  | 
|  | # Decode input word | 
|  | v0 = data_word >> 16 | 
|  | v1 = data_word & 0x0000FFFF | 
|  |  | 
|  | # Process | 
|  | u = (v0 * v1) & 0xFFFFFFFF | 
|  |  | 
|  | # Store | 
|  | output_data.append(u) | 
|  |  | 
|  | if dump: | 
|  | print("%04X * %04X = %08X" % (v0, v1, u)) | 
|  |  | 
|  | # Join lists, convert to strings | 
|  | return [("%08X" % v, "%08X" % u) for v, u in zip(input_data, output_data)] | 
|  |  | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def main(): | 
|  |  | 
|  | # Argument parser | 
|  | parser = argparse.ArgumentParser() | 
|  | parser.add_argument( | 
|  | "--port", type=str, default="/dev/ttyUSB1", help="Serial port" | 
|  | ) | 
|  | parser.add_argument("--baud", type=int, default=9600, help="Baud rate") | 
|  | parser.add_argument("--rom-size", type=int, default=64, help="ROM size") | 
|  | parser.add_argument( | 
|  | "--verbose", type=int, default=0, help="Verbosity level" | 
|  | ) | 
|  |  | 
|  | args = parser.parse_args() | 
|  |  | 
|  | # Generate the expected pattern | 
|  | pattern = generate_expected_pattern( | 
|  | args.rom_size, True if args.verbose > 0 else False | 
|  | ) | 
|  |  | 
|  | # Open the port | 
|  | print("Opening '%s' at %d" % (args.port, args.baud)) | 
|  | with serial.Serial(args.port, baudrate=args.baud, timeout=0.5) as port: | 
|  |  | 
|  | port.reset_input_buffer() | 
|  |  | 
|  | in_sync = False | 
|  | sync_cnt = 0 | 
|  | pat_index = 0 | 
|  |  | 
|  | # Read and process data | 
|  | print("Waiting for pattern...") | 
|  | while (True): | 
|  |  | 
|  | # Read line | 
|  | line = port.readline() | 
|  | if len(line) == 0: | 
|  | continue | 
|  |  | 
|  | # Decode | 
|  | try: | 
|  | line = line.decode("ascii") | 
|  | except UnicodeDecodeError as ex: | 
|  | print("Warning:", repr(ex)) | 
|  | continue | 
|  |  | 
|  | # Strip | 
|  | line = line.strip() | 
|  |  | 
|  | # Invalid line length | 
|  | if (len(line) % 8) != 0: | 
|  | print("Warning: Got len=%d ('%s')" % (len(line), line)) | 
|  | continue | 
|  |  | 
|  | # Split the line into 32-bit words | 
|  | words = [line[8 * i:8 * i + 8] for i in range(len(line) // 8)] | 
|  | if args.verbose >= 1: | 
|  | print("".join([word + " " for word in words])) | 
|  |  | 
|  | # Process words | 
|  | for word in words: | 
|  |  | 
|  | # Not in sync | 
|  | if not in_sync: | 
|  |  | 
|  | # Got a match | 
|  | if word == pattern[pat_index][1]: | 
|  | print( | 
|  | "rx:'%s' pat:'%s' V" % | 
|  | (word, pattern[pat_index][1]) | 
|  | ) | 
|  | sync_cnt += 1 | 
|  | pat_index = (pat_index + 1) % int(len(pattern)) | 
|  |  | 
|  | # Got a mismatch | 
|  | else: | 
|  | if sync_cnt != 0: | 
|  | print( | 
|  | "rx:'%s' pat:'%s' X (!)" % | 
|  | (word, pattern[pat_index][1]) | 
|  | ) | 
|  | sync_cnt = 0 | 
|  | pat_index = 0 | 
|  |  | 
|  | # Got enough | 
|  | if sync_cnt >= 5: | 
|  | print( | 
|  | "Got %d consecutive matches. In sync." % sync_cnt | 
|  | ) | 
|  | in_sync = True | 
|  |  | 
|  | # In sync | 
|  | else: | 
|  |  | 
|  | # Got a match | 
|  | if word == pattern[pat_index][1]: | 
|  | pat_index = (pat_index + 1) % len(pattern) | 
|  | sync_cnt += 1 | 
|  | if sync_cnt % 1000 == 0: | 
|  | print('In sync, sync_cnt = {}'.format(sync_cnt)) | 
|  | # Got a mismatch | 
|  | else: | 
|  | print( | 
|  | "MISMATCH! (rx='%s', pat='%s'), Sync lost!" % | 
|  | (word, pattern[pat_index][1]) | 
|  | ) | 
|  | in_sync = False | 
|  | sync_cnt = 0 | 
|  | pat_index = 0 | 
|  |  | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  | if __name__ == "__main__": | 
|  | main() |