def __init__(self, *args, **kwargs): super().__init__(args, kwargs) self._uart = None self._pps_pin = None if kwargs is not None: if 'gps_uart' in kwargs: self._uart = kwargs['gps_uart'] if 'pps_pin' in kwargs: self._pps_pin = kwargs['pps_pin'] if (self._uart == None): raise ValueError("need a uart for the gps") if (self._pps_pin == None): raise ValueError("need a pin that gps sends 1pps to us on") # we also need the RTC device self._rtc = RTC() self._pps_event = Event() self._rtc_ssr = uctypes.struct(_RTC_BASE + _RTC_SSR_OFFSET, self._rtc_ssr_struct, uctypes.NATIVE) self._rtc_dr = uctypes.struct(_RTC_BASE + _RTC_DR_OFFSET, self._rtc_dr_struct, uctypes.NATIVE) self._pps_rtc = 0 self._pps_discard = 0 self._ss_offset = -10000 self._refclk = (0, 0, 0, 0, 0, 0)
def __init__(self, i2c, addr=95, fixed=False): self.i2c = i2c self.addr = addr self.fixed = fixed if (self.i2c.readfrom_mem(addr, HTS_WHO_AM_I, 1) != b'\xbc'): raise OSError("No HTS221 device on address {} found".format(addr)) self.cal_buf = bytearray(16) self.calib = uctypes.struct(uctypes.addressof(self.cal_buf), { 'h0_rh':(uctypes.UINT8 | 0), 'h1_rh':(uctypes.UINT8 | 1), 't0_deg':(uctypes.UINT8 | 2), 't1_deg':(uctypes.UINT8 | 3), 'res':(uctypes.UINT8 | 4), 't1t0msb':(uctypes.UINT8 | 5), 'h0_out':(uctypes.INT16 | 6), 'res1':(uctypes.INT16 | 8), 'h1_out':(uctypes.INT16 | 10), 't0_out':(uctypes.INT16 | 12), 't1_out':(uctypes.INT16 | 14)}) self.val_buf = bytearray(5) self.raw_val = uctypes.struct(uctypes.addressof(self.val_buf), { 'status':(uctypes.UINT8 | 0), 'h_out':(uctypes.INT16 | 1), 't_out':(uctypes.INT16 | 3)}) # enable sensor, one-shot i2c.writeto_mem(addr, 0x20, b'\x84') i2c.readfrom_mem_into(95, 0x30|0x80, self.cal_buf) # add 2 bits from reg 0x35 -> 10bit unsigned values) self.t0_deg = (self.calib.t0_deg | ((self.calib.t1t0msb & 0x3) << 8)) self.t1_deg = (self.calib.t1_deg | ((self.calib.t1t0msb & 0xc) << 6)) # multiply with large base to keep it accurate for fixed point division self.t_slope = (1000 * (self.t1_deg - self.t0_deg)) // (self.calib.t1_out - self.calib.t0_out) self.h_slope = (10000 * (self.calib.h1_rh - self.calib.h0_rh)) // (self.calib.h1_out - self.calib.h0_out)
def __init__(self, path): self._fbdev = open(path, 'w+') self._fix_info_data = bytearray(sizeof(_fb_fix_screeninfo)) fd = self._fbdev.fileno() ioctl(fd, _FBIOGET_FSCREENINFO, self._fix_info_data, mut=True) self._fix_info = struct(addressof(self._fix_info_data), _fb_fix_screeninfo) self._var_info_data = bytearray(sizeof(_fb_var_screeninfo)) ioctl(fd, _FBIOGET_VSCREENINFO, self._var_info_data, mut=True) self._var_info = struct(addressof(self._var_info_data), _fb_var_screeninfo) self._fb_data = {}
def __init__(self): self._fbdev = open('/dev/fb0', 'w+') self._fix_info_data = bytearray(uctypes.sizeof(fb_fix_screeninfo)) fd = self._fbdev.fileno() ioctl(fd, FBIOGET_FSCREENINFO, self._fix_info_data, mut=True) self._fix_info = uctypes.struct(uctypes.addressof(self._fix_info_data), fb_fix_screeninfo) self._var_info_data = bytearray(uctypes.sizeof(fb_var_screeninfo)) ioctl(fd, FBIOGET_VSCREENINFO, self._var_info_data, mut=True) self._var_info = uctypes.struct(uctypes.addressof(self._var_info_data), fb_var_screeninfo) self._fb_data = {}
def read_i2c_block_data(self, address, command, length): """Performs a read of arbitrary size Args: address (7-bit): The I2C address command (8-bit): The I2C register length: The number of bytes to read (max 32) Returns: A list of ``length`` values that were read Raises: OSError: There was an I/O error RuntimeError: The I2C adapter does not support this function """ if not self._func['smbus_read_i2c_block']: raise RuntimeError('Function is not supported by the hardware') b = bytearray(_size_of_i2c_smbus_data) data = struct(addressof(b), _i2c_smbus_data) length = min(length, 32) data.block[0] = length if length == 32: size = _I2C_SMBUS_I2C_BLOCK_BROKEN else: size = _I2C_SMBUS_I2C_BLOCK_DATA self._access(address, _I2C_SMBUS_READ, command, size, data) return data.block[1:][:data.block[0]]
def write_i2c_block_data(self, command, values): b = bytearray(_size_of_i2c_smbus_data) data = uctypes.struct(uctypes.addressof(b), _i2c_smbus_data) values = values[:32] data.block = [len(values)] + values self._access(_I2C_SMBUS_WRITE, command, _I2C_SMBUS_I2C_BLOCK_BROKEN, data)
def __init__(self, addr, size): self._head = uctypes.struct(addr, POOL_DEF) if self._head.magic != POOL_MAGIC: print("create new pool, addr={:x}, size={}".format(addr, size)) self._head.magic = POOL_MAGIC self._head.top = addr + size self._head.addr = addr + uctypes.sizeof(POOL_DEF)
def codeobj2rawcode(codeobj): buf = bytearray(uctypes.sizeof(mp_raw_code_t_layout)) rc = uctypes.struct(uctypes.addressof(buf), mp_raw_code_t_layout) rc.kind = 2 # MP_CODE_BYTECODE rc.fun_data = uctypes.addressof(codeobj.get_code()) rc.const_table = uctypes.addressof(codeobj.get_const_table()) return rc
def make_ins(layout): """ transform textual instruction layout description into a ready-to-use uctypes struct """ struct_def = make_ins_struct_def(layout) instruction = bytearray(4) return struct(addressof(instruction), struct_def, LITTLE_ENDIAN)
def __init__(self, mem_desc, struct): """ Attach to an existing queue or create a new one at the location defined by the pool parameter. Parameters ---------- addr Address of an memory area. size Size of the memory area at addr struct Definition of an uctype structure. This describes the messages we will manage in the queue. magic Optional. """ hdr_size = uctypes.sizeof(FIFO_HEADER) elem_size = uctypes.sizeof(struct) hdr = uctypes.struct(mem_desc.addr, FIFO_HEADER) entries = (mem_desc.size - hdr_size) // elem_size if hdr.magic != FIFO_MAGIC or hdr.elem_size != elem_size or hdr.elements != entries: print("MemFifo: init queue") hdr.rd_i = 0 hdr.wr_i = 0 hdr.elem_size = elem_size hdr.elements = entries hdr.magic = FIFO_MAGIC hdr.full = False self._hdr = hdr self._data_addr = mem_desc.addr + uctypes.sizeof(self._hdr) self._struct = struct
def _access(self, read_write, command, size, data): b = bytearray(_size_of_i2c_smbus_ioctl_data) args = uctypes.struct(uctypes.addressof(b), _i2c_smbus_ioctl_data) args.read_write = read_write args.command = command args.size = size args.data = uctypes.addressof(data) ioctl(self._fd, _I2C_SMBUS, args, mut=True)
def block_process_call(self, command, values): b = bytearray(_size_of_i2c_smbus_data) data = uctypes.struct(uctypes.addressof(b), _i2c_smbus_data) values = values[:32] data.block = [len(values)] + values self._access(_I2C_SMBUS_WRITE, command, _I2C_SMBUS_BLOCK_PROC_CALL, data) return data.block[1:][:data.block[0]]
def open(self, bus): """Open the device node Parameters: bus (int): The index of the I2C adapter This only needs to be called if ``bus`` was not supplied in the constructor. """ self._devnode = open('/dev/i2c-{}'.format(bus), 'w+') self._fd = self._devnode.fileno() flags = bytearray(4) ioctl(self._fd, _I2C_FUNCS, flags, mut=True) flags = struct( addressof(flags), { 'flags': UINT32 # unsigned long }).flags self._func = { 'i2c': bool(flags & _I2C_FUNC_I2C), 'ten_bit_addr': bool(flags & _I2C_FUNC_10BIT_ADDR), 'protocol_mangling': bool(flags & _I2C_FUNC_PROTOCOL_MANGLING), 'smbus_pec': bool(flags & _I2C_FUNC_SMBUS_PEC), 'no_start': bool(flags & _I2C_FUNC_NOSTART), 'slave': bool(flags & _I2C_FUNC_SLAVE), 'smbus_block_proc_call': bool(flags & _I2C_FUNC_SMBUS_BLOCK_PROC_CALL), 'smbus_quick': bool(flags & _I2C_FUNC_SMBUS_QUICK), 'smbus_read_byte': bool(flags & _I2C_FUNC_SMBUS_READ_BYTE), 'smbus_write_byte': bool(flags & _I2C_FUNC_SMBUS_WRITE_BYTE), 'smbus_read_byte_data': bool(flags & _I2C_FUNC_SMBUS_READ_BYTE_DATA), 'smbus_write_byte_data': bool(flags & _I2C_FUNC_SMBUS_WRITE_BYTE_DATA), 'smbus_read_word_data': bool(flags & _I2C_FUNC_SMBUS_READ_WORD_DATA), 'smbus_write_word_data': bool(flags & _I2C_FUNC_SMBUS_WRITE_WORD_DATA), 'smbus_proc_call': bool(flags & _I2C_FUNC_SMBUS_PROC_CALL), 'smbus_read_block_data': bool(flags & _I2C_FUNC_SMBUS_READ_BLOCK_DATA), 'smbus_write_block_data': bool(flags & _I2C_FUNC_SMBUS_WRITE_BLOCK_DATA), 'smbus_read_i2c_block': bool(flags & _I2C_FUNC_SMBUS_READ_I2C_BLOCK), 'smbus_write_i2c_block': bool(flags & _I2C_FUNC_SMBUS_WRITE_I2C_BLOCK), }
def __init__(self): self._beep_dev = open(_BEEP_DEV, 'b+') self._mixer = Mixer() self._pcm = PCM() self._tone_data = bytearray(sizeof(_input_event)) self._tone_event = struct(addressof(self._tone_data), _input_event) self._timeout = Timeout(0, None) self._cancel = None self._lock = _thread.allocate_lock()
def __init__(self): dict.__init__(self) env = uctypes.struct(_environ_ptr.get(), _ENV_STRUCT) for i in range(4096): if int(env.arr[i]) == 0: break s = uctypes.bytes_at(env.arr[i]).decode() k, v = s.split("=", 1) dict.__setitem__(self, k, v)
def get_bluetooth_rfcomm_socket(address, channel): addr_data = bytearray(sizeof(sockaddr_rc)) addr = struct(addressof(addr_data), sockaddr_rc) addr.rc_family = AF_BLUETOOTH str2ba(address, addr.rc_bdaddr) addr.rc_channel = channel sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) sock.connect(addr_data) return sock
def read_i2c_block_data(self, command, length): b = bytearray(_size_of_i2c_smbus_data) data = uctypes.struct(uctypes.addressof(b), _i2c_smbus_data) length = min(length, 32) data.block[0] = length if length == 32: size = _I2C_SMBUS_I2C_BLOCK_BROKEN else: size = _I2C_SMBUS_I2C_BLOCK_DATA self._access(_I2C_SMBUS_READ, command, size, data) return data.block[1:][:data.block[0]]
def _accept(self): client, addr_data = self._sock.accept() try: addr = struct(addressof(addr_data), _sockaddr_rc) debug_print('client', _ba2str(addr.rc_bdaddr)) while True: data = client.recv(1) debug_print(data) # TODO: need a lms2012 bytecode interpreter finally: client.close()
def __init__(self): self._data = dict() env = uctypes.struct(_environ_ptr.get(), _ENV_STRUCT) for i in range(4096): if int(env.arr[i]) == 0: break # requires micropython change f20a730 s = uctypes.bytestring_at(int(env.arr[i])).decode() k, v = s.split("=", 1) self._data[k] = v self.__getitem__ = self._data.__getitem__
def __init__(self): self._sock = socket(_AF_BLUETOOTH, SOCK_STREAM, _BTPROTO_RFCOMM) addr_data = bytearray(sizeof(_sockaddr_rc)) addr = struct(addressof(addr_data), _sockaddr_rc) addr.rc_family = _AF_BLUETOOTH _str2ba(_BDADDR_ANY, addr.rc_bdaddr) addr.rc_channel = 1 self._sock.bind(addr_data)
def _access(self, address, read_write, command, size, data): if self._force: ioctl(self._fd, _I2C_SLAVE_FORCE, address) else: ioctl(self._fd, _I2C_SLAVE, address) b = bytearray(_size_of_i2c_smbus_ioctl_data) args = struct(addressof(b), _i2c_smbus_ioctl_data) args.read_write = read_write args.command = command args.size = size args.data = addressof(data) ioctl(self._fd, _I2C_SMBUS, args, mut=True)
def handle_request(self): addr_data = bytearray(sizeof(sockaddr_rc)) addr = struct(addressof(addr_data), sockaddr_rc) addr.rc_family = AF_BLUETOOTH str2ba(self.client_address[0], addr.rc_bdaddr) addr.rc_channel = self.client_address[1] self.socket.connect(addr_data) try: self.process_request(self.socket, self.client_address) except: self.socket.close() raise
def __init__(self, name): # TODO: Need a way to convert name to MAC address (maybe) self._sock = socket(_AF_BLUETOOTH, SOCK_STREAM, _BTPROTO_RFCOMM) addr_data = bytearray(sizeof(_sockaddr_rc)) addr = struct(addressof(addr_data), _sockaddr_rc) addr.rc_family = _AF_BLUETOOTH _str2ba(name, addr.rc_bdaddr) addr.rc_channel = 1 self._sock.connect(addr_data)
def __init__(self, path): info_data = bytearray(sizeof(_SF_INFO)) info = struct(addressof(info_data), _SF_INFO) self._file = _sf_open(path, _SMF_READ, info_data) if not self._file: raise SoundFileError(_sf_strerror(0)) self._frames = info.frames self._samplerate = info.samplerate self._channels = info.channels self._format = info.format self._sections = info.sections self._seekable = bool(info.seekable)
def send_recv(self, data, recv=None): """Shift out `data` and return shifted in data. Args: data (bytes, bytearray, list): a byte array or list of 8-bit integers to shift out. Returns: bytes, bytearray, list: data shifted in. Raises: OSError: if an I/O or OS error occurs. TypeError: if `data` type is invalid. ValueError: if data is not valid bytes. """ if not isinstance(data, (bytes, bytearray, list)): raise TypeError( "Invalid data type, should be bytes, bytearray, or list.") # Create mutable array try: buf = array.array('B', data) except OverflowError: raise ValueError("Invalid data bytes.") buf_addr = ctypes.addressof(buf) buf_in = bytearray(len(buf)) buf_in_addr = ctypes.addressof(buf_in) # Prepare transfer structure spi_xfer = ctypes.struct(ctypes.addressof(SPI.xfer_data), SPI.desc, ctypes.LITTLE_ENDIAN) spi_xfer.tx_buf = buf_addr spi_xfer.rx_buf = buf_in_addr spi_xfer.len = len(buf) # Transfer try: fcntl.ioctl(self._fd, SPI._SPI_IOC_MESSAGE_1, spi_xfer, True) except OSError as e: raise OSError("SPI transfer: error") if recv is not None: recv = bytearray(buf_in) else: # Return shifted out data with the same type as shifted in data if isinstance(data, bytes): return bytes(bytearray(buf_in)) elif isinstance(data, bytearray): return bytearray(buf_in) elif isinstance(data, list): return buf_in.tolist()
def handle_request(self): try: request, addr_data = self.socket.accept() except OSError: return try: addr = struct(addressof(addr_data), sockaddr_rc) client_address = (ba2str(addr.rc_bdaddr), addr.rc_channel) self.process_request(request, client_address) except: request.close() raise
def __getattr__(self, name): if name == "ogf": return self._ogf elif name == "ogf_name": return self._ogf_name elif name == "ocf": return self._ocf elif name == "ocf_name": return self._ocf_name elif name == "opcode": return self._opcode elif name == "evtcode": return self._evtcode elif name == "request_struct": if self._request_struct is None: return None return uctypes.struct( uctypes.addressof(self.request_data), self._request_struct.get(self._module, self._request_struct), uctypes.LITTLE_ENDIAN ) elif name == "response_struct": if self._response_struct is None: return None return uctypes.struct( uctypes.addressof(self.response_data), self._response_struct.get(self._module, self._response_struct), uctypes.LITTLE_ENDIAN ) elif name == "request_length": return len(self._request_data) elif name == "request_data": return self._request_data elif name == "response_length": return len(self._response_data) elif name == "response_data": return self._response_data else: raise AttributeError(name)
def from_buffer(data): """ Parse HCI SCO data References can be found here: * https://www.bluetooth.org/en-us/specification/adopted-specifications ** Core specification 4.1 ** [vol 2] Part E (Section 5) - HCI Data Formats ** [vol 2] Part E (Section 5.4) - Exchange of HCI-specific information """ hci_sco = uctypes.struct(uctypes.addressof(data[:HCI_SCO.struct_size]), HCI_SCO_STRUCT, uctypes.LITTLE_ENDIAN) data = data[HCI_SCO.struct_size:] return HCI_SCO(hci_sco.handle, hci_sco.ps, hci_sco.xx, data)
def _dequeue(self): """ Removes the first message from the queue and returns either the data as uctype struct or None when the queue is empty. The returned value references memory directly in the queue slot, so it might change when enqueue() is called! """ hdr = self._hdr if (not hdr.full) and (hdr.rd_i == hdr.wr_i): return None addr = self._data_addr + hdr.elem_size * hdr.rd_i hdr.rd_i = self._incr_wrap(hdr.rd_i) hdr.full = False return uctypes.struct(addr, self._struct)
def __init__(self, i2c, addr=92, fixed=False): self.i2c = i2c self.addr = addr self.fixed = fixed if (self.i2c.readfrom_mem(addr, WHO_AM_I, 1) != b'\xbd'): raise OSError("No LPS25 device on address {} found".format(addr)) self.val_buf = bytearray(5) self.raw_val = uctypes.struct(uctypes.addressof(self.val_buf), { 'p_low':(uctypes.UINT8 | 0), 'p_out':(uctypes.UINT16 | 1), 't_out':(uctypes.INT16 | 3)}) i2c.writeto_mem(addr, 0x20, b'\x00') i2c.writeto_mem(addr, 0x20, b'\x84')
def next(self): if self.subf: self.subf.skip() buf = self.f.read(512) if not buf: return None h = uctypes.struct(uctypes.addressof(buf), TAR_HEADER, uctypes.LITTLE_ENDIAN) # Empty block means end of archive if h.name[0] == 0: return None d = TarInfo() d.name = str(h.name, "utf-8").rstrip() d.size = int(bytes(h.size).rstrip(), 8) d.type = [REGTYPE, DIRTYPE][d.name[-1] == "/"] self.subf = d.subf = FileSection(self.f, d.size, roundup(d.size, 512)) return d
import uctypes ACCEL_CONFIG = { 'x_self_test' : uctypes.BFUINT8 | 0 | 7 << uctypes.BF_POS | 1 << uctypes.BF_LEN, 'y_self_test' : uctypes.BFUINT8 | 0 | 6 << uctypes.BF_POS | 1 << uctypes.BF_LEN, 'z_self_test' : uctypes.BFUINT8 | 0 | 5 << uctypes.BF_POS | 1 << uctypes.BF_LEN, 'range' : uctypes.BFUINT8 | 0 | 3 << uctypes.BF_POS | 2 << uctypes.BF_LEN, } buf = bytearray(1) buf[0] = 0xa8 print('buf[0] =', hex(buf[0])) accel_config = uctypes.struct(ACCEL_CONFIG, uctypes.addressof(buf)) print('x_self_test =', accel_config.x_self_test) print('y_self_test =', accel_config.y_self_test) print('z_self_test =', accel_config.z_self_test) print('range =', accel_config.range) accel_config.y_self_test = 1 print('buf[0] =', hex(buf[0]))
import sys import uctypes if sys.byteorder != "little": print("SKIP") sys.exit() desc = { "ptr": (uctypes.PTR | 0, uctypes.UINT8), "ptr16": (uctypes.PTR | 0, uctypes.UINT16), "ptr2": (uctypes.PTR | 0, {"b": uctypes.UINT8 | 0}), } bytes = b"01" addr = uctypes.addressof(bytes) buf = addr.to_bytes(uctypes.sizeof(desc), "little") S = uctypes.struct(uctypes.addressof(buf), desc, uctypes.LITTLE_ENDIAN) print(S.ptr[0]) assert S.ptr[0] == ord("0") print(S.ptr[1]) assert S.ptr[1] == ord("1") print(hex(S.ptr16[0])) assert hex(S.ptr16[0]) == "0x3130" print(S.ptr2[0].b, S.ptr2[1].b) print(S.ptr2[0].b, S.ptr2[1].b) print(hex(S.ptr16[0])) assert (S.ptr2[0].b, S.ptr2[1].b) == (48, 49)
# test printing of uctypes objects try: import uctypes except ImportError: import sys print("SKIP") sys.exit() # we use an address of "0" because we just want to print something deterministic # and don't actually need to set/get any values in the struct desc = {"arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 1)} S = uctypes.struct(0, desc) print(S) desc2 = [(uctypes.ARRAY | 0, uctypes.UINT8 | 1)] S2 = uctypes.struct(0, desc2) print(S2) desc3 = ((uctypes.ARRAY | 0, uctypes.UINT8 | 1)) S3 = uctypes.struct(0, desc3) print(S3) desc4 = ((uctypes.PTR | 0, uctypes.UINT8 | 1)) S4 = uctypes.struct(0, desc4) print(S4)
try: import uctypes except ImportError: print("SKIP") raise SystemExit desc = { "f1": 0 | uctypes.UINT32, "f2": 4 | uctypes.UINT8, } # uctypes.NATIVE is default print(uctypes.sizeof(desc) == uctypes.sizeof(desc, uctypes.NATIVE)) # Here we assume that that we run on a platform with convential ABI # (which rounds up structure size based on max alignment). For platforms # where that doesn't hold, this tests should be just disabled in the runner. print(uctypes.sizeof(desc, uctypes.NATIVE) > uctypes.sizeof(desc, uctypes.LITTLE_ENDIAN)) # When taking sizeof of instantiated structure, layout type param # is prohibited (because structure already has its layout type). s = uctypes.struct(0, desc, uctypes.LITTLE_ENDIAN) try: uctypes.sizeof(s, uctypes.LITTLE_ENDIAN) except TypeError: print("TypeError")
def new(sdesc): buf = bytearray(uctypes.sizeof(sdesc)) s = uctypes.struct(uctypes.addressof(buf), sdesc, uctypes.NATIVE) return s
"arr2": (uctypes.ARRAY | 0, 2, {"b": uctypes.UINT8 | 0}), "bitf0": uctypes.BFUINT16 | 0 | 0 << uctypes.BF_POS | 8 << uctypes.BF_LEN, "bitf1": uctypes.BFUINT16 | 0 | 8 << uctypes.BF_POS | 8 << uctypes.BF_LEN, "bf0": uctypes.BFUINT16 | 0 | 0 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "bf1": uctypes.BFUINT16 | 0 | 4 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "bf2": uctypes.BFUINT16 | 0 | 8 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "bf3": uctypes.BFUINT16 | 0 | 12 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "ptr": (uctypes.PTR | 0, uctypes.UINT8), "ptr2": (uctypes.PTR | 0, {"b": uctypes.UINT8 | 0}), } data = bytearray(b"01") S = uctypes.struct(uctypes.addressof(data), desc, uctypes.LITTLE_ENDIAN) #print(S) print(hex(S.s0)) assert hex(S.s0) == "0x3130" #print(S.sub.b0) print(S.sub.b0, S.sub.b1) assert S.sub.b0, S.sub.b1 == (0x30, 0x31) try: S[0] assert False, "Can't index struct" except TypeError: print("TypeError") print("arr:", S.arr[0], S.arr[1])
assert uctypes.sizeof(S4) == 12 S5 = { "a": uctypes.UINT8 | 0, "b": uctypes.UINT32 | 4, "c": uctypes.UINT8 | 8, "d": uctypes.UINT32 | 0, "sub": (4, { "b0": uctypes.UINT8 | 0, "b1": uctypes.UINT8 | 1, }), } assert uctypes.sizeof(S5) == 12 s5 = uctypes.struct(0, S5) assert uctypes.sizeof(s5) == 12 assert uctypes.sizeof(s5.sub) == 2 S6 = { "ptr": (uctypes.PTR | 0, uctypes.UINT8), } # As if there're no other arch bitnesses assert uctypes.sizeof(S6) in (4, 8) S7 = { "arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 5), } assert uctypes.sizeof(S7) == 5 S8 = {
import uctypes if sys.byteorder != "little": print("SKIP") sys.exit() desc = { "ptr": (uctypes.PTR | 0, uctypes.UINT8), "ptr16": (uctypes.PTR | 0, uctypes.UINT16), "ptr2": (uctypes.PTR | 0, {"b": uctypes.UINT8 | 0}), } bytes = b"01" addr = uctypes.addressof(bytes) buf = addr.to_bytes(uctypes.sizeof(desc)) S = uctypes.struct(uctypes.addressof(buf), desc, uctypes.NATIVE) print(S.ptr[0]) assert S.ptr[0] == ord("0") print(S.ptr[1]) assert S.ptr[1] == ord("1") print(hex(S.ptr16[0])) assert hex(S.ptr16[0]) == "0x3130" print(S.ptr2[0].b, S.ptr2[1].b) print (S.ptr2[0].b, S.ptr2[1].b) print(hex(S.ptr16[0])) assert (S.ptr2[0].b, S.ptr2[1].b) == (48, 49)
# This test checks previously known problem values for 32-bit ports. # It's less useful for 64-bit ports. try: import uctypes except ImportError: import sys print("SKIP") sys.exit() buf = b"12345678abcd" struct = uctypes.struct( uctypes.addressof(buf), {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4}, uctypes.LITTLE_ENDIAN ) struct.f32 = 0x7fffffff print(buf) struct.f32 = 0x80000000 print(buf) struct.f32 = 0xff010203 print(buf) struct.f64 = 0x80000000 print(buf) struct.f64 = 0x80000000 * 2 print(buf)
# aligned "arr5": (uctypes.ARRAY | 0, uctypes.UINT32 | 1), "arr7": (uctypes.ARRAY | 0, 1, {"l": uctypes.UINT32 | 0}), "arr8": (uctypes.ARRAY | 0, uctypes.INT8 | 1), "arr9": (uctypes.ARRAY | 0, uctypes.INT16 | 1), "arr10": (uctypes.ARRAY | 0, uctypes.INT32 | 1), "arr11": (uctypes.ARRAY | 0, uctypes.INT64 | 1), "arr12": (uctypes.ARRAY | 0, uctypes.UINT64| 1), "arr13": (uctypes.ARRAY | 1, 1, {"l": {}}), } data = bytearray(8) S = uctypes.struct(uctypes.addressof(data), desc) # assign byte S.arr[0] = 0x11 print(hex(S.arr[0])) assert hex(S.arr[0]) == "0x11" # assign word S.arr3[0] = 0x2233 print(hex(S.arr3[0])) assert hex(S.arr3[0]) == "0x2233" # assign word, with index S.arr3[1] = 0x4455 print(hex(S.arr3[1])) assert hex(S.arr3[1]) == "0x4455"
S3 = {"a": uctypes.UINT8 | 0, "b": uctypes.UINT8 | 1} assert uctypes.sizeof(S3) == 2 S4 = {"a": uctypes.UINT8 | 0, "b": uctypes.UINT32 | 4, "c": uctypes.UINT8 | 8} assert uctypes.sizeof(S4) == 12 S5 = { "a": uctypes.UINT8 | 0, "b": uctypes.UINT32 | 4, "c": uctypes.UINT8 | 8, "d": uctypes.UINT32 | 0, "sub": (4, {"b0": uctypes.UINT8 | 0, "b1": uctypes.UINT8 | 1}), } assert uctypes.sizeof(S5) == 12 s5 = uctypes.struct(S5, 0) assert uctypes.sizeof(s5) == 12 assert uctypes.sizeof(s5.sub) == 2 S6 = {"ptr": (uctypes.PTR | 0, uctypes.UINT8)} # As if there're no other arch bitnesses assert uctypes.sizeof(S6) in (4, 8) S7 = {"arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 5)} assert uctypes.sizeof(S7) == 5 S8 = {"arr": (uctypes.ARRAY | 0, 3, {"a": uctypes.UINT32 | 0, "b": uctypes.UINT8 | 4})} assert uctypes.sizeof(S8) == 24
def __init__(self, dev_port, show=Bus.SHOW_NONE): desc = { "model": uctypes.UINT16 | 0, "version": uctypes.UINT8 | 2, "dev_id": uctypes.UINT8 | 3, "baud_rate": uctypes.UINT8 | 4, "rdt": uctypes.UINT8 | 5, "num_adcs": uctypes.UINT8 | cfg.NUM_ADCS_OFFSET, "num_gpios": uctypes.UINT8 | cfg.NUM_GPIOS_OFFSET, "adc_pin": ( uctypes.ARRAY | cfg.ADC_PIN, cfg.NUM_ADCS, { "port": uctypes.BFUINT8 | 0 | 4 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "pin": uctypes.BFUINT8 | 0 | 0 << uctypes.BF_POS | 4 << uctypes.BF_LEN, }, ), "gpio_pin": ( uctypes.ARRAY | cfg.GPIO_PIN, cfg.NUM_GPIOS, { "port": uctypes.BFUINT8 | 0 | 4 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "pin": uctypes.BFUINT8 | 0 | 0 << uctypes.BF_POS | 4 << uctypes.BF_LEN, }, ), "gpio_cfg": ( uctypes.ARRAY | cfg.GPIO_CFG, cfg.NUM_GPIOS, { "dir": uctypes.BFUINT8 | 0 | 0 << uctypes.BF_POS | 1 << uctypes.BF_LEN, "pu": uctypes.BFUINT8 | 0 | 1 << uctypes.BF_POS | 1 << uctypes.BF_LEN, "pd": uctypes.BFUINT8 | 0 | 2 << uctypes.BF_POS | 1 << uctypes.BF_LEN, "od": uctypes.BFUINT8 | 0 | 3 << uctypes.BF_POS | 1 << uctypes.BF_LEN, }, ), # End of persistent values "adc_value": (uctypes.ARRAY | cfg.ADC_VALUE, uctypes.UINT16 | cfg.NUM_ADCS), "gpio_set": uctypes.UINT32 | cfg.GPIO_SET, "gpio_clear": uctypes.UINT32 | cfg.GPIO_CLEAR, "gpio_odr": uctypes.UINT32 | cfg.GPIO_ODR, "gpio_idr": uctypes.UINT32 | cfg.GPIO_IDR, } initial_bytes = bytearray(cfg.NUM_CTL_BYTES) init = uctypes.struct(uctypes.addressof(initial_bytes), desc, uctypes.LITTLE_ENDIAN) init.model = 123 init.version = 1 init.dev_id = Device.INITIAL_DEV_ID init.baud_rate = Device.INITIAL_BAUD init.rdt = Device.INITIAL_RDT for idx in range(cfg.NUM_GPIOS): init.gpio_cfg[idx].dir = 1 ctl_bytes = bytearray(cfg.NUM_CTL_BYTES) self.ctl = uctypes.struct(uctypes.addressof(ctl_bytes), desc, uctypes.LITTLE_ENDIAN) notifications = ( (cfg.ADC_PIN, cfg.NUM_ADCS, self.adc_pin_updated), (cfg.GPIO_PIN, cfg.NUM_GPIOS, self.gpio_pin_updated), (cfg.GPIO_CFG, cfg.NUM_GPIOS, self.gpio_cfg_updated), (cfg.GPIO_SET, 4, self.gpio_set_updated), (cfg.GPIO_CLEAR, 4, self.gpio_clear_updated), (cfg.GPIO_ODR, 4, self.gpio_odr_updated), ) self.adc = [None] * cfg.NUM_ADCS self.gpio = [None] * cfg.NUM_GPIOS super().__init__(dev_port, cfg.PERSISTENT_BYTES, initial_bytes, ctl_bytes, notifications, show)
import uctypes desc = { # arr is array at offset 0, of UINT8 elements, array size is 2 "arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 2), # arr2 is array at offset 0, size 2, of structures defined recursively "arr2": (uctypes.ARRAY | 0, 2, {"b": uctypes.UINT8 | 0}), "arr3": (uctypes.ARRAY | 2, uctypes.UINT16 | 2), } data = bytearray(b"01234567") S = uctypes.struct(desc, uctypes.addressof(data), uctypes.LITTLE_ENDIAN) print(uctypes.sizeof(S.arr)) assert uctypes.sizeof(S.arr) == 2 print(uctypes.sizeof(S.arr2)) assert uctypes.sizeof(S.arr2) == 2 print(uctypes.sizeof(S.arr3)) try: print(uctypes.sizeof(S.arr3[0])) except TypeError: print("TypeError")
import uctypes desc = { "f32": uctypes.FLOAT32 | 0, "f64": uctypes.FLOAT64 | 0, } data = bytearray(8) S = uctypes.struct(uctypes.addressof(data), desc, uctypes.NATIVE) S.f32 = 12.34 print('%.4f' % S.f32) S.f64 = 12.34 print('%.4f' % S.f64)
# test general errors with uctypes try: import uctypes except ImportError: print("SKIP") raise SystemExit data = bytearray(b"01234567") # del subscr not supported S = uctypes.struct(uctypes.addressof(data), {}) try: del S[0] except TypeError: print('TypeError') # list is an invalid descriptor S = uctypes.struct(uctypes.addressof(data), []) try: S.x except TypeError: print('TypeError') # can't access attribute with invalid descriptor S = uctypes.struct(uctypes.addressof(data), {'x':[]}) try: S.x except TypeError: print('TypeError')