Exemplo n.º 1
0
        def _update(self):
            with self._mutex:
                done = False
                while not done:
                    done = True

                    # get amount of data available
                    numToRead = hal.readSPIAutoReceivedData(
                        self._port, self._buf, 0, 0)

                    # only get whole responses
                    numToRead -= numToRead % self._xferSize
                    if numToRead > self._xferSize * self.kAccumulateDepth:
                        numToRead = self._xferSize * self.kAccumulateDepth
                        done = False

                    if numToRead == 0:
                        return  # no samples

                    # read buffered data
                    hal.readSPIAutoReceivedData(self._port, self._buf,
                                                numToRead, 0)

                    # loop over all responses
                    off = 0
                    while True:
                        if off > numToRead:
                            break

                        # convert from bytes
                        resp = self._struct.unpack_from(self._buf, off)[0]

                        # process response
                        if (resp & self._validMask) == self._validValue:

                            # valid sensor data extract data field
                            data = resp >> self._dataShift
                            data &= self._dataMax - 1

                            # 2s complement conversion if signed MSB is set
                            if (self._isSigned
                                    and (data & self._dataMsbMask) != 0):
                                data -= self._dataMax

                            # center offset
                            data -= self._center

                            # only accumulate if outside deadband
                            if (data < -self._deadband
                                    or data > self._deadband):
                                self._value += data

                            self._count += 1
                            self._lastValue = data
                        else:
                            # no data from the sensor just clear the last value
                            self._lastValue = 0

                        off += self._xferSize
Exemplo n.º 2
0
    def readAutoReceivedData(self, buffer: bytes, numToRead: int,
                             timeout: float) -> Tuple[int, bytes]:
        """Read data that has been transferred by the automatic SPI transfer engine.

        Transfers may be made a byte at a time, so it's necessary for the caller
        to handle cases where an entire transfer has not been completed.

        Each received data sequence consists of a timestamp followed by the
        received data bytes, one byte per word (in the least significant byte).
        The length of each received data sequence is the same as the combined
        size of the data and zeroSize set in setAutoTransmitData().

        Blocks until numToRead words have been read or timeout expires.
        May be called with numToRead=0 to retrieve how many words are available.

        :param buffer:    A ctypes c_uint32 buffer to read the data into
        :param numToRead: number of words to read
        :param timeout:   timeout in seconds (ms resolution)
        
        :returns: Number of words remaining to be read
        """
        if len(buffer) < numToRead:
            raise ValueError("buffer is too small, must be at least %s" %
                             numToRead)
        return hal.readSPIAutoReceivedData(self.port, buffer, numToRead,
                                           timeout)
Exemplo n.º 3
0
    def readAutoReceivedData(
        self, buffer: bytes, numToRead: int, timeout: float
    ) -> Tuple[int, bytes]:
        """Read data that has been transferred by the automatic SPI transfer engine.

        Transfers may be made a byte at a time, so it's necessary for the caller
        to handle cases where an entire transfer has not been completed.

        Each received data sequence consists of a timestamp followed by the
        received data bytes, one byte per word (in the least significant byte).
        The length of each received data sequence is the same as the combined
        size of the data and zeroSize set in setAutoTransmitData().

        Blocks until numToRead words have been read or timeout expires.
        May be called with numToRead=0 to retrieve how many words are available.

        :param buffer:    A ctypes c_uint32 buffer to read the data into
        :param numToRead: number of words to read
        :param timeout:   timeout in seconds (ms resolution)
        
        :returns: Number of words remaining to be read
        """
        if len(buffer) < numToRead:
            raise ValueError("buffer is too small, must be at least %s" % numToRead)
        return hal.readSPIAutoReceivedData(self.port, buffer, numToRead, timeout)
Exemplo n.º 4
0
    def readAutoReceivedData(self, buffer, numToRead: int, timeout: float) -> (int, bytes):
        """Read data that has been transferred by the automatic SPI transfer engine.

        Transfers may be made a byte at a time, so it's necessary for the caller
        to handle cases where an entire transfer has not been completed.

        Blocks until numToRead bytes have been read or timeout expires.
        May be called with numToRead=0 to retrieve how many bytes are available.

        :param buffer: A ctypes c_uint8 buffer to read the data into
        :param numToRead: number of bytes to read
        :param timeout: timeout in seconds (ms resolution)
        :returns: Number of bytes remaining to be read
        """
        if len(buffer) < numToRead:
            raise ValueError("buffer is too small, must be at least %s" % numToRead)
        return hal.readSPIAutoReceivedData(self.port, buffer, numToRead, timeout)
Exemplo n.º 5
0
        def _update(self) -> None:
            with self._mutex:
                done = False
                while not done:
                    done = True

                    # get amount of data available
                    numToRead = hal.readSPIAutoReceivedData(
                        self._port, self._buf, 0, 0)

                    # only get whole responses
                    numToRead -= numToRead % self._xferSize
                    if numToRead > self._xferSize * self.kAccumulateDepth:
                        numToRead = self._xferSize * self.kAccumulateDepth
                        done = False

                    if numToRead == 0:
                        return  # no samples

                    # read buffered data
                    hal.readSPIAutoReceivedData(self._port, self._buf,
                                                numToRead, 0)

                    # loop over all responses
                    for off in range(0, numToRead, self._xferSize):
                        # get timestamp from first word
                        timestamp = self._buf[off] & 0xFFFFFFFF

                        # convert from bytes
                        resp = 0
                        if self._bigEndian:
                            for i in range(1, self._xferSize):
                                resp <<= 8
                                resp |= self._buf[off + i] & 0xFF
                        else:
                            for i in range(self._xferSize - 1, 0):
                                resp <<= 8
                                resp |= self._buf[off + i] & 0xFF

                        # process response
                        if (resp & self._validMask) == self._validValue:

                            # valid sensor data extract data field
                            data = resp >> self._dataShift
                            data &= self._dataMax - 1

                            # 2s complement conversion if signed MSB is set
                            if self._isSigned and (data
                                                   & self._dataMsbMask) != 0:
                                data -= self._dataMax

                            # center offset
                            dataNoCenter = data
                            data -= self._center

                            # only accumulate if outside deadband
                            if data < -self._deadband or data > self._deadband:
                                self._value += data
                                if self._count != 0:
                                    # timestamps use the 1us FPGA clock; also handle rollover
                                    if timestamp >= self._lastTimestamp:
                                        self._integratedValue = (
                                            dataNoCenter *
                                            (timestamp - self._lastTimestamp) *
                                            1e-6 - self._integratedCenter)
                                    else:
                                        self._integratedValue += (
                                            dataNoCenter *
                                            ((1 << 32) - self._lastTimestamp +
                                             timestamp) * 1e-6 -
                                            self._integratedCenter)

                            self._count += 1
                            self._lastValue = data
                        else:
                            # no data from the sensor just clear the last value
                            self._lastValue = 0

                        self._lastTimestamp = timestamp
Exemplo n.º 6
0
        def _update(self) -> None:
            with self._mutex:
                done = False
                while not done:
                    done = True

                    # get amount of data available
                    numToRead = hal.readSPIAutoReceivedData(self._port, self._buf, 0, 0)

                    # only get whole responses
                    numToRead -= numToRead % self._xferSize
                    if numToRead > self._xferSize * self.kAccumulateDepth:
                        numToRead = self._xferSize * self.kAccumulateDepth
                        done = False

                    if numToRead == 0:
                        return  # no samples

                    # read buffered data
                    hal.readSPIAutoReceivedData(self._port, self._buf, numToRead, 0)

                    # loop over all responses
                    for off in range(0, numToRead, self._xferSize):
                        # get timestamp from first word
                        timestamp = self._buf[off] & 0xFFFFFFFF

                        # convert from bytes
                        resp = 0
                        if self._bigEndian:
                            for i in range(1, self._xferSize):
                                resp <<= 8
                                resp |= self._buf[off + i] & 0xFF
                        else:
                            for i in range(self._xferSize - 1, 0):
                                resp <<= 8
                                resp |= self._buf[off + i] & 0xFF

                        # process response
                        if (resp & self._validMask) == self._validValue:

                            # valid sensor data extract data field
                            data = resp >> self._dataShift
                            data &= self._dataMax - 1

                            # 2s complement conversion if signed MSB is set
                            if self._isSigned and (data & self._dataMsbMask) != 0:
                                data -= self._dataMax

                            # center offset
                            dataNoCenter = data
                            data -= self._center

                            # only accumulate if outside deadband
                            if data < -self._deadband or data > self._deadband:
                                self._value += data
                                if self._count != 0:
                                    # timestamps use the 1us FPGA clock; also handle rollover
                                    if timestamp >= self._lastTimestamp:
                                        self._integratedValue = (
                                            dataNoCenter
                                            * (timestamp - self._lastTimestamp)
                                            * 1e-6
                                            - self._integratedCenter
                                        )
                                    else:
                                        self._integratedValue += (
                                            dataNoCenter
                                            * (
                                                (1 << 32)
                                                - self._lastTimestamp
                                                + timestamp
                                            )
                                            * 1e-6
                                            - self._integratedCenter
                                        )

                            self._count += 1
                            self._lastValue = data
                        else:
                            # no data from the sensor just clear the last value
                            self._lastValue = 0

                        self._lastTimestamp = timestamp