1#!/usr/bin/env python 2# 3# Copyright (C) 2014 Analog Devices, Inc. 4# Author: Paul Cercueil <paul.cercueil@analog.com> 5# 6# This library is free software; you can redistribute it and/or 7# modify it under the terms of the GNU Lesser General Public 8# License as published by the Free Software Foundation; either 9# version 2.1 of the License, or (at your option) any later version. 10# 11# This library is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14# Lesser General Public License for more details. 15 16from ctypes import Structure, c_char_p, c_uint, c_int, c_size_t, \ 17 c_ssize_t, c_char, c_void_p, c_bool, create_string_buffer, \ 18 POINTER as _POINTER, CDLL as _cdll, memmove as _memmove, byref as _byref 19from os import strerror as _strerror 20from platform import system as _system 21import weakref 22 23if 'Windows' in _system(): 24 from ctypes import get_last_error 25else: 26 from ctypes import get_errno 27 28def _checkNull(result, func, arguments): 29 if result: 30 return result 31 else: 32 err = get_last_error() if 'Windows' in _system() else get_errno() 33 raise OSError(err, _strerror(err)) 34 35def _checkNegative(result, func, arguments): 36 if result >= 0: 37 return result 38 else: 39 raise OSError(-result, _strerror(-result)) 40 41class _ScanContext(Structure): 42 pass 43class _ContextInfo(Structure): 44 pass 45class _Context(Structure): 46 pass 47class _Device(Structure): 48 pass 49class _Channel(Structure): 50 pass 51class _Buffer(Structure): 52 pass 53 54_ScanContextPtr = _POINTER(_ScanContext) 55_ContextInfoPtr = _POINTER(_ContextInfo) 56_ContextPtr = _POINTER(_Context) 57_DevicePtr = _POINTER(_Device) 58_ChannelPtr = _POINTER(_Channel) 59_BufferPtr = _POINTER(_Buffer) 60 61_lib = _cdll('libiio.dll' if 'Windows' in _system() else 'libiio.so.0', 62 use_errno = True, use_last_error = True) 63 64_get_backends_count = _lib.iio_get_backends_count 65_get_backends_count.restype = c_uint 66 67_get_backend = _lib.iio_get_backend 68_get_backend.argtypes = (c_uint, ) 69_get_backend.restype = c_char_p 70_get_backend.errcheck = _checkNull 71 72_create_scan_context = _lib.iio_create_scan_context 73_create_scan_context.argtypes = (c_char_p, c_uint) 74_create_scan_context.restype = _ScanContextPtr 75_create_scan_context.errcheck = _checkNull 76 77_destroy_scan_context = _lib.iio_scan_context_destroy 78_destroy_scan_context.argtypes = (_ScanContextPtr, ) 79 80_get_context_info_list = _lib.iio_scan_context_get_info_list 81_get_context_info_list.argtypes = (_ScanContextPtr, _POINTER(_POINTER(_ContextInfoPtr))) 82_get_context_info_list.restype = c_ssize_t 83_get_context_info_list.errcheck = _checkNegative 84 85_context_info_list_free = _lib.iio_context_info_list_free 86_context_info_list_free.argtypes = (_POINTER(_ContextInfoPtr), ) 87 88_context_info_get_description = _lib.iio_context_info_get_description 89_context_info_get_description.argtypes = (_ContextInfoPtr, ) 90_context_info_get_description.restype = c_char_p 91 92_context_info_get_uri = _lib.iio_context_info_get_uri 93_context_info_get_uri.argtypes = (_ContextInfoPtr, ) 94_context_info_get_uri.restype = c_char_p 95 96_new_local = _lib.iio_create_local_context 97_new_local.restype = _ContextPtr 98_new_local.errcheck = _checkNull 99 100_new_xml = _lib.iio_create_xml_context 101_new_xml.restype = _ContextPtr 102_new_xml.argtypes = (c_char_p, ) 103_new_xml.errcheck = _checkNull 104 105_new_network = _lib.iio_create_network_context 106_new_network.restype = _ContextPtr 107_new_network.argtypes = (c_char_p, ) 108_new_network.errcheck = _checkNull 109 110_new_default = _lib.iio_create_default_context 111_new_default.restype = _ContextPtr 112_new_default.errcheck = _checkNull 113 114_new_uri = _lib.iio_create_context_from_uri 115_new_uri.restype = _ContextPtr 116_new_uri.errcheck = _checkNull 117 118_destroy = _lib.iio_context_destroy 119_destroy.argtypes = (_ContextPtr, ) 120 121_get_name = _lib.iio_context_get_name 122_get_name.restype = c_char_p 123_get_name.argtypes = (_ContextPtr, ) 124_get_name.errcheck = _checkNull 125 126_get_description = _lib.iio_context_get_description 127_get_description.restype = c_char_p 128_get_description.argtypes = (_ContextPtr, ) 129 130_get_xml = _lib.iio_context_get_xml 131_get_xml.restype = c_char_p 132_get_xml.argtypes = (_ContextPtr, ) 133 134_get_library_version = _lib.iio_library_get_version 135_get_library_version.argtypes = (_POINTER(c_uint), _POINTER(c_uint), c_char_p, ) 136 137_get_version = _lib.iio_context_get_version 138_get_version.restype = c_int 139_get_version.argtypes = (_ContextPtr, _POINTER(c_uint), _POINTER(c_uint), c_char_p, ) 140_get_version.errcheck = _checkNegative 141 142_get_attrs_count = _lib.iio_context_get_attrs_count 143_get_attrs_count.restype = c_uint 144_get_attrs_count.argtypes = (_ContextPtr, ) 145 146_get_attr = _lib.iio_context_get_attr 147_get_attr.restype = c_int 148_get_attr.argtypes = (_ContextPtr, c_uint, _POINTER(c_char_p), _POINTER(c_char_p)) 149_get_attr.errcheck = _checkNegative 150 151_devices_count = _lib.iio_context_get_devices_count 152_devices_count.restype = c_uint 153_devices_count.argtypes = (_ContextPtr, ) 154 155_get_device = _lib.iio_context_get_device 156_get_device.restype = _DevicePtr 157_get_device.argtypes = (_ContextPtr, c_uint) 158_get_device.errcheck = _checkNull 159 160_set_timeout = _lib.iio_context_set_timeout 161_set_timeout.restype = c_int 162_set_timeout.argtypes = (_ContextPtr, c_uint, ) 163_set_timeout.errcheck = _checkNegative 164 165_clone = _lib.iio_context_clone 166_clone.restype = _ContextPtr 167_clone.argtypes = (_ContextPtr, ) 168_clone.errcheck = _checkNull 169 170_d_get_id = _lib.iio_device_get_id 171_d_get_id.restype = c_char_p 172_d_get_id.argtypes = (_DevicePtr, ) 173_d_get_id.errcheck = _checkNull 174 175_d_get_name = _lib.iio_device_get_name 176_d_get_name.restype = c_char_p 177_d_get_name.argtypes = (_DevicePtr, ) 178 179_d_attr_count = _lib.iio_device_get_attrs_count 180_d_attr_count.restype = c_uint 181_d_attr_count.argtypes = (_DevicePtr, ) 182 183_d_get_attr = _lib.iio_device_get_attr 184_d_get_attr.restype = c_char_p 185_d_get_attr.argtypes = (_DevicePtr, ) 186_d_get_attr.errcheck = _checkNull 187 188_d_read_attr = _lib.iio_device_attr_read 189_d_read_attr.restype = c_ssize_t 190_d_read_attr.argtypes = (_DevicePtr, c_char_p, c_char_p, c_size_t) 191_d_read_attr.errcheck = _checkNegative 192 193_d_write_attr = _lib.iio_device_attr_write 194_d_write_attr.restype = c_ssize_t 195_d_write_attr.argtypes = (_DevicePtr, c_char_p, c_char_p) 196_d_write_attr.errcheck = _checkNegative 197 198_d_debug_attr_count = _lib.iio_device_get_debug_attrs_count 199_d_debug_attr_count.restype = c_uint 200_d_debug_attr_count.argtypes = (_DevicePtr, ) 201 202_d_get_debug_attr = _lib.iio_device_get_debug_attr 203_d_get_debug_attr.restype = c_char_p 204_d_get_debug_attr.argtypes = (_DevicePtr, ) 205_d_get_debug_attr.errcheck = _checkNull 206 207_d_read_debug_attr = _lib.iio_device_debug_attr_read 208_d_read_debug_attr.restype = c_ssize_t 209_d_read_debug_attr.argtypes = (_DevicePtr, c_char_p, c_char_p, c_size_t) 210_d_read_debug_attr.errcheck = _checkNegative 211 212_d_write_debug_attr = _lib.iio_device_debug_attr_write 213_d_write_debug_attr.restype = c_ssize_t 214_d_write_debug_attr.argtypes = (_DevicePtr, c_char_p, c_char_p) 215_d_write_debug_attr.errcheck = _checkNegative 216 217_d_reg_write = _lib.iio_device_reg_write 218_d_reg_write.restype = c_int 219_d_reg_write.argtypes = (_DevicePtr, c_uint, c_uint) 220_d_reg_write.errcheck = _checkNegative 221 222_d_reg_read = _lib.iio_device_reg_read 223_d_reg_read.restype = c_int 224_d_reg_read.argtypes = (_DevicePtr, c_uint, _POINTER(c_uint)) 225_d_reg_read.errcheck = _checkNegative 226 227_channels_count = _lib.iio_device_get_channels_count 228_channels_count.restype = c_uint 229_channels_count.argtypes = (_DevicePtr, ) 230 231_get_channel = _lib.iio_device_get_channel 232_get_channel.restype = _ChannelPtr 233_get_channel.argtypes = (_DevicePtr, c_uint) 234_get_channel.errcheck = _checkNull 235 236_get_sample_size = _lib.iio_device_get_sample_size 237_get_sample_size.restype = c_int 238_get_sample_size.argtypes = (_DevicePtr, ) 239_get_sample_size.errcheck = _checkNegative 240 241_d_is_trigger = _lib.iio_device_is_trigger 242_d_is_trigger.restype = c_bool 243_d_is_trigger.argtypes = (_DevicePtr, ) 244 245_d_get_trigger = _lib.iio_device_get_trigger 246_d_get_trigger.restype = c_int 247_d_get_trigger.argtypes = (_DevicePtr, _DevicePtr, ) 248_d_get_trigger.errcheck = _checkNegative 249 250_d_set_trigger = _lib.iio_device_set_trigger 251_d_set_trigger.restype = c_int 252_d_set_trigger.argtypes = (_DevicePtr, _DevicePtr, ) 253_d_set_trigger.errcheck = _checkNegative 254 255_d_set_buffers_count = _lib.iio_device_set_kernel_buffers_count 256_d_set_buffers_count.restype = c_int 257_d_set_buffers_count.argtypes = (_DevicePtr, c_uint) 258_d_set_buffers_count.errcheck = _checkNegative 259 260_c_get_id = _lib.iio_channel_get_id 261_c_get_id.restype = c_char_p 262_c_get_id.argtypes = (_ChannelPtr, ) 263_c_get_id.errcheck = _checkNull 264 265_c_get_name = _lib.iio_channel_get_name 266_c_get_name.restype = c_char_p 267_c_get_name.argtypes = (_ChannelPtr, ) 268 269_c_is_output = _lib.iio_channel_is_output 270_c_is_output.restype = c_bool 271_c_is_output.argtypes = (_ChannelPtr, ) 272 273_c_is_scan_element = _lib.iio_channel_is_scan_element 274_c_is_scan_element.restype = c_bool 275_c_is_scan_element.argtypes = (_ChannelPtr, ) 276 277_c_attr_count = _lib.iio_channel_get_attrs_count 278_c_attr_count.restype = c_uint 279_c_attr_count.argtypes = (_ChannelPtr, ) 280 281_c_get_attr = _lib.iio_channel_get_attr 282_c_get_attr.restype = c_char_p 283_c_get_attr.argtypes = (_ChannelPtr, ) 284_c_get_attr.errcheck = _checkNull 285 286_c_get_filename = _lib.iio_channel_attr_get_filename 287_c_get_filename.restype = c_char_p 288_c_get_filename.argtypes = (_ChannelPtr, c_char_p, ) 289_c_get_filename.errcheck = _checkNull 290 291_c_read_attr = _lib.iio_channel_attr_read 292_c_read_attr.restype = c_ssize_t 293_c_read_attr.argtypes = (_ChannelPtr, c_char_p, c_char_p, c_size_t) 294_c_read_attr.errcheck = _checkNegative 295 296_c_write_attr = _lib.iio_channel_attr_write 297_c_write_attr.restype = c_ssize_t 298_c_write_attr.argtypes = (_ChannelPtr, c_char_p, c_char_p) 299_c_write_attr.errcheck = _checkNegative 300 301_c_enable = _lib.iio_channel_enable 302_c_enable.argtypes = (_ChannelPtr, ) 303 304_c_disable = _lib.iio_channel_disable 305_c_disable.argtypes = (_ChannelPtr, ) 306 307_c_is_enabled = _lib.iio_channel_is_enabled 308_c_is_enabled.restype = c_bool 309_c_is_enabled.argtypes = (_ChannelPtr, ) 310 311_c_read = _lib.iio_channel_read 312_c_read.restype = c_ssize_t 313_c_read.argtypes = (_ChannelPtr, _BufferPtr, c_void_p, c_size_t, ) 314 315_c_read_raw = _lib.iio_channel_read_raw 316_c_read_raw.restype = c_ssize_t 317_c_read_raw.argtypes = (_ChannelPtr, _BufferPtr, c_void_p, c_size_t, ) 318 319_c_write = _lib.iio_channel_write 320_c_write.restype = c_ssize_t 321_c_write.argtypes = (_ChannelPtr, _BufferPtr, c_void_p, c_size_t, ) 322 323_c_write_raw = _lib.iio_channel_write_raw 324_c_write_raw.restype = c_ssize_t 325_c_write_raw.argtypes = (_ChannelPtr, _BufferPtr, c_void_p, c_size_t, ) 326 327_create_buffer = _lib.iio_device_create_buffer 328_create_buffer.restype = _BufferPtr 329_create_buffer.argtypes = (_DevicePtr, c_size_t, c_bool, ) 330_create_buffer.errcheck = _checkNull 331 332_buffer_destroy = _lib.iio_buffer_destroy 333_buffer_destroy.argtypes = (_BufferPtr, ) 334 335_buffer_refill = _lib.iio_buffer_refill 336_buffer_refill.restype = c_ssize_t 337_buffer_refill.argtypes = (_BufferPtr, ) 338_buffer_refill.errcheck = _checkNegative 339 340_buffer_push_partial = _lib.iio_buffer_push_partial 341_buffer_push_partial.restype = c_ssize_t 342_buffer_push_partial.argtypes = (_BufferPtr, c_uint, ) 343_buffer_push_partial.errcheck = _checkNegative 344 345_buffer_start = _lib.iio_buffer_start 346_buffer_start.restype = c_void_p 347_buffer_start.argtypes = (_BufferPtr, ) 348 349_buffer_end = _lib.iio_buffer_end 350_buffer_end.restype = c_void_p 351_buffer_end.argtypes = (_BufferPtr, ) 352 353def _get_lib_version(): 354 major = c_uint() 355 minor = c_uint() 356 buf = create_string_buffer(8) 357 _get_library_version(_byref(major), _byref(minor), buf) 358 return (major.value, minor.value, buf.value.decode('ascii') ) 359 360version = _get_lib_version() 361backends = [ _get_backend(x).decode('ascii') for x in range(0, _get_backends_count()) ] 362 363class _Attr(object): 364 def __init__(self, name, filename = None): 365 self._name = name 366 self._name_ascii = name.encode('ascii') 367 self._filename = name if filename is None else filename 368 369 def __str__(self): 370 return self._name 371 372 name = property(lambda self: self._name, None, None, 373 "The name of this attribute.\n\ttype=str") 374 filename = property(lambda self: self._filename, None, None, 375 "The filename in sysfs to which this attribute is bound.\n\ttype=str") 376 value = property(lambda self: self.__read(), lambda self, x: self.__write(x), 377 None, "Current value of this attribute.\n\ttype=str") 378 379class ChannelAttr(_Attr): 380 """Represents an attribute of a channel.""" 381 382 def __init__(self, channel, name): 383 super(ChannelAttr, self).__init__(name, _c_get_filename(channel, name.encode('ascii')).decode('ascii')) 384 self._channel = channel 385 386 def _Attr__read(self): 387 buf = create_string_buffer(1024) 388 _c_read_attr(self._channel, self._name_ascii, buf, len(buf)) 389 return buf.value.decode('ascii') 390 391 def _Attr__write(self, value): 392 _c_write_attr(self._channel, self._name_ascii, value.encode('ascii')) 393 394class DeviceAttr(_Attr): 395 """Represents an attribute of an IIO device.""" 396 397 def __init__(self, device, name): 398 super(DeviceAttr, self).__init__(name) 399 self._device = device 400 401 def _Attr__read(self): 402 buf = create_string_buffer(1024) 403 _d_read_attr(self._device, self._name_ascii, buf, len(buf)) 404 return buf.value.decode('ascii') 405 406 def _Attr__write(self, value): 407 _d_write_attr(self._device, self._name_ascii, value.encode('ascii')) 408 409class DeviceDebugAttr(DeviceAttr): 410 """Represents a debug attribute of an IIO device.""" 411 412 def __init__(self, device, name): 413 super(DeviceDebugAttr, self).__init__(device, name) 414 415 def _Attr__read(self): 416 buf = create_string_buffer(1024) 417 _d_read_debug_attr(self._device, self._name_ascii, buf, len(buf)) 418 return buf.value.decode('ascii') 419 420 def _Attr__write(self, value): 421 _d_write_debug_attr(self._device, self._name_ascii, value.encode('ascii')) 422 423class Channel(object): 424 def __init__(self, _channel): 425 self._channel = _channel 426 self._attrs = { name : ChannelAttr(_channel, name) for name in \ 427 [_c_get_attr(_channel, x).decode('ascii') for x in range(0, _c_attr_count(_channel))] } 428 self._id = _c_get_id(self._channel).decode('ascii') 429 430 name_raw = _c_get_name(self._channel) 431 self._name = name_raw.decode('ascii') if name_raw is not None else None 432 self._output = _c_is_output(self._channel) 433 self._scan_element = _c_is_scan_element(self._channel) 434 435 def read(self, buf, raw = False): 436 """ 437 Extract the samples corresponding to this channel from the given iio.Buffer object. 438 439 parameters: 440 buf: type=iio.Buffer 441 A valid instance of the iio.Buffer class 442 raw: type=bool 443 If set to True, the samples are not converted from their 444 native format to their host format 445 446 returns: type=bytearray 447 An array containing the samples for this channel 448 """ 449 array = bytearray(buf._length) 450 mytype = c_char * len(array) 451 c_array = mytype.from_buffer(array) 452 if raw: 453 length = _c_read_raw(self._channel, buf._buffer, c_array, len(array)) 454 else: 455 length = _c_read(self._channel, buf._buffer, c_array, len(array)) 456 return array[:length] 457 458 def write(self, buf, array, raw = False): 459 """ 460 Write the specified array of samples corresponding to this channel into the given iio.Buffer object. 461 462 parameters: 463 buf: type=iio.Buffer 464 A valid instance of the iio.Buffer class 465 array: type=bytearray 466 The array containing the samples to copy 467 raw: type=bool 468 If set to True, the samples are not converted from their 469 host format to their native format 470 471 returns: type=int 472 The number of bytes written 473 """ 474 mytype = c_char * len(array) 475 c_array = mytype.from_buffer(array) 476 if raw: 477 return _c_write_raw(self._channel, buf._buffer, c_array, len(array)) 478 else: 479 return _c_write(self._channel, buf._buffer, c_array, len(array)) 480 481 id = property(lambda self: self._id, None, None, 482 "An identifier of this channel.\n\tNote that it is possible that two channels have the same ID, if one is an input channel and the other is an output channel.\n\ttype=str") 483 name = property(lambda self: self._name, None, None, 484 "The name of this channel.\n\ttype=str") 485 attrs = property(lambda self: self._attrs, None, None, 486 "List of attributes for this channel.\n\ttype=dict of iio.ChannelAttr") 487 output = property(lambda self: self._output, None, None, 488 "Contains True if the channel is an output channel, False otherwise.\n\ttype=bool") 489 scan_element = property(lambda self: self._scan_element, None, None, 490 "Contains True if the channel is a scan element, False otherwise.\n\tIf a channel is a scan element, then it is possible to enable it and use it for I/O operations.\n\ttype=bool") 491 enabled = property(lambda self: _c_is_enabled(self._channel), \ 492 lambda self, x: _c_enable(self._channel) if x else _c_disable(self._channel), 493 None, "Configured state of the channel\n\ttype=bool") 494 495class Buffer(object): 496 """The class used for all I/O operations.""" 497 498 def __init__(self, device, samples_count, cyclic = False): 499 """ 500 Initializes a new instance of the Buffer class. 501 502 parameters: 503 device: type=iio.Device 504 The iio.Device object that represents the device where the I/O 505 operations will be performed 506 samples_count: type=int 507 The size of the buffer, in samples 508 circular: type=bool 509 If set to True, the buffer is circular 510 511 returns: type=iio.Buffer 512 An new instance of this class 513 """ 514 try: 515 self._buffer = _create_buffer(device._device, samples_count, cyclic) 516 except: 517 self._buffer = None 518 raise 519 self._length = samples_count * device.sample_size 520 self._samples_count = samples_count 521 522 self._ctx = device.ctx() 523 # Holds a reference to the corresponding IIO Context. This ensures that 524 # every iio.Buffer object is destroyed before its corresponding IIO Context. 525 526 def __del__(self): 527 if self._buffer is not None: 528 _buffer_destroy(self._buffer) 529 530 def __len__(self): 531 """The size of this buffer, in bytes.""" 532 return self._length 533 534 def refill(self): 535 """Fetch a new set of samples from the hardware.""" 536 _buffer_refill(self._buffer) 537 538 def push(self, samples_count = None): 539 """ 540 Submit the samples contained in this buffer to the hardware. 541 542 parameters: 543 samples_count: type=int 544 The number of samples to submit, default = full buffer 545 """ 546 _buffer_push_partial(self._buffer, samples_count or self._samples_count) 547 548 def read(self): 549 """ 550 Retrieve the samples contained inside the Buffer object. 551 552 returns: type=bytearray 553 An array containing the samples 554 """ 555 556 start = _buffer_start(self._buffer) 557 end = _buffer_end(self._buffer) 558 array = bytearray(end - start) 559 mytype = c_char * len(array) 560 c_array = mytype.from_buffer(array) 561 _memmove(c_array, start, len(array)) 562 return array 563 564 def write(self, array): 565 """ 566 Copy the given array of samples inside the Buffer object. 567 568 parameters: 569 array: type=bytearray 570 The array containing the samples to copy 571 572 returns: type=int 573 The number of bytes written into the buffer 574 """ 575 start = _buffer_start(self._buffer) 576 end = _buffer_end(self._buffer) 577 length = end - start 578 if length > len(array): 579 length = len(array) 580 mytype = c_char * len(array) 581 c_array = mytype.from_buffer(array) 582 _memmove(start, c_array, length) 583 return length 584 585class _DeviceOrTrigger(object): 586 def __init__(self, _device): 587 self._device = _device 588 self._attrs = { name : DeviceAttr(_device, name) for name in \ 589 [_d_get_attr(_device, x).decode('ascii') for x in range(0, _d_attr_count(_device))] } 590 self._debug_attrs = { name: DeviceDebugAttr(_device, name) for name in \ 591 [_d_get_debug_attr(_device, x).decode('ascii') for x in range(0, _d_debug_attr_count(_device))] } 592 593 # TODO(pcercuei): Use a dictionary for the channels. 594 chans = [ Channel(_get_channel(self._device, x)) 595 for x in range(0, _channels_count(self._device)) ] 596 self._channels = sorted(chans, key=lambda c: c.id) 597 self._id = _d_get_id(self._device).decode('ascii') 598 599 name_raw = _d_get_name(self._device) 600 self._name = name_raw.decode('ascii') if name_raw is not None else None 601 602 def reg_write(self, reg, value): 603 """ 604 Set a value to one register of this device. 605 606 parameters: 607 reg: type=int 608 The register address 609 value: type=int 610 The value that will be used for this register 611 """ 612 _d_reg_write(self._device, reg, value) 613 614 def reg_read(self, reg): 615 """ 616 Read the content of a register of this device. 617 618 parameters: 619 reg: type=int 620 The register address 621 622 returns: type=int 623 The value of the register 624 """ 625 value = c_uint() 626 _d_reg_read(self._device, reg, _byref(value)) 627 return value.value 628 629 def find_channel(self, name_or_id, is_output = False): 630 """ 631 632 Find a IIO channel by its name or ID. 633 634 parameters: 635 name_or_id: type=str 636 The name or ID of the channel to find 637 is_output: type=bool 638 Set to True to search for an output channel 639 640 returns: type=iio.Device or type=iio.Trigger 641 The IIO Device 642 """ 643 return next((x for x in self.channels \ 644 if name_or_id == x.name or name_or_id == x.id and \ 645 x.output == is_output), None) 646 647 def set_kernel_buffers_count(self, count): 648 """ 649 650 Set the number of kernel buffers to use with the specified device. 651 652 parameters: 653 count: type=int 654 The number of kernel buffers 655 656 """ 657 return _d_set_buffers_count(self._device, count) 658 659 @property 660 def sample_size(self): 661 """ 662 Current sample size of this device. 663 type: int 664 665 The sample size varies each time channels get enabled or disabled.""" 666 return _get_sample_size(self._device) 667 668 id = property(lambda self: self._id, None, None, 669 "An identifier of this device, only valid in this IIO context.\n\ttype=str") 670 name = property(lambda self: self._name, None, None, 671 "The name of this device.\n\ttype=str") 672 attrs = property(lambda self: self._attrs, None, None, 673 "List of attributes for this IIO device.\n\ttype=dict of iio.DeviceAttr") 674 debug_attrs = property(lambda self: self._debug_attrs, None, None, 675 "List of debug attributes for this IIO device.\n\ttype=dict of iio.DeviceDebugAttr") 676 channels = property(lambda self: self._channels, None, None, 677 "List of channels available with this IIO device.\n\ttype=list of iio.Channel objects") 678 679class Trigger(_DeviceOrTrigger): 680 """Contains the representation of an IIO device that can act as a trigger.""" 681 682 def __init__(self, _device): 683 super(Trigger, self).__init__(_device) 684 685 def _get_rate(self): 686 return int(self._attrs['frequency'].value) 687 688 def _set_rate(self, value): 689 self._attrs['frequency'].value = str(value) 690 691 frequency = property(_get_rate, _set_rate, None, 692 "Configured frequency (in Hz) of this trigger\n\ttype=int") 693 694class Device(_DeviceOrTrigger): 695 """Contains the representation of an IIO device.""" 696 697 def __init__(self, ctx, _device): 698 super(Device, self).__init__(_device) 699 self.ctx = weakref.ref(ctx) 700 701 def _set_trigger(self, trigger): 702 _d_set_trigger(self._device, trigger._device if trigger else None) 703 704 def _get_trigger(self): 705 value = _Device() 706 _d_get_trigger(self._device, _byref(value)) 707 708 for dev in self.ctx()._devices: 709 if value == dev._device: 710 return dev 711 return None 712 713 trigger = property(_get_trigger, _set_trigger, None, \ 714 "Contains the configured trigger for this IIO device.\n\ttype=iio.Trigger") 715 716class Context(object): 717 """Contains the representation of an IIO context.""" 718 719 def __init__(self, _context=None): 720 """ 721 Initializes a new instance of the Context class, using the local or the network backend of the IIO library. 722 723 returns: type=iio.Context 724 An new instance of this class 725 726 This function will create a network context if the IIOD_REMOTE 727 environment variable is set to the hostname where the IIOD server runs. 728 If set to an empty string, the server will be discovered using ZeroConf. 729 If the environment variable is not set, a local context will be created instead. 730 """ 731 self._context = None 732 733 if(_context is None): 734 self._context = _new_default() 735 elif type(_context) is str or type(_context) is unicode: 736 self._context = _new_uri(_context.encode('ascii')) 737 else: 738 self._context = _context 739 740 self._attrs = {} 741 for x in range(0, _get_attrs_count(self._context)): 742 str1 = c_char_p() 743 str2 = c_char_p() 744 _get_attr(self._context, x, _byref(str1), _byref(str2)) 745 self._attrs[str1.value.decode('ascii')] = str2.value.decode('ascii') 746 747 # TODO(pcercuei): Use a dictionary for the devices. 748 self._devices = [ Trigger(dev) if _d_is_trigger(dev) else Device(self, dev) for dev in \ 749 [ _get_device(self._context, x) for x in range(0, _devices_count(self._context)) ]] 750 self._name = _get_name(self._context).decode('ascii') 751 self._description = _get_description(self._context).decode('ascii') 752 self._xml = _get_xml(self._context).decode('ascii') 753 754 major = c_uint() 755 minor = c_uint() 756 buf = create_string_buffer(8) 757 _get_version(self._context, _byref(major), _byref(minor), buf) 758 self._version = (major.value, minor.value, buf.value.decode('ascii') ) 759 760 def __del__(self): 761 if(self._context is not None): 762 _destroy(self._context) 763 764 def set_timeout(self, timeout): 765 """ 766 Set a timeout for I/O operations. 767 768 parameters: 769 timeout: type=int 770 The timeout value, in milliseconds 771 """ 772 _set_timeout(self._context, timeout) 773 774 def clone(self): 775 """ 776 Clone this instance. 777 778 returns: type=iio.LocalContext 779 An new instance of this class 780 """ 781 return Context(_clone(self._context)) 782 783 def find_device(self, name_or_id): 784 """ 785 786 Find a IIO device by its name or ID. 787 788 parameters: 789 name_or_id: type=str 790 The name or ID of the device to find 791 792 returns: type=iio.Device or type=iio.Trigger 793 The IIO Device 794 """ 795 return next((x for x in self.devices \ 796 if name_or_id == x.name or name_or_id == x.id), None) 797 798 name = property(lambda self: self._name, None, None, \ 799 "Name of this IIO context.\n\ttype=str") 800 description = property(lambda self: self._description, None, None, \ 801 "Description of this IIO context.\n\ttype=str") 802 xml = property(lambda self: self._xml, None, None, \ 803 "XML representation of the current context.\n\ttype=str") 804 version = property(lambda self: self._version, None, None, \ 805 "Version of the backend.\n\ttype=(int, int, str)") 806 attrs = property(lambda self: self._attrs, None, None, \ 807 "List of context-specific attributes\n\ttype=dict of str objects") 808 devices = property(lambda self: self._devices, None, None, \ 809 "List of devices contained in this context.\n\ttype=list of iio.Device and iio.Trigger objects") 810 811class LocalContext(Context): 812 def __init__(self): 813 """ 814 Initializes a new instance of the Context class, using the local backend of the IIO library. 815 816 returns: type=iio.LocalContext 817 An new instance of this class 818 """ 819 ctx = _new_local() 820 super(LocalContext, self).__init__(ctx) 821 822class XMLContext(Context): 823 def __init__(self, xmlfile): 824 """ 825 Initializes a new instance of the Context class, using the XML backend of the IIO library. 826 827 parameters: 828 xmlfile: type=str 829 Filename of the XML file to build the context from 830 831 returns: type=iio.XMLContext 832 An new instance of this class 833 """ 834 ctx = _new_xml(xmlfile.encode('ascii')) 835 super(XMLContext, self).__init__(ctx) 836 837class NetworkContext(Context): 838 def __init__(self, hostname = None): 839 """ 840 Initializes a new instance of the Context class, using the network backend of the IIO library. 841 842 parameters: 843 hostname: type=str 844 Hostname, IPv4 or IPv6 address where the IIO Daemon is running 845 846 returns: type=iio.NetworkContext 847 An new instance of this class 848 """ 849 ctx = _new_network(hostname.encode('ascii') if hostname is not None else None) 850 super(NetworkContext, self).__init__(ctx) 851 852def scan_contexts(): 853 d = dict() 854 ptr = _POINTER(_ContextInfoPtr)() 855 856 ctx = _create_scan_context(None, 0) 857 nb = _get_context_info_list(ctx, _byref(ptr)); 858 859 for i in range(0, nb): 860 d[_context_info_get_uri(ptr[i]).decode('ascii')] = _context_info_get_description(ptr[i]).decode('ascii') 861 862 _context_info_list_free(ptr) 863 _destroy_scan_context(ctx) 864 return d 865