11/*
2- * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
66
77#include <stdlib.h>
88#include <sys/lock.h>
9- #include "sdkconfig.h"
10- #if CONFIG_GPTIMER_ENABLE_DEBUG_LOG
11- // The local log level must be defined before including esp_log.h
12- // Set the maximum log level for this source file
13- #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
14- #endif
15- #include "freertos/FreeRTOS.h"
16- #include "esp_attr.h"
17- #include "esp_err.h"
18- #include "esp_log.h"
19- #include "esp_check.h"
209#include "driver/gptimer.h"
21- #include "esp_memory_utils.h"
2210#include "gptimer_priv.h"
23-
24- static const char * TAG = "gptimer" ;
11+ #include "esp_memory_utils.h"
2512
2613static void gptimer_default_isr (void * args );
2714
@@ -136,9 +123,6 @@ static esp_err_t gptimer_destroy(gptimer_t *timer)
136123
137124esp_err_t gptimer_new_timer (const gptimer_config_t * config , gptimer_handle_t * ret_timer )
138125{
139- #if CONFIG_GPTIMER_ENABLE_DEBUG_LOG
140- esp_log_level_set (TAG , ESP_LOG_DEBUG );
141- #endif
142126 esp_err_t ret = ESP_OK ;
143127 gptimer_t * timer = NULL ;
144128 ESP_RETURN_ON_FALSE (config && ret_timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
@@ -188,7 +172,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
188172 timer -> direction = config -> direction ;
189173 timer -> intr_priority = config -> intr_priority ;
190174 timer -> flags .intr_shared = config -> flags .intr_shared ;
191- ESP_LOGD (TAG , "new gptimer (%d,%d) at %p, resolution=%" PRIu32 "Hz" , group_id , timer_id , timer , timer -> resolution_hz );
175+ ESP_LOGD (TAG , "new gptimer (%d,%d) at %p, %zu bytes used" , group_id , timer_id , timer , heap_caps_get_allocated_size ( timer ) );
192176 * ret_timer = timer ;
193177 return ESP_OK ;
194178
@@ -231,7 +215,9 @@ esp_err_t gptimer_del_timer(gptimer_handle_t timer)
231215
232216esp_err_t gptimer_set_raw_count (gptimer_handle_t timer , unsigned long long value )
233217{
234- ESP_RETURN_ON_FALSE_ISR (timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
218+ if (timer == NULL ) {
219+ return ESP_ERR_INVALID_ARG ;
220+ }
235221
236222 portENTER_CRITICAL_SAFE (& timer -> spinlock );
237223 timer_hal_set_counter_value (& timer -> hal , value );
@@ -241,7 +227,9 @@ esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, unsigned long long value
241227
242228esp_err_t gptimer_get_raw_count (gptimer_handle_t timer , unsigned long long * value )
243229{
244- ESP_RETURN_ON_FALSE_ISR (timer && value , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
230+ if (timer == NULL || value == NULL ) {
231+ return ESP_ERR_INVALID_ARG ;
232+ }
245233
246234 portENTER_CRITICAL_SAFE (& timer -> spinlock );
247235 * value = timer_hal_capture_and_get_counter_value (& timer -> hal );
@@ -258,7 +246,9 @@ esp_err_t gptimer_get_resolution(gptimer_handle_t timer, uint32_t *out_resolutio
258246
259247esp_err_t gptimer_get_captured_count (gptimer_handle_t timer , uint64_t * value )
260248{
261- ESP_RETURN_ON_FALSE_ISR (timer && value , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
249+ if (timer == NULL || value == NULL ) {
250+ return ESP_ERR_INVALID_ARG ;
251+ }
262252
263253 portENTER_CRITICAL_SAFE (& timer -> spinlock );
264254 * value = timer_ll_get_counter_value (timer -> hal .dev , timer -> timer_id );
@@ -274,7 +264,7 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer
274264 int group_id = group -> group_id ;
275265 int timer_id = timer -> timer_id ;
276266
277- #if CONFIG_GPTIMER_ISR_IRAM_SAFE
267+ #if CONFIG_GPTIMER_ISR_CACHE_SAFE
278268 if (cbs -> on_alarm ) {
279269 ESP_RETURN_ON_FALSE (esp_ptr_in_iram (cbs -> on_alarm ), ESP_ERR_INVALID_ARG , TAG , "on_alarm callback not in IRAM" );
280270 }
@@ -308,14 +298,22 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer
308298
309299esp_err_t gptimer_set_alarm_action (gptimer_handle_t timer , const gptimer_alarm_config_t * config )
310300{
311- ESP_RETURN_ON_FALSE_ISR (timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
301+ if (timer == NULL ) {
302+ return ESP_ERR_INVALID_ARG ;
303+ }
312304 if (config ) {
313305#if CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
314- ESP_RETURN_ON_FALSE_ISR (esp_ptr_internal (config ), ESP_ERR_INVALID_ARG , TAG , "alarm config struct not in internal RAM" );
306+ // when the function is placed in IRAM, we expect the config struct is also placed in internal RAM
307+ // if the cache is disabled, the function can still access the config struct
308+ if (esp_ptr_internal (config ) == false) {
309+ return ESP_ERR_INVALID_ARG ;
310+ }
315311#endif
316312 // When auto_reload is enabled, alarm_count should not be equal to reload_count
317313 bool valid_auto_reload = !config -> flags .auto_reload_on_alarm || config -> alarm_count != config -> reload_count ;
318- ESP_RETURN_ON_FALSE_ISR (valid_auto_reload , ESP_ERR_INVALID_ARG , TAG , "reload count can't equal to alarm count" );
314+ if (valid_auto_reload == false) {
315+ return ESP_ERR_INVALID_ARG ;
316+ }
319317
320318 portENTER_CRITICAL_SAFE (& timer -> spinlock );
321319 timer -> reload_count = config -> reload_count ;
@@ -343,6 +341,7 @@ esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_c
343341esp_err_t gptimer_enable (gptimer_handle_t timer )
344342{
345343 ESP_RETURN_ON_FALSE (timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
344+ // the only acceptable FSM change: init->enable
346345 gptimer_fsm_t expected_fsm = GPTIMER_FSM_INIT ;
347346 ESP_RETURN_ON_FALSE (atomic_compare_exchange_strong (& timer -> fsm , & expected_fsm , GPTIMER_FSM_ENABLE ),
348347 ESP_ERR_INVALID_STATE , TAG , "timer not in init state" );
@@ -363,6 +362,7 @@ esp_err_t gptimer_enable(gptimer_handle_t timer)
363362esp_err_t gptimer_disable (gptimer_handle_t timer )
364363{
365364 ESP_RETURN_ON_FALSE (timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
365+ // the only acceptable FSM change: enable->init
366366 gptimer_fsm_t expected_fsm = GPTIMER_FSM_ENABLE ;
367367 ESP_RETURN_ON_FALSE (atomic_compare_exchange_strong (& timer -> fsm , & expected_fsm , GPTIMER_FSM_INIT ),
368368 ESP_ERR_INVALID_STATE , TAG , "timer not in enable state" );
@@ -382,7 +382,14 @@ esp_err_t gptimer_disable(gptimer_handle_t timer)
382382
383383esp_err_t gptimer_start (gptimer_handle_t timer )
384384{
385- ESP_RETURN_ON_FALSE_ISR (timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
385+ if (timer == NULL ) {
386+ return ESP_ERR_INVALID_ARG ;
387+ }
388+
389+ // if the timer is already started, do nothing
390+ if (atomic_load (& timer -> fsm ) == GPTIMER_FSM_RUN ) {
391+ return ESP_OK ;
392+ }
386393
387394 gptimer_fsm_t expected_fsm = GPTIMER_FSM_ENABLE ;
388395 if (atomic_compare_exchange_strong (& timer -> fsm , & expected_fsm , GPTIMER_FSM_RUN_WAIT )) {
@@ -396,15 +403,24 @@ esp_err_t gptimer_start(gptimer_handle_t timer)
396403 atomic_store (& timer -> fsm , GPTIMER_FSM_RUN );
397404 portEXIT_CRITICAL_SAFE (& timer -> spinlock );
398405 } else {
399- ESP_RETURN_ON_FALSE_ISR (false, ESP_ERR_INVALID_STATE , TAG , "timer is not ready for a new start" );
406+ // return error if the timer is not in the expected state
407+ return ESP_ERR_INVALID_STATE ;
400408 }
401409
402410 return ESP_OK ;
403411}
404412
405413esp_err_t gptimer_stop (gptimer_handle_t timer )
406414{
407- ESP_RETURN_ON_FALSE_ISR (timer , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
415+ if (timer == NULL ) {
416+ // not printing error message here because the return value already indicates the error well
417+ return ESP_ERR_INVALID_ARG ;
418+ }
419+
420+ // if the timer is not started, do nothing
421+ if (atomic_load (& timer -> fsm ) == GPTIMER_FSM_ENABLE ) {
422+ return ESP_OK ;
423+ }
408424
409425 gptimer_fsm_t expected_fsm = GPTIMER_FSM_RUN ;
410426 if (atomic_compare_exchange_strong (& timer -> fsm , & expected_fsm , GPTIMER_FSM_ENABLE_WAIT )) {
@@ -415,7 +431,8 @@ esp_err_t gptimer_stop(gptimer_handle_t timer)
415431 atomic_store (& timer -> fsm , GPTIMER_FSM_ENABLE );
416432 portEXIT_CRITICAL_SAFE (& timer -> spinlock );
417433 } else {
418- ESP_RETURN_ON_FALSE_ISR (false, ESP_ERR_INVALID_STATE , TAG , "timer is not running" );
434+ // return error if the timer is not in the expected state
435+ return ESP_ERR_INVALID_STATE ;
419436 }
420437
421438 return ESP_OK ;
0 commit comments