Skip to content

Commit f713301

Browse files
committed
Fix broken ESP32 Timer
1 parent f035178 commit f713301

File tree

3 files changed

+39
-32
lines changed

3 files changed

+39
-32
lines changed

src/AudioPWM/PWMAudioBase.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ class DriverPWMBase {
119119
if (audio_config.channels>maxChannels()){
120120
LOGE("Only max %d channels are supported!",maxChannels());
121121
return false;
122-
}
122+
}
123+
if (audio_config.bits_per_sample!=16){
124+
LOGE("bits_per_sample must be 16!");
125+
return false;
126+
}
123127
// allocate buffer if necessary
124128
if (user_callback==nullptr) {
125129
if (buffer!=nullptr){
@@ -157,7 +161,7 @@ class DriverPWMBase {
157161
virtual size_t write(const uint8_t *wrt_buffer, size_t size){
158162
if (is_blocking_write && availableForWrite()==0){
159163
LOGD("Waiting for buffer to clear");
160-
while (availableForWrite()==0);
164+
while (availableForWrite()==0) delay(1);
161165
}
162166

163167
size_t available = min((size_t)availableForWrite(),size);

src/AudioPWM/PWMAudioESP32.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,10 @@ class PWMDriverESP32 : public DriverPWMBase {
143143
case 11: return 39.0625;
144144
}
145145
return 312.5;
146-
}
147-
148-
146+
}
149147
};
150-
/// timer callback: write the next frame to the pins
148+
149+
/// timer callback: write the next frame to the pins
151150
void IRAM_ATTR defaultPWMAudioOutputCallback() {
152151
if (accessAudioPWM!=nullptr){
153152
portENTER_CRITICAL_ISR(&(accessAudioPWM->timerMux));
@@ -156,7 +155,6 @@ void IRAM_ATTR defaultPWMAudioOutputCallback() {
156155
}
157156
}
158157

159-
160158
}
161159

162160
#endif

src/AudioTimer/AudioTimerESP32.h

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ static IRAM_ATTR void timerCallback3() {
107107
}
108108

109109

110-
111110
/**
112111
* @brief Repeating Timer functions for simple scheduling of repeated execution.
113112
* The basic logic is taken from https://www.toptal.com/embedded/esp32-audio-sampling.
@@ -124,6 +123,11 @@ class TimerAlarmRepeatingDriverESP32 : public TimerAlarmRepeatingDriverBase {
124123
setTimerFunction(DirectTimerCallback);
125124
setTimer(0);
126125
}
126+
127+
TimerAlarmRepeatingDriverESP32(int timer, TimerFunction function){
128+
setTimerFunction(function);
129+
setTimer(timer);
130+
}
127131

128132
void setTimer(int id) override {
129133
if (id>=0 && id<4) {
@@ -156,8 +160,7 @@ class TimerAlarmRepeatingDriverESP32 : public TimerAlarmRepeatingDriverBase {
156160
break;
157161
}
158162
LOGI("Timer every: %u us", timeUs);
159-
uint32_t cpu_freq = getCpuFrequencyMhz(); // 80 ?
160-
adc_timer = timerBegin(0, cpu_freq, true); // divider=80 -> 1000000 calls per second
163+
adc_timer = timerBegin(timer_id, 80, true); // divider=80 -> 1000000 calls per second
161164

162165

163166
switch (function) {
@@ -184,6 +187,7 @@ class TimerAlarmRepeatingDriverESP32 : public TimerAlarmRepeatingDriverBase {
184187
bool end() override {
185188
TRACED();
186189
if (started){
190+
timerDetachInterrupt(adc_timer);
187191
timerEnd(adc_timer);
188192
if (handler_task!=nullptr){
189193
vTaskDelete(handler_task);
@@ -209,19 +213,37 @@ class TimerAlarmRepeatingDriverESP32 : public TimerAlarmRepeatingDriverBase {
209213
int priority = configMAX_PRIORITIES -1;
210214
uint32_t timeUs;
211215

212-
213216
/// direct timer callback
214217
void setupDirectTimerCallback(repeating_timer_callback_t callback_f){
218+
TRACED();
219+
// We start the timer which executes the callbacks directly
220+
if (simpleUserCallback==nullptr){
221+
simpleUserCallback = new UserCallback[4];
222+
}
223+
simpleUserCallback[timer_id].setup(callback_f, object, true);
224+
if (timer_id==0) timerAttachInterrupt(adc_timer, userCallback0, false);
225+
else if (timer_id==1) timerAttachInterrupt(adc_timer, userCallback1, false);
226+
else if (timer_id==2) timerAttachInterrupt(adc_timer, userCallback2, false);
227+
else if (timer_id==3) timerAttachInterrupt(adc_timer, userCallback3, false);
228+
229+
timerAlarmWrite(adc_timer, timeUs, true);
230+
//timerSetAutoReload(adc_timer, true);
231+
timerAlarmEnable(adc_timer);
232+
233+
}
234+
235+
/// timer callback is notifiying task
236+
void setupTimerCallbackInThread(repeating_timer_callback_t callback_f){
215237
TRACED();
216238
// we start the timer which runs the callback in a seprate task
217239
if (timerCallbackArray==nullptr){
218240
timerCallbackArray = new TimerCallback[4];
219241
}
220242

221-
if (timer_id==0) timerAttachInterrupt(adc_timer, timerCallback0, true);
222-
else if (timer_id==1) timerAttachInterrupt(adc_timer, timerCallback1, true);
223-
else if (timer_id==2) timerAttachInterrupt(adc_timer, timerCallback2, true);
224-
else if (timer_id==3) timerAttachInterrupt(adc_timer, timerCallback3, true);
243+
if (timer_id==0) timerAttachInterrupt(adc_timer, timerCallback0, false);
244+
else if (timer_id==1) timerAttachInterrupt(adc_timer, timerCallback1, false);
245+
else if (timer_id==2) timerAttachInterrupt(adc_timer, timerCallback2, false);
246+
else if (timer_id==3) timerAttachInterrupt(adc_timer, timerCallback3, false);
225247

226248
// we record the callback method and user data
227249
user_callback.setup(callback_f, object, false);
@@ -235,23 +257,6 @@ class TimerAlarmRepeatingDriverESP32 : public TimerAlarmRepeatingDriverBase {
235257
timerAlarmEnable(adc_timer);
236258
}
237259

238-
// timer callback is notifiying task
239-
void setupTimerCallbackInThread(repeating_timer_callback_t callback_f){
240-
TRACED();
241-
// We start the timer which executes the callbacks directly
242-
if (simpleUserCallback==nullptr){
243-
simpleUserCallback = new UserCallback[4];
244-
}
245-
simpleUserCallback[timer_id].setup(callback_f, object, true);
246-
if (timer_id==0) timerAttachInterrupt(adc_timer, userCallback0, true);
247-
else if (timer_id==1) timerAttachInterrupt(adc_timer, userCallback1, true);
248-
else if (timer_id==2) timerAttachInterrupt(adc_timer, userCallback2, true);
249-
else if (timer_id==3) timerAttachInterrupt(adc_timer, userCallback3, true);
250-
251-
timerAlarmWrite(adc_timer, timeUs, true);
252-
timerAlarmEnable(adc_timer);
253-
254-
}
255260

256261
/// No timer - just a simple task loop
257262
void setupSimpleThreadLoop(repeating_timer_callback_t callback_f){

0 commit comments

Comments
 (0)