Skyward boardcore
Loading...
Searching...
No Matches
TimerUtils.h
Go to the documentation of this file.
1/* Copyright (c) 2018-2021 Skyward Experimental Rocketry
2 * Authors: Luca Erbetta, Davide Mor, Alberto Nidasio
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include <utils/ClockUtils.h>
26
27#include <cassert>
28
29namespace Boardcore
30{
31
35namespace TimerUtils
36{
37
59enum class TriggerSource : uint16_t
60{
64 ITR0 = 0,
65
69 ITR1 = TIM_SMCR_TS_0,
70
74 ITR2 = TIM_SMCR_TS_1,
75
79 ITR3 = TIM_SMCR_TS_1 | TIM_SMCR_TS_0,
80
84 TI1F_ED = TIM_SMCR_TS_2,
85
89 TI1FP1 = TIM_SMCR_TS_2 | TIM_SMCR_TS_0,
90
94 TI2FP2 = TIM_SMCR_TS_2 | TIM_SMCR_TS_1
95};
96
97enum class MasterMode : uint32_t
98{
103 RESET = 0,
104
110 ENABLE = TIM_CR2_MMS_0,
111
118 UPDATE = TIM_CR2_MMS_1,
119
125 COMPARE_PULSE = TIM_CR2_MMS_1 | TIM_CR2_MMS_0,
126
130 OC1REF_OUTPUT = TIM_CR2_MMS_2,
131
135 OC2REF_OUTPUT = TIM_CR2_MMS_2 | TIM_CR2_MMS_0,
136
140 OC3REF_OUTPUT = TIM_CR2_MMS_2 | TIM_CR2_MMS_1,
141
145 OC4REF_OUTPUT = TIM_CR2_MMS
146};
147
148enum class SlaveMode : uint16_t
149{
155 DISABLED = 0,
156
163 RESET_MODE = TIM_SMCR_SMS_2,
164
175 GATED_MODE = TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0,
176
183 TRIGGER_MODE = TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1,
184
190 EXTERNAL_CLOCK_MODE_1 = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_2
191};
192
193enum class OutputCompareMode : uint16_t
194{
199 FROZEN = 0,
200
204 ACTIVE_ON_MATCH = 0x1,
205
209 INACTIVE_ON_MATCH = 0x2,
210
215 TOGGLE = 0x3,
216
220 FORCE_INACTIVE = 0x4,
221
225 FORCE_ACTIVE = 0x5,
226
231 PWM_MODE_1 = 0x6,
232
237 PWM_MODE_2 = 0x7
238};
239
240enum class OutputComparePolarity : uint16_t
241{
242 ACTIVE_HIGH = 0,
243 ACTIVE_LOW = 0x1
244};
245
246enum class Channel : uint8_t
247{
248 CHANNEL_1 = 0,
249 CHANNEL_2 = 1,
250 CHANNEL_3 = 2,
251 CHANNEL_4 = 3
252};
253
259ClockUtils::APB getTimerInputClock(const TIM_TypeDef* timer);
260
269uint32_t getPrescalerInputFrequency(const TIM_TypeDef* timer);
270
277uint32_t getFrequency(TIM_TypeDef* timer);
278
285float toMicroSeconds(TIM_TypeDef* timer, uint32_t value);
286
293float toMicroSeconds(TIM_TypeDef* timer);
294
303uint64_t toIntMicroSeconds(TIM_TypeDef* timer, uint32_t value);
304
313uint64_t toIntMicroSeconds(TIM_TypeDef* timer);
314
321float toMilliSeconds(TIM_TypeDef* timer, uint32_t value);
322
329float toMilliSeconds(TIM_TypeDef* timer);
330
337float toSeconds(TIM_TypeDef* timer);
338
344float getResolution(TIM_TypeDef* timer);
345
351float getMaxDuration(TIM_TypeDef* timer);
352
361uint16_t computePrescalerValue(TIM_TypeDef* timer, int targetFrequency);
362
367
368} // namespace TimerUtils
369
370inline ClockUtils::APB TimerUtils::getTimerInputClock(const TIM_TypeDef* timer)
371{
372 // Timers can be connected to APB1 or APB2 clocks.
373 // APB1: TIM2-7,12-15
374 // APB2: TIM1,8-11
375 // TODO: Add support for F103
376 if (timer == TIM1 || timer == TIM8 || timer == TIM9 || timer == TIM10 ||
377 timer == TIM11)
378 {
380 }
381 else
382 {
384 }
385}
386
387inline uint32_t TimerUtils::getPrescalerInputFrequency(const TIM_TypeDef* timer)
388{
390}
391
392inline uint32_t TimerUtils::getFrequency(TIM_TypeDef* timer)
393{
394 return getPrescalerInputFrequency(timer) / (1 + timer->PSC);
395}
396
397inline float TimerUtils::toMicroSeconds(TIM_TypeDef* timer, uint32_t value)
398{
399 return (1.0f * value * 1e6 * (1 + timer->PSC)) /
401}
402
403inline float TimerUtils::toMicroSeconds(TIM_TypeDef* timer)
404{
405 return toMicroSeconds(timer, timer->CNT);
406}
407
408inline uint64_t TimerUtils::toIntMicroSeconds(TIM_TypeDef* timer,
409 uint32_t value)
410{
411 return ((uint64_t)value * 1e6 * (uint64_t)(1 + timer->PSC)) /
413}
414
415inline uint64_t TimerUtils::toIntMicroSeconds(TIM_TypeDef* timer)
416{
417 return toIntMicroSeconds(timer, timer->CNT);
418}
419
420inline float TimerUtils::toMilliSeconds(TIM_TypeDef* timer, uint32_t value)
421{
422 return (1.0f * value * 1e3 * (1 + timer->PSC)) /
424}
425
426inline float TimerUtils::toMilliSeconds(TIM_TypeDef* timer)
427{
428 return toMilliSeconds(timer, timer->CNT);
429}
430
431inline float TimerUtils::toSeconds(TIM_TypeDef* timer)
432{
433 return (1.0f * timer->CNT * (1 + timer->PSC)) /
435}
436
437inline float TimerUtils::getResolution(TIM_TypeDef* timer)
438{
439 return (1.0e6f * (1 + timer->PSC)) / getPrescalerInputFrequency(timer);
440}
441
442inline float TimerUtils::getMaxDuration(TIM_TypeDef* timer)
443{
444 return (1.0f * timer->ARR * 1e6 * (1 + timer->PSC)) /
446}
447
448inline uint16_t TimerUtils::computePrescalerValue(TIM_TypeDef* timer,
449 int targetFrequency)
450{
451 int32_t targetPrescaler =
452 TimerUtils::getPrescalerInputFrequency(timer) / targetFrequency - 1;
453 return targetPrescaler >= 0 ? targetPrescaler : 0;
454}
455
457 const Channel channel)
458{
459 switch (channel)
460 {
461 case Channel::CHANNEL_1:
462 return MasterMode::OC1REF_OUTPUT;
463 case Channel::CHANNEL_2:
464 return MasterMode::OC2REF_OUTPUT;
465 case Channel::CHANNEL_3:
466 return MasterMode::OC3REF_OUTPUT;
467 case Channel::CHANNEL_4:
468 return MasterMode::OC4REF_OUTPUT;
469 default:
470 assert(false && "Invalid channel!");
471 return MasterMode::RESET;
472 }
473}
474
475} // namespace Boardcore
APB
Timer input clock.
Definition ClockUtils.h:38
uint32_t getAPBTimersClock(APB bus)
Computes the output clock frequency for timers on the given APB.
Definition ClockUtils.h:114
float toMicroSeconds(TIM_TypeDef *timer, uint32_t value)
Returns the specified value converted in microseconds based on the timer clock frequency and prescale...
Definition TimerUtils.h:397
ClockUtils::APB getTimerInputClock(const TIM_TypeDef *timer)
Returns the timer input clock.
Definition TimerUtils.h:370
uint32_t getPrescalerInputFrequency(const TIM_TypeDef *timer)
Returns the timer clock frequency before the prescaler.
Definition TimerUtils.h:387
uint64_t toIntMicroSeconds(TIM_TypeDef *timer, uint32_t value)
Returns the specified value converted in microseconds based on the timer clock frequency and prescale...
Definition TimerUtils.h:408
float toMilliSeconds(TIM_TypeDef *timer, uint32_t value)
Returns the specified value converted in milliseconds based on the timer clock frequency and prescale...
Definition TimerUtils.h:420
TriggerSource
Trigger sources.
Definition TimerUtils.h:60
@ TI1FP1
Filtered timer input 1.
@ TI2FP2
Filtered timer input 2.
@ OC2REF_OUTPUT
OC2REF signal is used as trigger output (TRGO).
@ UPDATE
The UEV is selected as trigger output.
@ OC4REF_OUTPUT
OC4REF signal is used as trigger output (TRGO).
@ COMPARE_PULSE
The trigger output send a positive pulse when the OC1IF flag is to be set (even if it was already hig...
@ OC1REF_OUTPUT
OC1REF signal is used as trigger output (TRGO).
@ ENABLE
Only the timer enable is used as trigger output.
@ RESET
Only the updateGeneration() function is used as trigger output.
@ OC3REF_OUTPUT
OC3REF signal is used as trigger output (TRGO).
float getMaxDuration(TIM_TypeDef *timer)
Computes the number of seconds for timer reset.
Definition TimerUtils.h:442
uint32_t getFrequency(TIM_TypeDef *timer)
Return the timer clock frequency.
Definition TimerUtils.h:392
@ DISABLED
Slave mode disabled.
@ EXTERNAL_CLOCK_MODE_1
External clock mode 1.
float getResolution(TIM_TypeDef *timer)
Computes the timer resolution in microseconds.
Definition TimerUtils.h:437
float toSeconds(TIM_TypeDef *timer)
Returns the timer counter converted in seconds based on the timer clock frequency and prescaler.
Definition TimerUtils.h:431
@ FROZEN
The comparison between the output compare register and the counter has no effect on the outputs.
@ TOGGLE
The output toggles when the output compare register and the counter match.
@ ACTIVE_ON_MATCH
Set channel to active level on match.
@ PWM_MODE_1
Output is active as long as the counter is smaller than the compare register (reverse when downcounti...
@ FORCE_ACTIVE
Output is forced high.
@ INACTIVE_ON_MATCH
Set channel to inactive level on match.
@ PWM_MODE_2
Output is active as long as the counter is greater than the compare register (reverse when downcounti...
uint16_t computePrescalerValue(TIM_TypeDef *timer, int targetFrequency)
Compute the prescaler value for the specified target frequency.
Definition TimerUtils.h:448
MasterMode masterModeFromChannel(const Channel channel)
Returns the corresponding master for for the given channel.
Definition TimerUtils.h:456
This file includes all the types the logdecoder script will decode.