8000 Merge pull request #1605 from dhalbert/pwmout-tcc-lock-ccb · zencuke/circuitpython@7535326 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7535326

Browse files
authored
Merge pull request adafruit#1605 from dhalbert/pwmout-tcc-lock-ccb
Use TCC LUPD lock when updating CCB
2 parents 5af2c7f + 3c24e89 commit 7535326

File tree

1 file changed

+18
-20
lines changed
  • ports/atmel-samd/common-hal/pulseio

1 file changed

+18
-20
lines changed

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

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -328,32 +328,29 @@ extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self,
328328
#endif
329329
#ifdef SAMD51
330330
Tc* tc = tc_insts[t->index];
331-
while (tc->COUNT16.SYNCBUSY.bit.CC1 != 0) {
332-
// Wait for a previous value to be written. This can wait up to one period so we do
333-
// other stuff in the meantime.
334-
#ifdef MICROPY_VM_HOOK_LOOP
335-
MICROPY_VM_HOOK_LOOP
336-
#endif
337-
}
331+
while (tc->COUNT16.SYNCBUSY.bit.CC1 != 0) {}
338332
tc->COUNT16.CCBUF[1].reg = adjusted_duty;
339333
#endif
340334
} else {
341335
uint32_t adjusted_duty = ((uint64_t) tcc_periods[t->index]) * duty / 0xffff;
342336
uint8_t channel = tcc_channel(t);
343337
Tcc* tcc = tcc_insts[t->index];
344-
while ((tcc->SYNCBUSY.vec.CC & (1 << channel)) != 0) {
345-
// Wait for a previous value to be written. This can wait up to one period so we do
346-
// other stuff in the meantime.
347-
#ifdef MICROPY_VM_HOOK_LOOP
348-
MICROPY_VM_HOOK_LOOP
349-
#endif
350-
}
338+
339+
// Write into the CC buffer register, which will be transferred to the
340+
// CC register on an UPDATE (when period is finished).
341+
// Do clock domain syncing as necessary.
342+
343+
while (tcc->SYNCBUSY.reg != 0) {}
344+
345+
// Lock out double-buffering while updating the CCB value.
346+
tcc->CTRLBSET.bit.LUPD = 1;
351347
#ifdef SAMD21
352348
tcc->CCB[channel].reg = adjusted_duty;
353349
#endif
354350
#ifdef SAMD51
355351
tcc->CCBUF[channel].reg = adjusted_duty;
356352
#endif
353+
tcc->CTRLBCLR.bit.LUPD = 1;
357354
}
358355
}
359356

@@ -368,7 +365,12 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
368365
Tcc* tcc = tcc_insts[t->index];
369366
uint8_t channel = tcc_channel(t);
370367
uint32_t cv = 0;
368+
369+
while (tcc->SYNCBUSY.bit.CTRLB) {}
370+
371371
#ifdef SAMD21
372+
// If CCBV (CCB valid) is set, the CCB value hasn't yet been copied
373+
// to the CC value.
372374
if ((tcc->STATUS.vec.CCBV & (1 << channel)) != 0) {
373375
cv = tcc->CCB[channel].reg;
374376
} else {
@@ -425,9 +427,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
425427
tc->COUNT16.CC[0].reg = new_top;
426428
#endif
427429
#ifdef SAMD51
428-
while (tc->COUNT16.SYNCBUSY.reg != 0) {
429-
/* Wait for sync */
430-
}
430+
while (tc->COUNT16.SYNCBUSY.reg != 0) {}
431431
tc->COUNT16.CCBUF[0].reg = new_top;
432432
#endif
433433
} else {
@@ -438,14 +438,12 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
438438
tcc->CTRLA.bit.PRESCALER = new_divisor;
439439
tcc_set_enable(tcc, true);
440440
}
441+
while (tcc->SYNCBUSY.reg != 0) {}
441442
tcc_periods[t->index] = new_top;
442443
#ifdef SAMD21
443444
tcc->PERB.bit.PERB = new_top;
444445
#endif
445446
#ifdef SAMD51
446-
while (tcc->SYNCBUSY.reg != 0) {
447-
/* Wait for sync */
448-
}
449447
tcc->PERBUF.bit.PERBUF = new_top;
450448
#endif
451449
}

0 commit comments

Comments
 (0)
0