Skyward boardcore
Loading...
Searching...
No Matches
CountedPWM.cpp
Go to the documentation of this file.
1/* Copyright (c) 2023 Skyward Experimental Rocketry
2 * Authors: Emilio Corigliano, 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#include "CountedPWM.h"
24
25namespace Boardcore
26{
27
28CountedPWM::CountedPWM(TIM_TypeDef* const pulseTimer,
29 TimerUtils::Channel const pulseChannel,
30 TimerUtils::TriggerSource const pulseTriggerSource,
31 TIM_TypeDef* const counterTimer,
32 TimerUtils::Channel const counterChannel,
33 TimerUtils::TriggerSource const counterTriggerSource)
34 : pulseTimer(pulseTimer), pulseChannel(pulseChannel),
35 pulseTriggerSource(pulseTriggerSource), counterTimer(counterTimer),
36 counterChannel(counterChannel), counterTriggerSource(counterTriggerSource)
37{
38 // Erase the previous timer configuration
39 this->pulseTimer.reset();
40 this->counterTimer.reset();
41
42 configureTimers();
43
44 // Keep the timers always enabled. The clock of the pwm timer will be
45 // enabled based on the output of the counter timer
46 this->pulseTimer.enable();
47 this->counterTimer.enable();
48}
49
51{
52 pulseTimer.reset();
53 counterTimer.reset();
54}
55
56void CountedPWM::setFrequency(unsigned int pulseFrequency)
57{
58 this->pulseFrequency = pulseFrequency;
59
60 if (pulseFrequency == 0)
61 return;
62
63 pulseTimer.setFrequency(pulseFrequency * dutyCycleResolution);
64 pulseTimer.setAutoReloadRegister(
65 TimerUtils::getFrequency(pulseTimer.getTimer()) / pulseFrequency);
66}
67
68void CountedPWM::setDutyCycle(float dutyCycle)
69{
70 if (dutyCycle >= 0 && dutyCycle <= 1)
71 {
72 this->dutyCycle = dutyCycle;
74 pulseChannel,
75 static_cast<uint16_t>(
76 dutyCycle * pulseTimer.readAutoReloadRegister() + 0.5));
77 }
78}
79
80void CountedPWM::setDutyCycleResolution(unsigned int dutyCycleResolution)
81{
82 this->dutyCycleResolution = dutyCycleResolution;
83 setFrequency(pulseFrequency);
84}
85
86void CountedPWM::generatePulses(uint16_t pulses)
87{
88 // Reset only the counter timer so that the pulses are generated always with
89 // the correct frequency and duty cycle
90 counterTimer.setCounter(0);
91
92 // Set the capture and compare register to the number of pulses to generate
93 counterTimer.setCaptureCompareRegister(counterChannel, pulses);
94}
95
97{
98 return counterTimer.readCounter() !=
99 counterTimer.readCaptureCompareRegister(counterChannel);
100}
101
102void CountedPWM::configureTimers()
103{
104 // PWM timer
105 {
106 setFrequency(pulseFrequency);
107
108 // Output/Master: Select TRGO source
109 pulseTimer.setMasterMode(masterModeFromChannel(pulseChannel));
110
111 // Input/Slave: Enable the pulseTimer when the output from the
112 // counterTimer is high
113 pulseTimer.setTriggerSource(pulseTriggerSource);
115
116 // Capture Compare Channel setup in PWM mode
117 pulseTimer.setOutputCompareMode(
119 setDutyCycle(dutyCycle);
120 pulseTimer.enableCaptureCompareOutput(pulseChannel);
121
122 // Force the timer to update its configuration
123 pulseTimer.generateUpdate();
124 }
125
126 // Counter timer
127 {
128 counterTimer.setAutoReloadRegister(-1);
129
130 // Output/Master: Select TRGO source
131 counterTimer.setMasterMode(masterModeFromChannel(counterChannel));
132
133 // Input/Slave: Use the output from counterTimer as clock for pulseTimer
134 counterTimer.setTriggerSource(counterTriggerSource);
136
137 // Capture Compare Channel setup in PWM mode
138 counterTimer.setOutputCompareMode(
140 counterTimer.setCaptureCompareRegister(counterChannel, 0);
141 counterTimer.enableCaptureCompareOutput(counterChannel);
142
143 // The output is enabled also for the counterTimer if the user wants to
144 // output an enable signal
145
146 // Force the timer to update its configuration
147 counterTimer.generateUpdate();
148 }
149}
150
151} // namespace Boardcore
virtual void generateUpdate() final
Re-initializes the timer counter and generate an update of the registers (the prescaler is cleared to...
Definition BasicTimer.h:286
TIM_TypeDef * getTimer()
Definition BasicTimer.h:214
virtual void setFrequency(int frequency) final
Allows to set directly the frequency of the timer's clock.
Definition BasicTimer.h:307
void generatePulses(uint16_t pulses)
Triggers the generation of a specific number of PWM periods.
void setFrequency(unsigned int pulseFrequency)
void setDutyCycle(float dutyCycle)
Sets the duty cycle for the specified channel.
CountedPWM(TIM_TypeDef *const pulseTimer, TimerUtils::Channel const pulseChannel, TimerUtils::TriggerSource const pulseTriggerSource, TIM_TypeDef *const counterTimer, TimerUtils::Channel const counterChannel, TimerUtils::TriggerSource const counterTriggerSource)
Constructor that initializes the timers.
void setDutyCycleResolution(unsigned int dutyCycleResolution)
Sets the granularity of the PulseTimer duty cycle. So it sets the Auto Reload Register of the PulseTi...
bool isGenerating()
Returns whether the timers are generating the PWM signal or not.
void enableCaptureCompareOutput(TimerUtils::Channel channel)
void setCaptureCompareRegister(TimerUtils::Channel channel, T value)
void setMasterMode(TimerUtils::MasterMode masterMode) override
void setOutputCompareMode(TimerUtils::Channel channel, TimerUtils::OutputCompareMode modeChannel)
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 setSlaveMode(TimerUtils::SlaveMode slaveMode)
TriggerSource
Trigger sources.
Definition TimerUtils.h:60
uint32_t getFrequency(TIM_TypeDef *timer)
Return the timer clock frequency.
Definition TimerUtils.h:392
@ EXTERNAL_CLOCK_MODE_1
External clock mode 1.
@ PWM_MODE_1
Output is active as long as the counter is smaller than the compare register (reverse when downcounti...
This file includes all the types the logdecoder script will decode.