3
3
*
4
4
* The MIT License (MIT)
5
5
*
6
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
6
7
* Copyright (c) 2016 Damien P. George
7
8
*
8
9
* 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,
104
105
const pin_timer_t * t = NULL ;
105
106
uint8_t index = 0 ;
106
107
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 )) {
111
112
t = & pin -> primary_timer ;
112
113
index = primary_timer_index ;
113
114
} else if (!variable_frequency &&
@@ -153,6 +154,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
153
154
break ;
154
155
}
155
156
}
157
+ self -> period = top ;
156
158
if (t -> is_tc ) {
157
159
struct tc_config config_tc ;
158
160
tc_get_config_defaults (& config_tc );
@@ -228,34 +230,33 @@ extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
228
230
extern void common_hal_pulseio_pwmout_set_duty_cycle (pulseio_pwmout_obj_t * self , uint16_t duty ) {
229
231
const pin_timer_t * t = self -> timer ;
230
232
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 ;
233
234
tc_set_compare_value (& self -> tc_instance , t -> channel , adjusted_duty );
234
235
} 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 ;
237
237
tcc_set_compare_value (& self -> tcc_instance , t -> channel , adjusted_duty );
238
238
}
239
239
}
240
240
241
241
uint16_t common_hal_pulseio_pwmout_get_duty_cycle (pulseio_pwmout_obj_t * self ) {
242
242
const pin_timer_t * t = self -> timer ;
243
243
if (t -> is_tc ) {
244
- uint16_t top = t -> tc -> COUNT16 .CC [0 ].reg ;
245
244
while (tc_is_syncing (& self -> tc_instance )) {
246
245
/* Wait for sync */
247
246
}
248
247
uint16_t cv = t -> tc -> COUNT16 .CC [t -> channel ].reg ;
249
- return cv * 0xffff / top ;
248
+ return cv * 0xffff / self -> period ;
250
249
} else {
251
- uint32_t top = t -> tcc -> PER .reg ;
252
250
uint32_t cv = 0 ;
253
251
if ((t -> tcc -> STATUS .vec .CCBV & (1 << t -> channel )) != 0 ) {
254
252
cv = t -> tcc -> CCB [t -> channel ].reg ;
255
253
} else {
256
254
cv = t -> tcc -> CC [t -> channel ].reg ;
257
255
}
258
- return cv * 0xffff / top ;
256
+
257
+ uint32_t duty_cycle = ((uint64_t ) cv ) * 0xffff / self -> period ;
258
+
259
+ return duty_cycle ;
259
260
}
260
261
}
261
262
@@ -299,6 +300,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
299
300
tcc_enable (& self -> tcc_instance );
300
301
}
301
302
}
303
+ self -> period = new_top ;
302
304
if (t -> is_tc ) {
303
305
while (tc_is_syncing (& self -> tc_instance )) {
304
306
/* Wait for sync */
@@ -321,6 +323,9 @@ uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
321
323
divisor = t -> tc -> COUNT16 .CTRLA .bit .PRESCALER ;
322
324
} else {
323
325
top = t -> tcc -> PER .reg ;
326
+ if (t -> tcc -> STATUS .bit .PERBV ) {
327
+ top = t -> tcc -> PERB .reg ;
328
+ }
324
329
divisor = t -> tcc -> CTRLA .bit .PRESCALER ;
325
330
}
326
331
return (system_clock / prescaler [divisor ]) / (top + 1 );
0 commit comments