3
3
*
4
4
* The MIT License (MIT)
5
5
*
6
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
7
6
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
8
7
* Uses code from Micropython, Copyright (c) 2013-2016 Damien P. George
9
8
*
@@ -46,7 +45,13 @@ STATIC bool never_reset_tim[TIM_BANK_ARRAY_LEN];
46
45
STATIC void tim_clock_enable (uint16_t mask );
47
46
STATIC void tim_clock_disable (uint16_t mask );
48
47
49
- // Get the frequency (in Hz)
48
+ RCC -> CFGR & RCC_CFGR_PPRE1
49
+
50
+ // Get the frequency (in Hz) of the source clock for the given timer.
51
+ // On STM32F405/407/415/417 there are 2 cases for how the clock freq is set.
52
+ // If the APB prescaler is 1, then the timer clock is equal to its respective
53
+ // APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its
54
+ // respective APB clock. See DM00031020 Rev 4, page 115.
50
55
static uint32_t timer_get_source_freq (uint32_t tim_id ) {
51
56
uint32_t source , clk_div ;
52
57
if (tim_id == 1 || (8 <= tim_id && tim_id <= 11 )) {
@@ -68,7 +73,7 @@ static uint32_t timer_get_source_freq(uint32_t tim_id) {
68
73
void pwmout_reset (void ) {
69
74
uint16_t never_reset_mask = 0x00 ;
70
75
for (int i = 0 ;i < TIM_BANK_ARRAY_LEN ;i ++ ) {
71
- if (!never_reset_tim [i ]) {
76
+ if (!never_reset_tim [i ]) {
72
77
reserved_tim [i ] = 0x00 ;
73
78
tim_frequencies [i ] = 0x00 ;
74
79
} else {
@@ -89,8 +94,6 @@ void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
89
94
}
90
95
91
96
void common_hal_pulseio_pwmout_reset_ok (pulseio_pwmout_obj_t * self ) {
92
- //TODO: doesn't this need an equivalent release pin in microcontroller.c?
93
- //I don't see that implemented in any port.
94
97
for (size_t i = 0 ; i < TIM_BANK_ARRAY_LEN ; i ++ ) {
95
98
if (mcu_tim_banks [i ] == self -> handle .Instance ) {
96
99
never_reset_tim [i ] = false;
@@ -106,36 +109,32 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
106
109
bool variable_frequency ) {
107
110
if (frequency == 0 || frequency > 6000000 ) {
108
111
mp_raise_ValueError (translate ("Invalid frequency supplied" ));
109
- //return PWMOUT_INVALID_FREQUENCY;
110
112
}
111
113
112
114
TIM_TypeDef * TIMx ;
113
- //TODO: style/safety question, use this instead?
114
- //uint8_t tim_num_pins = TIM_PIN_ARRAY_LEN;
115
115
uint8_t tim_num = sizeof (mcu_tim_pin_list )/sizeof (* mcu_tim_pin_list );
116
- //TODO: use an enum to make this prettier?
117
116
bool tim_chan_taken = false;
118
117
bool tim_taken_f_mismatch = false;
119
118
bool var_freq_mismatch = false;
120
119
bool first_time_setup = true;
121
120
122
121
for (uint i = 0 ; i < tim_num ; i ++ ) {
123
122
//if pin is same
124
- if (mcu_tim_pin_list [i ].pin == pin ) {
123
+ if (mcu_tim_pin_list [i ].pin == pin ) {
125
124
//check if the timer has a channel active
126
125
if (reserved_tim [mcu_tim_pin_list [i ].tim_index - 1 ] != 0 ) {
127
126
//is it the same channel? (or all channels reserved by a var-freq)
128
- if (reserved_tim [mcu_tim_pin_list [i ].tim_index - 1 ] & 1 <<(mcu_tim_pin_list [i ].channel_index - 1 )) {
127
+ if (reserved_tim [mcu_tim_pin_list [i ].tim_index - 1 ] & 1 <<(mcu_tim_pin_list [i ].channel_index - 1 )) {
129
128
tim_chan_taken = true;
130
129
continue ; //keep looking, might be another viable option
131
130
}
132
131
//If the frequencies are the same it's ok
133
- if (tim_frequencies [mcu_tim_pin_list [i ].tim_index - 1 ] != frequency ) {
132
+ if (tim_frequencies [mcu_tim_pin_list [i ].tim_index - 1 ] != frequency ) {
134
133
tim_taken_f_mismatch = true;
135
134
continue ; //keep looking
136
135
}
137
136
//you can't put a variable frequency on a partially reserved timer
138
- if (variable_frequency ) {
137
+ if (variable_frequency ) {
139
138
var_freq_mismatch = true;
140
139
continue ; //keep looking
141
140
}
@@ -148,9 +147,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
148
147
}
149
148
150
149
//handle valid/invalid timer instance
151
- //TODO: why doesn't PWM handle its own value errors like every other module?
152
- //The samd value errors don't really fit for STM32.
153
- if (self -> tim != NULL ) {
150
+ if (self -> tim != NULL ) {
154
151
//create instance
155
152
TIMx = mcu_tim_banks [self -> tim -> tim_index - 1 ];
156
153
//reserve timer/channel
@@ -162,17 +159,13 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
162
159
tim_frequencies [self -> tim -> tim_index - 1 ] = frequency ;
163
160
} else { //no match found
164
161
if (tim_chan_taken ) {
165
- mp_raise_ValueError (translate ("Timer hardware is reserved" ));
166
- //return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
162
+ mp_raise_ValueError (translate ("No more timers available on this pin." ));
167
163
} else if (tim_taken_f_mismatch ) {
168
- mp_raise_ValueError (translate ("Frequency mismatch with existing reserved channel" ));
169
- //return PWMOUT_INVALID_FREQUENCY;
164
+ mp_raise_ValueError (translate ("Frequency must be the same as as the existing PWMOut using this timer" ));
170
165
} else if (var_freq_mismatch ) {
171
- mp_raise_ValueError (translate ("Cannot vary frequency of a partially reserved timer" ));
172
- //return PWMOUT_INVALID_FREQUENCY; //I guess?
166
+ mp_raise_ValueError (translate ("Cannot vary frequency on a timer that is already in use" ));
173
167
} else {
174
168
mp_raise_ValueError (translate ("Invalid pins" ));
175
- //return PWMOUT_INVALID_PIN;
176
169
}
177
170
}
178
171
@@ -197,7 +190,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
197
190
198
191
uint32_t source_freq = timer_get_source_freq (self -> tim -> tim_index );
199
192
uint32_t period = PWM_MAX_FREQ /frequency ;
200
- //TODO: remove before merging.
193
+ //Used for Debugging
201
194
// mp_printf(&mp_plat_print, "SysCoreClock: %d\n", SystemCoreClock);
202
195
// mp_printf(&mp_plat_print, "Source Freq: %d\n", source_freq);
203
196
// mp_printf(&mp_plat_print, "Timer Freq: %d\n", source_freq/(source_freq / PWM_MAX_FREQ));
@@ -214,8 +207,8 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
214
207
self -> handle .Init .RepetitionCounter = 0 ;
215
208
216
209
//only run init if this is the first instance of this timer
217
- if (first_time_setup ) {
218
- if (HAL_TIM_PWM_Init (& self -> handle ) != HAL_OK ) {
210
+ if (first_time_setup ) {
211
+ if (HAL_TIM_PWM_Init (& self -> handle ) != HAL_OK ) {
219
212
mp_raise_ValueError (translate ("Timer Init Error" ));
220
213
}
221
214
}
@@ -228,10 +221,10 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
228
221
self -> chan_handle .OCNPolarity = TIM_OCNPOLARITY_LOW ; // needed for TIM1 and TIM8
229
222
self -> chan_handle .OCIdleState = TIM_OCIDLESTATE_SET ; // needed for TIM1 and TIM8
230
223
self -> chan_handle .OCNIdleState = TIM_OCNIDLESTATE_SET ; // needed for TIM1 and TIM8
231
- if (HAL_TIM_PWM_ConfigChannel (& self -> handle , & self -> chan_handle , self -> channel ) != HAL_OK ) {
224
+ if (HAL_TIM_PWM_ConfigChannel (& self -> handle , & self -> chan_handle , self -> channel ) != HAL_OK ) {
232
225
mp_raise_ValueError (translate ("Channel Init Error" ));
233
226
}
234
- if (HAL_TIM_PWM_Start (& self -> handle , self -> channel ) != HAL_OK ) {
227
+ if (HAL_TIM_PWM_Start (& self -> handle , self -> channel ) != HAL_OK ) {
235
228
mp_raise_ValueError (translate ("Error starting PWM" ));
236
229
}
237
230
@@ -251,7 +244,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
251
244
return ;
252
245
}
253
246
//var freq shuts down entire timer, others just their channel
254
- if (self -> variable_frequency ) {
247
+ if (self -> variable_frequency ) {
255
248
reserved_tim [self -> tim -> tim_index - 1 ] = 0x00 ;
256
249
} else {
257
250
reserved_tim [self -> tim -> tim_index - 1 ] &= ~(1 <<self -> tim -> channel_index );
@@ -271,7 +264,7 @@ void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16
271
264
uint16_t duty = duty_cycle /655 ;
272
265
uint32_t period = PWM_MAX_FREQ /self -> frequency ;
273
266
uint32_t input = (period * duty )/100 ;
274
- //TODO: remove before merging
267
+ //Used for debugging
275
268
//mp_printf(&mp_plat_print, "duty_cycle %d, Duty: %d, Input %d\n", duty_cycle, duty, input);
276
269
__HAL_TIM_SET_COMPARE (& self -> handle , self -> channel , input );
277
270
@@ -299,14 +292,14 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_
299
292
self -> handle .Init .Prescaler = (source_freq / PWM_MAX_FREQ ) - 1 ; // TIM runs at ~6MHz
300
293
301
294
//restart everything, adjusting for new speed
302
- if (HAL_TIM_PWM_Init (& self -> handle ) != HAL_OK ) {
295
+ if (HAL_TIM_PWM_Init (& self -> handle ) != HAL_OK ) {
303
296
mp_raise_ValueError (translate ("Timer Re-Init Error" ));
304
297
}
305
298
self -> chan_handle .Pulse = (period * self -> duty_cycle )/100 - 1 ;
306
- if (HAL_TIM_PWM_ConfigChannel (& self -> handle , & self -> chan_handle , self -> channel ) != HAL_OK ) {
299
+ if (HAL_TIM_PWM_ConfigChannel (& self -> handle , & self -> chan_handle , self -> channel ) != HAL_OK ) {
307
300
mp_raise_ValueError (translate ("Channel Re-Init Error" ));
308
301
}
309
- if (HAL_TIM_PWM_Start (& self -> handle , self -> channel ) != HAL_OK ) {
302
+ if (HAL_TIM_PWM_Start (& self -> handle , self -> channel ) != HAL_OK ) {
310
303
mp_raise_ValueError (translate ("Error restarting PWM" ));
311
304
}
312
305
@@ -324,80 +317,80 @@ bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self
324
317
325
318
STATIC void tim_clock_enable (uint16_t mask ) {
326
319
#ifdef TIM1
327
- if (mask & 1 <<0 ) __HAL_RCC_TIM1_CLK_ENABLE ();
320
+ if (mask & 1 <<0 ) __HAL_RCC_TIM1_CLK_ENABLE ();
328
321
#endif
329
322
#ifdef TIM2
330
- if (mask & 1 <<1 ) __HAL_RCC_TIM2_CLK_ENABLE ();
323
+ if (mask & 1 <<1 ) __HAL_RCC_TIM2_CLK_ENABLE ();
331
324
#endif
332
325
#ifdef TIM3
333
- if (mask & 1 <<2 ) __HAL_RCC_TIM3_CLK_ENABLE ();
326
+ if (mask & 1 <<2 ) __HAL_RCC_TIM3_CLK_ENABLE ();
334
327
#endif
335
328
#ifdef TIM4
336
- if (mask & 1 <<3 ) __HAL_RCC_TIM4_CLK_ENABLE ();
329
+ if (mask & 1 <<3 ) __HAL_RCC_TIM4_CLK_ENABLE ();
337
330
#endif
338
331
#ifdef TIM5
339
- if (mask & 1 <<4 ) __HAL_RCC_TIM5_CLK_ENABLE ();
332
+ if (mask & 1 <<4 ) __HAL_RCC_TIM5_CLK_ENABLE ();
340
333
#endif
341
334
//6 and 7 are reserved ADC timers
342
335
#ifdef TIM8
343
- if (mask & 1 <<7 ) __HAL_RCC_TIM8_CLK_ENABLE ();
336
+ if (mask & 1 <<7 ) __HAL_RCC_TIM8_CLK_ENABLE ();
344
337
#endif
345
338
#ifdef TIM9
346
- if (mask & 1 <<8 ) __HAL_RCC_TIM9_CLK_ENABLE ();
339
+ if (mask & 1 <<8 ) __HAL_RCC_TIM9_CLK_ENABLE ();
347
340
#endif
348
341
#ifdef TIM10
349
- if (mask & 1 <<9 ) __HAL_RCC_TIM10_CLK_ENABLE ();
342
+ if (mask & 1 <<9 ) __HAL_RCC_TIM10_CLK_ENABLE ();
350
343
#endif
351
344
#ifdef TIM11
352
- if (mask & 1 <<10 ) __HAL_RCC_TIM11_CLK_ENABLE ();
345
+ if (mask & 1 <<10 ) __HAL_RCC_TIM11_CLK_ENABLE ();
353
346
#endif
354
347
#ifdef TIM12
355
- if (mask & 1 <<11 ) __HAL_RCC_TIM12_CLK_ENABLE ();
348
+ if (mask & 1 <<11 ) __HAL_RCC_TIM12_CLK_ENABLE ();
356
349
#endif
357
350
#ifdef TIM13
358
- if (mask & 1 <<12 ) __HAL_RCC_TIM13_CLK_ENABLE ();
351
+ if (mask & 1 <<12 ) __HAL_RCC_TIM13_CLK_ENABLE ();
359
352
#endif
360
353
#ifdef TIM14
361
- if (mask & 1 <<13 ) __HAL_RCC_TIM14_CLK_ENABLE ();
354
+ if (mask & 1 <<13 ) __HAL_RCC_TIM14_CLK_ENABLE ();
362
355
#endif
363
356
}
364
357
365
358
STATIC void tim_clock_disable (uint16_t mask ) {
366
359
#ifdef TIM1
367
- if (mask & 1 <<0 ) __HAL_RCC_TIM1_CLK_DISABLE ();
360
+ if (mask & 1 <<0 ) __HAL_RCC_TIM1_CLK_DISABLE ();
368
361
#endif
369
362
#ifdef TIM2
370
- if (mask & 1 <<1 ) __HAL_RCC_TIM2_CLK_DISABLE ();
363
+ if (mask & 1 <<1 ) __HAL_RCC_TIM2_CLK_DISABLE ();
371
364
#endif
372
365
#ifdef TIM3
373
- if (mask & 1 <<2 ) __HAL_RCC_TIM3_CLK_DISABLE ();
366
+ if (mask & 1 <<2 ) __HAL_RCC_TIM3_CLK_DISABLE ();
374
367
#endif
375
368
#ifdef TIM4
376
- if (mask & 1 <<3 ) __HAL_RCC_TIM4_CLK_DISABLE ();
369
+ if (mask & 1 <<3 ) __HAL_RCC_TIM4_CLK_DISABLE ();
377
370
#endif
378
371
#ifdef TIM5
379
- if (mask & 1 <<4 ) __HAL_RCC_TIM5_CLK_DISABLE ();
372
+ if (mask & 1 <<4 ) __HAL_RCC_TIM5_CLK_DISABLE ();
380
373
#endif
381
374
//6 and 7 are reserved ADC timers
382
375
#ifdef TIM8
383
- if (mask & 1 <<7 ) __HAL_RCC_TIM8_CLK_DISABLE ();
376
+ if (mask & 1 <<7 ) __HAL_RCC_TIM8_CLK_DISABLE ();
384
377
#endif
385
378
#ifdef TIM9
386
- if (mask & 1 <<8 ) __HAL_RCC_TIM9_CLK_DISABLE ();
379
+ if (mask & 1 <<8 ) __HAL_RCC_TIM9_CLK_DISABLE ();
387
380
#endif
388
381
#ifdef TIM10
389
- if (mask & 1 <<9 ) __HAL_RCC_TIM10_CLK_DISABLE ();
382
+ if (mask & 1 <<9 ) __HAL_RCC_TIM10_CLK_DISABLE ();
390
383
#endif
391
384
#ifdef TIM11
392
- if (mask & 1 <<10 ) __HAL_RCC_TIM11_CLK_DISABLE ();
385
+ if (mask & 1 <<10 ) __HAL_RCC_TIM11_CLK_DISABLE ();
393
386
#endif
394
387
#ifdef TIM12
395
- if (mask & 1 <<11 ) __HAL_RCC_TIM12_CLK_DISABLE ();
388
+ if (mask & 1 <<11 ) __HAL_RCC_TIM12_CLK_DISABLE ();
396
389
#endif
397
390
#ifdef TIM13
398
- if (mask & 1 <<12 ) __HAL_RCC_TIM13_CLK_DISABLE ();
391
+ if (mask & 1 <<12 ) __HAL_RCC_TIM13_CLK_DISABLE ();
399
392
#endif
400
393
#ifdef TIM14
401
- if (mask & 1 <<13 ) __HAL_RCC_TIM14_CLK_DISABLE ();
394
+ if (mask & 1 <<13 ) __HAL_RCC_TIM14_CLK_DISABLE ();
402
395
#endif
403
- }
396
+ }
0 commit comments