def capture_segment(handle, xs_buf, xs_size, capture_buf): messages = Lepton.ROWS iow = _IOW(SPI_IOC_MAGIC, 0, xs_size) ioctl(handle, iow, xs_buf, True) while (capture_buf[0] & 0x000f) == 0x000f: # byteswapped 0x0f00 ioctl(handle, iow, xs_buf, True) messages -= 1 # NB: the default spidev bufsiz is 4096 bytes so that's where the 24 message limit comes from: 4096 / Lepton.VOSPI_FRAME_SIZE_BYTES = 24.97... # This 24 message limit works OK, but if you really need to optimize the read speed here, this hack is for you: # The limit can be changed when spidev is loaded, but since it is compiled statically into newer raspbian kernels, that means # modifying the kernel boot args to pass this option. This works too: # $ sudo chmod 666 /sys/module/spidev/parameters/bufsiz # $ echo 65536 > /sys/module/spidev/parameters/bufsiz # Then Lepton.SPIDEV_MESSAGE_LIMIT of 24 can be raised to 59 while messages > 0: if messages > Lepton.SPIDEV_MESSAGE_LIMIT: count = Lepton.SPIDEV_MESSAGE_LIMIT else: count = messages iow = _IOW(SPI_IOC_MAGIC, 0, xs_size * count) ret = ioctl(handle, iow, xs_buf[xs_size * (60 - messages):], True) if ret < 1: raise IOError("can't send {0} spi messages ({1})".format( 60, ret)) messages -= count
def capture_segment(handle, xs_buf, xs_size, capture_buf): messages = Lepton.ROWS iow = _IOW(SPI_IOC_MAGIC, 0, xs_size) ioctl(handle, iow, xs_buf, True) while (capture_buf[0] & 0x000f) == 0x000f: # byteswapped 0x0f00 ioctl(handle, iow, xs_buf, True) messages -= 1 # NB: the default spidev bufsiz is 4096 bytes so that's where the 24 message limit comes from: 4096 / Lepton.VOSPI_FRAME_SIZE_BYTES = 24.97... # This 24 message limit works OK, but if you really need to optimize the read speed here, this hack is for you: # The limit can be changed when spidev is loaded, but since it is compiled statically into newer raspbian kernels, that means # modifying the kernel boot args to pass this option. This works too: # $ sudo chmod 666 /sys/module/spidev/parameters/bufsiz # $ echo 65536 > /sys/module/spidev/parameters/bufsiz # Then Lepton.SPIDEV_MESSAGE_LIMIT of 24 can be raised to 59 while messages > 0: if messages > Lepton.SPIDEV_MESSAGE_LIMIT: count = Lepton.SPIDEV_MESSAGE_LIMIT else: count = messages iow = _IOW(SPI_IOC_MAGIC, 0, xs_size * count) ret = ioctl(handle, iow, xs_buf[xs_size * (60 - messages):], True) if ret < 1: raise IOError("can't send {0} spi messages ({1})".format(60, ret)) messages -= count
def __init__(self, spi_dev="/dev/spidev0.1"): self.__spi_dev = spi_dev self.__txbuf = np.zeros(Lepton.VOSPI_FRAME_SIZE, dtype=np.uint16) # struct spi_ioc_transfer { # __u64 tx_buf; # __u64 rx_buf; # __u32 len; # __u32 speed_hz; # __u16 delay_usecs; # __u8 bits_per_word; # __u8 cs_change; # __u32 pad; # }; self.__xmit_struct = struct.Struct("=QQIIHBBI") self.__msg_size = self.__xmit_struct.size self.__xmit_buf = np.zeros((self.__msg_size * Lepton.ROWS), dtype=np.uint8) self.__msg = _IOW(SPI_IOC_MAGIC, 0, self.__xmit_struct.format) self.__capture_buf = np.zeros( (Lepton.ROWS, Lepton.VOSPI_FRAME_SIZE, 1), dtype=np.uint16) for i in range(Lepton.ROWS): self.__xmit_struct.pack_into( self.__xmit_buf, i * self.__msg_size, self.__txbuf.ctypes.data, # __u64 tx_buf; self.__capture_buf.ctypes.data + Lepton.VOSPI_FRAME_SIZE_BYTES * i, # __u64 rx_buf; Lepton.VOSPI_FRAME_SIZE_BYTES, # __u32 len; Lepton.SPEED, # __u32 speed_hz; 0, # __u16 delay_usecs; Lepton.BITS, # __u8 bits_per_word; 1, # __u8 cs_change; 0) # __u32 pad;
def __init__(self, spi_dev = "/dev/spidev0.0"): self.__spi_dev = spi_dev self.__txbuf = np.zeros(Lepton.VOSPI_FRAME_SIZE, dtype=np.uint16) # struct spi_ioc_transfer { # __u64 tx_buf; # __u64 rx_buf; # __u32 len; # __u32 speed_hz; # __u16 delay_usecs; # __u8 bits_per_word; # __u8 cs_change; # __u32 pad; # }; self.__xmit_struct = struct.Struct("=QQIIHBBI") self.__msg_size = self.__xmit_struct.size self.__xmit_buf = np.zeros((self.__msg_size * Lepton.ROWS), dtype=np.uint8) self.__msg = _IOW(SPI_IOC_MAGIC, 0, self.__xmit_struct.format) self.__capture_buf = np.zeros((Lepton.ROWS, Lepton.VOSPI_FRAME_SIZE, 1), dtype=np.uint16) for i in range(Lepton.ROWS): self.__xmit_struct.pack_into(self.__xmit_buf, i * self.__msg_size, self.__txbuf.ctypes.data, # __u64 tx_buf; self.__capture_buf.ctypes.data + Lepton.VOSPI_FRAME_SIZE_BYTES * i, # __u64 rx_buf; Lepton.VOSPI_FRAME_SIZE_BYTES, # __u32 len; Lepton.SPEED, # __u32 speed_hz; 0, # __u16 delay_usecs; Lepton.BITS, # __u8 bits_per_word; 1, # __u8 cs_change; 0) # __u32 pad;
def __init__(self, spi_dev="/dev/spidev0.0"): self.__spi_dev = spi_dev self.__txbuf = np.zeros(Lepton.VOSPI_FRAME_SIZE, dtype=np.uint16) # struct spi_ioc_transfer { # __u64 tx_buf; # __u64 rx_buf; # __u32 len; # __u32 speed_hz; # __u16 delay_usecs; # __u8 bits_per_word; # __u8 cs_change; # __u8 tx_nbits; # __u8 rx_nbits; # __u16 pad; # }; self.__xmit_struct = struct.Struct("=QQIIHBBBBH") self.__xmit_buf = ctypes.create_string_buffer(self.__xmit_struct.size) self.__msg = _IOW(SPI_IOC_MAGIC, 0, self.__xmit_struct.format) self.__capture_buf = np.zeros((60, 82, 1), dtype=np.uint16)
def __init__(self, spi_dev = "/dev/spidev0.0"): self.__spi_dev = spi_dev self.__txbuf = np.zeros(Lepton.VOSPI_FRAME_SIZE, dtype=np.uint16) # struct spi_ioc_transfer { # __u64 tx_buf; # __u64 rx_buf; # __u32 len; # __u32 speed_hz; # __u16 delay_usecs; # __u8 bits_per_word; # __u8 cs_change; # __u8 tx_nbits; # __u8 rx_nbits; # __u16 pad; # }; self.__xmit_struct = struct.Struct("=QQIIHBBBBH") self.__xmit_buf = ctypes.create_string_buffer(self.__xmit_struct.size) self.__msg = _IOW(SPI_IOC_MAGIC, 0, self.__xmit_struct.format) self.__capture_buf = np.zeros((60, 82, 1), dtype=np.uint16)
#!/usr/bin/env python import numpy as np import ctypes import struct import time from ioctl_numbers import _IOR, _IOW from fcntl import ioctl SPI_IOC_MAGIC = ord("k") SPI_IOC_RD_MODE = _IOR(SPI_IOC_MAGIC, 1, "=B") SPI_IOC_WR_MODE = _IOW(SPI_IOC_MAGIC, 1, "=B") SPI_IOC_RD_LSB_FIRST = _IOR(SPI_IOC_MAGIC, 2, "=B") SPI_IOC_WR_LSB_FIRST = _IOW(SPI_IOC_MAGIC, 2, "=B") SPI_IOC_RD_BITS_PER_WORD = _IOR(SPI_IOC_MAGIC, 3, "=B") SPI_IOC_WR_BITS_PER_WORD = _IOW(SPI_IOC_MAGIC, 3, "=B") SPI_IOC_RD_MAX_SPEED_HZ = _IOR(SPI_IOC_MAGIC, 4, "=I") SPI_IOC_WR_MAX_SPEED_HZ = _IOW(SPI_IOC_MAGIC, 4, "=I") SPI_CPHA = 0x01 # /* clock phase */ SPI_CPOL = 0x02 # /* clock polarity */ SPI_MODE_0 = (0 | 0) # /* (original MicroWire) */ SPI_MODE_1 = (0 | SPI_CPHA) SPI_MODE_2 = (SPI_CPOL | 0) SPI_MODE_3 = (SPI_CPOL | SPI_CPHA)
#!/usr/bin/env python import numpy as np import ctypes import struct import time from ioctl_numbers import _IOR, _IOW from fcntl import ioctl SPI_IOC_MAGIC = ord("k") SPI_IOC_RD_MODE = _IOR(SPI_IOC_MAGIC, 1, "=B") SPI_IOC_WR_MODE = _IOW(SPI_IOC_MAGIC, 1, "=B") SPI_IOC_RD_LSB_FIRST = _IOR(SPI_IOC_MAGIC, 2, "=B") SPI_IOC_WR_LSB_FIRST = _IOW(SPI_IOC_MAGIC, 2, "=B") SPI_IOC_RD_BITS_PER_WORD = _IOR(SPI_IOC_MAGIC, 3, "=B") SPI_IOC_WR_BITS_PER_WORD = _IOW(SPI_IOC_MAGIC, 3, "=B") SPI_IOC_RD_MAX_SPEED_HZ = _IOR(SPI_IOC_MAGIC, 4, "=I") SPI_IOC_WR_MAX_SPEED_HZ = _IOW(SPI_IOC_MAGIC, 4, "=I") SPI_CPHA = 0x01 # /* clock phase */ SPI_CPOL = 0x02 # /* clock polarity */ SPI_MODE_0 = (0|0) # /* (original MicroWire) */ SPI_MODE_1 = (0|SPI_CPHA) SPI_MODE_2 = (SPI_CPOL|0) SPI_MODE_3 = (SPI_CPOL|SPI_CPHA)
def SPI_IOC_MESSAGE(size): return _IOW(SPI_IOC_MAGIC, 0, "=" + ("QQIIHBBI" * size))