@@ -328,32 +328,29 @@ extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self,
328
328
#endif
329
329
#ifdef SAMD51
330
330
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 ) {}
338
332
tc -> COUNT16 .CCBUF [1 ].reg = adjusted_duty ;
339
333
#endif
340
334
} else {
341
335
uint32_t adjusted_duty = ((uint64_t ) tcc_periods [t -> index ]) * duty / 0xffff ;
342
336
uint8_t channel = tcc_channel (t );
343
337
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 ;
351
347
#ifdef SAMD21
352
348
tcc -> CCB [channel ].reg = adjusted_duty ;
353
349
#endif
354
350
#ifdef SAMD51
355
351
tcc -> CCBUF [channel ].reg = adjusted_duty ;
356
352
#endif
353
+ tcc -> CTRLBCLR .bit .LUPD = 1 ;
357
354
}
358
355
}
359
356
@@ -368,7 +365,12 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
368
365
Tcc * tcc = tcc_insts [t -> index ];
369
366
uint8_t channel = tcc_channel (t );
370
367
uint32_t cv = 0 ;
368
+
369
+ while (tcc -> SYNCBUSY .bit .CTRLB ) {}
370
+
371
371
#ifdef SAMD21
372
+ // If CCBV (CCB valid) is set, the CCB value hasn't yet been copied
373
+ // to the CC value.
372
374
if ((tcc -> STATUS .vec .CCBV & (1 << channel )) != 0 ) {
373
375
cv = tcc -> CCB [channel ].reg ;
374
376
} else {
@@ -425,9 +427,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
425
427
tc -> COUNT16 .CC [0 ].reg = new_top ;
426
428
#endif
427
429
#ifdef SAMD51
428
- while (tc -> COUNT16 .SYNCBUSY .reg != 0 ) {
429
- /* Wait for sync */
430
- }
430
+ while (tc -> COUNT16 .SYNCBUSY .reg != 0 ) {}
431
431
tc -> COUNT16 .CCBUF [0 ].reg = new_top ;
432
432
#endif
433
433
} else {
@@ -438,14 +438,12 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
438
438
tcc -> CTRLA .bit .PRESCALER = new_divisor ;
439
439
tcc_set_enable (tcc , true);
440
440
}
441
+ while (tcc -> SYNCBUSY .reg != 0 ) {}
441
442
tcc_periods [t -> index ] = new_top ;
442
443
#ifdef SAMD21
443
444
tcc -> PERB .bit .PERB = new_top ;
444
445
#endif
445
446
#ifdef SAMD51
446
- while (tcc -> SYNCBUSY .reg != 0 ) {
447
- /* Wait for sync */
448
- }
449
447
tcc -> PERBUF .bit .PERBUF = new_top ;
450
448
#endif
451
449
}
0 commit comments