Skip to content

Commit a16e41a

Browse files
authored
Update PWMOut.py
lgpio native changes
1 parent 74d02c4 commit a16e41a

File tree

1 file changed

+46
-44
lines changed
  • src/adafruit_blinka/microcontroller/bcm283x/pwmio

1 file changed

+46
-44
lines changed

src/adafruit_blinka/microcontroller/bcm283x/pwmio/PWMOut.py

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
# pylint: disable=invalid-name
12
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
23
#
34
# SPDX-License-Identifier: MIT
4-
"""Custom PWMOut Wrapper for Rpi.GPIO PWM Class"""
5-
from RPi import GPIO
6-
7-
GPIO.setmode(GPIO.BCM) # Use BCM pins D4 = GPIO #4
8-
GPIO.setwarnings(False) # shh!
5+
# pylint: enable=invalid-name
6+
""" PWMOut Class for lgpio lg library tx_pwm library """
97

8+
import lgpio
9+
import board # need board to get access to the CHIP object in the pin module
1010

1111
# pylint: disable=unnecessary-pass
1212
class PWMError(IOError):
@@ -18,47 +18,47 @@ class PWMError(IOError):
1818
# pylint: enable=unnecessary-pass
1919

2020

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

24-
def __init__(self, pin, *, frequency=500, duty_cycle=0, variable_frequency=False):
25-
self._pwmpin = None
24+
def __init__(self, pin, *, frequency=500, duty_cycle=0,
25+
variable_frequency=False):
26+
if variable_frequency:
27+
print("Variable Frequency is not supported, ignoring...")
28+
self._pin = pin
29+
result = lgpio.gpio_claim_output(board.pin.CHIP, self._pin.id,
30+
lFlags=lgpio.SET_PULL_NONE)
31+
if result < 0:
32+
raise RuntimeError(lgpio.error_text(result))
33+
self._enabled = False
34+
self._deinited = False
2635
self._period = 0
27-
self._open(pin, duty_cycle, frequency, variable_frequency)
36+
# set frequency
37+
self._frequency = frequency
38+
# set duty
39+
self.duty_cycle = duty_cycle
40+
self.enabled = True
2841

2942
def __del__(self):
3043
self.deinit()
3144

3245
def __enter__(self):
3346
return self
3447

35-
def __exit__(self, t, value, traceback):
48+
def __exit__(self, exc_type, exc_val, exc_tb):
3649
self.deinit()
3750

38-
def _open(self, pin, duty=0, freq=500, variable_frequency=False):
39-
self._pin = pin
40-
GPIO.setup(pin.id, GPIO.OUT)
41-
self._pwmpin = GPIO.PWM(pin.id, freq)
42-
43-
if variable_frequency:
44-
print("Variable Frequency is not supported, continuing without it...")
45-
46-
# set frequency
47-
self.frequency = freq
48-
# set duty
49-
self.duty_cycle = duty
50-
51-
self.enabled = True
52-
5351
def deinit(self):
5452
"""Deinit the PWM."""
55-
if self._pwmpin is not None:
56-
self._pwmpin.stop()
57-
GPIO.cleanup(self._pin.id)
58-
self._pwmpin = None
53+
if not self._deinited:
54+
if self.enabled:
55+
self._enabled = False # turn off the pwm
56+
self._deinited = True
57+
5958

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

105105
if not 0 <= duty_cycle <= 65535:
106-
raise ValueError("Invalid duty cycle value, should be between 0 and 65535")
106+
raise ValueError("Invalid duty cycle value, should be between "
107+
"0 and 65535")
107108

108109
# convert from 16-bit
109110
duty_cycle /= 65535.0
110111

111112
self._duty_cycle = duty_cycle
112-
self._pwmpin.ChangeDutyCycle(round(self._duty_cycle * 100))
113+
if self._enabled:
114+
self.enabled = True # turn on with new values
113115

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

132-
self._pwmpin.ChangeFrequency(round(frequency))
133134
self._frequency = frequency
135+
if self.enabled:
136+
self.enabled = True # turn on with new values
134137

135138
@property
136139
def enabled(self):
@@ -147,19 +150,18 @@ def enabled(self):
147150
@enabled.setter
148151
def enabled(self, value):
149152
if not isinstance(value, bool):
150-
raise TypeError("Invalid enabled type, should be string.")
151-
152-
if value:
153-
self._pwmpin.start(round(self._duty_cycle * 100))
154-
else:
155-
self._pwmpin.stop()
153+
raise TypeError("Invalid enabled type, should be bool.")
156154

155+
frequency = self._frequency if value else 0
156+
duty_cycle = round(self._duty_cycle * 100)
157157
self._enabled = value
158+
result = lgpio.tx_pwm(board.pin.CHIP, self._pin.id, frequency, duty_cycle)
159+
if result < 0:
160+
raise RuntimeError(lgpio.error_text(result))
161+
return result
162+
158163

159164
# String representation
160165
def __str__(self):
161-
return "pin %s (freq=%f Hz, duty_cycle=%f%%)" % (
162-
self._pin,
163-
self.frequency,
164-
self.duty_cycle,
165-
)
166+
return (f"pin {self._pin} (freq={self.frequency:f} Hz, duty_cycle="
167+
f"{self.duty_cycle}({round(self.duty_cycle / 655.35)}%)")

0 commit comments

Comments
 (0)