Skip to content

Commit

Permalink
ESP32: added PWM output support
Browse files Browse the repository at this point in the history
  • Loading branch information
tomcombriat committed Jan 19, 2025
1 parent 8adeb54 commit 4964133
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
30 changes: 24 additions & 6 deletions internal/MozziGuts_impl_ESP32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ namespace MozziPrivate {

//# include <driver/i2s.h> // for I2S-based output modes, including - technically - internal DAC
#include<driver/i2s_std.h>

/*
#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
#include<driver/dac_continuous.h>
namespace MozziPrivate {
/* static*/ dac_continuous_handle_t dac_handle;
}
static dac_continuous_handle_t dac_handle;
}*/
#endif

//#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
Expand Down Expand Up @@ -99,7 +99,8 @@ namespace MozziPrivate {
return _esp32_can_buffer_next;
}

# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)

# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
inline void audioOutput(const AudioOutput f) {
/*
# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
Expand All @@ -115,6 +116,13 @@ namespace MozziPrivate {
# if (MOZZI_AUDIO_CHANNELS > 1)
dacWrite(26, f.l() + MOZZI_AUDIO_BIAS);
# endif

# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
ledcWrite(MOZZI_AUDIO_PIN_1,(f.l()+MOZZI_AUDIO_BIAS));
# if (MOZZI_AUDIO_CHANNELS > 1)
ledcWrite(MOZZI_AUDIO_PIN_2,(f.l()+MOZZI_AUDIO_BIAS));
# endif

# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
for (uint8_t i=0; i<MOZZI_PDM_RESOLUTION; ++i) {
_esp32_prev_sample[i] = pdmCode32(f.l() + MOZZI_AUDIO_BIAS);
Expand All @@ -124,14 +132,16 @@ namespace MozziPrivate {
_esp32_prev_sample[0] = f.l();
_esp32_prev_sample[1] = f.r();
# endif
# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
_esp32_can_buffer_next = esp32_tryWriteSample();
# endif
}
#endif
} // namespace MozziPrivate


namespace MozziPrivate {
#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_INTERNAL_DAC)
#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_PWM)
#include <driver/gptimer.h>

bool CACHED_FUNCTION_ATTR timer_on_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
Expand All @@ -144,7 +154,7 @@ namespace MozziPrivate {
static void startAudio() {
/* Normally, the internal DAC can run on DMA, hence self triggering. Did not managed to get that to work (see: https://github.com/espressif/arduino-esp32/issues/10851) so, for now, we are just using the Mozzi buffer and send dacWrite orders.
*/
#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) // set up a timer running a audio rate
#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_PWM) //|| MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) // set up a timer running a audio rate

gptimer_handle_t gptimer = NULL;
gptimer_config_t timer_config = {
Expand All @@ -166,9 +176,17 @@ namespace MozziPrivate {
.on_alarm = timer_on_alarm_cb, // register user callback
};


gptimer_register_event_callbacks(gptimer,&cbs,NULL);
gptimer_enable(gptimer);
gptimer_start(gptimer);

# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
ledcAttach(MOZZI_AUDIO_PIN_1, MOZZI_AUDIO_RATE, MOZZI_AUDIO_BITS);
# if (MOZZI_AUDIO_CHANNELS > 1)
ledcAttach(MOZZI_AUDIO_PIN_2, MOZZI_AUDIO_RATE, MOZZI_AUDIO_BITS);
# endif
# endif

# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)

Expand Down
15 changes: 13 additions & 2 deletions internal/config_checks_esp32.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
#if !defined(MOZZI_AUDIO_MODE)
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
#endif
MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC)
MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_PWM)

#if !defined(MOZZI_AUDIO_RATE)
#define MOZZI_AUDIO_RATE 32768
Expand Down Expand Up @@ -155,6 +155,16 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
# endif
#endif

#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
# define MOZZI_AUDIO_BITS 10 // not configurable (could be 8)
# if !defined(MOZZI_AUDIO_PIN_1)
# define MOZZI_AUDIO_PIN_1 18
# endif
# if !defined(MOZZI_AUDIO_PIN_2)
# define MOZZI_AUDIO_PIN_2 19
# endif
#endif

#if !defined(MOZZI_AUDIO_BITS)
# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
# define MOZZI_AUDIO_BITS 8
Expand All @@ -171,8 +181,9 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
# define MOZZI_PDM_RESOLUTION 1 // unconditionally, no other value allowed
#endif


// All modes besides timed external bypass the output buffer!
#if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_INTERNAL_DAC)
#if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_PWM)
# define BYPASS_MOZZI_OUTPUT_BUFFER true
#endif

Expand Down

0 comments on commit 4964133

Please sign in to comment.