X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/blobdiff_plain/8fe9bc8bda76d6f0202ae5aacc7dab6d103f89fc..18bc57adc610625742d7be9bc3422d02615d6d4f:/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py diff --git a/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py b/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py index de663e9..6cf477c 100644 --- a/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py +++ b/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py @@ -1,21 +1,30 @@ -# Much code from https://github.com/vsergeev/python-periphery/blob/master/periphery/pwm.py -# Copyright (c) 2015-2016 vsergeev / Ivan (Vanya) A. Sergeev -# License: MIT +""" +Much code from https://github.com/vsergeev/python-periphery/blob/master/periphery/pwm.py +Copyright (c) 2015-2016 vsergeev / Ivan (Vanya) A. Sergeev +License: MIT +""" import os -import digitalio try: from microcontroller.pin import pwmOuts except ImportError: raise RuntimeError("No PWM outputs defined for this board") + +# pylint: disable=unnecessary-pass class PWMError(IOError): """Base class for PWM errors.""" + pass -class PWMOut(object): +# pylint: enable=unnecessary-pass + + +class PWMOut: + """Pulse Width Modulation Output Class""" + # Sysfs paths _sysfs_path = "/sys/class/pwm/" _channel_path = "pwmchip{}" @@ -52,6 +61,8 @@ class PWMOut(object): """ self._pwmpin = None + self._channel = None + self._period = 0 self._open(pin, duty_cycle, frequency, variable_frequency) def __del__(self): @@ -74,28 +85,36 @@ class PWMOut(object): if self._channel is None: raise RuntimeError("No PWM channel found for this Pin") - channel_path = os.path.join(self._sysfs_path, self._channel_path.format(self._channel)) + if variable_frequency: + print("Variable Frequency is not supported, continuing without it...") + + channel_path = os.path.join( + self._sysfs_path, self._channel_path.format(self._channel) + ) if not os.path.isdir(channel_path): - raise ValueError("PWM channel does not exist, check that the required modules are loaded.") + raise ValueError( + "PWM channel does not exist, check that the required modules are loaded." + ) - pin_path = os.path.join(channel_path, self._pin_path.format(self._pwmpin)) try: - with open(os.path.join(channel_path, self._unexport_path), "w") as f_unexport: + with open( + os.path.join(channel_path, self._unexport_path), "w" + ) as f_unexport: f_unexport.write("%d\n" % self._pwmpin) except IOError as e: - pass # not unusual, it doesnt already exist + pass # not unusual, it doesnt already exist try: with open(os.path.join(channel_path, self._export_path), "w") as f_export: f_export.write("%d\n" % self._pwmpin) except IOError as e: raise PWMError(e.errno, "Exporting PWM pin: " + e.strerror) - self._set_enabled(False) + # self._set_enabled(False) # This line causes a write error when trying to enable # Look up the period, for fast duty cycle updates self._period = self._get_period() - self.duty_cycle = 0 + # self.duty_cycle = 0 # This line causes a write error when trying to enable # set frequency self.frequency = freq @@ -109,8 +128,12 @@ class PWMOut(object): if self._channel is not None: self.duty_cycle = 0 try: - channel_path = os.path.join(self._sysfs_path, self._channel_path.format(self._channel)) - with open(os.path.join(channel_path, self._unexport_path), "w") as f_unexport: + channel_path = os.path.join( + self._sysfs_path, self._channel_path.format(self._channel) + ) + with open( + os.path.join(channel_path, self._unexport_path), "w" + ) as f_unexport: f_unexport.write("%d\n" % self._pwmpin) except IOError as e: raise PWMError(e.errno, "Unexporting PWM pin: " + e.strerror) @@ -118,34 +141,50 @@ class PWMOut(object): self._channel = None self._pwmpin = None + def _is_deinited(self): + if self._pwmpin is None: + raise ValueError( + "Object has been deinitialize and can no longer " + "be used. Create a new object." + ) + def _write_pin_attr(self, attr, value): + # Make sure the pin is active + self._is_deinited() + path = os.path.join( self._sysfs_path, self._channel_path.format(self._channel), self._pin_path.format(self._pwmpin), - attr) + attr, + ) - with open(path, 'w') as f_attr: - #print(value, path) + with open(path, "w") as f_attr: + # print(value, path) f_attr.write(value + "\n") def _read_pin_attr(self, attr): + # Make sure the pin is active + self._is_deinited() + path = os.path.join( self._sysfs_path, self._channel_path.format(self._channel), self._pin_path.format(self._pwmpin), - attr) + attr, + ) - with open(path, 'r') as f_attr: + with open(path, "r") as f_attr: return f_attr.read().strip() # Mutable properties def _get_period(self): + period_ns = self._read_pin_attr(self._pin_period_path) try: - period_ns = int(self._read_pin_attr(self._pin_period_path)) + period_ns = int(period_ns) except ValueError: - raise PWMError(None, "Unknown period value: \"%s\"" % period_ns) + raise PWMError(None, 'Unknown period value: "%s"' % period_ns) # Convert period from nanoseconds to seconds period = period_ns / 1e9 @@ -167,6 +206,8 @@ class PWMOut(object): # Update our cached period self._period = float(period) + period = property(_get_period, _set_period) + """Get or set the PWM's output period in seconds. Raises: @@ -177,10 +218,11 @@ class PWMOut(object): """ def _get_duty_cycle(self): + duty_cycle_ns = self._read_pin_attr(self._pin_duty_cycle_path) try: - duty_cycle_ns = int(self._read_pin_attr(self._pin_duty_cycle_path)) + duty_cycle_ns = int(duty_cycle_ns) except ValueError: - raise PWMError(None, "Unknown duty cycle value: \"%s\"" % duty_cycle_ns) + raise PWMError(None, 'Unknown duty cycle value: "%s"' % duty_cycle_ns) # Convert duty cycle from nanoseconds to seconds duty_cycle = duty_cycle_ns / 1e9 @@ -244,28 +286,31 @@ class PWMOut(object): if enabled == "1": return True - elif enabled == "0": + if enabled == "0": return False - raise PWMError(None, "Unknown enabled value: \"%s\"" % enabled) + raise PWMError(None, 'Unknown enabled value: "%s"' % enabled) def _set_enabled(self, value): + """Get or set the PWM's output enabled state. + + Raises: + PWMError: if an I/O or OS error occurs. + TypeError: if value type is not bool. + + :type: bool + """ if not isinstance(value, bool): raise TypeError("Invalid enabled type, should be string.") self._write_pin_attr(self._pin_enable_path, "1" if value else "0") - """Get or set the PWM's output enabled state. - - Raises: - PWMError: if an I/O or OS error occurs. - TypeError: if value type is not bool. - - :type: bool - """ - # String representation def __str__(self): - return "PWM%d, pin %s (freq=%f Hz, duty_cycle=%f%%)" % \ - (self._channel, self._pin, self.frequency, self.duty_cycle * 100,) + return "PWM%d, pin %s (freq=%f Hz, duty_cycle=%f%%)" % ( + self._channel, + self._pin, + self.frequency, + self.duty_cycle * 100, + )