diff --git a/artiq/coredevice/comm_serial.py b/artiq/coredevice/comm_serial.py index b26c31a6a..4652aadc2 100644 --- a/artiq/coredevice/comm_serial.py +++ b/artiq/coredevice/comm_serial.py @@ -22,6 +22,7 @@ class _H2DMsgType(Enum): REQUEST_IDENT = 1 LOAD_OBJECT = 2 RUN_KERNEL = 3 + UART_SET_BDRATE = 4 class _D2HMsgType(Enum): @@ -58,6 +59,34 @@ class Comm: def __init__(self, dev="/dev/ttyUSB1", baud=115200): self._fd = os.open(dev, os.O_RDWR | os.O_NOCTTY) self.port = os.fdopen(self._fd, "r+b", buffering=0) + self.dev = dev + real_baud = baud + baud = 115200 + self.set_baud(baud) + if real_baud != baud: + baud = real_baud + self.set_remote_baud(baud) + self.set_baud(baud) + self.current_baud = baud + + def set_remote_baud(self, baud): + clk_freq = 80000000 + _write_exactly(self.port, struct.pack( + ">lbl", 0x5a5a5a5a, _H2DMsgType.UART_SET_BDRATE.value, + int((baud/clk_freq)*2**32))) + handshake = 0 + while handshake < 4: + recv = struct.unpack( + "B", _read_exactly(self.port, 1)) + if recv[0] == 0x5a: + handshake += 1 + else: + logger.debug("SYNC ERR {:02x}\n".format(int(recv[0]))) + handshake = 0 + self.set_baud(baud) + logger.debug("Synchronized") + + def set_baud(self, baud): iflag, oflag, cflag, lflag, ispeed, ospeed, cc = \ termios.tcgetattr(self._fd) iflag = termios.IGNBRK | termios.IGNPAR @@ -72,9 +101,12 @@ class Comm: termios.tcdrain(self._fd) termios.tcflush(self._fd, termios.TCOFLUSH) termios.tcflush(self._fd, termios.TCIFLUSH) - logger.debug("connected to {} at {} baud".format(dev, baud)) + logger.debug("connected to {} at {} baud".format(self.dev, baud)) def close(self): + if self.current_baud != 115200: + self.set_remote_baud(115200) + self.set_baud(115200) self.port.close() def __enter__(self): diff --git a/soc/runtime/comm_serial.c b/soc/runtime/comm_serial.c index cbacb67a9..928f888cc 100644 --- a/soc/runtime/comm_serial.c +++ b/soc/runtime/comm_serial.c @@ -10,6 +10,7 @@ enum { MSGTYPE_REQUEST_IDENT = 1, MSGTYPE_LOAD_OBJECT, MSGTYPE_RUN_KERNEL, + MSGTYPE_UART_SETBDRATE, }; /* device to host */ @@ -161,7 +162,12 @@ void comm_serve(object_loader load_object, kernel_runner run_kernel) receive_and_load_object(load_object); else if(msgtype == MSGTYPE_RUN_KERNEL) receive_and_run_kernel(run_kernel); - else + else if(msgtype == MSGTYPE_UART_SETBDRATE) { + unsigned int ftw = receive_int(); + send_int(0x5a5a5a5a); + uart_sync(); + uart_tuning_word_write(ftw); + } else send_char(MSGTYPE_MESSAGE_UNRECOGNIZED); } }