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) {
228230extern 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
241241uint16_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 );
0 commit comments