From: Scott Main Date: Fri, 4 Dec 2020 20:09:22 +0000 (-0800) Subject: Add timout loop after exporting the PWM pin. X-Git-Tag: 5.8.1^2~4 X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/commitdiff_plain/48a8b0cfe0b7d5b75ffcb357a1125ca25d972045 Add timout loop after exporting the PWM pin. This gives udev time to respond to the device event. Without this, the subsequent attempts to modify pin properties will fail when depending on udev rules to apply new user permissions. This code is essentially copied from python-periphery, as was most of this file (both MIT licenced). Although it appears sergeev added this loop recently, compared to when this code was originally cloned. --- diff --git a/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py b/src/adafruit_blinka/microcontroller/generic_linux/sysfs_pwmout.py index 4fc8e23..e95a1e6 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 @@ -24,6 +26,10 @@ 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/" @@ -109,6 +115,22 @@ 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' + ): + print('#### okay ####') + break + except IOError as e: + if e.errno != EACCES or (e.errno == EACCES and i == PWMOut.PWM_STAT_RETRIES - 1): + print('#### catch ####') + raise PWMError(e.errno, "Opening PWM period: " + e.strerror) + 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