Skip to content

Commit dc337bc

Browse files
author
Daniel L. Christensen
committed
Ensure that the period doesn't fall below the 10 bit resolution
that the API implies. For SAMD51, which doesn't have any spare bits, don't try to adjust the period.
1 parent 2f2768a commit dc337bc

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

cores/arduino/wiring_pwm.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ static void syncTCC(Tcc* TCCx) {
4747
#define MAX_PERIOD 0xFFFF
4848
#endif
4949

50+
// API uses 10 bit resolution
51+
#define PWM_API_RESOLUTION 10
52+
5053
static inline unsigned long calcPrescaler(uint32_t frequency, uint32_t &period)
5154
{
5255
//if it's a rest, set to 1Hz (below audio range)
@@ -68,6 +71,14 @@ static inline unsigned long calcPrescaler(uint32_t frequency, uint32_t &period)
6871
i++;
6972
}
7073

74+
#if defined(__SAMD51__)
75+
period = MAX_PERIOD;
76+
#else
77+
// Ensure that our period does not erode the API resolution
78+
if(period < (1<<PWM_API_RESOLUTION))
79+
period = (1<<PWM_API_RESOLUTION) - 1;
80+
#endif
81+
7182
switch (i - 1)
7283
{
7384
case 0:
@@ -117,7 +128,7 @@ void pwm(uint32_t outputPin, uint32_t frequency, uint32_t duty)
117128
uint32_t period;
118129

119130
prescalerConfigVal = calcPrescaler(frequency, period);
120-
duty = map(duty, 0, 1024, 0, period);
131+
duty = map(duty, 0, (1<<PWM_API_RESOLUTION), 0, period);
121132

122133
uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel);
123134
uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel);
@@ -275,7 +286,7 @@ void pwm(uint32_t outputPin, uint32_t frequency, uint32_t duty)
275286
}
276287
else
277288
{
278-
duty = map(duty, 0, 1024, 0, period);
289+
duty = map(duty, 0, (1<<PWM_API_RESOLUTION), 0, period);
279290
// -- Configure TCC
280291
Tcc *TCCx = (Tcc *)GetTC(pinDesc.ulPWMChannel);
281292
// Disable TCCx

0 commit comments

Comments
 (0)