Beispiel #1
0
    def setup(self, direction, resistor=GPIO.PULL_UP):
        if not direction in [self.OUTPUT, self.INPUT]:
            raise IoTPy_APIError(
                "Invalid digital pin direction. Should be INPUT or OUTPUT")

        if direction == self.INPUT and not resistor in [
                GPIO.NONE, GPIO.PULL_UP, GPIO.PULL_DOWN
        ]:
            raise IoTPy_APIError(
                "Invalid GPIO resistor setting. Should be GPIO.NONE, GPIO.PULL_UP or GPIO.PULL_DOWN"
            )

        self.direction = direction

        if direction == self.INPUT:
            self.resistor = resistor

            if resistor == self.PULL_UP:
                mode = 4  # PULL_UP
            elif resistor == self.PULL_DOWN:
                mode = 2  # PULL_DOWN
            else:
                mode = 0  # HIGH_Z
        else:
            mode = 1  # OUTPUT

        self.board.low_level_io(
            0,
            encode_sfp(
                3, [self._logical_pins,
                    chr(mode) * len(self._logical_pins)]))
Beispiel #2
0
    def set_pulse_time(self, pulse_us):
        """
        Set PWM high (on state) time.

        :param pulse_us: Pulse time in microseconds.
        :type pulse_us: int
        :raise: IoTPy_APIError
        """
        if self.primary:
            self.board.low_level_io(0, encode_sfp(
                2, [self.logical_pin]))  # set pin secondary function
            self.primary = False
        if 0 <= pulse_us <= PWM_PORT_RUNNING[self.pwm_port]['period']:
            self.pulse_time = pulse_us

            high_time = pulse_us
            if self.polarity == 0:
                high_time = PWM_PORT_RUNNING[
                    self.pwm_port]['period'] - pulse_us

            self.board.low_level_io(
                0,
                encode_sfp(PWM._PWM_PORT_FUNCTIONS[self.pwm_port][1],
                           [self.pwm_pin, high_time]))
        else:
            errmsg(
                "UPER error: PWM high time is out of range on logical pin %d."
                % self.logical_pin)
            raise IoTPy_APIError("PWM high time is out of range.")
Beispiel #3
0
 def __init__(self, *args, **kw):
     super(IoPinout, self).__init__(*args, **kw)
     for key in self:
         if not (isinstance(key, int) or isinstance(
                 key, string_types)) or not isinstance(self[key], Pin):
             raise IoTPy_APIError(
                 "IoPinout must consist of integer or string keys and Pin values."
             )
Beispiel #4
0
    def spi(self, name, clock=1000000, mode=SPI.MODE_0):
        _names = {"SPI0": 0, "SPI1": 1}
        if isinstance(name, int):
            port = name
        elif isinstance(name, str):
            if _names.has_key(name):
                port = _names[name]
            else:
                raise IoTPy_APIError(
                    "Invalid SPI name %s. Must be one of %s." %
                    (name, ", ".join(sorted(_names.keys()))))
        else:
            raise IoTPy_APIError("PWM name must be an integer or a string")

        divider = int(round(2.0e6 / clock))

        return SPI(self, port, divider, mode)
Beispiel #5
0
def _encode_bytes(byte_string):
    if len(byte_string) < 64:
        return chr(0x40 | len(byte_string)).encode('latin-1') + byte_string
    packedlen = pack('>I', len(byte_string)).lstrip(b'\x00')
    if len(packedlen) == 1:
        return b'\xc4' + packedlen + byte_string
    elif len(packedlen) == 2:
        return b'\xc5' + packedlen + byte_string
    else:
        raise IoTPy_APIError("UPER API: - too long string passed to UPER, encode_bytes can't handle it.")
Beispiel #6
0
    def __init__(self, board, pin):
        self.board = board
        if self.board.pinout[pin].capabilities & CAP_GPIO:
            self.logical_pin = self.board.pinout[pin].pinID
        else:
            raise IoTPy_APIError("Trying to assign OneWire function to non GPIO pin.")

        #self.board.low_level_io(0, encode_sfp(1, [self.logical_pin]))  # set primary
        #self.board.low_level_io(0, encode_sfp(3, [self.logical_pin, 1])) # gpio mode output
        self.board.low_level_io(0, encode_sfp(100, [self.logical_pin]))
Beispiel #7
0
    def low_level_io(self, ret, output_buf):
        """

        :param ret:
        :param output_buf:
        :return:
        """
        # print(':'.join(hex(ord(n)) for n in output_buf))
        try:
            self.io.write(output_buf)
        except:
            raise IoTPy_APIError(
                "Unrecoverable transport writing error, dying.")
        data = None
        if ret != 0:
            try:
                data = self.outq.get(True, 1)
            except queue.Empty:
                raise IoTPy_APIError(
                    "IoTPy: Nothing to read on port exception.")
            # print('|'.join(hex(ord(n)) for n in data))
        return data
Beispiel #8
0
 def __init__(self, board, pin):
     self.board = board
     if self.board.pinout[pin].capabilities & CAP_ADC:
         self.logical_pin = self.board.pinout[pin].pinID
     else:
         errmsg("IO API: Pin " + str(pin) + " is not an ADC pin.")
         raise IoTPy_APIError(
             "Trying to assign ADC function to non ADC pin.")
     self.adc_pin = self.board.pinout[pin].extra[0]
     self.board.low_level_io(0, encode_sfp(
         3, [self.logical_pin, 0]))  # set GPIO to HIGH_Z
     self.board.low_level_io(0, encode_sfp(
         2, [self.logical_pin]))  # set secondary pin function
     self.primary = False
Beispiel #9
0
    def setup(self, direction, resistor=PULL_UP):
        """
        Configure GPIO.

        :param direction: GPIO direction: GPIO.OUTPUT or GPIO.INPUT
        :param resistor: GPIO internal resistor mode. Used when direction is GPIO.INPUT. Should be GPIO.PULL_UP, \
        GPIO.PULL_DOWN or GPIO.NONE.

        :raise: IoTPy_APIError
        """
        if not direction in [self.OUTPUT, self.INPUT]:
            raise IoTPy_APIError(
                "Invalid digital pin direction. Should be INPUT or OUTPUT")

        if direction == self.INPUT and not resistor in [
                self.NONE, self.PULL_UP, self.PULL_DOWN
        ]:
            raise IoTPy_APIError(
                "Invalid digital pin resistor setting. Should be GPIO.NONE, GPIO.PULL_UP or GPIO.PULL_DOWN"
            )

        self.direction = direction

        if direction == self.INPUT:
            self.resistor = resistor

            if resistor == self.PULL_UP:
                mode = 4  # PULL_UP
            elif resistor == self.PULL_DOWN:
                mode = 2  # PULL_DOWN
            else:
                mode = 0  # HIGH_Z
        else:
            mode = 1  # OUTPUT

        self.board.low_level_io(0, encode_sfp(3, [self.logical_pin, mode]))
Beispiel #10
0
 def __init__(self, board, pin, freq=100, polarity=1):
     self.board = board
     if self.board.pinout[pin].capabilities & CAP_PWM:
         self.logical_pin = self.board.pinout[pin].pinID
     else:
         errmsg("UPER API: Pin No:%d is not a PWM pin.", pin)
         raise IoTPy_APIError(
             "Trying to assign PWM function to non PWM pin.")
     self.pwm_port = self.board.pinout[pin].extra[0]
     self.pwm_pin = self.board.pinout[pin].extra[1]
     self.primary = True
     self.pulse_time = 0
     self.polarity = polarity
     PWM_PORT_RUNNING[self.pwm_port]['channels'] += 1
     if PWM_PORT_RUNNING[self.pwm_port]['channels'] == 1:
         self.set_frequency(freq)
Beispiel #11
0
def decode_sfp(io_buffer):
    """
    Decode SFP command from byte buffer.

    :param io_buffer: A byte buffer which stores SFP command.
    :type io_buffer: bytes string
    :return: SFP function ID and arguments list.
    """
    if io_buffer[0:1] != b'\xd4':
        return
    command_length = unpack('>H', io_buffer[1:3])[0] + 3    # get SFP command length located in two bytes
    sfp_command = unpack('B', io_buffer[3:4])[0]            # get SFP command code
    pointer = 4
    args = []
    while pointer < command_length:
        arg_type = ord(io_buffer[pointer:pointer + 1])
        pointer += 1
        if arg_type < 64:                    # short int
            args.append(arg_type)
        elif arg_type < 128:                    # short str
            arg_len = arg_type & 0x3f
            args.append(io_buffer[pointer:pointer + arg_len])
            pointer += arg_len
        else:
            arg_len = arg_type & 0x0f
            if arg_len < 4:            # decoding integers
                if arg_len == 0:
                    args.append(ord(io_buffer[pointer:pointer + 1]))
                elif arg_len == 1:
                    args.append(unpack('>H', io_buffer[pointer:pointer + 2])[0])
                elif arg_len == 2:
                    args.append(unpack('>I', b'\x00' + io_buffer[pointer:pointer + 3])[0])
                elif arg_len == 3:
                    args.append(unpack('>I', io_buffer[pointer:pointer + 4])[0])
                pointer += arg_len + 1
            else:
                if arg_type == 0xc4:        # decoding strings
                    arg_len = ord(io_buffer[pointer:pointer + 1])
                elif arg_type == 0xc5:
                    arg_len = unpack('>H', io_buffer[pointer:pointer + 2])[0]
                    pointer += 1
                else:
                    raise IoTPy_APIError("UPER API: Bad parameter type in decodeSFP method.")
                pointer += 1
                args.append(io_buffer[pointer:pointer + arg_len])
                pointer += arg_len
    return sfp_command, args
Beispiel #12
0
def detect_sfp_serial(uid=None):
    ports_list = []
    my_platform = platform.system()
    if uid:
        uid = UUID(uid)

    if my_platform == "Windows":
        for i in range(256):
            try:
                serial_tmp = serial.Serial('COM' + str(i))
                ports_list.append(serial_tmp.portstr)
                serial_tmp.close()
            except serial.SerialException:
                pass
    elif my_platform == "Darwin":
        ports_list = glob.glob("/dev/tty.usbmodem*")
    elif my_platform == "Linux":
        ports_list = glob.glob("/dev/ttyACM*")

    for my_port in ports_list:
        try:
            port_to_try = serial.Serial(
                port=my_port,
                baudrate=230400,  # virtual com port on USB is always max speed
                parity=serial.PARITY_ODD,
                stopbits=serial.STOPBITS_ONE,
                bytesize=serial.EIGHTBITS,
                timeout=1)
            komanda_siuntimui = encode_sfp(255, [])
            port_to_try.write(komanda_siuntimui)
            response = port_to_try.read(1)  # read one, blocking
            n = port_to_try.inWaiting()  # look if there is more
            if n:
                response = response + port_to_try.read(n)
                sfp = decode_sfp(response)

                if sfp[0] == 255:  # device info sfp packet
                    dev_uid = UUID(bytes=sfp[1][1])
                    if not uid or uid == dev_uid:
                        return port_to_try

            port_to_try.close()
        except:
            pass

    raise IoTPy_APIError("No SFP device was found on serial ports.")
Beispiel #13
0
    def __init__(self, board, pin):
        self.board = board
        if self.board.pinout[pin].capabilities & CAP_GPIO:
            self.logical_pin = self.board.pinout[pin].pinID
        else:
            errmsg("UPER API: Pin No:%d is not GPIO pin.", pin)
            raise IoTPy_APIError(
                "Trying to assign GPIO function to non GPIO pin.")

        # Configure default state to be input with pull-up resistor
        self.board.low_level_io(0,
                                encode_sfp(1,
                                           [self.logical_pin]))  # set primary
        self.direction = self.INPUT
        self.resistor = self.PULL_UP
        self.setup(
            self.direction,
            self.resistor)  # default GPIO pin state is INPUT and PULL_UP
Beispiel #14
0
    def __init__(self, board, pins):
        self.board = board

        for pin in pins:
            if not self.board.pinout[pin].capabilities & CAP_GPIO:
                raise IoTPy_APIError(
                    "Trying to assign GPIO function to non GPIO pin.")

        self._logical_pins = list(self.board.pinout[pin].pinID for pin in pins)
        self._logical_pins = struct.pack("B" * len(self._logical_pins),
                                         *self._logical_pins)

        # Configure default state to be input with pull-up resistor
        self.direction = GPIO.INPUT
        self.resistor = GPIO.PULL_UP
        self.setup(self.direction, self.resistor)
        self.board.low_level_io(0, encode_sfp(
            1, [self._logical_pins]))  # set primary
Beispiel #15
0
    def attach_irq(self,
                   event,
                   callback=None,
                   user_object=None,
                   debounce_time=50):
        """
        Attach (enable) or reconfigure GPIO interrupt event.

        :param event: GPIO interrupt event. Can have one of these values: GPIO.RISE, GPIO.FALL, GPIO.CHANGE, \
        GPIO.LOW or GPIO.HIGH.
        :param callback: User callback function. This function is executed when the interrupt event is received. \
        It should take two arguments: interrupt event description and user object. Interrupt event descriptor is \
        dictionary with three fields: 'id' - the interrupt ID (interrupt channel), 'event' - interrupt event type \
        and 'values' - the logical values on each of interrupt channel (N-th bit represents logical pin value of \
        interrupt channel N). User object is the same object as user_object.
        :param user_object: User defined object, which will be passed back to the callback function. Optional,  \
        default is None.
        :param debounce_time: Interrupt disable time in milliseconds after the triggering event. This is used to \
        "debounce" buttons or to protect communication channel from data flood. Optional, default is 50ms.

        :return: Logical interrupt ID
        :rtype: int
        :raise: IoTPy_APIError
        """
        try:
            irq_id = self.board.interrupts.index(self.logical_pin)
            self.board.low_level_io(0,
                                    encode_sfp(7,
                                               [irq_id]))  # detach interrupt
        except ValueError:
            try:
                irq_id = self.board.interrupts.index(None)
                self.board.interrupts[irq_id] = self.logical_pin
            except ValueError:
                errmsg("UPER API: more than 8 interrupts requested")
                raise IoTPy_APIError("Too many interrupts.")
        self.board.callbackdict[self.logical_pin] = {
            'mode': event,
            'callback': callback,
            'userobject': user_object
        }
        self.board.low_level_io(
            0, encode_sfp(6, [irq_id, self.logical_pin, event, debounce_time]))
        return irq_id
Beispiel #16
0
    def __init__(self, board, port=0, divider=1, mode=MODE_0):
        divider = min(max(divider, 1), 256)

        self.board = board
        self.port = port
        self.divider = divider
        self.mode = mode
        if self.port == 1:
            self.board.low_level_io(0, encode_sfp(2, [4]))
            self.board.low_level_io(0, encode_sfp(2, [5]))
            self.board.low_level_io(0, encode_sfp(2, [11]))
            self.board.low_level_io(0, encode_sfp(30, [self.divider, self.mode]))
        elif self.port == 0:
            self.board.low_level_io(0, encode_sfp(2, [12]))
            self.board.low_level_io(0, encode_sfp(2, [13]))
            self.board.low_level_io(0, encode_sfp(2, [14]))
            self.board.low_level_io(0, encode_sfp(20, [self.divider, self.mode]))
        else:
            errmsg("UPER API: Wrong SPI port number.", self.port)
            raise IoTPy_APIError("SPI port must be 0 or 1, trying to assign something else.")
Beispiel #17
0
    def set_period(self, period_us):
        """
        Set PWM period.

        :param period_us: PWM signal period in microseconds.
        :type period_us: int
        :raise: IoTPy_APIError
        """
        if 0 <= period_us <= self._PWM_PORT_MAX[self.pwm_port]:
            if PWM_PORT_RUNNING[self.pwm_port]['period'] != period_us:
                self.board.low_level_io(
                    0,
                    encode_sfp(self._PWM_PORT_FUNCTIONS[self.pwm_port][0],
                               [period_us]))
                PWM_PORT_RUNNING[self.pwm_port]['period'] = period_us
        else:
            errmsg(
                "UPER API: PWM period for port %d can be only between 0-%d" %
                (self.pwm_port, self._PWM_PORT_MAX[self.pwm_port]))
            raise IoTPy_APIError("PWM period is out of range.")
Beispiel #18
0
 def __delitem__(self, key):
     raise IoTPy_APIError("IoPinout can not be modified.")
Beispiel #19
0
 def __setitem__(self, key, value):
     raise IoTPy_APIError("IoPinout can not be modified.")
Beispiel #20
0
 def digital_port(self, names):
     for name in names:
         if not isinstance(name, int):
             raise IoTPy_APIError("GPIO name must be an integer.")
     return GPIOPort(self, names)
Beispiel #21
0
 def digital(self, name):
     if not (isinstance(name, int) or isinstance(name, string_types)):
         raise IoTPy_APIError("GPIO name must be an integer.")
     return GPIO(self, name)