Skyward boardcore
Loading...
Searching...
No Matches
GeneralPurposeTimer.h
Go to the documentation of this file.
1/* Copyright (c) 2021 Skyward Experimental Rocketry
2 * Author: 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 <type_traits>
26
27#include "BasicTimer.h"
28
29namespace Boardcore
30{
31
97template <typename T>
98class GeneralPurposeTimer final : public BasicTimer
99{
100public:
101 static_assert(std::is_same<T, uint16_t>::value ||
102 std::is_same<T, uint32_t>::value,
103 "Type must be either uint16_t or uint32_t.");
104
110 explicit GeneralPurposeTimer(TIM_TypeDef* timer);
111
116
117 void reset() override;
118
119 void enable() override;
120
121 void disable() override;
122
124
125 void setCounter(T counterValue);
126
128
129 void setAutoReloadRegister(T autoReloadValue);
130
131 void setMasterMode(TimerUtils::MasterMode masterMode) override;
132
134
136
138
140
142
144
146
148
150
152
160
168
171
173
175
183
188
190
192 TimerUtils::Channel channel);
193
196
198 TimerUtils::Channel channel,
200
202
204
206
208};
209
216using GP16bitTimer = GeneralPurposeTimer<uint16_t>;
217
221using GP32bitTimer = GeneralPurposeTimer<uint32_t>;
222
223template <typename T>
225 : BasicTimer(timer)
226{
227}
228
229template <typename T>
234
235template <typename T>
237{
238 timer->CR1 = 0;
239 timer->CR2 = 0;
240 timer->SMCR = 0;
241 timer->DIER = 0;
242 timer->EGR = 0;
243 timer->CCMR1 = 0;
244 timer->CCMR2 = 0;
245 timer->CCER = 0;
246 timer->CNT = 0;
247 timer->PSC = 0;
248 timer->ARR = static_cast<uint32_t>(0xFFFFFFFFF);
249 timer->CCR1 = 0;
250 timer->CCR2 = 0;
251 timer->CCR3 = 0;
252 timer->CCR4 = 0;
253 timer->DCR = 0;
254 timer->DMAR = 0;
255 timer->OR = 0;
256}
257
258template <typename T>
260{
261 timer->CR1 |= TIM_CR1_CEN;
262
263 // On TIM1 and TIM8 the outputs are enabled only if the MOE bit in the BDTR
264 // register is set
265 if (timer == TIM1 || timer == TIM8)
266 timer->BDTR |= TIM_BDTR_MOE;
267}
268
269template <typename T>
271{
272 timer->CR1 &= ~TIM_CR1_CEN;
273
274 // On TIM1 and TIM8 the outputs are enabled only if the MOE bit in the BDTR
275 // register is set
276 if (timer == TIM1 || timer == TIM8)
277 timer->BDTR |= TIM_BDTR_MOE;
278}
279
280template <typename T>
282{
283 return timer->CNT;
284}
285
286template <typename T>
287inline void GeneralPurposeTimer<T>::setCounter(T counterValue)
288{
289 timer->CNT = counterValue;
290}
291
292template <typename T>
294{
295 return timer->ARR;
296}
297
298template <typename T>
300{
301 timer->ARR = autoReloadValue;
302}
303
304template <typename T>
306 TimerUtils::MasterMode masterMode)
307{
308 // First clear the configuration
309 timer->CR2 &= ~TIM_CR2_MMS;
310
311 // Set the new value
312 timer->CR2 |= static_cast<uint16_t>(masterMode);
313}
314
315template <typename T>
317 TimerUtils::SlaveMode slaveMode)
318{
319 // First clear the configuration
320 timer->SMCR &= ~TIM_SMCR_SMS;
321
322 // Set the new value
323 timer->SMCR |= static_cast<uint16_t>(slaveMode);
324}
325
326template <typename T>
328 TimerUtils::TriggerSource triggerSource)
329{
330 // First clear the configuration
331 timer->SMCR &= ~TIM_SMCR_TS;
332
333 // Set the new value
334 timer->SMCR |= static_cast<uint16_t>(triggerSource);
335}
336
337template <typename T>
339{
340 timer->DIER |= TIM_DIER_TIE;
341}
342
343template <typename T>
345{
346 timer->DIER &= ~TIM_DIER_TIE;
347}
348
349template <typename T>
351 TimerUtils::Channel channel)
352{
353 timer->DIER |= TIM_DIER_CC1IE << static_cast<int>(channel);
354}
355
356template <typename T>
358 TimerUtils::Channel channel)
359{
360 timer->DIER &= ~(TIM_DIER_CC1IE << static_cast<int>(channel));
361}
362
363template <typename T>
365 TimerUtils::Channel channel)
366{
367 timer->DIER |= TIM_DIER_CC1DE << static_cast<int>(channel);
368}
369
370template <typename T>
372 TimerUtils::Channel channel)
373{
374 timer->DIER &= ~(TIM_DIER_CC1DE << static_cast<int>(channel));
375}
376
377template <typename T>
379{
380 timer->EGR |= TIM_EGR_TG;
381}
382
383template <typename T>
385 TimerUtils::Channel channel)
386{
387 timer->EGR |= TIM_EGR_CC1G << static_cast<int>(channel);
388}
389
390template <typename T>
392 TimerUtils::Channel channel)
393{
394 switch (channel)
395 {
397 timer->CCMR1 |= TIM_CCMR1_OC1PE;
398 break;
400 timer->CCMR1 |= TIM_CCMR1_OC2PE;
401 break;
403 timer->CCMR2 |= TIM_CCMR2_OC3PE;
404 break;
406 timer->CCMR2 |= TIM_CCMR2_OC4PE;
407 break;
408 }
409}
410
411template <typename T>
413 TimerUtils::Channel channel)
414{
415 switch (channel)
416 {
418 timer->CCMR1 &= ~TIM_CCMR1_OC1PE;
419 break;
421 timer->CCMR1 &= ~TIM_CCMR1_OC2PE;
422 break;
424 timer->CCMR2 &= ~TIM_CCMR2_OC3PE;
425 break;
427 timer->CCMR2 &= ~TIM_CCMR2_OC4PE;
428 break;
429 }
430}
431
432template <typename T>
435{
436 switch (channel)
437 {
439 // First clear the configuration
440 timer->CCMR1 &= ~TIM_CCMR1_OC1M;
441
442 // Set the new value
443 timer->CCMR1 |= static_cast<uint16_t>(mode) << 4;
444 break;
446 // First clear the configuration
447 timer->CCMR1 &= ~TIM_CCMR1_OC2M;
448
449 // Set the new value
450 timer->CCMR1 |= static_cast<uint16_t>(mode) << 12;
451 break;
453 // First clear the configuration
454 timer->CCMR2 &= ~TIM_CCMR2_OC3M;
455
456 // Set the new value
457 timer->CCMR2 |= static_cast<uint16_t>(mode) << 4;
458 break;
460 // First clear the configuration
461 timer->CCMR2 &= ~TIM_CCMR2_OC4M;
462
463 // Set the new value
464 timer->CCMR2 |= static_cast<uint16_t>(mode) << 12;
465 break;
466 }
467}
468
469template <typename T>
471 TimerUtils::Channel channel)
472{
473 timer->CCER |= TIM_CCER_CC1E << (static_cast<int>(channel) * 4);
474}
475
476template <typename T>
478 TimerUtils::Channel channel)
479{
480 timer->CCER |= TIM_CCER_CC1NE << (static_cast<int>(channel) * 4);
481}
482
483template <typename T>
485 TimerUtils::Channel channel)
486{
487 timer->CCER &= ~(TIM_CCER_CC1E << (static_cast<int>(channel) * 4));
488}
489
490template <typename T>
492 TimerUtils::Channel channel)
493{
494 timer->CCER &= ~(TIM_CCER_CC1NE << (static_cast<int>(channel) * 4));
495}
496
497template <typename T>
499 TimerUtils::Channel channel)
500{
501 return timer->CCER & (TIM_CCER_CC1E << (static_cast<int>(channel) * 4));
502}
503
504template <typename T>
506 TimerUtils::Channel channel)
507{
508 return timer->CCER & (TIM_CCER_CC1NE << (static_cast<int>(channel) * 4));
509}
510
511template <typename T>
514{
515 timer->CCER |= static_cast<uint16_t>(polarity)
516 << (1 + static_cast<int>(channel) * 4);
517}
518
519template <typename T>
522{
523 timer->CCER |= static_cast<uint16_t>(polarity)
524 << (3 + static_cast<int>(channel) * 4);
525}
526
527template <typename T>
529 TimerUtils::Channel channel, T value)
530{
531 switch (channel)
532 {
534 timer->CCR1 = value;
535 break;
537 timer->CCR2 = value;
538 break;
540 timer->CCR3 = value;
541 break;
543 timer->CCR4 = value;
544 break;
545 }
546}
547
548template <typename T>
550 TimerUtils::Channel channel)
551{
552 switch (channel)
553 {
555 return timer->CCR1;
557 return timer->CCR2;
559 return timer->CCR3;
561 return timer->CCR4;
562 }
563
564 return 0;
565}
566
567template <typename T>
569{
570 timer->SR &= ~TIM_SR_TIF;
571}
572
573template <typename T>
575 TimerUtils::Channel channel)
576{
577 timer->SR &= ~(TIM_SR_CC1IF << static_cast<int>(channel));
578}
579
580} // namespace Boardcore
Driver for STM32 basic timers.
Definition BasicTimer.h:79
TIM_TypeDef * timer
Definition BasicTimer.h:204
Driver for STM32 general purpose timers.
void enableCaptureCompareOutput(TimerUtils::Channel channel)
GeneralPurposeTimer(TIM_TypeDef *timer)
Create a GeneralPurposeTimer object. Note that this does not resets the timer configuration but autom...
~GeneralPurposeTimer()
Disables the peripheral clock.
void setCaptureCompareRegister(TimerUtils::Channel channel, T value)
void generateCaptureCompareEvent(TimerUtils::Channel channel)
void enableCaptureCompareComplementaryOutput(TimerUtils::Channel channel)
void enableCaptureComparePreload(TimerUtils::Channel channel)
The capture/compare register is buffered.
void enableCaptureCompareDMARequest(TimerUtils::Channel channel)
void setMasterMode(TimerUtils::MasterMode masterMode) override
void setOutputCompareMode(TimerUtils::Channel channel, TimerUtils::OutputCompareMode modeChannel)
void setCaptureComparePolarity(TimerUtils::Channel channel, TimerUtils::OutputComparePolarity polarity)
void setTriggerSource(TimerUtils::TriggerSource triggerSource)
void reset() override
Resets the timer configuration to the default state.
void setAutoReloadRegister(T autoReloadValue)
T readCaptureCompareRegister(TimerUtils::Channel channel)
void disableCaptureCompareDMARequest(TimerUtils::Channel channel)
void disableCaptureCompareOutput(TimerUtils::Channel channel)
void disableCaptureComparePreload(TimerUtils::Channel channel)
The capture/compare register is not buffered.
void setSlaveMode(TimerUtils::SlaveMode slaveMode)
void disableCaptureCompareComplementaryOutput(TimerUtils::Channel channel)
bool isCaptureCompareComplementaryOutputEnabled(TimerUtils::Channel channel)
bool isCaptureCompareOutputEnabled(TimerUtils::Channel channel)
void enableCaptureCompareInterrupt(TimerUtils::Channel channel)
void disableCaptureCompareInterrupt(TimerUtils::Channel channel)
void setCaptureCompareComplementaryPolarity(TimerUtils::Channel channel, TimerUtils::OutputComparePolarity polarity)
void clearCaptureCompareInterruptFlag(TimerUtils::Channel channel)
bool disablePeripheralClock(void *peripheral)
Disables a peripheral clock source from the APB1 and APB2 peripheral buses.
Definition ClockUtils.h:531
TriggerSource
Trigger sources.
Definition TimerUtils.h:60
This file includes all the types the logdecoder script will decode.
GeneralPurposeTimer< uint32_t > GP32bitTimer
General purpose 32bit timer.