Skip to content

Commit c79dbfc

Browse files
committed
Comments
1 parent c715f19 commit c79dbfc

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

src/AudioTools/CoreAudio/AudioPWM/PWMComplementaryDriverESP32.h

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@
77
namespace audio_tools {
88

99
/**
10-
* @brief Information for a PIN
11-
* @author Phil Schatzmann
12-
* @copyright GPLv3
10+
* @brief Mapping information for one complementary PWM audio channel.
11+
*
12+
* A single logical audio PWM channel is produced by one MCPWM timer within an
13+
* MCPWM unit. Each timer provides two generator outputs (A and B) which we map
14+
* to a high-side MOSFET gate (gpio_high / PWMxA) and a low-side MOSFET gate
15+
* (gpio_low / PWMxB). When dead time is enabled the peripheral inserts blanking
16+
* around switching edges to avoid shoot-through between the high and low
17+
* transistors on a half bridge.
1318
*/
1419
struct PinInfoESP32Compl {
1520
int gpio_high; // high-side pin (PWMxA)
@@ -26,6 +31,67 @@ struct PinInfoESP32Compl {
2631
* @copyright GPLv3
2732
*/
2833

34+
/**
35+
* @class PWMComplementaryDriverESP32
36+
* @brief Complementary (half‑bridge) PWM audio driver for ESP32 using the legacy MCPWM driver API.
37+
*
38+
* @details This driver produces audio by modulating one or more complementary
39+
* PWM pairs (high / low outputs) using the ESP32 MCPWM peripheral. Each audio
40+
* channel occupies one MCPWM timer (up to 3 timers per MCPWM unit, and 2 units
41+
* → maximum of 6 complementary channels). For every channel two GPIOs are
42+
* driven 180° out of phase. Optional hardware dead time can be inserted to
43+
* protect external half‑bridge power stages.
44+
*
45+
* The duty cycle is derived from the (optionally decimated) audio samples in
46+
* the base class buffer. The effective output sample rate equals the rate at
47+
* which new duty values are pushed to the MCPWM hardware (timer interrupt /
48+
* alarm frequency) and may differ from the nominal input sample rate due to
49+
* decimation (see DriverPWMBase).
50+
*
51+
* Resolution & PWM Frequency:
52+
* The requested bit resolution (e.g. 8–11 bits) determines the PWM carrier
53+
* frequency using empirically chosen values (see frequency()). If
54+
* PWMConfig::pwm_frequency is left as 0 the driver derives it from the
55+
* resolution. Otherwise the provided frequency is used.
56+
*
57+
* Dead Time:
58+
* If PWMConfig::dead_time_us > 0 the driver configures hardware complementary
59+
* mode with symmetric dead time (rising & falling) in ticks computed from the
60+
* APB clock (assumed 80 MHz). For very large dead time requests relative to
61+
* the PWM period the value is limited to maintain a usable duty range.
62+
* Without dead time the driver emulates complementary operation by inverting
63+
* the B duty in software (B = 100% - A).
64+
*
65+
* Pin Assignment:
66+
* Provide either 2 * channels GPIO values (high0, low0, high1, low1, ...). If
67+
* only one pin per channel is supplied the low pin is assumed to be high+1.
68+
*
69+
* Limitations:
70+
* - Uses the legacy MCPWM API (driver/mcpwm.h). ESP-IDF v5+ introduces a new
71+
* prelude API which is not covered here.
72+
* - Maximum 6 complementary channels (2 units * 3 timers).
73+
* - Dead time calculation assumes 80 MHz APB clock.
74+
* - No dynamic reconfiguration of frequency / dead time while running; call
75+
* end() and begin() again to change.
76+
*
77+
* Thread Safety:
78+
* Access from a single task context; ISR only invokes playNextFrame().
79+
*
80+
* Typical Usage:
81+
* @code
82+
* PWMComplementaryDriverESP32 drv;
83+
* PWMConfig cfg = drv.defaultConfig();
84+
* cfg.channels = 2; // stereo
85+
* cfg.setPins({25,26, 27,14}); // high0,low0, high1,low1
86+
* cfg.dead_time_us = 1; // 1 microsecond dead time
87+
* drv.begin(cfg);
88+
* // write PCM frames (uint8_t / int16_t depending on bits_per_sample)
89+
* drv.write(samples, len);
90+
* drv.end();
91+
* @endcode
92+
*
93+
* @ingroup platform
94+
*/
2995
class PWMComplementaryDriverESP32 : public DriverPWMBase {
3096
public:
3197
// friend void pwm_callback(void*ptr);

0 commit comments

Comments
 (0)