X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/blobdiff_plain/d2e478aaa029730c2b59466ec28b5651da46cccc..6245fc91a42d1833ab9351e2764805cf09fe1b19:/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 4fc8e23..f751b71 100644 --- a/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py +++ b/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py @@ -5,6 +5,8 @@ License: MIT """ import os +from time import sleep +from errno import EACCES try: from microcontroller.pin import pwmOuts @@ -25,6 +27,11 @@ class PWMError(IOError): class PWMOut: """Pulse Width Modulation Output Class""" + # Number of retries to check for successful PWM export on open + PWM_STAT_RETRIES = 10 + # Delay between check for scucessful PWM export on open (100ms) + PWM_STAT_DELAY = 0.1 + # Sysfs paths _sysfs_path = "/sys/class/pwm/" _channel_path = "pwmchip{}" @@ -109,6 +116,25 @@ class PWMOut: except IOError as e: raise PWMError(e.errno, "Exporting PWM pin: " + e.strerror) from IOError + # Loop until 'period' is writable, because application of udev rules + # after the above pin export is asynchronous. + # Without this loop, the following properties may not be writable yet. + for i in range(PWMOut.PWM_STAT_RETRIES): + try: + with open( + os.path.join( + channel_path, self._pin_path.format(self._pwmpin), "period" + ), + "w", + ): + break + except IOError as e: + if e.errno != EACCES or ( + e.errno == EACCES and i == PWMOut.PWM_STAT_RETRIES - 1 + ): + raise PWMError(e.errno, "Opening PWM period: " + e.strerror) from e + sleep(PWMOut.PWM_STAT_DELAY) + # self._set_enabled(False) # This line causes a write error when trying to enable # Look up the period, for fast duty cycle updates