/ lib / python / pyhal.py
pyhal.py
  1  """hal library python interface using ctypes ffi interface"""
  2  
  3  from ctypes import*
  4  
  5  
  6  lib = CDLL('liblinuxcnchal.so')
  7  lib.hal_malloc.restype = c_void_p
  8  lib.hal_malloc.argtype = [c_long]
  9  lib.hal_comp_name.restype = c_char_p
 10  
 11  lib.hal_pin_new.argtypes = [c_char_p, c_int, c_int, c_void_p, c_int]
 12  
 13  lib.hal_signal_new.argtypes = [c_char_p, c_int]
 14  
 15  lib.hal_link.argtypes = [c_char_p, c_char_p]
 16  
 17  lib.hal_port_read.argtypes = [c_int, c_char_p, c_uint]
 18  lib.hal_port_read.restype = c_bool
 19  
 20  lib.hal_port_peek.argtypes = [c_int, c_char_p, c_uint]
 21  lib.hal_port_peek.restype = c_bool
 22  
 23  lib.hal_port_peek_commit.argtypes = [c_int, c_char_p, c_uint]
 24  lib.hal_port_peek.restype = c_bool
 25  
 26  lib.hal_port_write.argtypes = [c_int, c_char_p, c_uint]
 27  lib.hal_port_write.restype = c_bool
 28  
 29  lib.hal_port_readable.argtypes = [c_int]
 30  lib.hal_port_readable.restype = c_uint
 31  
 32  lib.hal_port_writable.argtypes = [c_int]
 33  lib.hal_port_writable.restype = c_uint
 34  
 35  lib.hal_port_buffer_size.argtypes = [c_int]
 36  lib.hal_port_buffer_size.restype = c_uint
 37  
 38  lib.hal_port_clear.argtypes = [c_int]
 39  
 40  lib.hal_port_wait_readable.argtypes = [POINTER(POINTER(c_int)), c_uint, c_int]
 41  lib.hal_port_wait_writable.argtypes = [POINTER(POINTER(c_int)), c_uint, c_int]
 42  
 43  class HalException(Exception):
 44      """An exception raised by hal library functions"""
 45      pass
 46  
 47  
 48  class halType:
 49      BIT = 1
 50      FLOAT = 2
 51      SIGNED = 3
 52      UNSIGNED = 4
 53      PORT = 5
 54  
 55      values = [BIT, FLOAT, SIGNED, UNSIGNED, PORT ]
 56  
 57      typeConversion = { BIT : c_bool,
 58                         FLOAT : c_double,
 59                         SIGNED : c_int32,
 60                         UNSIGNED : c_uint32,
 61                         PORT : c_int }
 62  
 63  class pinDir:
 64      IN = 16
 65      OUT = 32
 66      IO = IN | OUT
 67  
 68      values =  [IN, OUT, IO]
 69  
 70  
 71  class pin(object):
 72      def __init__(self, component, name, type, dir, data_ptr):
 73          self.comp = component
 74          self.name = name
 75          self.type = type
 76          self.dir = dir
 77          self.data_ptr = data_ptr
 78  
 79      @property
 80      def fullname(self):
 81          return "{0}.{1}".format(self.comp.name, self.name)
 82  
 83      @property
 84      def value(self):
 85          if self.type == halType.PORT:
 86              raise HalException("cannot get value of PORT pin")
 87          else:
 88              return self.data_ptr.contents.contents.value
 89  
 90      @value.setter
 91      def value(self, val):
 92          if self.type == halType.PORT:
 93              raise HalException("cannot set value of PORT pin")
 94          else:
 95              self.data_ptr.contents.contents.value = val
 96  
 97  
 98  class port(pin):
 99      def __init__(self, component, name, type, dir, data_ptr):
100          pin.__init__(self, component, name, type, dir, data_ptr)
101  
102      @property
103      def __port(self):
104          return self.data_ptr.contents.contents.value
105  
106      def read(self, count):
107          if self.dir != pinDir.IN:
108              raise HalException("cannot read output port")
109  
110          buff = create_string_buffer(count)
111          if not lib.hal_port_read(self.__port, buff, count):
112              return ''
113          else:
114              return buff.raw
115  
116      def peek(self, count):
117          if self.dir != pinDir.IN:
118              raise HalException("cannot peek output port")
119  
120          buff = create_string_buffer(count)
121          if not lib.hal_port_peek(self.__port, buff, count):
122              return ''
123          else:
124              return buff.raw
125  
126      def peek_commit(self, count):
127          if self.dir != pinDir.IN:
128              raise HalException("cannot peek commit output port")
129          return lib.hal_port_peek_commit(self.__port, count)
130  
131      def write(self, buff):
132          if self.dir != pinDir.OUT:
133             raise HalException("cannot write input port")
134  
135          return lib.hal_port_write(self.__port, buff, len(buff))
136  
137      def readable(self):
138          if self.dir != pinDir.IN:
139              raise HalException("cannot read output port")
140  
141          return lib.hal_port_readable(self.__port)
142  
143      def writable(self):
144          if self.dir != pinDir.OUT:
145              raise HalException("cannot write input port")
146  
147          return lib.hal_port_writable(self.__port)
148  
149      def size(self):
150          return lib.hal_port_buffer_size(self.__port)
151  
152      def clear(self):
153          if self.dir != pinDir.IN:
154              raise HalException("cannot clear output port")
155  
156          lib.hal_port_clear(self.__port)
157  
158      def waitReadable(self, count):
159          if self.dir != pinDir.IN:
160              raise HalException("cannot read ouput port")
161  
162          lib.hal_port_wait_readable(self.data_ptr, count, 0)
163  
164      def waitWritable(self, count):
165          if self.dir != pinDir.OUT:
166              raise HalException("cannot write input port")
167  
168          lib.hal_port_wait_writable(self.data_ptr, count, 0)
169  
170      
171  
172  class component:
173      def __init__(self, name):
174          self.id = lib.hal_init(name)
175          self.name = name
176          self.pins = {}
177          if self.id < 0:
178              raise HalException('failed to initialized component "{0}"'.format(name))
179              
180  
181      def __del__(self):
182          self.exit()
183  
184            
185      def exit(self):
186          if self.id > 0:
187              result = lib.hal_exit(self.id)
188              self.id = -1
189              if result < 0:
190                  raise HalException('hal_exit failed with code {0}'.format(result))
191  
192          
193      def ready(self):
194          result = lib.hal_ready(self.id)
195          if result < 0:
196              raise HalException('hal_ready failed with code {0}'.format(result))
197  
198      def name(self):
199          return lib.hal_comp_name(self.id)
200  
201  
202      def pinNew(self, name, type, dir):
203          if not type in halType.typeConversion:
204              raise HalException('failed to create pin "{0}". Unknown type {1}'.format(name, type))
205  
206          if not dir in pinDir.values:
207              raise HalException('failed to create pin "{0}". Unknown dir {1}'.format(name, dir))
208  
209          ctype = halType.typeConversion[type]
210  
211          ptr = self.halMalloc(sizeof(c_void_p))
212          result = lib.hal_pin_new("{0}.{1}".format(self.name, name), type, dir, ptr, self.id)
213          if result < 0:
214              raise HalException('failed to create pin "{0}" with code {1}'.format(name, result))
215  
216          if type == halType.PORT:
217              self.pins[name] = port(self, name, type, dir,  cast(ptr, POINTER(POINTER(ctype))))
218          else:
219              self.pins[name] = pin(self, name, type, dir, cast(ptr, POINTER(POINTER(ctype))))
220  
221          return self.pins[name]
222  
223      def sigNew(self, name, type):
224          if not type in halType.values:
225              raise HalException('failed to create signal "{0}". Invalid type {1}'.format(name, type))
226  
227          result = lib.hal_signal_new(name, type)
228  
229          if result < 0:
230              raise HalException('failed to create signal "{0}" with code {1}'.format(name, result))
231  
232      def sigLink(self, pin_name, sig_name):
233          result = lib.hal_link(pin_name, sig_name)
234          if result < 0:
235              raise HalException('failed to link sig "{0}" to pin "{1}" with result {2}'.format(sig_name, pin_name, result))
236  
237  
238      def halMalloc(self, count):
239          ptr = lib.hal_malloc(count)
240          memset(ptr, 0, count)
241          return ptr
242  
243  
244  
245