Import LinuxCNC source tree
This commit is contained in:
262
lib/python/pyhal.py
Normal file
262
lib/python/pyhal.py
Normal file
@@ -0,0 +1,262 @@
|
||||
"""hal library python interface using ctypes ffi interface"""
|
||||
|
||||
from ctypes import*
|
||||
|
||||
|
||||
lib = CDLL('liblinuxcnchal.so')
|
||||
lib.hal_malloc.restype = c_void_p
|
||||
lib.hal_malloc.argtype = [c_long]
|
||||
lib.hal_comp_name.restype = c_char_p
|
||||
|
||||
lib.hal_pin_new.argtypes = [c_char_p, c_int, c_int, c_void_p, c_int]
|
||||
|
||||
lib.hal_signal_new.argtypes = [c_char_p, c_int]
|
||||
|
||||
lib.hal_link.argtypes = [c_char_p, c_char_p]
|
||||
|
||||
lib.hal_port_read.argtypes = [POINTER(c_int), c_char_p, c_uint]
|
||||
lib.hal_port_read.restype = c_bool
|
||||
|
||||
lib.hal_port_peek.argtypes = [POINTER(c_int), c_char_p, c_uint]
|
||||
lib.hal_port_peek.restype = c_bool
|
||||
|
||||
lib.hal_port_peek_commit.argtypes = [POINTER(c_int), c_char_p, c_uint]
|
||||
lib.hal_port_peek.restype = c_bool
|
||||
|
||||
lib.hal_port_write.argtypes = [POINTER(c_int), c_char_p, c_uint]
|
||||
lib.hal_port_write.restype = c_bool
|
||||
|
||||
lib.hal_port_readable.argtypes = [POINTER(c_int)]
|
||||
lib.hal_port_readable.restype = c_uint
|
||||
|
||||
lib.hal_port_writable.argtypes = [POINTER(c_int)]
|
||||
lib.hal_port_writable.restype = c_uint
|
||||
|
||||
lib.hal_port_buffer_size.argtypes = [POINTER(c_int)]
|
||||
lib.hal_port_buffer_size.restype = c_uint
|
||||
|
||||
lib.hal_port_clear.argtypes = [POINTER(c_int)]
|
||||
|
||||
lib.hal_port_wait_readable.argtypes = [POINTER(POINTER(c_int)), c_uint, c_int]
|
||||
lib.hal_port_wait_writable.argtypes = [POINTER(POINTER(c_int)), c_uint, c_int]
|
||||
|
||||
import functools
|
||||
import inspect
|
||||
import warnings
|
||||
|
||||
def pyhaldeprecate(reason):
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def warnfunc(*args, **kwargs):
|
||||
warnings.warn("Use of deprecated class/function {} ({}).".format(func.__name__, reason),
|
||||
FutureWarning, stacklevel=2)
|
||||
return func(*args, **kwargs)
|
||||
return warnfunc
|
||||
return decorator
|
||||
|
||||
|
||||
class HalException(Exception):
|
||||
"""An exception raised by hal library functions"""
|
||||
pass
|
||||
|
||||
|
||||
class halType:
|
||||
BIT = 1
|
||||
FLOAT = 2
|
||||
SIGNED = 3
|
||||
UNSIGNED = 4
|
||||
PORT = 5
|
||||
|
||||
values = [BIT, FLOAT, SIGNED, UNSIGNED, PORT ]
|
||||
|
||||
typeConversion = { BIT : c_bool,
|
||||
FLOAT : c_double,
|
||||
SIGNED : c_int32,
|
||||
UNSIGNED : c_uint32,
|
||||
PORT : c_int }
|
||||
|
||||
class pinDir:
|
||||
IN = 16
|
||||
OUT = 32
|
||||
IO = IN | OUT
|
||||
|
||||
values = [IN, OUT, IO]
|
||||
|
||||
|
||||
class pin(object):
|
||||
def __init__(self, component, name, type, dir, data_ptr):
|
||||
self.comp = component
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.dir = dir
|
||||
self.data_ptr = data_ptr
|
||||
|
||||
@property
|
||||
def fullname(self):
|
||||
return "{0}.{1}".format(self.comp.name, self.name)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
if self.type == halType.PORT:
|
||||
raise HalException("cannot get value of PORT pin")
|
||||
else:
|
||||
return self.data_ptr.contents.contents.value
|
||||
|
||||
@value.setter
|
||||
def value(self, val):
|
||||
if self.type == halType.PORT:
|
||||
raise HalException("cannot set value of PORT pin")
|
||||
else:
|
||||
self.data_ptr.contents.contents.value = val
|
||||
|
||||
|
||||
@pyhaldeprecate("'pyhal' causes severe problems, has been replaced by 'hal' and will soon be removed")
|
||||
class port(pin):
|
||||
def __init__(self, component, name, type, dir, data_ptr):
|
||||
pin.__init__(self, component, name, type, dir, data_ptr)
|
||||
|
||||
@property
|
||||
def __port(self):
|
||||
return self.data_ptr.contents
|
||||
|
||||
def read(self, count):
|
||||
if self.dir != pinDir.IN:
|
||||
raise HalException("cannot read output port")
|
||||
|
||||
buff = create_string_buffer(count)
|
||||
if not lib.hal_port_read(self.__port, buff, count):
|
||||
return ''
|
||||
else:
|
||||
return buff.raw
|
||||
|
||||
def peek(self, count):
|
||||
if self.dir != pinDir.IN:
|
||||
raise HalException("cannot peek output port")
|
||||
|
||||
buff = create_string_buffer(count)
|
||||
if not lib.hal_port_peek(self.__port, buff, count):
|
||||
return ''
|
||||
else:
|
||||
return buff.raw
|
||||
|
||||
def peek_commit(self, count):
|
||||
if self.dir != pinDir.IN:
|
||||
raise HalException("cannot peek commit output port")
|
||||
return lib.hal_port_peek_commit(self.__port, count)
|
||||
|
||||
def write(self, buff):
|
||||
if self.dir != pinDir.OUT:
|
||||
raise HalException("cannot write input port")
|
||||
|
||||
return lib.hal_port_write(self.__port, buff.encode(), len(buff))
|
||||
|
||||
def readable(self):
|
||||
if self.dir != pinDir.IN:
|
||||
raise HalException("cannot read output port")
|
||||
|
||||
return lib.hal_port_readable(self.__port)
|
||||
|
||||
def writable(self):
|
||||
if self.dir != pinDir.OUT:
|
||||
raise HalException("cannot write input port")
|
||||
|
||||
return lib.hal_port_writable(self.__port)
|
||||
|
||||
def size(self):
|
||||
return lib.hal_port_buffer_size(self.__port)
|
||||
|
||||
def clear(self):
|
||||
if self.dir != pinDir.IN:
|
||||
raise HalException("cannot clear output port")
|
||||
|
||||
lib.hal_port_clear(self.__port)
|
||||
|
||||
def waitReadable(self, count):
|
||||
if self.dir != pinDir.IN:
|
||||
raise HalException("cannot read output port")
|
||||
|
||||
lib.hal_port_wait_readable(self.data_ptr, count, 0)
|
||||
|
||||
def waitWritable(self, count):
|
||||
if self.dir != pinDir.OUT:
|
||||
raise HalException("cannot write input port")
|
||||
|
||||
lib.hal_port_wait_writable(self.data_ptr, count, 0)
|
||||
|
||||
|
||||
|
||||
@pyhaldeprecate("'pyhal' causes severe problems, has been replaced by 'hal' and will soon be removed")
|
||||
class component:
|
||||
def __init__(self, name):
|
||||
self.id = lib.hal_init(name.encode())
|
||||
self.name = name
|
||||
self.pins = {}
|
||||
if self.id < 0:
|
||||
raise HalException('failed to initialized component "{0}"'.format(name))
|
||||
|
||||
|
||||
def __del__(self):
|
||||
self.exit()
|
||||
|
||||
|
||||
def exit(self):
|
||||
if self.id > 0:
|
||||
result = lib.hal_exit(self.id)
|
||||
self.id = -1
|
||||
if result < 0:
|
||||
raise HalException('hal_exit failed with code {0}'.format(result))
|
||||
|
||||
|
||||
def ready(self):
|
||||
result = lib.hal_ready(self.id)
|
||||
if result < 0:
|
||||
raise HalException('hal_ready failed with code {0}'.format(result))
|
||||
|
||||
def name(self):
|
||||
return lib.hal_comp_name(self.id)
|
||||
|
||||
|
||||
def pinNew(self, name, type, dir):
|
||||
if not type in halType.typeConversion:
|
||||
raise HalException('failed to create pin "{0}". Unknown type {1}'.format(name, type))
|
||||
|
||||
if not dir in pinDir.values:
|
||||
raise HalException('failed to create pin "{0}". Unknown dir {1}'.format(name, dir))
|
||||
|
||||
ctype = halType.typeConversion[type]
|
||||
|
||||
ptr = self.halMalloc(sizeof(c_void_p))
|
||||
result = lib.hal_pin_new("{0}.{1}".format(self.name, name).encode(), type, dir, ptr, self.id)
|
||||
if result < 0:
|
||||
raise HalException('failed to create pin "{0}" with code {1}'.format(name, result))
|
||||
|
||||
if type == halType.PORT:
|
||||
self.pins[name] = port(self, name, type, dir, cast(ptr, POINTER(POINTER(ctype))))
|
||||
else:
|
||||
self.pins[name] = pin(self, name, type, dir, cast(ptr, POINTER(POINTER(ctype))))
|
||||
|
||||
return self.pins[name]
|
||||
|
||||
def sigNew(self, name, type):
|
||||
if not type in halType.values:
|
||||
raise HalException('failed to create signal "{0}". Invalid type {1}'.format(name, type))
|
||||
|
||||
result = lib.hal_signal_new(name.encode(), type)
|
||||
|
||||
if result < 0:
|
||||
raise HalException('failed to create signal "{0}" with code {1}'.format(name, result))
|
||||
|
||||
def sigLink(self, pin_name, sig_name):
|
||||
result = lib.hal_link(pin_name.encode(), sig_name.encode())
|
||||
if result < 0:
|
||||
raise HalException('failed to link sig "{0}" to pin "{1}" with result {2}'.format(sig_name, pin_name, result))
|
||||
|
||||
|
||||
def halMalloc(self, count):
|
||||
ptr = lib.hal_malloc(count)
|
||||
memset(ptr, 0, count)
|
||||
return ptr
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user