| """ Tool for reading bram test output and outputting human readable output. | |
| """ | |
| import argparse | |
| import serial | |
| from collections import deque, namedtuple | |
| import struct | |
| import itertools | |
| import enum | |
| class RamTestState(enum.Enum): | |
| START = 1 | |
| VERIFY_INIT = 2 | |
| WRITE_ZEROS = 3 | |
| VERIFY_ZEROS = 4 | |
| WRITE_ONES = 5 | |
| VERIFY_ONES = 6 | |
| WRITE_10 = 7 | |
| VERIFY_10 = 8 | |
| WRITE_01 = 9 | |
| VERIFY_01 = 10 | |
| WRITE_RANDOM = 11 | |
| VERIFY_RANDOM = 12 | |
| RESTART_LOOP = 13 | |
| Result = namedtuple('Results', 'error_count loop_count') | |
| Error = namedtuple('Error', 'state address expected_value actual_value') | |
| RESULT_LOG = '<BBHBB' | |
| RESULT_LOG_SIZE = struct.calcsize(RESULT_LOG) | |
| ERROR_LOG = '<BBHHHBB' | |
| ERROR_LOG_SIZE = struct.calcsize(ERROR_LOG) | |
| def process_buffer(data): | |
| while data: | |
| while data: | |
| first_char = bytes((data[0], )) | |
| if first_char in [b'E', b'L']: | |
| break | |
| data.popleft() | |
| if not data: | |
| return | |
| first_char = bytes((data[0], )) | |
| if first_char == b'L' and len(data) >= RESULT_LOG_SIZE: | |
| log = bytes(itertools.islice(data, 0, RESULT_LOG_SIZE)) | |
| data.popleft() | |
| header, error_count, loop_count, cr, lf = struct.unpack( | |
| RESULT_LOG, log | |
| ) | |
| if cr == ord('\r') and lf == ord('\n'): | |
| yield Result(error_count=error_count, loop_count=loop_count) | |
| elif first_char == b'E' and len(data) >= ERROR_LOG_SIZE: | |
| log = bytes(itertools.islice(data, 0, ERROR_LOG_SIZE)) | |
| data.popleft() | |
| header, state, address, expected_value, actual_value, cr, lf = struct.unpack( | |
| ERROR_LOG, log | |
| ) | |
| if cr == ord('\r') and lf == ord('\n'): | |
| try: | |
| state = RamTestState(state) | |
| except Exception: | |
| continue | |
| yield Error( | |
| state=RamTestState(state), | |
| address=hex(address), | |
| expected_value=hex(expected_value), | |
| actual_value=hex(actual_value) | |
| ) | |
| else: | |
| return | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument('uart') | |
| parser.add_argument('--file', action='store_true') | |
| parser.add_argument('--baudrate', '-B', type=int, default=500000) | |
| args = parser.parse_args() | |
| if args.file: | |
| with open(args.uart, 'rb') as f: | |
| data = deque(f.read()) | |
| for log in process_buffer(data): | |
| print(log) | |
| else: | |
| data = deque() | |
| with serial.Serial(port=args.uart, baudrate=args.baudrate, | |
| timeout=.200, inter_byte_timeout=.200) as s: | |
| while True: | |
| buf = s.read(10 * 1024) | |
| data.extend(buf) | |
| for log in process_buffer(data): | |
| print(log) | |
| if __name__ == '__main__': | |
| main() |