diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index d7d2e315e8..33434aa924 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -31,11 +31,6 @@ if(CONFIG_SOC_DAC_SUPPORTED) "deprecated/${target}/dac_legacy.c") endif() -# GPTimer legacy driver -if(CONFIG_SOC_GPTIMER_SUPPORTED) - list(APPEND srcs "deprecated/timer_legacy.c") -endif() - # I2C related source files if(CONFIG_SOC_I2C_SUPPORTED) list(APPEND srcs "i2c/i2c.c") diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 1e9fecc94d..90d0fd52cb 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -102,23 +102,6 @@ menu "Driver Configurations" This configuration option allows the user to bypass the conflict check mechanism with legacy code. endmenu # Legacy MCPWM Driver Configurations - menu "Legacy Timer Group Driver Configurations" - depends on SOC_GPTIMER_SUPPORTED - config GPTIMER_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - Whether to suppress the deprecation warnings when using legacy timer group driver (driver/timer.h). - If you want to continue using the legacy driver, and don't want to see related deprecation warnings, - you can enable this option. - - config GPTIMER_SKIP_LEGACY_CONFLICT_CHECK - bool "Skip legacy conflict check" - default n - help - This configuration option allows the user to bypass the conflict check mechanism with legacy code. - endmenu # Legacy Timer Group Driver Configurations - menu "Legacy RMT Driver Configurations" depends on SOC_RMT_SUPPORTED config RMT_SUPPRESS_DEPRECATE_WARN diff --git a/components/driver/deprecated/driver/timer.h b/components/driver/deprecated/driver/timer.h deleted file mode 100644 index 17a2402029..0000000000 --- a/components/driver/deprecated/driver/timer.h +++ /dev/null @@ -1,383 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include -#include "sdkconfig.h" -#include "esp_err.h" -#include "driver/timer_types_legacy.h" - -#if !CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN -#warning "legacy timer group driver is deprecated, please migrate to driver/gptimer.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Read the counter value of hardware timer. - * - * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param timer_val Pointer to accept timer counter value. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *timer_val); - -/** - * @brief Read the counter value of hardware timer, in unit of a given scale. - * - * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param time Pointer, type of double*, to accept timer counter value, in seconds. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double *time); - -/** - * @brief Set counter value to hardware timer. - * - * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param load_val Counter value to write to the hardware timer. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val); - -/** - * @brief Start the counter of hardware timer. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num); - -/** - * @brief Pause the counter of hardware timer. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num); - -/** - * @brief Set counting mode for hardware timer. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param counter_dir Counting direction of timer, count-up or count-down - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir); - -/** - * @brief Enable or disable counter reload function when alarm event occurs. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param reload Counter reload mode. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload); - -/** - * @brief Set hardware divider of the source clock to the timer group. - * By default, the source clock is APB clock running at 80 MHz. - * For more information, please check Chapter Reset and Clock in Chip Technical Reference Manual. - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param divider Timer clock divider value. The divider's range is from from 2 to 65536. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint32_t divider); - -/** - * @brief Set timer alarm value. - * - * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param alarm_value A 64-bit value to set the alarm value. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value); - -/** - * @brief Get timer alarm value. - * - * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param alarm_value Pointer of A 64-bit value to accept the alarm value. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *alarm_value); - -/** - * @brief Enable or disable generation of timer alarm events. - * - * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param alarm_en To enable or disable timer alarm function. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en); - -/** - * @brief Add ISR handle callback for the corresponding timer. - * - * @param group_num Timer group number - * @param timer_num Timer index of timer group - * @param isr_handler Interrupt handler function, it is a callback function. - * @param arg Parameter for handler function - * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) - * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. - * - * @note This ISR handler will be called from an ISR. - * This ISR handler do not need to handle interrupt status, and should be kept short. - * If you want to realize some specific applications or write the whole ISR, you can - * call timer_isr_register(...) to register ISR. - * - * The callback should return a bool value to determine whether need to do YIELD at - * the end of the ISR. - * - * If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set, - * the handler function must be declared with IRAM_ATTR attribute - * and can only call functions in IRAM or ROM. It cannot call other timer APIs. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_isr_callback_add(timer_group_t group_num, timer_idx_t timer_num, timer_isr_t isr_handler, void *arg, int intr_alloc_flags); - -/** - * @brief Remove ISR handle callback for the corresponding timer. - * - * @param group_num Timer group number - * @param timer_num Timer index of timer group - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_isr_callback_remove(timer_group_t group_num, timer_idx_t timer_num); - -/** - * @brief Register Timer interrupt handler, the handler is an ISR. - * The handler will be attached to the same CPU core that this function is running on. - * - * @param group_num Timer group number - * @param timer_num Timer index of timer group - * @param fn Interrupt handler function. - * @param arg Parameter for handler function - * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) - * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. - * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will - * be returned here. - * - * @note If use this function to register ISR, you need to write the whole ISR. - * In the interrupt handler, you need to call timer_spinlock_take(..) before - * your handling, and call timer_spinlock_give(...) after your handling. - * - * If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set, - * the handler function must be declared with IRAM_ATTR attribute - * and can only call functions in IRAM or ROM. It cannot call other timer APIs. - * Use direct register access to configure timers from inside the ISR in this case. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void *), void *arg, int intr_alloc_flags, timer_isr_handle_t *handle); - -/** @brief Initializes and configure the timer. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param config Pointer to timer initialization parameters. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config); - -/** @brief Deinitializes the timer. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num); - -/** @brief Get timer configure value. - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] - * @param config Pointer of struct to accept timer parameters. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config); - -/** @brief Enable timer group interrupt, by enable mask - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param intr_mask Timer interrupt enable mask. - * - TIMER_INTR_T0: t0 interrupt - * - TIMER_INTR_T1: t1 interrupt - * - TIMER_INTR_WDT: watchdog interrupt - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t intr_mask); - -/** @brief Disable timer group interrupt, by disable mask - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param intr_mask Timer interrupt disable mask. - * - TIMER_INTR_T0: t0 interrupt - * - TIMER_INTR_T1: t1 interrupt - * - TIMER_INTR_WDT: watchdog interrupt - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t intr_mask); - -/** @brief Enable timer interrupt - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num); - -/** @brief Disable timer interrupt - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num); - -/** @brief Clear timer interrupt status, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * - */ -void timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num); - -/** @brief Enable alarm interrupt, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * - */ -void timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num); - -/** @brief Get the current counter value, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * - * @return - * - Counter value - */ -uint64_t timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num); - -/** @brief Set the alarm threshold for the timer, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * @param alarm_val Alarm threshold. - * - */ -void timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val); - -/** @brief Enable/disable a counter, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index. - * @param counter_en Enable/disable. - * - */ -void timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en); - -/** @brief Get interrupt status, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * - * @return - * - Interrupt status - */ -uint32_t timer_group_get_intr_status_in_isr(timer_group_t group_num); -/** @brief Get auto reload enable status, just used in ISR - * - * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param timer_num Timer index - * - * @return - * - True Auto reload enabled - * - False Auto reload disabled - */ -bool timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num); - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/deprecated/driver/timer_types_legacy.h b/components/driver/deprecated/driver/timer_types_legacy.h deleted file mode 100644 index 6f3c9c44c6..0000000000 --- a/components/driver/deprecated/driver/timer_types_legacy.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "soc/soc_caps.h" -#include "soc/clk_tree_defs.h" -#include "hal/timer_types.h" -#include "esp_intr_alloc.h" -#include "esp_attr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Timer-Group ID - */ -typedef enum { - TIMER_GROUP_0 = 0, /*!< Hw timer group 0 */ -#if SOC_TIMER_GROUPS > 1 - TIMER_GROUP_1 = 1, /*!< Hw timer group 1 */ -#endif - TIMER_GROUP_MAX /*!< Maximum number of Hw timer groups */ -} timer_group_t; - -/** - * @brief Timer ID - */ -typedef enum { - TIMER_0 = 0, /*!< Select timer0 of GROUPx*/ -#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1 - TIMER_1 = 1, /*!< Select timer1 of GROUPx*/ -#endif - TIMER_MAX, -} timer_idx_t; - -/** - * @brief Interrupt types of the timer. - */ -typedef enum { - TIMER_INTR_T0 = 1 << 0, /*!< interrupt of timer 0 */ -#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1 - TIMER_INTR_T1 = 1 << 1, /*!< interrupt of timer 1 */ - TIMER_INTR_WDT = 1 << 2, /*!< interrupt of watchdog */ -#else - TIMER_INTR_WDT = 1 << 1, /*!< interrupt of watchdog */ -#endif - TIMER_INTR_NONE = 0 -} timer_intr_t; - -/** - * @brief Timer count direction - */ -typedef enum { - TIMER_COUNT_DOWN = GPTIMER_COUNT_DOWN, /*!< Descending Count from cnt.high|cnt.low*/ - TIMER_COUNT_UP = GPTIMER_COUNT_UP, /*!< Ascending Count from Zero*/ - TIMER_COUNT_MAX /*!< Maximum number of timer count directions */ -} timer_count_dir_t; - -/** - * @brief Timer start/stop command - */ -typedef enum { - TIMER_PAUSE, /*!< Pause timer counter*/ - TIMER_START, /*!< Start timer counter*/ -} timer_start_t; - -/** - * @brief Timer alarm command - */ -typedef enum { - TIMER_ALARM_DIS = 0, /*!< Disable timer alarm*/ - TIMER_ALARM_EN = 1, /*!< Enable timer alarm*/ - TIMER_ALARM_MAX -} timer_alarm_t; - -/** - * @brief Timer interrupt type - */ -typedef enum { - TIMER_INTR_LEVEL = 0, /*!< Interrupt mode: level mode*/ - TIMER_INTR_MAX -} timer_intr_mode_t; - -/** - * @brief Timer autoreload command - */ -typedef enum { - TIMER_AUTORELOAD_DIS = 0, /*!< Disable auto-reload: hardware will not load counter value after an alarm event*/ - TIMER_AUTORELOAD_EN = 1, /*!< Enable auto-reload: hardware will load counter value after an alarm event*/ - TIMER_AUTORELOAD_MAX, -} timer_autoreload_t; - -#if SOC_GPTIMER_SUPPORTED -/** - * @brief Timer group clock source - */ -typedef soc_periph_tg_clk_src_legacy_t timer_src_clk_t; -#else -/** - * @brief Default type - */ -typedef int timer_src_clk_t; -#endif - -/** - * @brief Interrupt handler callback function - * - * @return - * - True Do task yield at the end of ISR - * - False Not do task yield at the end of ISR - * - * @note If you called FreeRTOS functions in callback, you need to return true or false based on - * the return value of argument `pxHigherPriorityTaskWoken`. - * For example, `xQueueSendFromISR` is called in callback, if the return value `pxHigherPriorityTaskWoken` - * of any FreeRTOS calls is pdTRUE, return true; otherwise return false. - */ -typedef bool (*timer_isr_t)(void *); - -/** - * @brief Interrupt handle, used in order to free the isr after use. - */ -typedef intr_handle_t timer_isr_handle_t; - -/** - * @brief Timer configurations - */ -typedef struct { - timer_alarm_t alarm_en; /*!< Timer alarm enable */ - timer_start_t counter_en; /*!< Counter enable */ - timer_intr_mode_t intr_type; /*!< Interrupt mode */ - timer_count_dir_t counter_dir; /*!< Counter direction */ - timer_autoreload_t auto_reload; /*!< Timer auto-reload */ - timer_src_clk_t clk_src; /*!< Selects source clock. */ - uint32_t divider; /*!< Counter clock divider */ -} timer_config_t; - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/deprecated/timer_legacy.c b/components/driver/deprecated/timer_legacy.c deleted file mode 100644 index 48c8aeb725..0000000000 --- a/components/driver/deprecated/timer_legacy.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "esp_log.h" -#include "esp_err.h" -#include "esp_check.h" -#include "esp_intr_alloc.h" -#include "freertos/FreeRTOS.h" -#include "driver/timer_types_legacy.h" -#include "hal/timer_hal.h" -#include "hal/timer_ll.h" -#include "hal/check.h" -#include "soc/timer_periph.h" -#include "soc/soc_caps.h" -#include "esp_clk_tree.h" -#include "soc/timer_group_reg.h" -#include "esp_private/esp_clk_tree_common.h" -#include "esp_private/periph_ctrl.h" - -static const char *TIMER_TAG = "timer_group"; - -#define TIMER_GROUP_NUM_ERROR "TIMER GROUP NUM ERROR" -#define TIMER_NUM_ERROR "HW TIMER NUM ERROR" -#define TIMER_PARAM_ADDR_ERROR "HW TIMER PARAM ADDR ERROR" -#define TIMER_NEVER_INIT_ERROR "HW TIMER NEVER INIT ERROR" -#define TIMER_COUNT_DIR_ERROR "HW TIMER COUNTER DIR ERROR" -#define TIMER_AUTORELOAD_ERROR "HW TIMER AUTORELOAD ERROR" -#define TIMER_SCALE_ERROR "HW TIMER SCALE ERROR" -#define TIMER_ALARM_ERROR "HW TIMER ALARM ERROR" -#define DIVIDER_RANGE_ERROR "HW TIMER divider outside of [2, 65536] range error" - -#define TIMER_ENTER_CRITICAL(mux) portENTER_CRITICAL_SAFE(mux); -#define TIMER_EXIT_CRITICAL(mux) portEXIT_CRITICAL_SAFE(mux); - -#if SOC_PERIPH_CLK_CTRL_SHARED -#define GPTIMER_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() -#else -#define GPTIMER_CLOCK_SRC_ATOMIC() -#endif - -typedef struct { - timer_isr_t fn; /*!< isr function */ - void *args; /*!< isr function args */ - timer_isr_handle_t timer_isr_handle; /*!< interrupt handle */ - timer_group_t isr_timer_group; /*!< timer group of interrupt triggered */ -} timer_isr_func_t; - -typedef struct { - timer_hal_context_t hal; - timer_isr_func_t timer_isr_fun; - timer_src_clk_t clk_src; - gptimer_count_direction_t direction; - uint32_t divider; - uint64_t alarm_value; - bool alarm_en; - bool auto_reload_en; - bool counter_en; -} timer_obj_t; - -static timer_obj_t *p_timer_obj[TIMER_GROUP_MAX][TIMER_MAX] = {0}; -static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = { [0 ... TIMER_GROUP_MAX - 1] = portMUX_INITIALIZER_UNLOCKED, }; - -esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *timer_val) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_val != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - *timer_val = timer_hal_capture_and_get_counter_value(&p_timer_obj[group_num][timer_num]->hal); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double *time) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(time != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - uint64_t timer_val = timer_hal_capture_and_get_counter_value(&p_timer_obj[group_num][timer_num]->hal); - uint32_t div = p_timer_obj[group_num][timer_num]->divider; - // get clock source frequency - uint32_t counter_src_hz = 0; - ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)p_timer_obj[group_num][timer_num]->clk_src, - ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz), - TIMER_TAG, "get clock source frequency failed"); - *time = (double)timer_val * div / counter_src_hz; - return ESP_OK; -} - -esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_hal_set_counter_value(&(p_timer_obj[group_num][timer_num]->hal), load_val); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_counter(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, true); - p_timer_obj[group_num][timer_num]->counter_en = true; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_counter(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, false); - p_timer_obj[group_num][timer_num]->counter_en = false; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(counter_dir < TIMER_COUNT_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_COUNT_DIR_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_set_count_direction(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, counter_dir); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(reload < TIMER_AUTORELOAD_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_AUTORELOAD_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_auto_reload(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, reload); - p_timer_obj[group_num][timer_num]->auto_reload_en = reload; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint32_t divider) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(divider > 1 && divider < 65537, ESP_ERR_INVALID_ARG, TIMER_TAG, DIVIDER_RANGE_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_set_clock_prescale(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, divider); - p_timer_obj[group_num][timer_num]->divider = divider; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_value); - p_timer_obj[group_num][timer_num]->alarm_value = alarm_value; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *alarm_value) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(alarm_value != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - *alarm_value = p_timer_obj[group_num][timer_num]->alarm_value; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(alarm_en < TIMER_ALARM_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_ALARM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_alarm(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_en); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -static void IRAM_ATTR timer_isr_default(void *arg) -{ - bool is_awoken = false; - timer_obj_t *timer_obj = (timer_obj_t *)arg; - if (timer_obj == NULL || timer_obj->timer_isr_fun.fn == NULL) { - return; - } - uint32_t timer_id = timer_obj->hal.timer_id; - timer_hal_context_t *hal = &timer_obj->hal; - TIMER_ENTER_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]); - uint32_t intr_status = timer_ll_get_intr_status(hal->dev); - uint64_t old_alarm_value = timer_obj->alarm_value; - if (intr_status & TIMER_LL_EVENT_ALARM(timer_id)) { - // Clear interrupt status - timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_id)); - // call user registered callback - is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args); - // re-enable alarm if required - uint64_t new_alarm_value = timer_obj->alarm_value; - bool reenable_alarm = (new_alarm_value != old_alarm_value) || timer_obj->auto_reload_en; - timer_ll_enable_alarm(hal->dev, timer_id, reenable_alarm); - } - TIMER_EXIT_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]); - - if (is_awoken) { - portYIELD_FROM_ISR(); - } -} - -esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_intr(p_timer_obj[group_num][timer_num]->hal.dev, TIMER_LL_EVENT_ALARM(timer_num), true); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_intr(p_timer_obj[group_num][timer_num]->hal.dev, TIMER_LL_EVENT_ALARM(timer_num), false); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, - void (*fn)(void *), void *arg, int intr_alloc_flags, timer_isr_handle_t *handle) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(fn != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal; - return esp_intr_alloc_intrstatus(timer_group_periph_signals.groups[group_num].timer_irq_id[timer_num], - intr_alloc_flags, - (uint32_t)timer_ll_get_intr_status_reg(hal->dev), - TIMER_LL_EVENT_ALARM(timer_num), fn, arg, handle); -} - -esp_err_t timer_isr_callback_add(timer_group_t group_num, timer_idx_t timer_num, timer_isr_t isr_handler, void *args, int intr_alloc_flags) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - esp_err_t ret = ESP_OK; - - timer_disable_intr(group_num, timer_num); - p_timer_obj[group_num][timer_num]->timer_isr_fun.fn = isr_handler; - p_timer_obj[group_num][timer_num]->timer_isr_fun.args = args; - p_timer_obj[group_num][timer_num]->timer_isr_fun.isr_timer_group = group_num; - ret = timer_isr_register(group_num, timer_num, timer_isr_default, (void *)p_timer_obj[group_num][timer_num], - intr_alloc_flags, &(p_timer_obj[group_num][timer_num]->timer_isr_fun.timer_isr_handle)); - ESP_RETURN_ON_ERROR(ret, TIMER_TAG, "register interrupt service failed"); - timer_enable_intr(group_num, timer_num); - - return ret; -} - -esp_err_t timer_isr_callback_remove(timer_group_t group_num, timer_idx_t timer_num) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - - timer_disable_intr(group_num, timer_num); - p_timer_obj[group_num][timer_num]->timer_isr_fun.fn = NULL; - p_timer_obj[group_num][timer_num]->timer_isr_fun.args = NULL; - esp_intr_free(p_timer_obj[group_num][timer_num]->timer_isr_fun.timer_isr_handle); - - return ESP_OK; -} - -esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); - ESP_RETURN_ON_FALSE(config->divider > 1 && config->divider < 65537, ESP_ERR_INVALID_ARG, TIMER_TAG, DIVIDER_RANGE_ERROR); - ESP_RETURN_ON_FALSE(config->intr_type < TIMER_INTR_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, "only support Level Interrupt"); - if (p_timer_obj[group_num][timer_num] == NULL) { - p_timer_obj[group_num][timer_num] = (timer_obj_t *) heap_caps_calloc(1, sizeof(timer_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num], ESP_ERR_NO_MEM, TIMER_TAG, "no mem for timer object"); - } - timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal; - - PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[group_num].module, ref_count) { - if (ref_count == 0) { - timer_ll_enable_bus_clock(group_num, true); - timer_ll_reset_register(group_num); - } - } - - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_hal_init(hal, group_num, timer_num); - timer_hal_set_counter_value(hal, 0); - - timer_src_clk_t clk_src = TIMER_SRC_CLK_DEFAULT; - if (config->clk_src) { - clk_src = config->clk_src; - } - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); - GPTIMER_CLOCK_SRC_ATOMIC() { - // although `clk_src` is of `timer_src_clk_t` type, but it's binary compatible with `gptimer_clock_source_t`, - // as the underlying enum entries come from the same `soc_module_clk_t` - timer_ll_set_clock_source(group_num, timer_num, (gptimer_clock_source_t)clk_src); - timer_ll_enable_clock(group_num, timer_num, true); - } - timer_ll_set_clock_prescale(hal->dev, timer_num, config->divider); - timer_ll_set_count_direction(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, config->counter_dir); - timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false); - timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num)); - timer_ll_enable_alarm(hal->dev, timer_num, config->alarm_en); - timer_ll_enable_auto_reload(hal->dev, timer_num, config->auto_reload); - timer_ll_enable_counter(hal->dev, timer_num, config->counter_en); - p_timer_obj[group_num][timer_num]->clk_src = clk_src; - p_timer_obj[group_num][timer_num]->alarm_en = config->alarm_en; - p_timer_obj[group_num][timer_num]->auto_reload_en = config->auto_reload; - p_timer_obj[group_num][timer_num]->direction = config->counter_dir; - p_timer_obj[group_num][timer_num]->counter_en = config->counter_en; - p_timer_obj[group_num][timer_num]->divider = config->divider; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - - return ESP_OK; -} - -esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal; - - // disable the source clock - GPTIMER_CLOCK_SRC_ATOMIC() { - timer_ll_enable_clock(group_num, hal->timer_id, false); - } - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)p_timer_obj[group_num][timer_num]->clk_src, false)); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false); - timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num)); - timer_hal_deinit(hal); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - - PERIPH_RCC_RELEASE_ATOMIC(timer_group_periph_signals.groups[group_num].module, ref_count) { - if (ref_count == 0) { - timer_ll_enable_bus_clock(group_num, false); - } - } - - free(p_timer_obj[group_num][timer_num]); - p_timer_obj[group_num][timer_num] = NULL; - - return ESP_OK; -} - -esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); - ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - config->alarm_en = p_timer_obj[group_num][timer_num]->alarm_en; - config->auto_reload = p_timer_obj[group_num][timer_num]->auto_reload_en; - config->counter_dir = p_timer_obj[group_num][timer_num]->direction; - config->counter_en = p_timer_obj[group_num][timer_num]->counter_en; - config->divider = p_timer_obj[group_num][timer_num]->divider; - config->intr_type = TIMER_INTR_LEVEL; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t en_mask) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_intr(p_timer_obj[group_num][0]->hal.dev, en_mask, true); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t disable_mask) -{ - ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(p_timer_obj[group_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - timer_ll_enable_intr(p_timer_obj[group_num][0]->hal.dev, disable_mask, false); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -uint32_t IRAM_ATTR timer_group_get_intr_status_in_isr(timer_group_t group_num) -{ - uint32_t intr_status = 0; - if (p_timer_obj[group_num][TIMER_0] != NULL) { - intr_status = timer_ll_get_intr_status(TIMER_LL_GET_HW(group_num)) & TIMER_LL_EVENT_ALARM(0); - } -#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1 - else if (p_timer_obj[group_num][TIMER_1] != NULL) { - intr_status = timer_ll_get_intr_status(TIMER_LL_GET_HW(group_num)) & TIMER_LL_EVENT_ALARM(1); - } -#endif - return intr_status; -} - -void IRAM_ATTR timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num) -{ - timer_ll_clear_intr_status(p_timer_obj[group_num][timer_num]->hal.dev, TIMER_LL_EVENT_ALARM(timer_num)); -} - -void IRAM_ATTR timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num) -{ - timer_ll_enable_alarm(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, true); -} - -uint64_t IRAM_ATTR timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num) -{ - timer_ll_trigger_soft_capture(p_timer_obj[group_num][timer_num]->hal.dev, timer_num); - uint64_t val = timer_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num); - return val; -} - -void IRAM_ATTR timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val) -{ - timer_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_val); - p_timer_obj[group_num][timer_num]->alarm_value = alarm_val; -} - -void IRAM_ATTR timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en) -{ - timer_ll_enable_counter(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, counter_en); - p_timer_obj[group_num][timer_num]->counter_en = counter_en; -} - -bool IRAM_ATTR timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num) -{ - return p_timer_obj[group_num][timer_num]->auto_reload_en; -} - -#if !CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK -/** - * @brief This function will be called during start up, to check that this legacy timer group driver is not running along with the gptimer driver - */ -__attribute__((constructor)) -static void check_legacy_timer_driver_conflict(void) -{ - // This function was declared as weak here. gptimer driver has one implementation. - // So if gptimer driver is not linked in, then `gptimer_new_timer()` should be NULL at runtime. - extern __attribute__((weak)) esp_err_t gptimer_new_timer(const void *config, void **ret_timer); - if ((void *)gptimer_new_timer != NULL) { - ESP_EARLY_LOGE(TIMER_TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver"); - abort(); - } - ESP_EARLY_LOGW(TIMER_TAG, "legacy driver is deprecated, please migrate to `driver/gptimer.h`"); -} -#endif //CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 9d87486d62..97802baa2f 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -66,12 +66,6 @@ components/driver/test_apps/legacy_sigma_delta_driver: depends_components: - esp_driver_gpio -components/driver/test_apps/legacy_timer_driver: - disable: - - if: SOC_GPTIMER_SUPPORTED != 1 - depends_filepatterns: - - components/driver/deprecated/**/*timer* - components/driver/test_apps/legacy_twai: disable: - if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_SUPPORT_FD == 1 diff --git a/components/driver/test_apps/legacy_timer_driver/CMakeLists.txt b/components/driver/test_apps/legacy_timer_driver/CMakeLists.txt deleted file mode 100644 index 9dac72a6c8..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# This is the project CMakeLists.txt file for the test subproject -cmake_minimum_required(VERSION 3.16) - -# "Trim" the build. Include the minimal set of components, main, and anything it depends on. -set(COMPONENTS main) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(legacy_timer_driver_test) diff --git a/components/driver/test_apps/legacy_timer_driver/README.md b/components/driver/test_apps/legacy_timer_driver/README.md deleted file mode 100644 index 44f3780f1d..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_timer_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_timer_driver/main/CMakeLists.txt deleted file mode 100644 index c0633e16ff..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/main/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(srcs "test_app_main.c" - "test_legacy_timer.c") - -# In order for the cases defined by `TEST_CASE` to be linked into the final elf, -# the component can be registered as WHOLE_ARCHIVE -idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity driver - WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/legacy_timer_driver/main/test_app_main.c b/components/driver/test_apps/legacy_timer_driver/main/test_app_main.c deleted file mode 100644 index 183a88ae3c..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/main/test_app_main.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "unity.h" -#include "unity_test_runner.h" -#include "esp_heap_caps.h" - -#define TEST_MEMORY_LEAK_THRESHOLD (-600) - -static size_t before_free_8bit; -static size_t before_free_32bit; - -static void check_leak(size_t before_free, size_t after_free, const char *type) -{ - ssize_t delta = after_free - before_free; - printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); - TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); -} - -void setUp(void) -{ - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); -} - -void tearDown(void) -{ - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - check_leak(before_free_8bit, after_free_8bit, "8BIT"); - check_leak(before_free_32bit, after_free_32bit, "32BIT"); -} - -void app_main(void) -{ - unity_run_menu(); -} diff --git a/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c b/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c deleted file mode 100644 index 77c1eb5080..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "esp_system.h" -#include "unity.h" -#include "driver/timer.h" -#include "esp_private/esp_clk.h" -#include "esp_clk_tree.h" -#include "soc/soc_caps.h" -#include "esp_rom_sys.h" -#include "soc/soc.h" - -#define TEST_TIMER_RESOLUTION_HZ 1000000 // 1MHz resolution -#define TIMER_DELTA 0.001 - -static bool alarm_flag; -static QueueHandle_t timer_queue; - -typedef struct { - timer_group_t timer_group; - timer_idx_t timer_idx; -} timer_info_t; - -typedef struct { - timer_autoreload_t type; // the type of timer's event - timer_group_t timer_group; - timer_idx_t timer_idx; - uint64_t timer_counter_value; -} timer_event_t; - -#define TIMER_INFO_INIT(TG, TID) {.timer_group = (TG), .timer_idx = (TID),} - -static timer_info_t timer_info[] = { -#if SOC_TIMER_GROUP_TOTAL_TIMERS >= 4 - TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0), - TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_1), - TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0), - TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_1), -#elif SOC_TIMER_GROUP_TOTAL_TIMERS >= 2 - TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0), - TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0), -#else - TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0), -#endif -}; - -static intr_handle_t timer_isr_handles[SOC_TIMER_GROUP_TOTAL_TIMERS]; - -#define GET_TIMER_INFO(TG, TID) (&timer_info[(TG)*SOC_TIMER_GROUP_TIMERS_PER_GROUP+(TID)]) - -// timer group interruption handle callback -static bool test_timer_group_isr_cb(void *arg) -{ - bool is_awoken = false; - timer_info_t *info = (timer_info_t *) arg; - const timer_group_t timer_group = info->timer_group; - const timer_idx_t timer_idx = info->timer_idx; - uint64_t timer_val; - uint64_t alarm_value; - timer_event_t evt; - alarm_flag = true; - if (timer_group_get_auto_reload_in_isr(timer_group, timer_idx)) { // For autoreload mode, the counter value has been cleared - timer_group_clr_intr_status_in_isr(timer_group, timer_idx); - esp_rom_printf("This is TG%d timer[%d] reload-timer alarm!\n", timer_group, timer_idx); - timer_get_counter_value(timer_group, timer_idx, &timer_val); - evt.type = TIMER_AUTORELOAD_EN; - } else { - timer_group_clr_intr_status_in_isr(timer_group, timer_idx); - esp_rom_printf("This is TG%d timer[%d] count-up-timer alarm!\n", timer_group, timer_idx); - timer_get_counter_value(timer_group, timer_idx, &timer_val); - timer_get_alarm_value(timer_group, timer_idx, &alarm_value); - timer_set_counter_value(timer_group, timer_idx, 0); - evt.type = TIMER_AUTORELOAD_DIS; - } - evt.timer_group = timer_group; - evt.timer_idx = timer_idx; - evt.timer_counter_value = timer_val; - if (timer_queue != NULL) { - BaseType_t awoken = pdFALSE; - BaseType_t ret = xQueueSendFromISR(timer_queue, &evt, &awoken); - TEST_ASSERT_EQUAL(pdTRUE, ret); - if (awoken) { - is_awoken = true; - } - } - return is_awoken; -} - -// timer group interruption handle -static void test_timer_group_isr(void *arg) -{ - if (test_timer_group_isr_cb(arg)) { - portYIELD_FROM_ISR(); - } -} - -// initialize all timer -static void all_timer_init(timer_config_t *config, bool expect_init) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ASSERT_EQUAL((expect_init ? ESP_OK : ESP_ERR_INVALID_ARG), timer_init(tg_idx, timer_idx, config)); - } - } - if (timer_queue == NULL) { - timer_queue = xQueueCreate(10, sizeof(timer_event_t)); - } -} - -// deinitialize all timer -static void all_timer_deinit(void) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_deinit(tg_idx, timer_idx)); - } - } - if (timer_queue != NULL) { - vQueueDelete(timer_queue); - timer_queue = NULL; - } -} - -// start all of timer -static void all_timer_start(void) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_start(tg_idx, timer_idx)); - } - } -} - -static void all_timer_set_counter_value(uint64_t set_cnt_val) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_set_counter_value(tg_idx, timer_idx, set_cnt_val)); - } - } -} - -static void all_timer_pause(void) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_pause(tg_idx, timer_idx)); - } - } -} - -static void all_timer_get_counter_value(uint64_t set_cnt_val, bool expect_equal_set_val, - uint64_t *actual_cnt_val) -{ - uint64_t current_cnt_val; - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_get_counter_value(tg_idx, timer_idx, ¤t_cnt_val)); - if (expect_equal_set_val) { - TEST_ASSERT_EQUAL(set_cnt_val, current_cnt_val); - } else { - TEST_ASSERT_NOT_EQUAL(set_cnt_val, current_cnt_val); - if (actual_cnt_val != NULL) { - actual_cnt_val[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx] = current_cnt_val; - } - } - } - } -} - -static void all_timer_get_counter_time_sec(int expect_time) -{ - double time; - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_get_counter_time_sec(tg_idx, timer_idx, &time)); - TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, expect_time, time); - } - } -} - -static void all_timer_set_counter_mode(timer_count_dir_t counter_dir) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_set_counter_mode(tg_idx, timer_idx, counter_dir)); - } - } -} - -static void all_timer_set_divider(uint32_t divider) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_set_divider(tg_idx, timer_idx, divider)); - } - } -} - -static void all_timer_set_alarm_value(uint64_t alarm_cnt_val) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_set_alarm_value(tg_idx, timer_idx, alarm_cnt_val)); - } - } -} - -static void all_timer_get_alarm_value(uint64_t *alarm_vals) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_get_alarm_value(tg_idx, timer_idx, &alarm_vals[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx])); - } - } -} - -static void all_timer_isr_reg(void) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_isr_register(tg_idx, timer_idx, test_timer_group_isr, - GET_TIMER_INFO(tg_idx, timer_idx), ESP_INTR_FLAG_LOWMED, &timer_isr_handles[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx])); - } - } -} - -static void all_timer_isr_unreg(void) -{ - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(esp_intr_free(timer_isr_handles[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx])); - } - } -} - -// enable interrupt and start timer -static void timer_intr_enable_and_start(int timer_group, int timer_idx, double alarm_time) -{ - TEST_ESP_OK(timer_pause(timer_group, timer_idx)); - TEST_ESP_OK(timer_set_counter_value(timer_group, timer_idx, 0x0)); - TEST_ESP_OK(timer_set_alarm_value(timer_group, timer_idx, alarm_time * TEST_TIMER_RESOLUTION_HZ)); - TEST_ESP_OK(timer_set_alarm(timer_group, timer_idx, TIMER_ALARM_EN)); - TEST_ESP_OK(timer_enable_intr(timer_group, timer_idx)); - TEST_ESP_OK(timer_start(timer_group, timer_idx)); -} - -static void timer_isr_check(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t autoreload, uint64_t alarm_cnt_val) -{ - timer_event_t evt; - TEST_ASSERT_EQUAL(pdTRUE, xQueueReceive(timer_queue, &evt, 3000 / portTICK_PERIOD_MS)); - TEST_ASSERT_EQUAL(autoreload, evt.type); - TEST_ASSERT_EQUAL(group_num, evt.timer_group); - TEST_ASSERT_EQUAL(timer_num, evt.timer_idx); - TEST_ASSERT_EQUAL((uint32_t)(alarm_cnt_val >> 32), (uint32_t)(evt.timer_counter_value >> 32)); - TEST_ASSERT_UINT32_WITHIN(1000, (uint32_t)(alarm_cnt_val), (uint32_t)(evt.timer_counter_value)); -} - -static void timer_intr_enable_disable_test(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_cnt_val) -{ - alarm_flag = false; - TEST_ESP_OK(timer_set_counter_value(group_num, timer_num, 0)); - TEST_ESP_OK(timer_set_alarm(group_num, timer_num, TIMER_ALARM_EN)); - TEST_ESP_OK(timer_enable_intr(group_num, timer_num)); - TEST_ESP_OK(timer_start(group_num, timer_num)); - timer_isr_check(group_num, timer_num, TIMER_AUTORELOAD_DIS, alarm_cnt_val); - TEST_ASSERT_EQUAL(true, alarm_flag); - - // disable interrupt of tg0_timer0 - alarm_flag = false; - TEST_ESP_OK(timer_pause(group_num, timer_num)); - TEST_ESP_OK(timer_set_counter_value(group_num, timer_num, 0)); - TEST_ESP_OK(timer_disable_intr(group_num, timer_num)); - TEST_ESP_OK(timer_start(group_num, timer_num)); - vTaskDelay(2000 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(false, alarm_flag); -} - -TEST_CASE("Timer_init", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - // Test init 1:config parameter - // empty parameter - timer_config_t config0 = { }; - all_timer_init(&config0, false); - - // only one parameter - timer_config_t config1 = { - .auto_reload = TIMER_AUTORELOAD_EN - }; - all_timer_init(&config1, false); - - // lack one parameter - timer_config_t config2 = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - all_timer_init(&config2, true); - - config2.counter_en = TIMER_PAUSE; - all_timer_init(&config2, true); - - // Test init 2: init - uint64_t set_timer_val = 0x0; - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - - // judge get config parameters - timer_config_t get_config; - TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config)); - TEST_ESP_OK(timer_get_config(TIMER_GROUP_0, TIMER_0, &get_config)); - TEST_ASSERT_EQUAL(config.alarm_en, get_config.alarm_en); - TEST_ASSERT_EQUAL(config.auto_reload, get_config.auto_reload); - TEST_ASSERT_EQUAL(config.counter_dir, get_config.counter_dir); - TEST_ASSERT_EQUAL(config.counter_en, get_config.counter_en); - TEST_ASSERT_EQUAL(config.intr_type, get_config.intr_type); - TEST_ASSERT_EQUAL(config.divider, get_config.divider); - - all_timer_init(&config, true); - all_timer_pause(); - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - all_timer_get_counter_value(set_timer_val, false, NULL); - - // Test init 3: wrong parameter - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(-1, TIMER_0, &config)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_0, 2, &config)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_0, -1, &config)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(2, TIMER_0, &config)); - all_timer_deinit(); -} - -/** - * read count case: - * 1. start timer compare value - * 2. pause timer compare value - * 3. delay some time */ -TEST_CASE("Timer_read_counter_value", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - uint64_t set_timer_val = 0x0; - - all_timer_init(&config, true); - - // Test read value 1: start timer get counter value - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - all_timer_get_counter_value(set_timer_val, false, NULL); - - // Test read value 2: pause timer get counter value - all_timer_pause(); - set_timer_val = 0x30405000ULL; - all_timer_set_counter_value(set_timer_val); - all_timer_get_counter_value(set_timer_val, true, NULL); - - // Test read value 3:delay 1s get counter value - set_timer_val = 0x0; - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); - all_timer_get_counter_time_sec(1); - all_timer_deinit(); -} - -/** - * start timer case: - * 1. normal start - * 2. error start parameter - * */ -TEST_CASE("Timer_start", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - uint64_t set_timer_val = 0x0; - all_timer_init(&config, true); - - //Test start 1: normal start - all_timer_start(); - all_timer_set_counter_value(set_timer_val); - all_timer_get_counter_value(set_timer_val, false, NULL); - - //Test start 2:wrong parameter - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(2, TIMER_0)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(-1, TIMER_0)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_0, 2)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_0, -1)); - all_timer_deinit(); -} - -/** - * pause timer case: - * 1. normal pause, read value - * 2. error pause error - */ -TEST_CASE("Timer_pause", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - uint64_t set_timer_val = 0x0; - all_timer_init(&config, true); - - //Test pause 1: right parameter - all_timer_pause(); - all_timer_set_counter_value(set_timer_val); - all_timer_get_counter_value(set_timer_val, true, NULL); - - //Test pause 2: wrong parameter - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(-1, TIMER_0)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_0, -1)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(2, TIMER_0)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_0, 2)); - all_timer_deinit(); -} - -// positive mode and negative mode -TEST_CASE("Timer_counter_direction", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - uint64_t set_timer_val = 0x0; - all_timer_init(&config, true); - all_timer_pause(); - - // Test counter mode 1: TIMER_COUNT_UP - all_timer_set_counter_mode(TIMER_COUNT_UP); - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); - all_timer_get_counter_time_sec(1); - - // Test counter mode 2: TIMER_COUNT_DOWN - all_timer_pause(); - set_timer_val = TEST_TIMER_RESOLUTION_HZ * 3; // 3s clock counter value - all_timer_set_counter_mode(TIMER_COUNT_DOWN); - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); - all_timer_get_counter_time_sec(2); - - // Test counter mode 3 : wrong parameter - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, -1)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, 2)); - all_timer_deinit(); -} - -TEST_CASE("Timer_divider", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .intr_type = TIMER_INTR_LEVEL - }; - uint64_t set_timer_val = 0; - uint64_t time_val[TIMER_GROUP_MAX * TIMER_MAX]; - uint64_t comp_time_val[TIMER_GROUP_MAX * TIMER_MAX]; - all_timer_init(&config, true); - - all_timer_pause(); - all_timer_set_counter_value(set_timer_val); - - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); - all_timer_get_counter_value(set_timer_val, false, time_val); - - all_timer_pause(); - all_timer_set_divider(config.divider / 2); // half of original divider - all_timer_set_counter_value(set_timer_val); - - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time - all_timer_get_counter_value(set_timer_val, false, comp_time_val); - for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) { - TEST_ASSERT_INT_WITHIN(2000, 1000000, time_val[i]); - TEST_ASSERT_INT_WITHIN(2000, 2000000, comp_time_val[i]); - } - - all_timer_pause(); - all_timer_set_divider(256); - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time - all_timer_get_counter_value(set_timer_val, false, comp_time_val); - for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) { - TEST_ASSERT_INT_WITHIN(100, clk_src_hz / 256, comp_time_val[i]); - } - - all_timer_pause(); - all_timer_set_divider(2); - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); - all_timer_get_counter_value(set_timer_val, false, comp_time_val); - for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) { - TEST_ASSERT_INT_WITHIN(5000, clk_src_hz / 2, comp_time_val[i]); - } - - all_timer_pause(); - all_timer_set_divider(65536); - all_timer_set_counter_value(set_timer_val); - all_timer_start(); - vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time - all_timer_get_counter_value(set_timer_val, false, comp_time_val); - for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) { - TEST_ASSERT_INT_WITHIN(10, clk_src_hz / 65536, comp_time_val[i]); - } - - all_timer_pause(); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 1)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 65537)); - all_timer_deinit(); -} - -/** - * enable alarm case: - * 1. enable alarm ,set alarm value and get value - * 2. disable alarm ,set alarm value and get value - */ -TEST_CASE("Timer_enable_alarm", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config_test = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL - }; - all_timer_init(&config_test, true); - all_timer_isr_reg(); - - // enable alarm of tg0_timer1 - alarm_flag = false; - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN)); - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.2); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ); - TEST_ASSERT_EQUAL(true, alarm_flag); - - // disable alarm of tg0_timer1 - alarm_flag = false; - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.2); - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_DIS)); - vTaskDelay(2000 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(false, alarm_flag); - -#if SOC_TIMER_GROUPS > 1 - // enable alarm of tg1_timer0 - alarm_flag = false; - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN)); - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.2); - timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ); - TEST_ASSERT_EQUAL(true, alarm_flag); - - // disable alarm of tg1_timer0 - alarm_flag = false; - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.2); - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_DIS)); - vTaskDelay(2000 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(false, alarm_flag); -#endif - all_timer_isr_unreg(); - all_timer_deinit(); -} - -/** - * alarm value case: - * 1. set alarm value and get value - * 2. interrupt test time - */ -TEST_CASE("Timer_set_alarm_value", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - uint64_t alarm_val[SOC_TIMER_GROUP_TOTAL_TIMERS]; - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL - }; - all_timer_init(&config, true); - all_timer_isr_reg(); - - // set and get alarm value - all_timer_set_alarm_value(3 * TEST_TIMER_RESOLUTION_HZ); - all_timer_get_alarm_value(alarm_val); - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - TEST_ASSERT_EQUAL_UINT32(3 * TEST_TIMER_RESOLUTION_HZ, (uint32_t)alarm_val[i]); - } - - // set interrupt read alarm value - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 2.4); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 2.4 * TEST_TIMER_RESOLUTION_HZ); -#if SOC_TIMER_GROUPS > 1 - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4); - timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.4 * TEST_TIMER_RESOLUTION_HZ); -#endif - all_timer_isr_unreg(); - all_timer_deinit(); -} - -/** - * auto reload case: - * 1. no reload - * 2. auto reload - */ -TEST_CASE("Timer_auto_reload", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL - }; - all_timer_init(&config, true); - all_timer_isr_reg(); - - // test disable auto_reload - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.14); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TEST_TIMER_RESOLUTION_HZ); -#if SOC_TIMER_GROUPS > 1 - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.14); - timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TEST_TIMER_RESOLUTION_HZ); -#endif - - //test enable auto_reload - TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN)); - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.4); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN, 0); -#if SOC_TIMER_GROUPS > 1 - TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN)); - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4); - timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN, 0); -#endif - all_timer_isr_unreg(); - all_timer_deinit(); -} - -/** - * timer_enable_intr case: - * 1. enable timer_intr - * 2. disable timer_intr - */ -TEST_CASE("Timer_enable_timer_interrupt", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .counter_dir = TIMER_COUNT_UP, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL - }; - - all_timer_init(&config, true); - all_timer_pause(); - all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ); - all_timer_set_counter_value(0); - all_timer_isr_reg(); - timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ); -#if SOC_TIMER_GROUPS > 1 - timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ); -#endif - - // enable interrupt of tg0_timer0 again - alarm_flag = false; - TEST_ESP_OK(timer_pause(TIMER_GROUP_0, TIMER_0)); - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0)); - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN)); - TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ); - TEST_ASSERT_EQUAL(true, alarm_flag); - all_timer_isr_unreg(); - all_timer_deinit(); -} - -/** - * enable timer group case: - * 1. enable timer group - * 2. disable timer group - */ -TEST_CASE("Timer_enable_timer_group_interrupt", "[hw_timer][ignore]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - intr_handle_t isr_handle = NULL; - alarm_flag = false; - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL - }; - uint64_t set_timer_val = 0x0; - all_timer_init(&config, true); - all_timer_pause(); - all_timer_set_counter_value(set_timer_val); - all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ); - - // enable interrupt of tg0_timer0 - TEST_ESP_OK(timer_group_intr_enable(TIMER_GROUP_0, TIMER_INTR_T0)); - TEST_ESP_OK(timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr, - GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, &isr_handle)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ); - TEST_ASSERT_EQUAL(true, alarm_flag); - - // disable interrupt of tg0_timer0 - alarm_flag = false; - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val)); - TEST_ESP_OK(timer_group_intr_disable(TIMER_GROUP_0, TIMER_INTR_T0)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); - vTaskDelay(2000 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(false, alarm_flag); - esp_intr_free(isr_handle); -} - -/** - * isr_register case: - * Cycle register 15 times, compare the heap size to ensure no memory leaks - */ -TEST_CASE("Timer_interrupt_register", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL - }; - - for (int i = 0; i < 15; i++) { - all_timer_init(&config, true); - timer_isr_handle_t timer_isr_handle[TIMER_GROUP_MAX * TIMER_MAX]; - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(timer_isr_register(tg_idx, timer_idx, test_timer_group_isr, - GET_TIMER_INFO(tg_idx, timer_idx), ESP_INTR_FLAG_LOWMED, &timer_isr_handle[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx])); - } - } - - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN)); - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.54); -#if SOC_TIMER_GROUPS > 1 - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN)); - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.34); -#endif - - TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN)); - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN)); - timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.4); -#if SOC_TIMER_GROUPS > 1 - TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN)); - TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN)); - timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.6); -#endif - vTaskDelay(1000 / portTICK_PERIOD_MS); - - // ISR handle function should be free before next ISR register. - for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) { - for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) { - TEST_ESP_OK(esp_intr_free(timer_isr_handle[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx])); - } - } - all_timer_deinit(); - } -} - -#if SOC_TIMER_GROUP_SUPPORT_XTAL -TEST_CASE("Timer_xtal_clock_source", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - // configure clock source: XTAL - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_XTAL, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL, - }; - all_timer_init(&config, true); - all_timer_pause(); - all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ); - all_timer_set_counter_value(0); - all_timer_isr_reg(); - - timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ); -#if SOC_TIMER_GROUPS > 1 - timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ); -#endif - - all_timer_isr_unreg(); - all_timer_deinit(); -} -#endif - -/** - * Timer ISR callback test - */ -TEST_CASE("Timer_ISR_callback", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - alarm_flag = false; - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_DIS, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL, - }; - uint64_t alarm_cnt_val = 1.2 * TEST_TIMER_RESOLUTION_HZ; - uint64_t set_timer_val = 0x0; - all_timer_init(&config, true); - all_timer_pause(); - all_timer_set_alarm_value(alarm_cnt_val); - all_timer_set_counter_value(set_timer_val); - - // add isr callback for tg0_timer0 - TEST_ESP_OK(timer_isr_callback_add(TIMER_GROUP_0, TIMER_0, test_timer_group_isr_cb, - GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED)); - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); - timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, alarm_cnt_val); - TEST_ASSERT_EQUAL(true, alarm_flag); - - // remove isr callback for tg0_timer0 - TEST_ESP_OK(timer_pause(TIMER_GROUP_0, TIMER_0)); - TEST_ESP_OK(timer_isr_callback_remove(TIMER_GROUP_0, TIMER_0)); - alarm_flag = false; - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); - vTaskDelay(2000 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(false, alarm_flag); - -#if SOC_TIMER_GROUPS > 1 - // add isr callback for tg1_timer0 - TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0)); - TEST_ESP_OK(timer_isr_callback_add(TIMER_GROUP_1, TIMER_0, test_timer_group_isr_cb, - GET_TIMER_INFO(TIMER_GROUP_1, TIMER_0), ESP_INTR_FLAG_LOWMED)); - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_1, TIMER_0, set_timer_val)); - TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0)); - timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, alarm_cnt_val); - TEST_ASSERT_EQUAL(true, alarm_flag); - - // remove isr callback for tg1_timer0 - TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0)); - TEST_ESP_OK(timer_isr_callback_remove(TIMER_GROUP_1, TIMER_0)); - alarm_flag = false; - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_1, TIMER_0, set_timer_val)); - TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0)); - vTaskDelay(2000 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(false, alarm_flag); -#endif - all_timer_deinit(); -} - -/** - * Timer memory test - */ -TEST_CASE("Timer_init_deinit_stress_test", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = TIMER_AUTORELOAD_EN, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .intr_type = TIMER_INTR_LEVEL, - }; - for (uint32_t i = 0; i < 100; i++) { - all_timer_init(&config, true); - all_timer_deinit(); - } -} - -// The following test cases are used to check if the timer_group fix works. -// Some applications use a software reset, at the reset time, timer_group happens to generate an interrupt. -// but software reset does not clear interrupt status, this is not safe for application when enable the interrupt of timer_group. -// This case will check under this fix, whether the interrupt status is cleared after timer_group initialization. -static void timer_group_test_init(void) -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - static const uint32_t time_ms = 100; // Alarm value 100ms. - static const uint32_t ste_val = time_ms * TEST_TIMER_RESOLUTION_HZ / 1000; - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .alarm_en = TIMER_ALARM_EN, - .intr_type = TIMER_INTR_LEVEL, - .auto_reload = TIMER_AUTORELOAD_EN, - }; - TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config)); - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL)); - TEST_ESP_OK(timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, ste_val)); - //Now the timer is ready. - //We only need to check the interrupt status and don't have to register a interrupt routine. -} - -// -// Timer check reinitialization sequence -// -TEST_CASE("Timer_check_reinitialization_sequence", "[hw_timer]") -{ - uint32_t clk_src_hz = 0; - TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)TIMER_SRC_CLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); - // 1. step - install driver - timer_group_test_init(); - // 2 - register interrupt and start timer - TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); - // Do some work - vTaskDelay(80 / portTICK_PERIOD_MS); - // 3 - deinit timer driver - TEST_ESP_OK(timer_deinit(TIMER_GROUP_0, TIMER_0)); - timer_config_t config = { - .clk_src = TIMER_SRC_CLK_DEFAULT, - .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_START, - .alarm_en = TIMER_ALARM_EN, - .intr_type = TIMER_INTR_LEVEL, - .auto_reload = TIMER_AUTORELOAD_EN, - }; - // 4 - reinstall driver - TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config)); - // 5 - enable interrupt - TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); - vTaskDelay(30 / portTICK_PERIOD_MS); - // The pending timer interrupt should not be triggered - TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0); -} diff --git a/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py b/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py deleted file mode 100644 index 503d591c83..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 -import pytest -from pytest_embedded import Dut -from pytest_embedded_idf.utils import idf_parametrize - - -@pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - 'release', - ], - indirect=True, -) -@idf_parametrize('target', ['supported_targets'], indirect=['target']) -def test_legacy_timer_driver(dut: Dut) -> None: - dut.run_all_single_board_cases(timeout=120) diff --git a/components/driver/test_apps/legacy_timer_driver/sdkconfig.ci.release b/components/driver/test_apps/legacy_timer_driver/sdkconfig.ci.release deleted file mode 100644 index 91d93f163e..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/sdkconfig.ci.release +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_PM_ENABLE=y -CONFIG_FREERTOS_USE_TICKLESS_IDLE=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/driver/test_apps/legacy_timer_driver/sdkconfig.defaults b/components/driver/test_apps/legacy_timer_driver/sdkconfig.defaults deleted file mode 100644 index 889dd35776..0000000000 --- a/components/driver/test_apps/legacy_timer_driver/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT_EN=n -CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN=y diff --git a/components/esp_driver_gptimer/include/driver/gptimer.h b/components/esp_driver_gptimer/include/driver/gptimer.h index 18be980abb..fecacf8438 100644 --- a/components/esp_driver_gptimer/include/driver/gptimer.h +++ b/components/esp_driver_gptimer/include/driver/gptimer.h @@ -30,7 +30,6 @@ typedef struct { uint32_t intr_shared: 1; /*!< Set true, the timer interrupt number can be shared with other peripherals */ uint32_t allow_pd: 1; /*!< If set, driver allows the power domain to be powered off when system enters sleep mode. This can save power, but at the expense of more RAM being consumed to save register context. */ - uint32_t backup_before_sleep: 1; /*!< @deprecated, same meaning as allow_pd */ } flags; /*!< GPTimer config flags*/ } gptimer_config_t; diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index 88d6cea08d..3856a98f95 100644 --- a/components/esp_driver_gptimer/src/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -137,7 +137,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re TAG, "invalid interrupt priority:%d", config->intr_priority); } - bool allow_pd = (config->flags.allow_pd == 1) || (config->flags.backup_before_sleep == 1); + bool allow_pd = config->flags.allow_pd == 1; #if !SOC_TIMER_SUPPORT_SLEEP_RETENTION ESP_RETURN_ON_FALSE(allow_pd == false, ESP_ERR_NOT_SUPPORTED, TAG, "not able to power down in light sleep"); #endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION diff --git a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c index f9a9f5bc7a..4ca9b36742 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c +++ b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c @@ -153,7 +153,7 @@ static void test_gptimer_etm_sleep_retention(bool back_up_before_sleep) .clk_src = GPTIMER_CLK_SRC_DEFAULT, .direction = GPTIMER_COUNT_UP, .resolution_hz = 1 * 1000 * 1000, // 1MHz, 1 tick = 1us - .flags.backup_before_sleep = back_up_before_sleep, + .flags.allow_pd = back_up_before_sleep, }; TEST_ESP_OK(gptimer_new_timer(&timer_config, &gptimer)); diff --git a/docs/en/migration-guides/release-5.x/5.0/peripherals.rst b/docs/en/migration-guides/release-5.x/5.0/peripherals.rst index c979ba9e26..60b9cc19e0 100644 --- a/docs/en/migration-guides/release-5.x/5.0/peripherals.rst +++ b/docs/en/migration-guides/release-5.x/5.0/peripherals.rst @@ -119,12 +119,18 @@ GPIO - Channel configuration was done by channel allocation, in :cpp:func:`sdm_new_channel`. In the new driver, only the ``density`` can be changed at runtime, by :cpp:func:`sdm_channel_set_pulse_density`. Other parameters like ``gpio number`` and ``prescale`` are only allowed to set during channel allocation. - Before further channel operations, users should **enable** the channel in advance, by calling :cpp:func:`sdm_channel_enable`. This function helps to manage some system level services, like **Power Management**. -Timer Group Driver ------------------- + .. _deprecate_gptimer_legacy_driver: + +.. only:: not SOC_SDM_SUPPORTED + + .. _deprecate_gptimer_legacy_driver: + +Legacy Timer Group Driver is Deprecated +--------------------------------------- Timer Group driver has been redesigned into :doc:`GPTimer <../../../api-reference/peripherals/gptimer>`, which aims to unify and simplify the usage of general purpose timer. -Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/timer.h``. However, by default, including ``driver/timer.h`` triggers the build warning below. The warning can be suppressed by the Kconfig option :ref:`CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN`. +Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/timer.h``. However, by default, including ``driver/timer.h`` triggers the build warning below. The warning can be suppressed by the Kconfig option ``CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN``. .. code-block:: text diff --git a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst index a5467a12e4..8c0bbec0ef 100644 --- a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst @@ -49,3 +49,8 @@ Major Changes in Usage - ``i2c_slave_transmit`` has been replaced by ``i2c_slave_write``. - ``i2c_slave_write_ram`` has been removed。 - ``i2c_slave_read_ram`` has been removed。 + +Legacy Timer Group Driver is Removed +------------------------------------ + +The legacy timer group driver ``driver/timer.h`` is deprecated since version 5.0 (see :ref:`deprecate_gptimer_legacy_driver`). Starting from version 6.0, the legacy driver is completely removed. The new driver is placed in the :component:`esp_driver_gptimer`, and the header file path is ``driver/gptimer.h``. diff --git a/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst b/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst index db52767d53..298b6ab44c 100644 --- a/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst @@ -119,12 +119,18 @@ GPIO - 更新前,通道配置由通道分配在 :cpp:func:`sdm_new_channel` 完成。在新驱动中,只有 ``density`` 可在运行时由 :cpp:func:`sdm_channel_set_pulse_density` 更新。其他参数如 ``gpio number``、 ``prescale`` 只能在通道分配时进行设置。 - 在进行下一步通道操作前,用户应通过调用 :cpp:func:`sdm_channel_enable` 提前 **使能** 该通道。该函数有助于管理一些系统级服务,如 **电源管理**。 -定时器组驱动 ------------------------------------------ + .. _deprecate_gptimer_legacy_driver: + +.. only:: not SOC_SDM_SUPPORTED + + .. _deprecate_gptimer_legacy_driver: + +旧版定时器组驱动被弃用 +---------------------- 为统一和简化通用定时器的使用,定时器组驱动已更新为 :doc:`GPTimer <../../../api-reference/peripherals/gptimer>`。 -尽管我们推荐使用新的驱动 API, 旧版驱动仍然可用,其头文件引用路径为 ``driver/timer.h``。但是,引用 ``driver/timer.h`` 会默认触发如下编译警告,可通过配置 Kconfig 选项 :ref:`CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN` 关闭该警告。 +尽管我们推荐使用新的驱动 API, 旧版驱动仍然可用,其头文件引用路径为 ``driver/timer.h``。但是,引用 ``driver/timer.h`` 会默认触发如下编译警告,可通过配置 Kconfig 选项 ``CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN`` 关闭该警告。 .. code-block:: text diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst index 3585fed346..e5a7477d1c 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst @@ -49,3 +49,8 @@ I2C 从机在 v5.4 上已经被重新设计。在当前版本上,老的 I2C - ``i2c_slave_transmit`` 已被 ``i2c_slave_write`` 取代. - ``i2c_slave_write_ram`` 被移除。 - ``i2c_slave_read_ram`` 被移除。 + +旧版定时器组驱动被移除 +---------------------- + +旧版的定时器组驱动 ``driver/timer.h`` 在 5.0 的版本中就已经被弃用 (参考 :ref:`deprecate_gptimer_legacy_driver`)。从 6.0 版本开始,旧版驱动被完全移除。新驱动位于 :component:`esp_driver_gptimer` 组件中,头文件引用路径为 ``driver/gptimer.h``。 diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index dd0ae1d8df..5d7bba52a9 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -469,3 +469,30 @@ - re: "spi_hal: The clock_speed_hz should less than" hint: "When operating in full-duplex mode at high frequencies, the device may not read data correctly.\nTry using IOMUX pins to increase the frequency limit or switch to half-duplex mode.\nNote that the SPI master can only operate at divisors of 80 MHz, and the driver always selects the closest available frequency to your configuration.\nSpecify SPI_DEVICE_NO_DUMMY to bypass this check. This allows higher output speeds but may result in unreliable data reads." + +- + re: "has no member named 'io_loop_back'" + hint: "If you want to bind different driver objects to the same GPIO, just set them with the same GPIO number." + +- + re: "has no member named '{}'" + hint: "Please include 'driver/gpio.h' and call 'gpio_set_pull_mode' to set the correct pull mode." + variables: + - + re_variables: ['pull_up'] + hint_variables: [] + - + re_variables: ['pull_down'] + hint_variables: [] + +- + re: "has no member named 'io_od_mode'" + hint: "Please include 'driver/gpio.h' and call 'gpio_od_enable' to enable the open-drain mode." + +- + re: "fatal error: {}: No such file or directory" + hint: "The {} driver is removed. It should be replaced by '{}' in the '{}' component. Please read the migration guide for more details." + variables: + - + re_variables: ['driver/timer.h'] + hint_variables: ['legacy timer group', 'driver/gptimer.h', 'esp_driver_gptimer']