35
35
#include STM32_HAL_H
36
36
#include "common-hal/microcontroller/Pin.h"
37
37
38
+ #include "timers.h"
39
+
38
40
#define ALL_CLOCKS 0xFFFF
39
41
40
42
STATIC uint8_t reserved_tim [TIM_BANK_ARRAY_LEN ];
41
43
STATIC uint32_t tim_frequencies [TIM_BANK_ARRAY_LEN ];
42
44
STATIC bool never_reset_tim [TIM_BANK_ARRAY_LEN ];
43
45
44
- STATIC void tim_clock_enable (uint16_t mask );
45
- STATIC void tim_clock_disable (uint16_t mask );
46
-
47
- // Get the frequency (in Hz) of the source clock for the given timer.
48
- // On STM32F405/407/415/417 there are 2 cases for how the clock freq is set.
49
- // If the APB prescaler is 1, then the timer clock is equal to its respective
50
- // APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its
51
- // respective APB clock. See DM00031020 Rev 4, page 115.
52
- STATIC uint32_t timer_get_source_freq (uint32_t tim_id ) {
53
- uint32_t source , clk_div ;
54
- if (tim_id == 1 || (8 <= tim_id && tim_id <= 11 )) {
55
- // TIM{1,8,9,10,11} are on APB2
56
- source = HAL_RCC_GetPCLK2Freq ();
57
- clk_div = RCC -> CFGR & RCC_CFGR_PPRE2 ;
58
- } else {
59
- // TIM{2,3,4,5,6,7,12,13,14} are on APB1
60
- source = HAL_RCC_GetPCLK1Freq ();
61
- clk_div = RCC -> CFGR & RCC_CFGR_PPRE1 ;
62
- }
63
- if (clk_div != 0 ) {
64
- // APB prescaler for this timer is > 1
65
- source *= 2 ;
66
- }
67
- return source ;
68
- }
69
-
70
46
STATIC uint32_t timer_get_internal_duty (uint16_t duty , uint32_t period ) {
71
47
//duty cycle is duty/0xFFFF fraction x (number of pulses per period)
72
48
return (duty * period ) / ((1 << 16 ) - 1 );
@@ -97,7 +73,6 @@ void pwmout_reset(void) {
97
73
never_reset_mask |= 1 << i ;
98
74
}
99
75
}
100
- tim_clock_disable (ALL_CLOCKS & ~(never_reset_mask ));
101
76
}
102
77
103
78
pwmout_result_t common_hal_pulseio_pwmout_construct (pulseio_pwmout_obj_t * self ,
@@ -107,6 +82,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
107
82
bool variable_frequency ) {
108
83
TIM_TypeDef * TIMx ;
109
84
uint8_t tim_num = MP_ARRAY_SIZE (mcu_tim_pin_list );
85
+ bool tim_taken_internal = false;
110
86
bool tim_chan_taken = false;
111
87
bool tim_taken_f_mismatch = false;
112
88
bool var_freq_mismatch = false;
@@ -119,8 +95,13 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
119
95
120
96
//if pin is same
121
97
if (l_tim -> pin == pin ) {
122
- //check if the timer has a channel active
98
+ //check if the timer has a channel active, or is reserved by main timer system
123
99
if (reserved_tim [l_tim_index ] != 0 ) {
100
+ // Timer has already been reserved by an internal module
101
+ if (stm_peripherals_timer_is_reserved (mcu_tim_banks [l_tim_index ])) {
102
+ tim_taken_internal = true;
103
+ continue ; //keep looking
104
+ }
124
105
//is it the same channel? (or all channels reserved by a var-freq)
125
106
if (reserved_tim [l_tim_index ] & 1 << (l_tim_channel )) {
126
107
tim_chan_taken = true;
@@ -155,9 +136,12 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
155
136
reserved_tim [self -> tim -> tim_index - 1 ] |= 1 << (self -> tim -> channel_index - 1 );
156
137
}
157
138
tim_frequencies [self -> tim -> tim_index - 1 ] = frequency ;
139
+ stm_peripherals_timer_reserve (TIMx );
158
140
} else { //no match found
159
141
if (tim_chan_taken ) {
160
142
mp_raise_ValueError (translate ("No more timers available on this pin." ));
143
+ } else if (tim_taken_internal ) {
144
+ mp_raise_ValueError (translate ("Timer was reserved for internal use - declare PWM pins earlier in the program" ));
161
145
} else if (tim_taken_f_mismatch ) {
162
146
mp_raise_ValueError (translate ("Frequency must match existing PWMOut using this timer" ));
163
147
} else if (var_freq_mismatch ) {
@@ -182,8 +166,8 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
182
166
183
167
uint32_t prescaler = 0 ; //prescaler is 15 bit
184
168
uint32_t period = 0 ; //period is 16 bit
185
- timer_get_optimal_divisors ( & period , & prescaler , frequency ,
186
- timer_get_source_freq ( self -> tim -> tim_index ) );
169
+ uint32_t source_freq = stm_peripherals_timer_get_source_freq ( TIMx );
170
+ timer_get_optimal_divisors ( & period , & prescaler , frequency , source_freq );
187
171
188
172
//Timer init
189
173
self -> handle .Instance = TIMx ;
@@ -282,8 +266,8 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_
282
266
283
267
uint32_t prescaler = 0 ;
284
268
uint32_t period = 0 ;
285
- timer_get_optimal_divisors ( & period , & prescaler , frequency ,
286
- timer_get_source_freq ( self -> tim -> tim_index ) );
269
+ uint32_t source_freq = stm_peripherals_timer_get_source_freq ( self -> handle . Instance );
270
+ timer_get_optimal_divisors ( & period , & prescaler , frequency , source_freq );
287
271
288
272
//shut down
289
273
HAL_TIM_PWM_Stop (& self -> handle , self -> channel );
@@ -318,131 +302,3 @@ uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
318
302
bool common_hal_pulseio_pwmout_get_variable_frequency (pulseio_pwmout_obj_t * self ) {
319
303
return self -> variable_frequency ;
320
304
}
321
-
322
- STATIC void tim_clock_enable (uint16_t mask ) {
323
- #ifdef TIM1
324
- if (mask & (1 << 0 )) {
325
- __HAL_RCC_TIM1_CLK_ENABLE ();
326
- }
327
- #endif
328
- #ifdef TIM2
329
- if (mask & (1 << 1 )) {
330
- __HAL_RCC_TIM2_CLK_ENABLE ();
331
- }
332
- #endif
333
- #ifdef TIM3
334
- if (mask & (1 << 2 )) {
335
- __HAL_RCC_TIM3_CLK_ENABLE ();
336
- }
337
- #endif
338
- #ifdef TIM4
339
- if (mask & (1 << 3 )) {
340
- __HAL_RCC_TIM4_CLK_ENABLE ();
341
- }
342
- #endif
343
- #ifdef TIM5
344
- if (mask & (1 << 4 )) {
345
- __HAL_RCC_TIM5_CLK_ENABLE ();
346
- }
347
- #endif
348
- //6 and 7 are reserved ADC timers
349
- #ifdef TIM8
350
- if (mask & (1 << 7 )) {
351
- __HAL_RCC_TIM8_CLK_ENABLE ();
352
- }
353
- #endif
354
- #ifdef TIM9
355
- if (mask & (1 << 8 )) {
356
- __HAL_RCC_TIM9_CLK_ENABLE ();
357
- }
358
- #endif
359
- #ifdef TIM10
360
- if (mask & (1 << 9 )) {
361
- __HAL_RCC_TIM10_CLK_ENABLE ();
362
- }
363
- #endif
364
- #ifdef TIM11
365
- if (mask & (1 << 10 )) {
366
- __HAL_RCC_TIM11_CLK_ENABLE ();
367
- }
368
- #endif
369
- #ifdef TIM12
370
- if (mask & (1 << 11 )) {
371
- __HAL_RCC_TIM12_CLK_ENABLE ();
372
- }
373
- #endif
374
- #ifdef TIM13
375
- if (mask & (1 << 12 )) {
376
- __HAL_RCC_TIM13_CLK_ENABLE ();
377
- }
378
- #endif
379
- #ifdef TIM14
380
- if (mask & (1 << 13 )) {
381
- __HAL_RCC_TIM14_CLK_ENABLE ();
382
- }
383
- #endif
384
- }
385
-
386
- STATIC void tim_clock_disable (uint16_t mask ) {
387
- #ifdef TIM1
388
- if (mask & (1 << 0 )) {
389
- __HAL_RCC_TIM1_CLK_DISABLE ();
390
- }
391
- #endif
392
- #ifdef TIM2
393
- if (mask & (1 << 1 )) {
394
- __HAL_RCC_TIM2_CLK_DISABLE ();
395
- }
396
- #endif
397
- #ifdef TIM3
398
- if (mask & (1 << 2 )) {
399
- __HAL_RCC_TIM3_CLK_DISABLE ();
400
- }
401
- #endif
402
- #ifdef TIM4
403
- if (mask & (1 << 3 )) {
404
- __HAL_RCC_TIM4_CLK_DISABLE ();
405
- }
406
- #endif
407
- #ifdef TIM5
408
- if (mask & (1 << 4 )) {
409
- __HAL_RCC_TIM5_CLK_DISABLE ();
410
- }
411
- #endif
412
- //6 and 7 are reserved ADC timers
413
- #ifdef TIM8
414
- if (mask & (1 << 7 )) {
415
- __HAL_RCC_TIM8_CLK_DISABLE ();
416
- }
417
- #endif
418
- #ifdef TIM9
419
- if (mask & (1 << 8 )) {
420
- __HAL_RCC_TIM9_CLK_DISABLE ();
421
- }
422
- #endif
423
- #ifdef TIM10
424
- if (mask & (1 << 9 )) {
425
- __HAL_RCC_TIM10_CLK_DISABLE ();
426
- }
427
- #endif
428
- #ifdef TIM11
429
- if (mask & (1 << 10 )) {
430
- __HAL_RCC_TIM11_CLK_DISABLE ();
431
- }
432
- #endif
433
- #ifdef TIM12
434
- if (mask & (1 << 11 )) {
435
- __HAL_RCC_TIM12_CLK_DISABLE ();
436
- }
437
- #endif
438
- #ifdef TIM13
439
- if (mask & (1 << 12 )) {
440
- __HAL_RCC_TIM13_CLK_DISABLE ();
441
- }
442
- #endif
443
- #ifdef TIM14
444
- if (mask & (1 << 13 )) {
445
- __HAL_RCC_TIM14_CLK_DISABLE ();
446
- }
447
- #endif
448
- }
0 commit comments