arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
PWMAudioSTM32.h
1
2#pragma once
3#if defined(STM32)
4#include "AudioTools/CoreAudio/AudioPWM/PWMAudioBase.h"
5#include "AudioTools/CoreAudio/AudioTimer/AudioTimer.h"
6
7namespace audio_tools {
8
9// forward declaration
10class PWMDriverSTM32;
15using PWMDriver = PWMDriverSTM32;
16
27 struct PWMPin {
28 HardwareTimer *p_timer;
29 int channel;
30 int max_value;
31 bool active = false;
32 int pin;
33 int pwm_frequency;
34
35 PWMPin() = default;
36
37 PWMPin(HardwareTimer *p_timer, int channel, int pin, int maxValue,
38 int pwmFrequency = 30000) {
39 this->p_timer = p_timer;
40 this->channel = channel;
41 this->pin = pin;
42 this->max_value = maxValue;
43 this->pwm_frequency = pwmFrequency;
44 }
45
46 void begin() {
47 TRACEI();
48 p_timer->setPWM(channel, pin, pwm_frequency,
49 50); // 30k Hertz, 50% dutycycle
50 active = true;
51 }
52
53 void setRate(int rate) {
54 if (active) {
55 uint16_t sample = 100.0 * rate / max_value;
56 p_timer->setCaptureCompare(channel, sample,
57 PERCENT_COMPARE_FORMAT); // 50%
58 }
59 }
60 };
61
62 class PWM {
63 public:
64 PWM() = default;
65
66 void begin(HardwareTimer *pwm_timer, int pwm_frequency, int maxValue) {
67 this->p_timer = pwm_timer;
68 this->pwm_frequency = pwm_frequency;
69 this->max_value = maxValue;
70 }
71
72 void end() {
73 p_timer->pause();
74 }
75
76 bool addPin(int pin) {
77 LOGI("addPin: %d", pin);
78 TIM_TypeDef *p_instance = (TIM_TypeDef *)pinmap_peripheral(
79 digitalPinToPinName(pin), PinMap_PWM);
80 channel = STM_PIN_CHANNEL(
81 pinmap_function(digitalPinToPinName(pin), PinMap_PWM));
82 PWMPin pwm_pin{p_timer, channel, pin, max_value, pwm_frequency};
83 pins.push_back(pwm_pin);
84 // make sure that all pins use the same timer !
85 if (p_timer->getHandle()->Instance != p_instance) {
86 LOGE("Invalid pin %d with timer %s for timer %s", pin,
87 getTimerStr(p_instance),
88 getTimerStr(p_timer->getHandle()->Instance));
89 return false;
90 }
91 LOGI("Using Timer %s for PWM", getTimerStr(p_instance));
92 pins[pins.size() - 1].begin();
93 return true;
94 }
95
96 void setRate(int idx, int rate) {
97 if (idx < pins.size()) {
98 pins[idx].setRate(rate);
99 } else {
100 LOGE("Invalid index: %d", idx);
101 }
102 }
103
104 protected:
105 HardwareTimer *p_timer;
107 int channel;
108 int max_value;
109 int pwm_frequency;
110
111 const char *getTimerStr(TIM_TypeDef *inst) {
112 if (inst == TIM1)
113 return "TIM1";
114 else if (inst == TIM2)
115 return "TIM2";
116 else if (inst == TIM3)
117 return "TIM3";
118 else if (inst == TIM4)
119 return "TIM4";
120 else if (inst == TIM5)
121 return "TIM5";
122 return "N/A";
123 }
124 };
125
126 public:
128 TRACED();
129 ticker.setTimer(PWM_FREQ_TIMER_NO);
130 }
131
132 // Ends the output
133 virtual void end() override {
134 TRACED();
135 ticker.end(); // it does not hurt to call this even if it has not been
136 // started
137 pwm.end(); // stop pwm timer
138 deleteBuffer();
139 is_timer_started = false;
140 if (buffer != nullptr) {
141 delete buffer;
142 buffer = nullptr;
143 }
144 }
145
147 void setPWMTimer(HardwareTimer &t) { p_pwm_timer = &t; }
148
149 protected:
150 TimerAlarmRepeating ticker; // calls a callback repeatedly with a timeout
151 HardwareTimer *p_pwm_timer = nullptr;
152 PWM pwm;
153 int64_t max_value;
154
157 virtual void startTimer() override {
158 if (!is_timer_started) {
159 TRACED();
160 uint32_t time = AudioTime::toTimeUs(audio_config.sample_rate);
161 ticker.setCallbackParameter(this);
162 ticker.begin(defaultPWMAudioOutputCallback, time, US);
163 is_timer_started = true;
164 }
165 }
166
168 virtual void setupPWM() {
169 TRACED();
170 if (audio_config.pwm_frequency == 0){
171 audio_config.pwm_frequency = PWM_AUDIO_FREQUENCY;
172 }
173
174 // setup pwm timer
175 if (p_pwm_timer == nullptr) {
176 p_pwm_timer = new HardwareTimer(PWM_DEFAULT_TIMER);
177 }
178
179 // setup pins for output
180 int ch = 0;
181 pwm.begin(p_pwm_timer, audio_config.pwm_frequency, maxOutputValue());
182 for (auto gpio : audio_config.pins()) {
183 LOGD("Processing channel %d -> pin: %d", ch++, gpio);
184 pwm.addPin(gpio);
185 }
186 }
187
188 virtual void setupTimer() {}
189
191 virtual int maxChannels() { return 4; };
192
194 virtual int maxOutputValue() { return 10000; }
195
198 virtual void pwmWrite(int channel, int value) {
199 // analogWrite(pins[channel], value);
200 pwm.setRate(channel, value);
201 }
202
204 static void defaultPWMAudioOutputCallback(void *obj) {
205 PWMDriverSTM32 *accessAudioPWM = (PWMDriverSTM32 *)obj;
206 if (accessAudioPWM != nullptr) {
207 accessAudioPWM->playNextFrame();
208 }
209 }
210};
211
212} // namespace audio_tools
213
214#endif
static uint32_t toTimeUs(uint32_t samplingRate, uint8_t limit=10)
converts sampling rate to delay in microseconds (μs)
Definition AudioTypes.h:240
Base Class for all PWM drivers.
Definition PWMAudioBase.h:110
void playNextFrame()
writes the next frame to the output pins
Definition PWMAudioBase.h:270
Audio output to PWM pins for STM32. We use one timer to generate the sample rate and one timer for th...
Definition PWMAudioSTM32.h:25
virtual void startTimer() override
Definition PWMAudioSTM32.h:157
void setPWMTimer(HardwareTimer &t)
Defines the timer which is used to generate the PWM signal.
Definition PWMAudioSTM32.h:147
virtual int maxChannels()
One timer supports max 4 output pins.
Definition PWMAudioSTM32.h:191
virtual void setupPWM()
Setup PWM Pins.
Definition PWMAudioSTM32.h:168
virtual int maxOutputValue()
provides the max value for the configured resulution
Definition PWMAudioSTM32.h:194
virtual void pwmWrite(int channel, int value)
Definition PWMAudioSTM32.h:198
static void defaultPWMAudioOutputCallback(void *obj)
timer callback: write the next frame to the pins
Definition PWMAudioSTM32.h:204
Common Interface definition for TimerAlarmRepeating.
Definition AudioTimer.h:25
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
void defaultPWMAudioOutputCallback()
Definition PWMAudioAVR.h:132
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint32_t pwm_frequency
additinal info which might not be used by all processors
Definition PWMAudioBase.h:46