39
39
# define TCC_SIZES { MREPEAT(TCC_INST_NUM, _TCC_SIZE, 0) }
40
40
41
41
uint32_t target_timer_frequencies [TC_INST_NUM + TCC_INST_NUM ];
42
+ static uint32_t timer_periods [TC_INST_NUM + TCC_INST_NUM ];
42
43
uint8_t timer_refcount [TC_INST_NUM + TCC_INST_NUM ];
43
44
const uint16_t prescaler [8 ] = {1 , 2 , 4 , 8 , 16 , 64 , 256 , 1024 };
44
45
@@ -88,6 +89,10 @@ bool channel_ok(const pin_timer_t* t, uint8_t index) {
88
89
t -> is_tc ;
89
90
}
90
91
92
+ static uint8_t timer_index (uint32_t base_timer_address ) {
93
+ return (base_timer_address - ((uint32_t ) TCC0 )) / 0x400 ;
94
+ }
95
+
91
96
void common_hal_pulseio_pwmout_construct (pulseio_pwmout_obj_t * self ,
92
97
const mcu_pin_obj_t * pin ,
93
98
uint16_t duty ,
@@ -107,10 +112,10 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
107
112
uint16_t primary_timer_index = 0xff ;
108
113
uint16_t secondary_timer_index = 0xff ;
109
114
if (pin -> primary_timer .tc != NULL ) {
110
- primary_timer_index = ((( uint32_t ) pin -> primary_timer .tcc ) - (( uint32_t ) TCC0 )) / 0x400 ;
115
+ primary_timer_index = timer_index (( uint32_t ) pin -> primary_timer .tcc );
111
116
}
112
117
if (pin -> secondary_timer .tc != NULL ) {
113
- secondary_timer_index = ((( uint32_t ) pin -> secondary_timer .tcc ) - (( uint32_t ) TCC0 )) / 0x400 ;
118
+ secondary_timer_index = timer_index (( uint32_t ) pin -> secondary_timer .tcc );
114
119
}
115
120
116
121
// Figure out which timer we are using.
@@ -159,6 +164,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
159
164
mp_raise_RuntimeError ("All timers in use" );
160
165
return ;
161
166
}
167
+
162
168
uint8_t resolution = 0 ;
163
169
if (t -> is_tc ) {
164
170
resolution = 16 ;
@@ -177,7 +183,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
177
183
break ;
178
184
}
179
185
}
180
- self -> period = top ;
186
+ timer_periods [ index ] = top ;
181
187
if (t -> is_tc ) {
182
188
struct tc_config config_tc ;
183
189
tc_get_config_defaults (& config_tc );
@@ -258,11 +264,14 @@ extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
258
264
259
265
extern void common_hal_pulseio_pwmout_set_duty_cycle (pulseio_pwmout_obj_t * self , uint16_t duty ) {
260
266
const pin_timer_t * t = self -> timer ;
267
+ uint8_t index ;
261
268
if (t -> is_tc ) {
262
- uint16_t adjusted_duty = self -> period * duty / 0xffff ;
269
+ index = timer_index ((uint32_t ) self -> timer -> tc );
270
+ uint16_t adjusted_duty = timer_periods [index ] * duty / 0xffff ;
263
271
tc_set_compare_value (& self -> tc_instance , t -> channel , adjusted_duty );
264
272
} else {
265
- uint32_t adjusted_duty = ((uint64_t ) self -> period ) * duty / 0xffff ;
273
+ index = timer_index ((uint32_t ) self -> timer -> tcc );
274
+ uint32_t adjusted_duty = ((uint64_t ) timer_periods [index ]) * duty / 0xffff ;
266
275
tcc_set_compare_value (& self -> tcc_instance , t -> channel , adjusted_duty );
267
276
}
268
277
}
@@ -274,7 +283,7 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
274
283
/* Wait for sync */
275
284
}
276
285
uint16_t cv = t -> tc -> COUNT16 .CC [t -> channel ].reg ;
277
- return cv * 0xffff / self -> period ;
286
+ return cv * 0xffff / timer_periods [ timer_index (( uint32_t ) self -> timer -> tc )] ;
278
287
} else {
279
288
uint32_t cv = 0 ;
280
289
if ((t -> tcc -> STATUS .vec .CCBV & (1 << t -> channel )) != 0 ) {
@@ -283,7 +292,7 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
283
292
cv = t -> tcc -> CC [t -> channel ].reg ;
284
293
}
285
294
286
- uint32_t duty_cycle = ((uint64_t ) cv ) * 0xffff / self -> period ;
295
+ uint32_t duty_cycle = ((uint64_t ) cv ) * 0xffff / timer_periods [ timer_index (( uint32_t ) self -> timer -> tcc )] ;
287
296
288
297
return duty_cycle ;
289
298
}
@@ -313,9 +322,12 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
313
322
}
314
323
uint16_t old_duty = common_hal_pulseio_pwmout_get_duty_cycle (self );
315
324
uint8_t old_divisor ;
325
+ uint8_t index ;
316
326
if (t -> is_tc ) {
327
+ index = timer_index ((uint32_t ) self -> timer -> tc );
317
328
old_divisor = t -> tc -> COUNT16 .CTRLA .bit .PRESCALER ;
318
329
} else {
330
+ index = timer_index ((uint32_t ) self -> timer -> tcc );
319
331
old_divisor = t -> tcc -> CTRLA .bit .PRESCALER ;
320
332
}
321
333
if (new_divisor != old_divisor ) {
@@ -329,7 +341,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
329
341
tcc_enable (& self -> tcc_instance );
330
342
}
331
343
}
332
- self -> period = new_top ;
344
+ timer_periods [ index ] = new_top ;
333
345
if (t -> is_tc ) {
334
346
while (tc_is_syncing (& self -> tc_instance )) {
335
347
/* Wait for sync */
@@ -345,18 +357,16 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
345
357
uint32_t common_hal_pulseio_pwmout_get_frequency (pulseio_pwmout_obj_t * self ) {
346
358
uint32_t system_clock = system_cpu_clock_get_hz ();
347
359
const pin_timer_t * t = self -> timer ;
348
- uint32_t top ;
360
+ uint8_t index ;
349
361
uint8_t divisor ;
350
362
if (t -> is_tc ) {
351
- top = t -> tc -> COUNT16 . CC [ 0 ]. reg ;
363
+ index = timer_index (( uint32_t ) self -> timer -> tc ) ;
352
364
divisor = t -> tc -> COUNT16 .CTRLA .bit .PRESCALER ;
353
365
} else {
354
- top = t -> tcc -> PER .reg ;
355
- if (t -> tcc -> STATUS .bit .PERBV ) {
356
- top = t -> tcc -> PERB .reg ;
357
- }
366
+ index = timer_index ((uint32_t ) self -> timer -> tcc );
358
367
divisor = t -> tcc -> CTRLA .bit .PRESCALER ;
359
368
}
369
+ uint32_t top = timer_periods [index ];
360
370
return (system_clock / prescaler [divisor ]) / (top + 1 );
361
371
}
362
372
0 commit comments