Beispiel #1
0
    def _wait_status(self, val, mask=None):
        val = regmap.STATUS_FLAGS(val)

        if mask is None:
            mask = val
        else:
            mask = regmap.STATUS_FLAGS(mask)

        start_time = time()

        while time() - start_time < self._STATUS_TIMEOUT:
            status = self._read_reg(regmap.STATUS_REG)

            status_error = status & regmap.STATUS_MASKS.ERROR_MASK

            if status_error:
                if status_error & regmap.STATUS_FLAGS.ERROR_CREATION:
                    raise SessionSetupError
                else:
                    raise ClientError("server error: " + str(status_error).split(".")[1])

            if (status & mask) == val:
                return

        raise ClientError("timeout while waiting for status")
    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))

        self._send_cmd({"cmd": "get_board_sensor_count"})
        header, _ = self._recv_frame()
        info["board_sensor_count"] = int(header["message"])

        return info
Beispiel #3
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 = [int(3e6), int(1e6)]
            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_max_baudrate = self._read_reg("product_max_uart_baudrate")

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

        self._link.timeout = self._link.DEFAULT_TIMEOUT

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

        info = {}
        info.update(version_info)

        return info
    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")

        info = self._decode_stream_header(header)
        data = self._decode_stream_payload(payload)
        return info, data
Beispiel #5
0
    def _setup_session(self, config):
        self._config = config

        update_rate_limit = 100

        if config.mode == Mode.SPARSE:
            if config.sweep_rate is not None:
                sparse_frame_rate_limit = config.sweep_rate / config.sweeps_per_frame
                update_rate_limit = min(update_rate_limit,
                                        sparse_frame_rate_limit)

        if config.update_rate is None:
            self._update_rate = update_rate_limit
            self._missed = False
        else:
            self._update_rate = min(config.update_rate, update_rate_limit)
            self._missed = config.update_rate > self._update_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)
        info = self._mocker.session_info
        info["stitch_count"] = 0
        return info
Beispiel #6
0
    def _get_next(self):
        packet = self._recv_packet(allow_recovery_skip=True)

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

        info = {}
        for addr, enc_val in packet.result_info:
            try:
                reg = regmap.get_reg(addr, self._mode)
                val = reg.decode(enc_val)
            except (protocol.ProtocolError, ValueError):
                log.info("got unknown reg val in result info")
                log.info("addr: {}, value: {}".format(addr, fmt_enc_val(enc_val)))
            else:
                k = reg.stripped_name
                k = regmap.STRIPPED_NAME_TO_INFO_REMAP.get(k, k)

                if k is None:
                    continue

                info[k] = val

        sweeps_per_frame = getattr(self._config, "sweeps_per_frame", None)
        data = protocol.decode_output_buffer(packet.buffer, self._mode, sweeps_per_frame)

        if self.squeeze:
            return info, data
        else:
            return [info], np.expand_dims(data, 0)
Beispiel #7
0
    def _stop_session(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.RegWriteResponse):
                break
            if not isinstance(res, protocol.StreamData):
                raise ClientError("got unexpected packet while stopping session")
        else:
            raise ClientError("timeout while stopping session")

        mask = regmap.STATUS_FLAGS.CREATED | regmap.STATUS_FLAGS.ACTIVATED
        self._wait_status(0, mask=mask)
Beispiel #8
0
    def _write_reg_raw(self, addr, enc_val, expect_response=True):
        addr = regmap.get_reg_addr(addr)
        rrv = protocol.RegVal(addr, enc_val)
        req = protocol.RegWriteRequest(rrv)
        self._send_packet(req)

        log.debug("sent reg w req: addr: 0x{:02x} val: {}".format(addr, fmt_enc_val(enc_val)))

        if expect_response:
            res = self._recv_packet()
            if not isinstance(res, protocol.RegWriteResponse):
                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")
Beispiel #9
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)
    def _get_next(self):
        if self._measure_on_call:
            self._write_reg("main_control", "clear_status")

        poll_t = time()

        while True:
            status = self._read_reg("status")

            if status & regmap.STATUS_MASKS.ERROR_MASK:
                raise ClientError("server error: " + str(status).split(".")[1])
            elif status & regmap.STATUS_FLAGS.DATA_READY:
                break
            else:
                if (time() - poll_t) > self._poll_timeout:
                    raise ClientError("gave up polling")

                continue

        buffer = self._read_buf_raw()

        info = {}
        info_regs = regmap.get_data_info_regs(self._config.mode)
        for reg in info_regs:
            k = reg.stripped_name
            k = regmap.STRIPPED_NAME_TO_INFO_REMAP.get(k, k)

            if k is None:
                continue

            info[k] = self._read_reg(reg)

        if not self._measure_on_call:
            self._write_reg("main_control", "clear_status")

        sweeps_per_frame = getattr(self._config, "sweeps_per_frame", None)
        data = protocol.decode_output_buffer(buffer, self._mode,
                                             sweeps_per_frame)

        if self.squeeze:
            return info, data
        else:
            return [info], np.expand_dims(data, 0)
Beispiel #11
0
 def __cmd_proc(self, cmd, *args):
     log.debug("sending cmd to proc: {}".format(cmd))
     self._cmd_queue.put((cmd, args))
     if cmd == "stop_session":
         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
Beispiel #12
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
Beispiel #13
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_session":
                    self.poll()
                elif cmd == "disconnect":
                    break
            else:
                raise ClientError("unknown cmd {}".format(cmd))
Beispiel #14
0
    def get_next(self):
        poll_t = time()

        while True:
            status = self.read_reg("status", do_log=False)

            if status & regmap.STATUS_MASKS.ERROR_MASK:
                raise ClientError("server error: " + str(status).split(".")[1])
            elif status & regmap.STATUS_FLAGS.DATA_READY:
                break
            else:
                if (time() - poll_t) > self.poll_timeout:
                    raise ClientError("gave up polling")

                continue

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

        info = {}
        info_regs = regmap.get_data_info_regs(self.mode)
        for reg in info_regs:
            k = reg.stripped_name
            k = regmap.STRIPPED_NAME_TO_INFO_REMAP.get(k, k)

            if k is None:
                continue

            info[k] = self.read_reg(reg, do_log=False)

        self.write_reg("main_control", "clear_status", do_log=False)

        return info, buffer
Beispiel #15
0
    def _setup_session(self, config):
        expected_sensors = [i + 1 for i in range(len(self.clients))]

        if config.sensor != expected_sensors:
            raise ClientError(
                "Invalid sensor selection for multi client wrapper")

        config.sensor = 1

        for client in self.clients:
            info = client.setup_session(config)

        config.sensor = expected_sensors

        return info
Beispiel #16
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

        sweeps_per_frame = getattr(self._config, "sweeps_per_frame", None)
        data = protocol.decode_output_buffer(buffer, self._mode, sweeps_per_frame)

        if self.squeeze:
            return info, data
        else:
            return [info], np.expand_dims(data, 0)
Beispiel #17
0
    def _read_reg_raw(self, addr):
        addr = regmap.get_reg_addr(addr)
        req = protocol.RegReadRequest(addr)
        self._send_packet(req)

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

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

        enc_val = res.reg_val.val

        log.debug("recv reg r res: addr: 0x{:02x} val: {}".format(addr, fmt_enc_val(enc_val)))

        return enc_val
    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 SessionSetupError
        elif header["status"] != "ok":
            raise ClientError("got unexpected header")

        log.debug("session initialized")

        self._session_ready = True
        info = get_session_info_for_header(header)
        return info