# Path: IoTPy/pinmaps.py
# CAP_PWM      = 0x4
# 
# Path: IoTPy/errors.py
# class IoTPy_APIError(Exception):
#     pass
# 
# def errmsg(fmt, *args):
#     if not fmt.endswith('\n'):
#         fmt += '\n'
#     sys.stderr.write(os.path.basename(sys.argv[0]))
#     sys.stderr.write(': ')
#     if len(args):
#         sys.stderr.write(fmt % args)
#     else:
#         sys.stderr.write(fmt)
#     sys.stderr.flush()
# 
# Path: IoTPy/sfp.py
# def encode_sfp(command, args):
#     """
#     Construct binary SFP command.
# 
#     :param command: SFP command ID.
#     :type command: int
#     :param args: A list of SFP arguments, which can be either an integer or a byte collection (string).
#     :type args: list
#     :return: Binary SFP command.
#     :rtype: str
#     """
#     functions = {
#         binary_type: _encode_bytes,
#         integer_types[0]: _encode_int   # [0] - kinda hack to get class int
#     }
# 
#     sfp_command = pack('B', command) + b''.join(functions[type(arg)](arg) for arg in args)
#     sfp_command = b'\xd4' + pack('>H', len(sfp_command)) + sfp_command
#     return sfp_command


from IoTPy.pinmaps import CAP_PWM
from IoTPy.errors import IoTPy_APIError, errmsg
from IoTPy.sfp import encode_sfp
    def set_duty_cycle(self, duty_cycle):
        """
        Set PWM duty cycle.

        :param duty_cycle: PWM duty cycle in percents.
        :type duty_cycle: float
        """
        self.set_pulse_time(int(round(PWM_PORT_RUNNING[self.pwm_port]['period']*float(duty_cycle/100.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)

# Path: IoTPy/pinmaps.py
# CAP_PWM      = 0x4
# 
# Path: IoTPy/errors.py
# class IoTPy_APIError(Exception):
#     pass
# 
# def errmsg(fmt, *args):
#     if not fmt.endswith('\n'):
#         fmt += '\n'
#     sys.stderr.write(os.path.basename(sys.argv[0]))
#     sys.stderr.write(': ')
#     if len(args):
#         sys.stderr.write(fmt % args)
#     else:
#         sys.stderr.write(fmt)
#     sys.stderr.flush()
# 
# Path: IoTPy/sfp.py
# def encode_sfp(command, args):
#     """
#     Construct binary SFP command.
# 
#     :param command: SFP command ID.
#     :type command: int
#     :param args: A list of SFP arguments, which can be either an integer or a byte collection (string).
#     :type args: list
#     :return: Binary SFP command.
#     :rtype: str
#     """
#     functions = {
#         binary_type: _encode_bytes,
#         integer_types[0]: _encode_int   # [0] - kinda hack to get class int
#     }
# 
#     sfp_command = pack('B', command) + b''.join(functions[type(arg)](arg) for arg in args)
#     sfp_command = b'\xd4' + pack('>H', len(sfp_command)) + sfp_command
#     return sfp_command


# Path: IoTPy/interfaces/pwm.py
from IoTPy.pinmaps import CAP_PWM
from IoTPy.errors import IoTPy_APIError, errmsg
from IoTPy.sfp import encode_sfp

    def set_duty_cycle(self, duty_cycle):
        """
        Set PWM duty cycle.

        :param duty_cycle: PWM duty cycle in percents.
        :type duty_cycle: float
        """
        self.set_pulse_time(int(round(PWM_PORT_RUNNING[self.pwm_port]['period']*float(duty_cycle/100.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.")