8000 atmel-samd: Fix PWMOut duty_cycle when used with TCC peripherals. · sparkfun/circuitpython@a884acc · GitHub
[go: up one dir, main page]

Skip to content

Commit a884acc

Browse files
committed
atmel-samd: Fix PWMOut duty_cycle when used with TCC peripherals.
Fixes adafruit#148. Fixes adafruit#151
1 parent 9345562 commit a884acc

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

atmel-samd/common-hal/pulseio/PWMOut.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6+
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
67
* Copyright (c) 2016 Damien P. George
78
*
89
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -104,10 +105,10 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
104105
const pin_timer_t* t = NULL;
105106
uint8_t index = 0;
106107
if (!variable_frequency &&
107-
primary_timer_index != 0xff &&
108-
target_timer_frequencies[primary_timer_index] == frequency &&
109-
pin->primary_timer.tcc->CTRLA.bit.ENABLE == 1 &&
110-
channel_ok(&pin->primary_timer, primary_timer_index)) {
108+
primary_timer_index != 0xff &&
109+
target_timer_frequencies[primary_timer_index] == frequency &&
110+
pin->primary_timer.tcc->CTRLA.bit.ENABLE == 1 &&
111+
channel_ok(&pin->primary_timer, primary_timer_index)) {
111112
t = &pin->primary_timer;
112113
index = primary_timer_index;
113114
} else if (!variable_frequency &&
@@ -153,6 +154,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
153154
break;
154155
}
155156
}
157+
self->period = top;
156158
if (t->is_tc) {
157159
struct tc_config config_tc;
158160
tc_get_config_defaults(&config_tc);
@@ -228,34 +230,33 @@ extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
228230
extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) {
229231
const pin_timer_t* t = self->timer;
230232
if (t->is_tc) {
231-
uint32_t top = ((uint32_t) t->tc->COUNT16.CC[0].reg + 1);
232-
uint16_t adjusted_duty = top * duty / 0xffff;
233+
uint16_t adjusted_duty = self->period * duty / 0xffff;
233234
tc_set_compare_value(&self->tc_instance, t->channel, adjusted_duty);
234235
} else {
235-
uint32_t top = t->tcc->PER.reg + 1;
236-
uint32_t adjusted_duty = ((uint64_t) top) * duty / 0xffff;
236+
uint32_t adjusted_duty = ((uint64_t) self->period) * duty / 0xffff;
237237
tcc_set_compare_value(&self->tcc_instance, t->channel, adjusted_duty);
238238
}
239239
}
240240

241241
uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
242242
const pin_timer_t* t = self->timer;
243243
if (t->is_tc) {
244-
uint16_t top = t->tc->COUNT16.CC[0].reg;
245244
while (tc_is_syncing(&self->tc_instance)) {
246245
/* Wait for sync */
247246
}
248247
uint16_t cv = t->tc->COUNT16.CC[t->channel].reg;
249-
return cv * 0xffff / top;
248+
return cv * 0xffff / self->period;
250249
} else {
251-
uint32_t top = t->tcc->PER.reg;
252250
uint32_t cv = 0;
253251
if ((t->tcc->STATUS.vec.CCBV & (1 << t->channel)) != 0) {
254252
cv = t->tcc->CCB[t->channel].reg;
255253
} else {
256254
cv = t->tcc->CC[t->channel].reg;
257255
}
258-
return cv * 0xffff / top;
256+
257+
uint32_t duty_cycle = ((uint64_t) cv) * 0xffff / self->period;
258+
259+
return duty_cycle;
259260
}
260261
}
261262

@@ -299,6 +300,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
299300
tcc_enable(&self->tcc_instance);
300301
}
301302
}
303+
self->period = new_top;
302304
if (t->is_tc) {
303305
while (tc_is_syncing(&self->tc_instance)) {
304306
/* Wait for sync */
@@ -321,6 +323,9 @@ uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
321323
divisor = t->tc->COUNT16.CTRLA.bit.PRESCALER;
322324
} else {
323325
top = t->tcc->PER.reg;
326+
if (t->tcc->STATUS.bit.PERBV) {
327+
top = t->tcc->PERB.reg;
328+
}
324329
divisor = t->tcc->CTRLA.bit.PRESCALER;
325330
}
326331
return (system_clock / prescaler[divisor]) / (top + 1);

atmel-samd/common-hal/pulseio/PWMOut.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ typedef struct {
3838
const mcu_pin_obj_t *pin;
3939
const pin_timer_t* timer;
4040
bool variable_frequency;
41+
uint32_t period;
4142
union {
4243
struct tc_module tc_instance;
4344
struct tcc_module tcc_instance;

0 commit comments

Comments
 (0)
0