21
21
22
22
#define ESP_TIMER_HZ CONFIG_FREERTOS_HZ
23
23
24
+ typedef enum {
25
+ ESP_TIMER_INIT = 0 ,
26
+ ESP_TIMER_ONCE ,
27
+ ESP_TIMER_CYCLE ,
28
+ ESP_TIMER_STOP ,
29
+ ESP_TIMER_DELETE ,
30
+ } esp_timer_state_t ;
31
+
24
32
struct esp_timer {
25
33
TimerHandle_t os_timer ;
26
34
27
35
esp_timer_cb_t cb ;
28
36
29
37
void * arg ;
30
38
31
- TickType_t period_ticks ;
39
+ esp_timer_state_t state ;
32
40
};
33
41
34
42
static const char * TAG = "esp_timer" ;
35
43
44
+ static esp_err_t delete_timer (esp_timer_handle_t timer )
45
+ {
46
+ BaseType_t ret = xTimerDelete (timer -> os_timer , portMAX_DELAY );
47
+ if (ret == pdPASS )
48
+ heap_caps_free (timer );
49
+
50
+ return ret == pdPASS ? ESP_OK : ESP_ERR_NO_MEM ;
51
+ }
52
+
36
53
/**
37
54
* @brief FreeRTOS callback function
38
55
*/
39
56
static void esp_timer_callback (TimerHandle_t xTimer )
40
57
{
41
- BaseType_t os_ret ;
42
58
struct esp_timer * timer = (struct esp_timer * )pvTimerGetTimerID (xTimer );
43
59
44
60
timer -> cb (timer -> arg );
45
61
46
- if (!timer -> period_ticks ) {
47
- os_ret = xTimerStop (timer -> os_timer , 0 );
48
- if (os_ret != pdPASS ) {
49
- ESP_LOGE (TAG , "Set timer from periodic to once error" );
62
+ switch (timer -> state ) {
63
+ case ESP_TIMER_INIT :
64
+ case ESP_TIMER_STOP :
65
+ break ;
66
+ case ESP_TIMER_CYCLE : {
67
+ BaseType_t ret = xTimerReset (timer -> os_timer , portMAX_DELAY );
68
+ if (ret != pdPASS ) {
69
+ ESP_LOGE (TAG , "start timer at callback error" );
70
+ } else {
71
+ ESP_LOGD (TAG , "start timer at callback OK" );
72
+ }
73
+ break ;
74
+ }
75
+ case ESP_TIMER_ONCE : {
76
+ BaseType_t ret = xTimerStop (timer -> os_timer , portMAX_DELAY );
77
+ if (ret != pdPASS ) {
78
+ ESP_LOGE (TAG , "stop timer at callback error" );
79
+ } else {
80
+ timer -> state = ESP_TIMER_STOP ;
81
+ ESP_LOGD (TAG , "stop timer at callback OK" );
82
+ }
83
+ break ;
84
+ }
85
+ case ESP_TIMER_DELETE : {
86
+ esp_err_t ret = delete_timer (timer );
87
+ if (ret != ESP_OK ) {
88
+ ESP_LOGE (TAG , "delete timer at callback error" );
89
+ } else {
90
+ ESP_LOGD (TAG , "delete timer at callback OK" );
91
+ }
92
+ break ;
50
93
}
94
+ default :
95
+ ESP_LOGE (TAG , "timer state error is %d" , timer -> state );
96
+ break ;
51
97
}
52
98
}
53
99
@@ -83,17 +129,16 @@ esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
83
129
if (!esp_timer )
84
130
return ESP_ERR_NO_MEM ;
85
131
86
- esp_timer -> cb = create_args -> callback ;
87
- esp_timer -> arg = create_args -> arg ;
88
- esp_timer -> period_ticks = 0 ;
89
-
90
132
os_timer = xTimerCreate (create_args -> name ,
91
133
portMAX_DELAY ,
92
- pdTRUE ,
134
+ pdFALSE ,
93
135
esp_timer ,
94
136
esp_timer_callback );
95
137
if (os_timer ) {
96
138
esp_timer -> os_timer = os_timer ;
139
+ esp_timer -> cb = create_args -> callback ;
140
+ esp_timer -> arg = create_args -> arg ;
141
+ esp_timer -> state = ESP_TIMER_INIT ;
97
142
* out_handle = (esp_timer_handle_t )esp_timer ;
98
143
} else {
99
144
heap_caps_free (esp_timer );
@@ -120,14 +165,7 @@ esp_err_t esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us)
120
165
121
166
os_ret = xTimerChangePeriod (os_timer , ticks , portMAX_DELAY );
122
167
if (os_ret == pdPASS ) {
123
- TickType_t period_ticks = timer -> period_ticks ;
124
-
125
- timer -> period_ticks = 0 ;
126
- os_ret = xTimerStart (os_timer , portMAX_DELAY );
127
- if (os_ret != pdPASS ) {
128
- timer -> period_ticks = period_ticks ;
129
- return ESP_ERR_INVALID_STATE ;
130
- }
168
+ timer -> state = ESP_TIMER_ONCE ;
131
169
} else {
132
170
return ESP_ERR_INVALID_STATE ;
133
171
}
@@ -152,14 +190,7 @@ esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period)
152
190
153
191
os_ret = xTimerChangePeriod (os_timer , ticks , portMAX_DELAY );
154
192
if (os_ret == pdPASS ) {
155
- TickType_t period_ticks = timer -> period_ticks ;
156
-
157
- timer -> period_ticks = ticks ;
158
- os_ret = xTimerStart (os_timer , portMAX_DELAY );
159
- if (os_ret != pdPASS ) {
160
- timer -> period_ticks = period_ticks ;
161
- return ESP_ERR_INVALID_STATE ;
162
- }
193
+ timer -> state = ESP_TIMER_CYCLE ;
163
194
} else {
164
195
return ESP_ERR_INVALID_STATE ;
165
196
}
@@ -178,6 +209,8 @@ esp_err_t esp_timer_stop(esp_timer_handle_t timer)
178
209
BaseType_t os_ret ;
179
210
180
211
os_ret = xTimerStop (os_timer , portMAX_DELAY );
212
+ if (os_ret == pdPASS )
213
+ timer -> state = ESP_TIMER_STOP ;
181
214
182
215
return os_ret == pdPASS ? ESP_OK : ESP_ERR_INVALID_STATE ;
183
216
}
@@ -187,14 +220,25 @@ esp_err_t esp_timer_stop(esp_timer_handle_t timer)
187
220
*/
188
221
esp_err_t esp_timer_delete (esp_timer_handle_t timer )
189
222
{
223
+ esp_err_t ret ;
224
+
190
225
assert (timer );
191
226
192
- TimerHandle_t os_timer = timer -> os_timer ;
193
- BaseType_t os_ret ;
227
+ if (xTimerGetTimerDaemonTaskHandle () == xTaskGetCurrentTaskHandle ()) {
228
+ timer -> state = ESP_TIMER_DELETE ;
229
+ ret = ESP_OK ;
230
+ } else {
231
+ UBaseType_t prio = uxTaskPriorityGet (NULL );
232
+ if (prio >= configTIMER_TASK_PRIORITY )
233
+ vTaskPrioritySet (NULL , configTIMER_TASK_PRIORITY - 1 );
234
+ else
235
+ prio = 0 ;
194
236
195
- os_ret = xTimerDelete (os_timer , portMAX_DELAY );
196
- if (os_ret == pdPASS )
197
- heap_caps_free (timer );
237
+ ret = delete_timer (timer );
238
+
239
+ if (prio )
240
+ vTaskPrioritySet (NULL , prio );
241
+ }
198
242
199
- return os_ret == pdPASS ? ESP_OK : ESP_ERR_INVALID_STATE ;
243
+ return ret ;
200
244
}
0 commit comments