Skip to content

Commit

Permalink
Update PWMOut.py
Browse files Browse the repository at this point in the history
lgpio native changes
  • Loading branch information
frank-pet authored Nov 16, 2024
1 parent 74d02c4 commit a16e41a
Showing 1 changed file with 46 additions and 44 deletions.
90 changes: 46 additions & 44 deletions src/adafruit_blinka/microcontroller/bcm283x/pwmio/PWMOut.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# pylint: disable=invalid-name
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Custom PWMOut Wrapper for Rpi.GPIO PWM Class"""
from RPi import GPIO

GPIO.setmode(GPIO.BCM) # Use BCM pins D4 = GPIO #4
GPIO.setwarnings(False) # shh!
# pylint: enable=invalid-name
""" PWMOut Class for lgpio lg library tx_pwm library """

import lgpio
import board # need board to get access to the CHIP object in the pin module

# pylint: disable=unnecessary-pass
class PWMError(IOError):
Expand All @@ -18,47 +18,47 @@ class PWMError(IOError):
# pylint: enable=unnecessary-pass


class PWMOut:
class PWMOut: # pylint: disable=invalid-name
"""Pulse Width Modulation Output Class"""

def __init__(self, pin, *, frequency=500, duty_cycle=0, variable_frequency=False):
self._pwmpin = None
def __init__(self, pin, *, frequency=500, duty_cycle=0,
variable_frequency=False):
if variable_frequency:
print("Variable Frequency is not supported, ignoring...")
self._pin = pin
result = lgpio.gpio_claim_output(board.pin.CHIP, self._pin.id,
lFlags=lgpio.SET_PULL_NONE)
if result < 0:
raise RuntimeError(lgpio.error_text(result))
self._enabled = False
self._deinited = False
self._period = 0
self._open(pin, duty_cycle, frequency, variable_frequency)
# set frequency
self._frequency = frequency
# set duty
self.duty_cycle = duty_cycle
self.enabled = True

def __del__(self):
self.deinit()

def __enter__(self):
return self

def __exit__(self, t, value, traceback):
def __exit__(self, exc_type, exc_val, exc_tb):
self.deinit()

def _open(self, pin, duty=0, freq=500, variable_frequency=False):
self._pin = pin
GPIO.setup(pin.id, GPIO.OUT)
self._pwmpin = GPIO.PWM(pin.id, freq)

if variable_frequency:
print("Variable Frequency is not supported, continuing without it...")

# set frequency
self.frequency = freq
# set duty
self.duty_cycle = duty

self.enabled = True

def deinit(self):
"""Deinit the PWM."""
if self._pwmpin is not None:
self._pwmpin.stop()
GPIO.cleanup(self._pin.id)
self._pwmpin = None
if not self._deinited:
if self.enabled:
self._enabled = False # turn off the pwm
self._deinited = True


def _is_deinited(self):
if self._pwmpin is None:
""" raise Value error if the object has been de-inited """
if self._deinited:
raise ValueError(
"Object has been deinitialize and can no longer "
"be used. Create a new object."
Expand Down Expand Up @@ -103,13 +103,15 @@ def duty_cycle(self, duty_cycle):
raise TypeError("Invalid duty cycle type, should be int or float.")

if not 0 <= duty_cycle <= 65535:
raise ValueError("Invalid duty cycle value, should be between 0 and 65535")
raise ValueError("Invalid duty cycle value, should be between "
"0 and 65535")

# convert from 16-bit
duty_cycle /= 65535.0

self._duty_cycle = duty_cycle
self._pwmpin.ChangeDutyCycle(round(self._duty_cycle * 100))
if self._enabled:
self.enabled = True # turn on with new values

@property
def frequency(self):
Expand All @@ -129,8 +131,9 @@ def frequency(self, frequency):
if not isinstance(frequency, (int, float)):
raise TypeError("Invalid frequency type, should be int or float.")

self._pwmpin.ChangeFrequency(round(frequency))
self._frequency = frequency
if self.enabled:
self.enabled = True # turn on with new values

@property
def enabled(self):
Expand All @@ -147,19 +150,18 @@ def enabled(self):
@enabled.setter
def enabled(self, value):
if not isinstance(value, bool):
raise TypeError("Invalid enabled type, should be string.")

if value:
self._pwmpin.start(round(self._duty_cycle * 100))
else:
self._pwmpin.stop()
raise TypeError("Invalid enabled type, should be bool.")

frequency = self._frequency if value else 0
duty_cycle = round(self._duty_cycle * 100)
self._enabled = value
result = lgpio.tx_pwm(board.pin.CHIP, self._pin.id, frequency, duty_cycle)
if result < 0:
raise RuntimeError(lgpio.error_text(result))
return result


# String representation
def __str__(self):
return "pin %s (freq=%f Hz, duty_cycle=%f%%)" % (
self._pin,
self.frequency,
self.duty_cycle,
)
return (f"pin {self._pin} (freq={self.frequency:f} Hz, duty_cycle="
f"{self.duty_cycle}({round(self.duty_cycle / 655.35)}%)")

0 comments on commit a16e41a

Please sign in to comment.