3#if defined(ESP32) && defined(ARDUINO)
4#include <esp_task_wdt.h>
18 void setup(repeating_timer_callback_t my_callback,
void *user_data,
21 this->my_callback = my_callback;
22 this->user_data = user_data;
27 if (my_callback !=
nullptr) {
28 if (lock) portENTER_CRITICAL_ISR(&timerMux);
29 my_callback(user_data);
30 if (lock) portEXIT_CRITICAL_ISR(&timerMux);
36 void *user_data =
nullptr;
37 portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
40}
static *simpleUserCallback =
nullptr;
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(); }
57 timerMux = portMUX_INITIALIZER_UNLOCKED;
58 p_handler_task =
nullptr;
61 void setup(TaskHandle_t handler_task) {
63 p_handler_task = handler_task;
64 assert(handler_task !=
nullptr);
68 if (p_handler_task !=
nullptr) {
71 portENTER_CRITICAL_ISR(&timerMux);
73 vTaskNotifyGiveFromISR(p_handler_task, &xHigherPriorityTaskWoken);
74 if (xHigherPriorityTaskWoken) {
77 portEXIT_CRITICAL_ISR(&timerMux);
82 portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
85}
static *timerCallbackArray =
nullptr;
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(); }
102class AudioTimerDriverESP32Legacy :
public AudioTimerDriverBase {
104 AudioTimerDriverESP32Legacy() {
105 setTimerFunction(DirectTimerCallback);
109 AudioTimerDriverESP32Legacy(
int timer, TimerFunction function) {
110 setTimerFunction(function);
114 void setTimer(
int id)
override {
115 if (
id >= 0 &&
id < 4) {
117 handler_task =
nullptr;
119 LOGE(
"Invalid timer id %d", timer_id);
123 void setTimerFunction(TimerFunction function = DirectTimerCallback)
override {
124 this->function = function;
128 bool begin(repeating_timer_callback_t callback_f, uint32_t time,
129 TimeUnit unit = MS)
override {
135 timeUs = time * 1000;
142 timeUs = AudioTime::toTimeUs(time);
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,
150 uint32_t freq = AudioTime::AudioTime::toRateUs(timeUs);
151 LOGI(
"Timer freq: %u hz", (
unsigned)freq);
152 adc_timer = timerBegin(1000000);
156 setupDirectTimerCallback(callback_f);
160 setupTimerCallbackInThread(callback_f);
164 setupSimpleThreadLoop(callback_f);
173 bool end()
override {
176 timerDetachInterrupt(adc_timer);
178 if (handler_task !=
nullptr) {
179 vTaskDelete(handler_task);
180 handler_task =
nullptr;
187 void setCore(
int core) { this->core = core; }
191 void setIsSave(
bool is_save)
override {
197 volatile bool started =
false;
199 hw_timer_t *adc_timer =
nullptr;
200 UserCallback user_callback;
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);
211 timerAttachInterrupt(timer, cb,
false);
216 void setupDirectTimerCallback(repeating_timer_callback_t callback_f) {
219 if (simpleUserCallback ==
nullptr) {
220 simpleUserCallback =
new UserCallback[4];
222 simpleUserCallback[timer_id].setup(callback_f,
object,
true);
225 attach(adc_timer, userCallback0);
226 else if (timer_id == 1)
227 attach(adc_timer, userCallback1);
228 else if (timer_id == 2)
229 attach(adc_timer, userCallback2);
230 else if (timer_id == 3)
231 attach(adc_timer, userCallback3);
233#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
234 timerAlarmWrite(adc_timer, timeUs,
true);
235 timerAlarmEnable(adc_timer);
240 timerAlarm(adc_timer, timeUs,
true, 0);
246 void setupTimerCallbackInThread(repeating_timer_callback_t callback_f) {
249 if (timerCallbackArray ==
nullptr) {
250 timerCallbackArray =
new TimerCallback[4];
254 attach(adc_timer, timerCallback0);
255 else if (timer_id == 1)
256 attach(adc_timer, timerCallback1);
257 else if (timer_id == 2)
258 attach(adc_timer, timerCallback2);
259 else if (timer_id == 3)
260 attach(adc_timer, timerCallback3);
263 user_callback.setup(callback_f,
object,
false);
265 xTaskCreatePinnedToCore(complexTaskHandler,
"AudioTimerTask",
266 configMINIMAL_STACK_SIZE + 10000, &user_callback,
267 priority, &handler_task, core);
268 LOGI(
"Task created on core %d", core);
269 timerCallbackArray[timer_id].setup(handler_task);
271#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
272 timerAlarmWrite(adc_timer, timeUs,
true);
273 timerAlarmEnable(adc_timer);
275 timerAlarm(adc_timer, timeUs,
true, 0);
280 void setupSimpleThreadLoop(repeating_timer_callback_t callback_f) {
282 user_callback.setup(callback_f,
object,
false);
283 xTaskCreatePinnedToCore(simpleTaskLoop,
"AudioTimerTask",
284 configMINIMAL_STACK_SIZE + 10000,
this, priority,
285 &handler_task, core);
286 LOGI(
"Task created on core %d", core);
291 static void complexTaskHandler(
void *param) {
293 UserCallback *cb = (UserCallback *)param;
297 uint32_t thread_notification =
300 if (thread_notification) {
309 static void simpleTaskLoop(
void *param) {
311 AudioTimerDriverESP32Legacy *ta =
312 (AudioTimerDriverESP32Legacy *)param;
315 unsigned long end =
micros() + ta->timeUs;
316 ta->user_callback.call();
318 long waitMs = waitUs / 1000;
319 waitUs = waitUs - (waitMs * 1000);
329#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
#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
#define pdFALSE
Definition QueueZephyr.h:23
#define pdMS_TO_TICKS(ms)
Definition QueueZephyr.h:17
int BaseType_t
Definition QueueZephyr.h:12
#define pdTRUE
Definition QueueZephyr.h:20
#define assert(T)
Definition avr.h:10
@ US
Definition AudioTypes.h:44
@ HZ
Definition AudioTypes.h:44
@ MS
Definition AudioTypes.h:44
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