arduino-audio-tools
Loading...
Searching...
No Matches
AudioTimerESP32Legacy.h
Go to the documentation of this file.
1#pragma once
2
3#if defined(ESP32) && defined(ARDUINO)
4#include <esp_task_wdt.h>
5
7
8namespace audio_tools {
9
16class UserCallback {
17 public:
19 bool lock) {
20 TRACED();
21 this->my_callback = my_callback;
22 this->user_data = user_data;
23 this->lock = lock; // false when called from Task
24 }
25
26 IRAM_ATTR void call() {
27 if (my_callback != nullptr) {
31 }
32 }
33
34 protected:
36 void *user_data = nullptr;
38 bool lock;
39
40} static *simpleUserCallback = nullptr;
41
42static IRAM_ATTR void userCallback0() { simpleUserCallback[0].call(); }
43static IRAM_ATTR void userCallback1() { simpleUserCallback[1].call(); }
44static IRAM_ATTR void userCallback2() { simpleUserCallback[2].call(); }
45static IRAM_ATTR void userCallback3() { simpleUserCallback[3].call(); }
46
53class TimerCallback {
54 public:
56 TRACED();
58 p_handler_task = nullptr;
59 }
60
62 TRACED();
64 assert(handler_task != nullptr);
65 }
66
67 IRAM_ATTR void call() {
68 if (p_handler_task != nullptr) {
69 // A mutex protects the handler from reentry (which shouldn't happen, but
70 // just in case)
72 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
73 vTaskNotifyGiveFromISR(p_handler_task, &xHigherPriorityTaskWoken);
74 if (xHigherPriorityTaskWoken) {
76 }
78 }
79 }
80
81 protected:
84
85} static *timerCallbackArray = nullptr;
86
87static IRAM_ATTR void timerCallback0() { timerCallbackArray[0].call(); }
88static IRAM_ATTR void timerCallback1() { timerCallbackArray[1].call(); }
89static IRAM_ATTR void timerCallback2() { timerCallbackArray[2].call(); }
90static IRAM_ATTR void timerCallback3() { timerCallbackArray[3].call(); }
91
102class TimerAlarmRepeatingDriverESP32Legacy : public TimerAlarmRepeatingDriverBase {
103 public:
105 setTimerFunction(DirectTimerCallback);
106 setTimer(0);
107 }
108
110 setTimerFunction(function);
111 setTimer(timer);
112 }
113
114 void setTimer(int id) override {
115 if (id >= 0 && id < 4) {
116 this->timer_id = id;
117 handler_task = nullptr;
118 } else {
119 LOGE("Invalid timer id %d", timer_id);
120 }
121 }
122
123 void setTimerFunction(TimerFunction function = DirectTimerCallback) override {
124 this->function = function;
125 }
126
129 TimeUnit unit = MS) override {
130 TRACED();
131
132 // we determine the time in microseconds
133 switch (unit) {
134 case MS:
135 timeUs = time * 1000;
136 break;
137 case US:
138 timeUs = time;
139 break;
140 case HZ:
141 // convert hz to time in us
143 break;
144 }
145#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
146 LOGI("Timer every: %u us", timeUs);
147 adc_timer = timerBegin(timer_id, 80,
148 true); // divider=80 -> 1000000 calls per second
149#else
150 uint32_t freq = AudioTime::AudioTime::toRateUs(timeUs);
151 LOGI("Timer freq: %u hz", (unsigned)freq);
152 adc_timer = timerBegin(1000000); // divider=80 -> 1000000 calls per second
153#endif
154 switch (function) {
157 break;
158
161 break;
162
163 case SimpleThreadLoop:
165 break;
166 }
167
168 started = true;
169 return true;
170 }
171
173 bool end() override {
174 TRACED();
175 if (started) {
178 if (handler_task != nullptr) {
180 handler_task = nullptr;
181 }
182 }
183 started = false;
184 return true;
185 }
186
187 void setCore(int core) { this->core = core; }
188
191 void setIsSave(bool is_save) override {
193 }
194
195 protected:
196 int timer_id = 0;
197 volatile bool started = false;
198 TaskHandle_t handler_task = nullptr;
199 hw_timer_t *adc_timer = nullptr; // our timer
200 UserCallback user_callback; // for task
202 int core = 1;
203 int priority = 1; // configMAX_PRIORITIES - 1;
205
207 void attach(hw_timer_t *timer, void (*cb)()) {
208#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
209 timerAttachInterrupt(timer, cb);
210#else
211 timerAttachInterrupt(timer, cb, false);
212#endif
213 }
214
217 TRACED();
218 // We start the timer which executes the callbacks directly
219 if (simpleUserCallback == nullptr) {
221 }
222 simpleUserCallback[timer_id].setup(callback_f, object, true);
223
224 if (timer_id == 0)
226 else if (timer_id == 1)
228 else if (timer_id == 2)
230 else if (timer_id == 3)
232
233#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
236
237#else
238 // timerStart(adc_timer);
239 // timerWrite(adc_timer,timeUs);
240 timerAlarm(adc_timer, timeUs, true, 0);
241#endif
242 }
243
247 TRACED();
248 // we start the timer which runs the callback in a seprate task
249 if (timerCallbackArray == nullptr) {
251 }
252
253 if (timer_id == 0)
255 else if (timer_id == 1)
257 else if (timer_id == 2)
259 else if (timer_id == 3)
261
262 // we record the callback method and user data
263 user_callback.setup(callback_f, object, false);
264 // setup the timercallback
265 xTaskCreatePinnedToCore(complexTaskHandler, "TimerAlarmRepeatingTask",
267 priority, &handler_task, core);
268 LOGI("Task created on core %d", core);
269 timerCallbackArray[timer_id].setup(handler_task);
270
271#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
274#else
275 timerAlarm(adc_timer, timeUs, true, 0); // set time in us
276#endif
277 }
278
281 TRACED();
282 user_callback.setup(callback_f, object, false);
283 xTaskCreatePinnedToCore(simpleTaskLoop, "TimerAlarmRepeatingTask",
284 configMINIMAL_STACK_SIZE + 10000, this, priority,
285 &handler_task, core);
286 LOGI("Task created on core %d", core);
287 }
288
291 static void complexTaskHandler(void *param) {
292 TRACEI();
294
295 while (true) {
296 // Sleep until the ISR gives us something to do
299 // Do something complex and CPU-intensive
301 cb->call();
302 }
303 delay(0);
304 }
305 }
306
309 static void simpleTaskLoop(void *param) {
310 TRACEI();
313
314 while (true) {
315 unsigned long end = micros() + ta->timeUs;
316 ta->user_callback.call();
317 long waitUs = end - micros();
318 long waitMs = waitUs / 1000;
319 waitUs = waitUs - (waitMs * 1000);
320 delay(waitMs);
321 waitUs = end - micros();
322 if (waitUs > 0) {
324 }
325 }
326 }
327};
328
329#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
332#endif
333
334} // namespace audio_tools
335
336#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
#define IRAM_ATTR
Definition AudioStreams.h:13
void setup()
#define assert(T)
Definition avr.h:10
static uint32_t toTimeUs(uint32_t samplingRate, uint8_t limit=10)
converts sampling rate to delay in microseconds (μs)
Definition AudioTypes.h:242
TimeUnit
Time Units.
Definition AudioTypes.h:48
@ US
Definition AudioTypes.h:48
@ HZ
Definition AudioTypes.h:48
@ MS
Definition AudioTypes.h:48
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
TimerFunction
Definition AudioTimerBase.h:16
@ SimpleThreadLoop
Definition AudioTimerBase.h:19
@ TimerCallbackInThread
Definition AudioTimerBase.h:18
@ DirectTimerCallback
Definition AudioTimerBase.h:17
void(* repeating_timer_callback_t)(void *obj)
Definition AudioTimerAVR.h:7
void delayMicroseconds(unsigned int us)
Definition Time.h:28
void delay(unsigned long ms)
Definition Time.h:23
unsigned long micros(void)
Definition Time.h:33
TimerAlarmRepeatingDriverAVR TimerAlarmRepeatingDriver
use TimerAlarmRepeating!
Definition AudioTimerAVR.h:94
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
constexpr const _Ep * end(initializer_list< _Ep > __il) noexcept
Definition InitializerList.h:63
constexpr const _Ep * begin(initializer_list< _Ep > __il) noexcept
Definition InitializerList.h:55