arduino-audio-tools
Loading...
Searching...
No Matches
PWMDriverESP32.h
Go to the documentation of this file.
1
2#pragma once
3#ifdef ESP32
5#include "driver/gpio.h"
6#include "driver/ledc.h"
7#if __has_include("soc/soc_caps.h")
8#include "soc/soc_caps.h"
9#endif
10
11namespace audio_tools {
12
13#if defined(SOC_LEDC_CHANNEL_NUM)
15#else
16static constexpr int PWM_ESP32_LEDC_CHANNELS_PER_MODE = 8;
17#endif
18
19#if defined(SOC_LEDC_SUPPORT_HS_MODE) && SOC_LEDC_SUPPORT_HS_MODE
20static constexpr int PWM_ESP32_LEDC_SPEED_MODE_COUNT = 2;
21#else
22static constexpr int PWM_ESP32_LEDC_SPEED_MODE_COUNT = 1;
23#endif
24
25// forward declaration
26class PWMDriverESP32;
32
44
46
56 public:
57 // friend void pwm_callback(void*ptr);
58
60
61 // Ends the output
62 virtual void end() {
63 TRACED();
64 timer.end();
65 is_timer_started = false;
68 }
69
80
82 virtual void setupPWM() {
83 // frequency is driven by selected resolution
84 if (audio_config.pwm_frequency == 0) {
86 }
87
90 bool low_speed_configured = false;
91 #if defined(SOC_LEDC_SUPPORT_HS_MODE) && SOC_LEDC_SUPPORT_HS_MODE
92 bool high_speed_configured = false;
93 #endif
94 for (int j = 0; j < audio_config.channels; j++) {
95 pins[j].gpio = audio_config.pins()[j];
96 pins[j].speed_mode = speedModeForChannel(j);
97 pins[j].pwm_channel = ledcChannelForIndex(j);
98 pins[j].pwm_timer = LEDC_TIMER_0;
99
100 if (pins[j].speed_mode == LEDC_LOW_SPEED_MODE) {
103 }
104 }
105#if defined(SOC_LEDC_SUPPORT_HS_MODE) && SOC_LEDC_SUPPORT_HS_MODE
106 else {
109 }
110 }
111#endif
112
114 LOGI("setupPWM: pin=%d, channel=%d, frequency=%u, resolution=%d",
115 pins[j].gpio, (int)pins[j].pwm_channel,
117 }
118 logPins();
119 }
120
121 void logPins() {
122 for (int j = 0; j < pins.size(); j++) {
123 LOGI("pin%d: %d", j, pins[j].gpio);
124 }
125 }
126
128 virtual void setupTimer() {
130 timer.setIsSave(false);
131
133 timer.end();
134 startTimer();
135 }
136 }
137
140 virtual void pwmWrite(int channel, int value) {
141 if (channel < 0 || channel >= pins.size()) return;
142 uint32_t duty = value;
144 if (duty > max_duty) {
145 duty = max_duty;
146 }
147 esp_err_t rc = ledc_set_duty(pins[channel].speed_mode,
148 pins[channel].pwm_channel, duty);
149 if (rc != ESP_OK) {
150 LOGE("ledc_set_duty failed: pin=%d channel=%d error=%d",
151 pins[channel].gpio, (int)pins[channel].pwm_channel, (int)rc);
152 return;
153 }
154 rc = ledc_update_duty(pins[channel].speed_mode, pins[channel].pwm_channel);
155 if (rc != ESP_OK) {
156 LOGE("ledc_update_duty failed: pin=%d channel=%d error=%d",
157 pins[channel].gpio, (int)pins[channel].pwm_channel, (int)rc);
158 }
159 }
160
161 protected:
165
166 bool configureTimer(ledc_mode_t speed_mode) {
167 ledc_timer_config_t config = {};
168 config.speed_mode = speed_mode;
169 config.timer_num = LEDC_TIMER_0;
170 config.duty_resolution = resolutionBits();
171 config.freq_hz = audio_config.pwm_frequency;
172 config.clk_cfg = LEDC_AUTO_CLK;
173
174 esp_err_t rc = ledc_timer_config(&config);
175 if (rc != ESP_OK) {
176 LOGE("ledc_timer_config failed: mode=%d error=%d", (int)speed_mode,
177 (int)rc);
178 return false;
179 }
180 return true;
181 }
182
183 void configureChannel(const PinInfo& pin) {
184 ledc_channel_config_t config = {};
185 config.gpio_num = pin.gpio;
186 config.speed_mode = pin.speed_mode;
187 config.channel = pin.pwm_channel;
188 config.timer_sel = pin.pwm_timer;
189 config.duty = 0;
190 config.hpoint = 0;
191
193 if (rc != ESP_OK) {
194 LOGE("ledc_channel_config failed: pin=%d channel=%d error=%d", pin.gpio,
195 (int)pin.pwm_channel, (int)rc);
196 }
197 }
198
199 void releasePins() {
200 for (int j = 0; j < pins.size(); j++) {
201 ledc_stop(pins[j].speed_mode, pins[j].pwm_channel, 0);
203 }
204 pins.clear();
205 }
206
208#if defined(SOC_LEDC_SUPPORT_HS_MODE) && SOC_LEDC_SUPPORT_HS_MODE
211#else
212 (void)channel;
213 return LEDC_LOW_SPEED_MODE;
214#endif
215 }
216
218 return static_cast<ledc_channel_t>(channel %
220 }
221
225
227 int max_value = maxOutputValue() - 1;
228 return max_value > 0 ? (uint32_t)max_value : 0;
229 }
230
232 int maxUnsignedValue(int resolution) { return pow(2, resolution); }
233
237
239 virtual int maxOutputValue() {
241 }
242
244 float frequency(int resolution) {
245// On ESP32S2 and S3, the frequncy seems off by a factor of 2
246#if defined(ESP32S2) || defined(ESP32S3)
247 switch (resolution) {
248 case 7:
249 return 312.5;
250 case 8:
251 return 156.25;
252 case 9:
253 return 78.125;
254 case 10:
255 return 39.0625;
256 case 11:
257 return 19.53125;
258 }
259 return 312.5;
260#else
261 switch (resolution) {
262 case 8:
263 return 312.5;
264 case 9:
265 return 156.25;
266 case 10:
267 return 78.125;
268 case 11:
269 return 39.0625;
270 }
271 return 312.5;
272#endif
273 }
274
276 static void pwm_callback(void* ptr) {
278 if (accessAudioPWM != nullptr) {
280 }
281 }
282};
283
284} // namespace audio_tools
285
286#endif
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Base Class for all PWM drivers.
Definition PWMDriverBase.h:114
virtual int effectiveOutputSampleRate()
Provides the effective sample rate.
Definition PWMDriverBase.h:246
void playNextFrame()
writes the next frame to the output pins
Definition PWMDriverBase.h:274
bool is_timer_started
Definition PWMDriverBase.h:260
PWMConfig audio_config
Definition PWMDriverBase.h:251
void deleteBuffer()
Definition PWMDriverBase.h:265
Experimental: Audio output to PWM pins for the AVR. The AVR supports only up to 2 channels.
Definition PWMDriverAVR.h:24
Audio output to PWM pins for the ESP32. The ESP32 supports up to 16 channels.
Definition PWMDriverESP32.h:55
void configureChannel(const PinInfo &pin)
Definition PWMDriverESP32.h:183
PWMDriverESP32()
Definition PWMDriverESP32.h:59
ledc_timer_bit_t resolutionBits()
Definition PWMDriverESP32.h:222
float frequency(int resolution)
determiens the PWM frequency based on the requested resolution
Definition PWMDriverESP32.h:244
virtual int maxChannels()
Definition PWMDriverESP32.h:234
void releasePins()
Definition PWMDriverESP32.h:199
uint32_t maxDutyValue()
Definition PWMDriverESP32.h:226
ledc_channel_t ledcChannelForIndex(int channel)
Definition PWMDriverESP32.h:217
TimerAlarmRepeating timer
Definition PWMDriverESP32.h:163
Vector< PinInfo > pins
Definition PWMDriverESP32.h:162
virtual void setupPWM()
Setup LED PWM.
Definition PWMDriverESP32.h:82
virtual int maxOutputValue()
provides the max value for the configured resulution
Definition PWMDriverESP32.h:239
virtual void startTimer()
Definition PWMDriverESP32.h:72
int maxUnsignedValue(int resolution)
provides the max value for the indicated resulution
Definition PWMDriverESP32.h:232
virtual void pwmWrite(int channel, int value)
Definition PWMDriverESP32.h:140
static void pwm_callback(void *ptr)
timer callback: write the next frame to the pins
Definition PWMDriverESP32.h:276
ledc_mode_t speedModeForChannel(int channel)
Definition PWMDriverESP32.h:207
virtual void setupTimer()
Setup ESP32 timer with callback.
Definition PWMDriverESP32.h:128
virtual void end()
Definition PWMDriverESP32.h:62
uint32_t actual_timer_frequency
Definition PWMDriverESP32.h:164
void logPins()
Definition PWMDriverESP32.h:121
bool configureTimer(ledc_mode_t speed_mode)
Definition PWMDriverESP32.h:166
Common Interface definition for TimerAlarmRepeating.
Definition AudioTimer.h:29
void setIsSave(bool is_save)
Definition AudioTimer.h:66
void setCallbackParameter(void *obj)
Definition AudioTimer.h:56
bool begin(repeating_timer_callback_t callback_f, uint32_t time, TimeUnit unit=MS)
Definition AudioTimer.h:43
bool end()
Definition AudioTimer.h:51
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
@ HZ
Definition AudioTypes.h:48
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
static constexpr int PWM_ESP32_LEDC_SPEED_MODE_COUNT
Definition PWMDriverESP32.h:22
static PWMDriverAVR * accessAudioPWM
Definition PWMDriverAVR.h:14
PinInfoESP32 PinInfo
Definition PWMDriverESP32.h:45
static constexpr int PWM_ESP32_LEDC_CHANNELS_PER_MODE
Definition PWMDriverESP32.h:16
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t resolution
Only used by ESP32: must be between 8 and 11 -> drives pwm frequency // 20,000Hz (not used by ESP32)
Definition PWMDriverBase.h:48
uint32_t pwm_frequency
additinal info which might not be used by all processors
Definition PWMDriverBase.h:46
Information for a PIN.
Definition PWMDriverESP32.h:38
ledc_mode_t speed_mode
Definition PWMDriverESP32.h:41
int gpio
Definition PWMDriverESP32.h:42
ledc_channel_t pwm_channel
Definition PWMDriverESP32.h:39
ledc_timer_t pwm_timer
Definition PWMDriverESP32.h:40