1 /*
2 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*
8 * ets_timer module implements a set of legacy timer APIs which are
9 * used by the WiFi driver. This is done on top of the newer esp_timer APIs.
10 * Applications should not use ets_timer functions, as they may change without
11 * notice.
12 */
13
14 #include <string.h>
15 #include "esp_types.h"
16 #include "esp_log.h"
17 #include "esp_attr.h"
18 #include "esp_intr_alloc.h"
19 #include "sdkconfig.h"
20 #include "esp_timer.h"
21 // for ETSTimer type
22 #if CONFIG_IDF_TARGET_ESP32
23 #include "esp32/rom/ets_sys.h"
24 #elif CONFIG_IDF_TARGET_ESP32S2
25 #include "esp32s2/rom/ets_sys.h"
26 #elif CONFIG_IDF_TARGET_ESP32S3
27 #include "esp32s3/rom/ets_sys.h"
28 #elif CONFIG_IDF_TARGET_ESP32C3
29 #include "esp32c3/rom/ets_sys.h"
30 #elif CONFIG_IDF_TARGET_ESP32C2
31 #include "esp32c2/rom/ets_sys.h"
32 #elif CONFIG_IDF_TARGET_ESP32C6
33 #include "esp32c6/rom/ets_sys.h"
34 #elif CONFIG_IDF_TARGET_ESP32H2
35 #include "esp32h2/rom/ets_sys.h"
36 #endif
37
38 /* We abuse 'timer_arg' field of ETSTimer structure to hold a pointer to esp_timer */
39 #define ESP_TIMER(p_ets_timer) ((esp_timer_handle_t) (p_ets_timer)->timer_arg)
40
41 /* We abuse 'timer_expire' field of ETSTimer structure to hold a magic value
42 * signifying that the contents of the timer was zeroed out.
43 */
44 #define TIMER_INITIALIZED_FIELD(p_ets_timer) ((p_ets_timer)->timer_expire)
45 #define TIMER_INITIALIZED_VAL 0x12121212
46
timer_initialized(ETSTimer * ptimer)47 static IRAM_ATTR bool timer_initialized(ETSTimer *ptimer)
48 {
49 return TIMER_INITIALIZED_FIELD(ptimer) == TIMER_INITIALIZED_VAL;
50 }
51
ets_timer_setfn(ETSTimer * ptimer,ETSTimerFunc * pfunction,void * parg)52 void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg)
53 {
54 if (!timer_initialized(ptimer)) {
55 memset(ptimer, 0, sizeof(*ptimer));
56 TIMER_INITIALIZED_FIELD(ptimer) = TIMER_INITIALIZED_VAL;
57 }
58
59 if (ESP_TIMER(ptimer) == NULL) {
60 const esp_timer_create_args_t create_args = {
61 .callback = pfunction,
62 .arg = parg,
63 .name = "ETSTimer",
64 .dispatch_method = ESP_TIMER_TASK
65 };
66
67 ESP_ERROR_CHECK( esp_timer_create(&create_args, (esp_timer_handle_t*)&(ptimer->timer_arg)) );
68 }
69 }
70
71
ets_timer_arm_us(ETSTimer * ptimer,uint32_t time_us,bool repeat_flag)72 void IRAM_ATTR ets_timer_arm_us(ETSTimer *ptimer, uint32_t time_us, bool repeat_flag)
73 {
74 assert(timer_initialized(ptimer));
75 esp_timer_stop(ESP_TIMER(ptimer)); // no error check
76 if (!repeat_flag) {
77 ESP_ERROR_CHECK( esp_timer_start_once(ESP_TIMER(ptimer), time_us) );
78 } else {
79 ESP_ERROR_CHECK( esp_timer_start_periodic(ESP_TIMER(ptimer), time_us) );
80 }
81 }
82
ets_timer_arm(ETSTimer * ptimer,uint32_t time_ms,bool repeat_flag)83 void IRAM_ATTR ets_timer_arm(ETSTimer *ptimer, uint32_t time_ms, bool repeat_flag)
84 {
85 uint64_t time_us = 1000LL * (uint64_t) time_ms;
86 assert(timer_initialized(ptimer));
87 esp_timer_stop(ESP_TIMER(ptimer)); // no error check
88 if (!repeat_flag) {
89 ESP_ERROR_CHECK( esp_timer_start_once(ESP_TIMER(ptimer), time_us) );
90 } else {
91 ESP_ERROR_CHECK( esp_timer_start_periodic(ESP_TIMER(ptimer), time_us) );
92 }
93 }
94
ets_timer_done(ETSTimer * ptimer)95 void ets_timer_done(ETSTimer *ptimer)
96 {
97 if (timer_initialized(ptimer)) {
98 esp_timer_delete(ESP_TIMER(ptimer));
99 ptimer->timer_arg = NULL;
100 TIMER_INITIALIZED_FIELD(ptimer) = 0;
101 }
102 }
103
ets_timer_disarm(ETSTimer * ptimer)104 void IRAM_ATTR ets_timer_disarm(ETSTimer *ptimer)
105 {
106 if (timer_initialized(ptimer)) {
107 esp_timer_stop(ESP_TIMER(ptimer));
108 }
109 }
110
111
ets_timer_init(void)112 void ets_timer_init(void)
113 {
114
115 }
116
ets_timer_deinit(void)117 void ets_timer_deinit(void)
118 {
119
120 }
121
122 void os_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg) __attribute__((alias("ets_timer_setfn")));
123 void os_timer_disarm(ETSTimer *ptimer) __attribute__((alias("ets_timer_disarm")));
124 void os_timer_arm_us(ETSTimer *ptimer,uint32_t u_seconds,bool repeat_flag) __attribute__((alias("ets_timer_arm_us")));
125 void os_timer_arm(ETSTimer *ptimer,uint32_t milliseconds,bool repeat_flag) __attribute__((alias("ets_timer_arm")));
126 void os_timer_done(ETSTimer *ptimer) __attribute__((alias("ets_timer_done")));
127