Skip to content

Commit 8a1b3e7

Browse files
committed
disallow duty cycle rounding to 0
1 parent 9bc4f62 commit 8a1b3e7

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

ports/raspberrypi/common-hal/pwmio/PWMOut.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uin
176176
} else {
177177
compare_count = ((uint32_t)duty * self->top + MAX_TOP / 2) / MAX_TOP;
178178
}
179+
// do not allow count to be 0 (due to rounding) unless duty 0 was requested
180+
if (compare_count == 0 && duty != 0) {
181+
compare_count = 1;
182+
}
179183
// compare_count is the CC register value, which should be TOP+1 for 100% duty cycle.
180184
pwm_set_chan_level(self->slice, self->ab_channel, compare_count);
181185
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import board
2+
import pwmio
3+
import random
4+
import time
5+
import microcontroller
6+
import os
7+
import sys
8+
import random
9+
10+
exponents = [
11+
2,
12+
3,
13+
4,
14+
5,
15+
6,
16+
7,
17+
]
18+
19+
freqs = [int(10**f) for f in exponents]
20+
21+
top = 65536
22+
den = 10
23+
duties = [32767, 65535, 1, 65534, 0, 0]
24+
freq_duration = 1.2
25+
duty_duration = 0.2
26+
27+
print("\n\n")
28+
board_name = sys.implementation[2]
29+
30+
pins = {
31+
"Feather RP2040": (("D4", ""),),
32+
"RP2040-Zero": (("GP15", ""),),
33+
"Grand Central": (("D51", "TCC"), ("A15", "TC")),
34+
"Metro M0": (("A2", "TC"), ("A3", "TCC")),
35+
"ESP32-S3-DevKit": (("IO6", ""),), # marked D5 on board for XIAO-ESP32-s3
36+
"Feather ESP32-S2": (("D9", ""),),
37+
"XIAO nRF52840": (("D9", ""),),
38+
}
39+
40+
for board_key in pins:
41+
if board_key in board_name:
42+
pins_to_use = pins[board_key]
43+
break
44+
45+
while True:
46+
for pin_name, pin_type in pins_to_use:
47+
pin = getattr(board, pin_name)
48+
print('title="', end="")
49+
print(f"{board_name} at {microcontroller.cpu.frequency} Hz, pin {pin_name}", end="")
50+
if len(pin_type) > 0:
51+
print(f" ({pin_type})", end="")
52+
print('",')
53+
print(f'subtitle="{freq_duration:0.1f}s per frequency",')
54+
print(f'version="{sys.version}",')
55+
print("freq_calls=", end="")
56+
pwm = pwmio.PWMOut(pin, variable_frequency=True)
57+
t0 = time.monotonic()
58+
duty_time = t0 + duty_duration
59+
print("(", end="")
60+
offset = 0
61+
increment = 1
62+
for freq in freqs:
63+
i = 0
64+
try:
65+
pwm.frequency = freq
66+
except ValueError:
67+
break
68+
freq_time = t0 + freq_duration
69+
duty_time = t0 + duty_duration
70+
j = 0
71+
while time.monotonic() < freq_time:
72+
duty = duties[j]
73+
pwm.duty_cycle = duty
74+
while time.monotonic() < duty_time and time.monotonic() < freq_time:
75+
pass
76+
j += 1
77+
j = min(j, len(duties) - 1)
78+
duty_time += duty_duration
79+
i += 1
80+
if time.monotonic() > freq_time:
81+
break
82+
t0 = freq_time
83+
print(f"({freq}, {i/freq_duration:.0f}), ", end="")
84+
print(")")
85+
print("done.")
86+
pwm.deinit()
87+
time.sleep(5)

0 commit comments

Comments
 (0)