X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/blobdiff_plain/0b9e819a6206fe0ea87673d27fc6e3293f3e1809..fe2e8551973e8e19edd9593de7796c645804a277:/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 c966b41..fa72667 100644 --- a/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py +++ b/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py @@ -22,6 +22,7 @@ class PWMOut(object): # Channel paths _export_path = "export" + _unexport_path = "unexport" _pin_path = "pwm{}" # Pin attribute paths @@ -54,13 +55,13 @@ class PWMOut(object): self._open(pin, duty_cycle, frequency, variable_frequency) def __del__(self): - self.close() + self.deinit() def __enter__(self): return self def __exit__(self, t, value, traceback): - self.close() + self.deinit() def _open(self, pin, duty=0, freq=500, variable_frequency=False): self._channel = None @@ -78,29 +79,54 @@ class PWMOut(object): 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)) - if not os.path.isdir(pin_path): - 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) + try: + 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 + 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(True) + #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 # This line causes a write error when trying to enable + # set frequency self.frequency = freq # set duty self.duty_cycle = duty - def close(self): - """Close the sysfs PWM.""" + self._set_enabled(True) + + def deinit(self): + """Deinit the sysfs PWM.""" + 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: + f_unexport.write("%d\n" % self._pwmpin) + except IOError as e: + raise PWMError(e.errno, "Unexporting PWM pin: " + e.strerror) + 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), @@ -112,6 +138,9 @@ class PWMOut(object): 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), @@ -124,8 +153,9 @@ class PWMOut(object): # 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) @@ -149,6 +179,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: @@ -159,8 +191,9 @@ 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) @@ -172,16 +205,15 @@ class PWMOut(object): # convert to 16-bit duty_cycle = int(duty_cycle * 65535) - return duty_cycle def _set_duty_cycle(self, duty_cycle): - # convert from 16-bit - duty_cycle /= 65535 - if not isinstance(duty_cycle, (int, float)): raise TypeError("Invalid duty cycle type, should be int or float.") - elif not 0.0 <= duty_cycle <= 1.0: + + # convert from 16-bit + duty_cycle /= 65535.0 + if not 0.0 <= duty_cycle <= 1.0: raise ValueError("Invalid duty cycle value, should be between 0.0 and 1.0.") # Convert duty cycle from ratio to seconds