Пример #1
0
    def get_next(self):
        poll_t = time()
        while True:
            status = self.read_reg("status")
            if not status:
                if (time() - poll_t) > self.poll_timeout:
                    raise ClientError("gave up polling")
                continue
            elif status & protocol.STATUS_DATA_READY_MASK:
                break
            elif status & protocol.STATUS_ERROR_MASK:
                self.write_reg("main_control", "clear_status")
                log.info("lost sweep due to server error")
            else:
                raise ClientError("got unexpected status ({})".format(status))

        buffer_size = self.fixed_buf_size or self.read_reg(
            "output_data_buffer_length")
        if buffer_size > 0:
            buffer = self.read_buf_raw(protocol.MAIN_BUFFER_ADDR, buffer_size)
        else:
            buffer = bytearray()

        info = {}
        info_regs = utils.get_sweep_info_regs(self.mode)
        for reg in info_regs:
            info[reg.name] = self.read_reg(reg)

        self.write_reg("main_control", "clear_status")

        return info, buffer
Пример #2
0
    def _connect(self):
        self._link.timeout = self.CONNECT_ROUTINE_TIMEOUT

        if self.override_baudrate:
            self._link.baudrate = self.override_baudrate
            self._link.connect()

            try:
                self._handshake()
            except links.LinkError as e:
                raise ClientError("could not connect, no response") from e
        else:
            baudrates = [product.baudrate for product in protocol.PRODUCTS]
            baudrates.append(self.DEFAULT_BASE_BAUDRATE)
            baudrates = sorted(list(set(baudrates)))

            self._link.baudrate = baudrates[0]
            self._link.connect()

            for i, baudrate in enumerate(baudrates):
                if i != 0:
                    self._link.baudrate = baudrate
                    sleep(0.2)

                try:
                    self._handshake()
                except links.LinkError:
                    log.debug("handshake failed at {} baud".format(baudrate))
                else:
                    log.debug("handshake succeeded at {} baud".format(baudrate))
                    break
            else:
                raise ClientError("could not connect, no response")

            product_id = self._read_reg("product_id")
            product = {product.id: product for product in protocol.PRODUCTS}[product_id]

            if baudrate != product.baudrate:
                log.debug("switching to {} baud...".format(product.baudrate))
                self._write_reg("uart_baudrate", product.baudrate)
                self._link.baudrate = product.baudrate
                sleep(0.2)
                self._handshake()
                log.debug("handshake succeeded at {} baud".format(product.baudrate))

        self._link.timeout = self._link.DEFAULT_TIMEOUT

        ver = self._read_reg("product_version")
        if ver < protocol.MIN_VERSION:
            log.warning("server version is not supported (too old)")
        elif ver != protocol.DEV_VERSION:
            log.warning("server version might not be fully supported")

        version_buffer = self._read_buf_raw()
        version_info = decode_version_buffer(version_buffer)

        info = {}
        info.update(version_info)

        return info
Пример #3
0
    def _write_gpio(self, pin, val):
        req = protocol.GPIOPinAndVal(pin, val)
        self._send_packet(req)

        res = self._recv_packet()
        if not isinstance(res, protocol.GPIOPinAndVal):
            raise ClientError("got unexpected packet (expected gpio pin and value)")
        if res.val != val:
            raise ClientError("gpio write failed")
Пример #4
0
    def _get_next(self):
        header, payload = self._recv_frame()

        status = header["status"]
        if status == "end":
            raise ClientError("session ended")
        elif status != "ok":
            raise ClientError("server error")

        return protocol.decode_stream_frame(header, payload, self.squeeze,
                                            self._num_subsweeps)
Пример #5
0
    def _connect(self):
        use_dual_baudrate = bool(self.conf_baudrate)
        init_baudrate = self.conf_baudrate if use_dual_baudrate else self.base_baudrate

        self._link.baudrate = init_baudrate
        self._link.connect()
        log.debug("port opened at {} baud".format(init_baudrate))
        old_timeout = self._link.timeout
        self._link.timeout = self.CONNECT_ROUTINE_TIMEOUT

        if use_dual_baudrate:
            success = False
            try:
                self._handshake()
            except ClientError:
                log.info(
                    "handshake failed at {} baud, trying {} baud...".format(
                        self.conf_baudrate, self.base_baudrate))
            else:
                success = True

            if not success:
                self._link.baudrate = self.base_baudrate

                try:
                    self._handshake()
                except links.LinkError as e:
                    raise ClientError("could not connect, no response") from e

                log.info(
                    "handshake successful, switching to {} baud...".format(
                        self.conf_baudrate))

                self._write_reg("uart_baudrate", self.conf_baudrate)
                self._link.baudrate = self.conf_baudrate
                sleep(0.2)
                self._handshake()

                log.info("successfully connected at {} baud!".format(
                    self.conf_baudrate))
        else:
            try:
                self._handshake()
            except links.LinkError as e:
                raise ClientError("could not connect, no response") from e

        ver = self._read_reg("product_version")
        if ver < protocol.MIN_VERSION:
            log.warning("server version is not supported (too old)")
        elif ver != protocol.DEV_VERSION:
            log.warning("server version might not be fully supported")

        self._link.timeout = old_timeout
Пример #6
0
    def _stop_streaming(self):
        self._write_reg("main_control", "stop", expect_response=False)

        t0 = time()
        while time() - t0 < self._link._timeout:
            res = self._recv_packet()

            if isinstance(res, protocol.UnpackedRegWriteResponse):
                break
            if not isinstance(res, protocol.UnpackedStreamData):
                raise ClientError("got unexpected packet while stopping session")
        else:
            raise ClientError("timeout while stopping session")
Пример #7
0
    def _setup_session(self, config):
        if len(config.sensor) > 1:
            raise ValueError("the register protocol does not support multiple sensors")
        if config.sensor[0] != 1:
            raise ValueError("the register protocol currently only supports using sensor 1")

        mode = protocol.get_mode(config.mode)
        self._mode = mode

        self._experimental_stitching = bool(config.experimental_stitching)
        sweep_rate = None if config.experimental_stitching else config.sweep_rate
        self.__cmd_proc("set_mode_and_rate", mode, sweep_rate)

        self._write_reg("main_control", "stop")

        self._write_reg("mode_selection", mode)

        if config.experimental_stitching:
            self._write_reg("repetition_mode", "max")
            log.warning("experimental stitching on - switching to max freq. mode")
        else:
            self._write_reg("repetition_mode", "fixed")

        self._write_reg("streaming_control", "disable")
        self._write_reg("sensor_power_mode", "d")

        if mode == "iq":
            self._write_reg("output_data_compression", 1)

        rvs = utils.get_reg_vals_for_config(config)
        for rv in rvs:
            self._write_reg_raw(rv.addr, rv.val)

        self._write_reg("main_control", "create")
        sleep(SPI_MAIN_CTRL_SLEEP)
        status = self._read_reg("status")

        if status & protocol.STATUS_ERROR_ON_SERVICE_CREATION_MASK:
            raise ClientError("session setup failed")

        info = {}
        info_regs = utils.get_session_info_regs(mode)
        for reg in info_regs:
            info[reg.name] = self._read_reg(reg)

        self._num_subsweeps = info.get("number_of_subsweeps")

        # data rate check
        data_length = info.get("data_length")
        freq = info.get("frequency")
        bpp = protocol.BYTE_PER_POINT.get(mode)
        if data_length:
            log.debug("assumed data length: {}".format(data_length))

            if bpp and freq and not config.experimental_stitching:
                data_rate = 8 * bpp * data_length * freq
                log_text = "data rate: {:.2f} Mbit/s".format(data_rate*1e-6)
                log.info(log_text)

        return info
Пример #8
0
    def _connect(self):
        self._cmd_queue = mp.Queue()
        self._data_queue = mp.Queue()
        args = (
            self._cmd_queue,
            self._data_queue,
        )
        self._proc = SPICommProcess(*args)
        self._proc.start()

        self.__cmd_proc("connect")

        log.debug("connected")

        idn_reg = self._read_reg("product_id")
        possible_ids = [product.id for product in protocol.PRODUCTS]
        if idn_reg not in possible_ids:
            raise ClientError("unexpected product id")

        ver = self._read_reg("product_version")
        if ver < protocol.MIN_VERSION:
            log.warning("server version is not supported (too old)")
        elif ver != protocol.DEV_VERSION:
            log.warning("server version might not be fully supported")

        version_buffer = self._read_main_buffer()
        version_info = utils.decode_version_buffer(version_buffer)

        info = {}
        info.update(version_info)

        return info
Пример #9
0
    def _write_reg_raw(self, addr, enc_val, expect_response=True):
        addr = protocol.get_addr_for_reg(addr)
        rrv = protocol.UnpackedRegVal(addr, enc_val)
        req = protocol.UnpackedRegWriteRequest(rrv)
        self._send_packet(req)

        log.debug("sent reg w req: addr: {:3} val: {}".format(addr, self._fmt_enc_val(enc_val)))

        if expect_response:
            res = self._recv_packet()
            if not isinstance(res, protocol.UnpackedRegWriteResponse):
                raise ClientError("got unexpected packet (expected reg write response)")
            if res.reg_val != rrv:
                raise ClientError("reg write failed")

            log.debug("recv reg w res: ok")
Пример #10
0
    def _get_next(self):
        packet = self._recv_packet(allow_recovery_skip=True)

        if not isinstance(packet, protocol.UnpackedStreamData):
            raise ClientError("got unexpected type of frame")

        info = {}
        for addr, enc_val in packet.result_info:
            try:
                reg = protocol.get_reg(addr, self._mode)
                val = protocol.decode_reg_val(reg, enc_val)
            except protocol.ProtocolError:
                log.info("got unknown reg val in result info")
                log.info("addr: {}, value: {}".format(
                    addr, utils.fmt_enc_val(enc_val)))
            else:
                info[reg.name] = val

        data = protocol.decode_output_buffer(packet.buffer, self._mode,
                                             self._num_subsweeps)

        if self.squeeze:
            return info, data
        else:
            return [info], np.expand_dims(data, 0)
Пример #11
0
    def _get_next(self):
        ret_cmd, ret_args = self._data_queue.get()
        if ret_cmd == "error":
            raise ClientError("exception raised in SPI communcation process")
        elif ret_cmd != "get_next":
            raise ClientError
        info, buffer = ret_args

        data = protocol.decode_output_buffer(buffer, self._mode,
                                             self._num_subsweeps)

        if not self._experimental_stitching:
            cur_seq_num = info.get("sequence_number")
            if cur_seq_num:
                if self._seq_num:
                    if cur_seq_num > self._seq_num + 1:
                        log.info("missed sweep")
                    if cur_seq_num <= self._seq_num:
                        log.info("got same sweep twice")
                self._seq_num = cur_seq_num

        if self.squeeze:
            return info, data
        else:
            return [info], np.expand_dims(data, 0)
Пример #12
0
    def _init_session(self):
        if self._session_cmd is None:
            raise ClientError

        self._send_cmd(self._session_cmd)
        header, _ = self._recv_frame()

        if header["status"] == "error":
            raise ClientError("server error while initializing session")
        elif header["status"] != "ok":
            raise ClientError("got unexpected header")

        log.debug("session initialized")

        self._session_ready = True
        return protocol.get_session_info_for_header(header)
Пример #13
0
    def _recv_packet(self, allow_recovery_skip=False):
        buf_1 = self._link.recv(1 + protocol.LEN_FIELD_SIZE)

        start_marker = buf_1[0]
        packet_len = int.from_bytes(buf_1[1:], protocol.BO)

        if start_marker != protocol.START_MARKER:
            raise ClientError("got invalid frame (incorrect start marker)")

        buf_2 = self._link.recv(packet_len + 2)
        packet = buf_2[:-1]
        end_marker = buf_2[-1]

        if end_marker != protocol.END_MARKER:
            if not allow_recovery_skip:
                raise ClientError("got invalid frame (incorrect end marker)")

            log.debug(
                "got invalid frame (incorrect end marker), attempting recovery"
            )

            buf_2.extend(self._link.recv(1 + protocol.LEN_FIELD_SIZE))

            si = 0
            ei = len(buf_2)
            expected_sub_len = protocol.LEN_FIELD_SIZE + packet_len + 3
            while True:
                si = buf_2.find(buf_1, si, ei)
                if si < 0:
                    raise ClientError(
                        "got invalid frame and could not recover")

                sub_len_diff = expected_sub_len - (len(buf_2) - si)

                if sub_len_diff > 0:
                    buf_2.extend(self._link.recv(sub_len_diff))

                if buf_2[-1] != protocol.END_MARKER:
                    log.debug("recovery attempt failed")
                    continue

                packet = buf_2[si + 1 + protocol.LEN_FIELD_SIZE:-1]
                break

            log.warning("successfully recovered from corrupt frame")

        return protocol.unpack_packet(packet)
Пример #14
0
    def _read_gpio(self, pin):
        req = protocol.GPIOPin(pin)
        self._send_packet(req)

        res = self._recv_packet()

        if not isinstance(res, protocol.GPIOPinAndVal):
            raise ClientError("got unexpected packet (expected gpio pin and value)")

        return res.val
Пример #15
0
    def _setup_session(self, config):
        self._config = config

        try:
            mock_class = mock_class_map[config.mode]
        except KeyError as e:
            raise ClientError("mode not supported") from e

        self._mocker = mock_class(config)

        return self._mocker.session_info
Пример #16
0
 def __cmd_proc(self, cmd, *args):
     log.debug("sending cmd to proc: {}".format(cmd))
     self._cmd_queue.put((cmd, args))
     if cmd == "stop_streaming":
         while True:
             ret_cmd, _ = self._data_queue.get()
             if ret_cmd == cmd:
                 break
             elif ret_cmd == "error":
                 raise ClientError("exception raised in SPI communcation process")
             elif ret_cmd != "get_next":
                 raise ClientError
         ret_args = None
     else:
         ret_cmd, ret_args = self._data_queue.get()
         if ret_cmd == "error":
             raise ClientError("exception raised in SPI communcation process")
         elif ret_cmd != cmd:
             raise ClientError
     return ret_args
Пример #17
0
    def start_streaming(self):
        self.write_reg("main_control", "activate")
        sleep(SPI_MAIN_CTRL_SLEEP)
        self.write_reg("main_control", "clear_status")

        if protocol.FIXED_BUF_SIZE.get(self.mode):
            self.fixed_buf_size = self.read_reg("output_data_buffer_length")
            log.info("using fixed buffer size of {}".format(self.fixed_buf_size))
            if self.fixed_buf_size == 0:
                raise ClientError("got unexpected buffer length of 0")
        else:
            self.fixed_buf_size = None
Пример #18
0
    def _init_session(self, retry=True):
        if self._session_cmd is None:
            raise ClientError

        self._send_cmd(self._session_cmd)
        header, _ = self._recv_frame()

        if header["status"] == "error":
            if retry:
                return self._init_session(retry=False)
            else:
                raise ClientError("server error while initializing session")
        elif header["status"] != "ok":
            raise ClientError("got unexpected header")

        log.debug("session initialized")

        self._session_ready = True
        info = protocol.get_session_info_for_header(header)
        self._num_subsweeps = info.get("number_of_subsweeps")
        return info
Пример #19
0
    def _read_buf_raw(self, addr=protocol.MAIN_BUFFER_ADDR):
        req = protocol.BufferReadRequest(addr)
        self._send_packet(req)

        log.debug("sent buf r req: addr: 0x{:02x}".format(addr))

        res = self._recv_packet()
        if not isinstance(res, protocol.BufferReadResponse):
            raise ClientError("got unexpected type of frame")

        log.debug("recv buf r res: addr: 0x{:02x} len: {}".format(addr, len(res.buffer)))

        return res.buffer
Пример #20
0
    def _handshake(self):
        self._write_reg("main_control", "stop", expect_response=False)

        exp_addr = protocol.get_addr_for_reg("main_control")
        exp_enc_val = protocol.encode_reg_val("main_control", "stop")
        exp_reg_val = protocol.UnpackedRegVal(exp_addr, exp_enc_val)
        exp_packet = protocol.UnpackedRegWriteResponse(exp_reg_val)
        exp_frame = protocol.insert_packet_into_frame(exp_packet)
        self._link.recv_until(exp_frame)

        idn_reg = self._read_reg("product_id")
        if idn_reg != protocol.EXPECTED_ID:
            raise ClientError("unexpected product id")
Пример #21
0
    def _connect(self):
        info = {}

        self._link.connect()

        cmd = {"cmd": "get_version"}
        self._send_cmd(cmd)

        try:
            header, _ = self._recv_frame()
        except links.LinkError as e:
            raise ClientError("no response from server") from e

        log.debug("connected and got a response")

        if header["status"] != "ok":
            raise ClientError("server error while connecting")

        msg = header["message"].lower()
        log.info("version msg: {}".format(msg))

        startstr = "server version v"
        if not msg.startswith(startstr):
            log.warning("server version unknown")
            return info

        server_version_str = msg[len(startstr):].strip()
        info.update(decode_version_str(server_version_str))

        if info["strict_version"] >= StrictVersion("1.10"):
            cmd = {"cmd": "get_board_sensor_count"}
            self._send_cmd(cmd)
            header, _ = self._recv_frame()
            msg = header["message"]
            board_sensor_count = int(msg)
            info["board_sensor_count"] = board_sensor_count

        return info
Пример #22
0
    def _run(self):
        while True:
            (cmd, cmd_args) = self.cmd_q.get()

            if hasattr(self, cmd):
                ret = getattr(self, cmd)(*cmd_args)
                self.data_q.put((cmd, ret))

                if cmd == "start_streaming":
                    self.poll()
                elif cmd == "disconnect":
                    break
            else:
                raise ClientError("unknown cmd {}".format(cmd))
Пример #23
0
    def _handshake(self):
        self._write_reg("main_control", "stop", expect_response=False)

        exp_addr = protocol.get_addr_for_reg("main_control")
        exp_enc_val = protocol.encode_reg_val("main_control", "stop")
        exp_reg_val = protocol.RegVal(exp_addr, exp_enc_val)
        exp_packet = protocol.RegWriteResponse(exp_reg_val)
        exp_frame = protocol.insert_packet_into_frame(exp_packet)
        self._link.recv_until(exp_frame)

        idn_reg = self._read_reg("product_id")
        possible_ids = [product.id for product in protocol.PRODUCTS]
        if idn_reg not in possible_ids:
            raise ClientError("unexpected product id")
Пример #24
0
def get_dict_for_config(config):
    d = {}
    for pair in KEY_AND_CONFIG_ATTR_PAIRS:
        config_val = getattr(config, pair.config_attr, None)
        if config_val is None:
            if pair.required:
                raise ClientError("{} needs to be set in config".format(
                    pair.config_attr))
        else:
            if isinstance(config_val, bool):
                d[pair.key] = int(config_val)
            else:
                d[pair.key] = config_val
    return d
Пример #25
0
    def _connect(self):
        self._link.connect()

        cmd = {"cmd": "get_version"}
        self._send_cmd(cmd)

        try:
            header, _ = self._recv_frame()
        except links.LinkError as e:
            raise ClientError("no response from server") from e

        log.debug("connected and got a response")

        if header["status"] != "ok":
            raise ClientError("server error while connecting")

        msg = header["message"].lower()
        log.debug("version msg: {}".format(msg))

        startstr = "server version v"
        if not msg.startswith(startstr):
            log.warn("server version unknown")
            return

        server_version_str = msg[len(startstr):].strip()

        try:
            server_version = StrictVersion(server_version_str)
        except ValueError:
            log.warn("server version unknown")
            return

        if server_version < MIN_VERSION:
            log.warn("server version is not supported (too old)")
        elif server_version != DEV_VERSION:
            log.warn("server version might not be fully supported")
Пример #26
0
    def _read_reg_raw(self, addr):
        addr = protocol.get_addr_for_reg(addr)
        req = protocol.UnpackedRegReadRequest(addr)
        self._send_packet(req)

        log.debug("sent reg r req: addr: {:3}".format(addr))

        res = self._recv_packet()
        if not isinstance(res, protocol.UnpackedRegReadResponse):
            raise ClientError("got unexpected type of frame")

        enc_val = res.reg_val.val

        log.debug("recv reg r res: addr: {:3} val: {}".format(addr, self._fmt_enc_val(enc_val)))

        return enc_val
Пример #27
0
    def _setup_session(self, config):
        self._config = config

        update_rate_limit = 100
        if config.experimental_stitching or config.sweep_rate > update_rate_limit:
            self._update_rate = update_rate_limit
        else:
            self._update_rate = config.sweep_rate

        try:
            mock_class = mock_class_map[config.mode]
        except KeyError as e:
            raise ClientError("mode not supported") from e

        self._mocker = mock_class(config)

        return self._mocker.session_info
Пример #28
0
    def _connect(self):
        max_baud = links.BaseSerialLink.MAX_BAUDRATE
        default_baud = links.BaseSerialLink.DEFAULT_BAUDRATE

        self._link.baudrate = max_baud
        self._link.connect()

        log.debug("connected at {} baud".format(max_baud))

        success = False
        try:
            self._handshake()
        except ClientError:
            log.info("handshake failed at {} baud, trying {} baud..."
                     .format(max_baud, default_baud))
        else:
            success = True

        if not success:
            self._link.disconnect()
            self._link.baudrate = default_baud
            self._link.connect()

            try:
                self._handshake()
            except links.LinkError as e:
                raise ClientError("could not connect, no response") from e

            log.info("handshake successful, switching to {} baud...".format(max_baud))

            self._write_reg("uart_baudrate", max_baud)
            self._link.disconnect()
            self._link.baudrate = max_baud
            self._link.connect()
            self._handshake()

            log.info("successfully connected at {} baud!".format(max_baud))

        ver = self._read_reg("product_version")
        if ver < protocol.MIN_VERSION:
            log.warn("server version is not supported (too old)")
        elif ver != protocol.DEV_VERSION:
            log.warn("server version might not be fully supported")
Пример #29
0
    def _connect(self):
        self._cmd_queue = mp.Queue()
        self._data_queue = mp.Queue()
        args = (
            self._cmd_queue,
            self._data_queue,
        )
        self._proc = SPICommProcess(*args)
        self._proc.start()

        self.__cmd_proc("connect")

        log.debug("connected")

        idn_reg = self._read_reg("product_id")
        if idn_reg != protocol.EXPECTED_ID:
            raise ClientError("unexpected product id")

        ver = self._read_reg("product_version")
        if ver < protocol.MIN_VERSION:
            log.warning("server version is not supported (too old)")
        elif ver != protocol.DEV_VERSION:
            log.warning("server version might not be fully supported")