8000 atmel-samd: Handle TCC2 correctly. Unlike the other TCCs its 16bit · sparkfun/circuitpython@9434db0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9434db0

Browse files
committed
atmel-samd: Handle TCC2 correctly. Unlike the other TCCs its 16bit
rather than 24bit. Setting the period for more than a 16bit number caused the TCC to be in a weird state where resetting it would hard crash. Fixes adafruit#153
1 parent 43881f9 commit 9434db0

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535

3636
#undef ENABLE
3737

38+
# define _TCC_SIZE(n,unused) TPASTE3(TCC,n,_SIZE),
39+
# define TCC_SIZES { MREPEAT(TCC_INST_NUM, _TCC_SIZE, 0) }
40+
3841
uint32_t target_timer_frequencies[TC_INST_NUM + TCC_INST_NUM];
3942
uint8_t timer_refcount[TC_INST_NUM + TCC_INST_NUM];
4043
const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
@@ -55,6 +58,12 @@ void pwmout_reset(void) {
5558
}
5659
Tcc *tccs[TCC_INST_NUM] = TCC_INSTS;
5760
for (int i = 0; i < TCC_INST_NUM; i++) {
61+
// Disable the module before resetting it.
62+
if (tccs[i]->CTRLA.bit.ENABLE == 1) {
63+
tccs[i]->CTRLA.bit.ENABLE = 0;
64+
while (tccs[i]->SYNCBUSY.bit.ENABLE == 1) {
65+
}
66+
}
5867
tccs[i]->CTRLA.bit.SWRST = 1;
5968
}
6069
Tc *tcs[TC_INST_NUM] = TC_INSTS;
@@ -63,6 +72,8 @@ void pwmout_reset(void) {
6372
continue;
6473
}
6574
tcs[i]->COUNT16.CTRLA.bit.SWRST = 1;
75+
while (tcs[i]->COUNT16.CTRLA.bit.SWRST == 1) {
76+
}
6677
}
6778
}
6879

@@ -142,7 +153,9 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
142153
if (t->is_tc) {
143154
resolution = 16;
144155
} else {
145-
resolution = 24;
156+
// TCC resolution varies so look it up.
157+
const uint8_t _tcc_sizes[TCC_INST_NUM] = TCC_SIZES;
158+
resolution = _tcc_sizes[index];
146159
}
147160
// First determine the divisor that gets us the highest resolution.
148161
uint32_t system_clock = system_cpu_clock_get_hz();
@@ -164,7 +177,10 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
164177
config_tc.wave_generation = TC_WAVE_GENERATION_MATCH_PWM;
165178
config_tc.counter_16_bit.compare_capture_channel[0] = top;
166179

167-
BE90 tc_init(&self->tc_instance, t->tc, &config_tc);
180+
enum status_code status = tc_init(&self->tc_instance, t->tc, &config_tc);
181+
if (status != STATUS_OK) {
182+
mp_raise_RuntimeError("Failed to init timer");
183+
}
168184
tc_enable(&self->tc_instance);
169185
} else {
170186
struct tcc_config config_tcc;
@@ -174,7 +190,10 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
174190
config_tcc.counter.period = top;
175191
config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
176192

177-
tcc_init(&self->tcc_instance, t->tcc, &config_tcc);
193+
enum status_code status = tcc_init(&self->tcc_instance, t->tcc, &config_tcc);
194+
if (status != STATUS_OK) {
195+
mp_raise_RuntimeError("Failed to init timer");
196+
}
178197
tcc_enable(&self->tcc_instance);
179198
}
180199

0 commit comments

Comments
 (0)
0