@@ -249,34 +249,41 @@ extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uin
249249    // Track it here so that if frequency is changed we can use this value to recalculate the 
250250    // proper duty cycle. 
251251    // See https://github.com/adafruit/circuitpython/issues/2086 for more details 
252- 
253252    self -> duty_cycle  =  duty ;
253+ 
254254    const  pin_timer_t  * t  =  self -> timer ;
255255    if  (t -> is_tc ) {
256256        uint16_t  adjusted_duty  =  tc_periods [t -> index ] *  duty  / 0xffff ;
257-         if  (adjusted_duty  ==  0  &&  duty  !=  0 ) {
258-             adjusted_duty  =  1 ; // prevent rounding down to 0 
259-         }
260257        #ifdef  SAMD21 
261258        tc_insts [t -> index ]-> COUNT16 .CC [t -> wave_output ].reg  =  adjusted_duty ;
262259        #endif 
263260        #ifdef  SAM_D5X_E5X 
264261        Tc  * tc  =  tc_insts [t -> index ];
262+         while  (tc -> COUNT16 .SYNCBUSY .bit .CC1  !=  0 ) {
263+         }
265264        tc -> COUNT16 .CCBUF [1 ].reg  =  adjusted_duty ;
266265        #endif 
267266    } else  {
268267        uint32_t  adjusted_duty  =  ((uint64_t )tcc_periods [t -> index ]) *  duty  / 0xffff ;
269-         if  (adjusted_duty  ==  0  &&  duty  !=  0 ) {
270-             adjusted_duty  =  1 ; // prevent rounding down to 0 
271-         }
272268        uint8_t  channel  =  tcc_channel (t );
273269        Tcc  * tcc  =  tcc_insts [t -> index ];
270+ 
271+         // Write into the CC buffer register, which will be transferred to the 
272+         // CC register on an UPDATE (when period is finished). 
273+         // Do clock domain syncing as necessary. 
274+ 
275+         while  (tcc -> SYNCBUSY .reg  !=  0 ) {
276+         }
277+ 
278+         // Lock out double-buffering while updating the CCB value. 
279+         tcc -> CTRLBSET .bit .LUPD  =  1 ;
274280        #ifdef  SAMD21 
275281        tcc -> CCB [channel ].reg  =  adjusted_duty ;
276282        #endif 
277283        #ifdef  SAM_D5X_E5X 
278284        tcc -> CCBUF [channel ].reg  =  adjusted_duty ;
279285        #endif 
286+         tcc -> CTRLBCLR .bit .LUPD  =  1 ;
280287    }
281288}
282289
0 commit comments