Skip to content

Commit

Permalink
Merge branch 'refactor/gptimer_software_capture' into 'master'
Browse files Browse the repository at this point in the history
split gptimer software capture in hal driver

See merge request espressif/esp-idf!19749
  • Loading branch information
suda-morris committed Aug 26, 2022
2 parents e219510 + 995b89f commit 060f3a3
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 184 deletions.
5 changes: 3 additions & 2 deletions components/driver/deprecated/timer_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num
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_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_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;
}
Expand All @@ -74,7 +74,7 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_
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_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
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;
// [clk_tree] TODO: replace the following switch table by clk_tree API
switch (p_timer_obj[group_num][timer_num]->clk_src) {
Expand Down Expand Up @@ -432,6 +432,7 @@ void IRAM_ATTR timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_id

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;
}
Expand Down
4 changes: 2 additions & 2 deletions components/driver/gptimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ esp_err_t gptimer_get_raw_count(gptimer_handle_t timer, unsigned long long *valu
ESP_RETURN_ON_FALSE_ISR(timer && value, ESP_ERR_INVALID_ARG, TAG, "invalid argument");

portENTER_CRITICAL_SAFE(&timer->spinlock);
*value = timer_ll_get_counter_value(timer->hal.dev, timer->timer_id);
*value = timer_hal_capture_and_get_counter_value(&timer->hal);
portEXIT_CRITICAL_SAFE(&timer->spinlock);
return ESP_OK;
}
Expand Down Expand Up @@ -497,7 +497,7 @@ IRAM_ATTR static void gptimer_default_isr(void *args)
if (intr_status & TIMER_LL_EVENT_ALARM(timer->timer_id)) {
// Note: when alarm event happens, the alarm will be disabled automatically by hardware
gptimer_alarm_event_data_t edata = {
.count_value = timer_ll_get_counter_value(timer->hal.dev, timer->timer_id),
.count_value = timer_hal_capture_and_get_counter_value(&timer->hal),
.alarm_value = timer->alarm_count,
};

Expand Down
37 changes: 19 additions & 18 deletions components/driver/include/driver/gptimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ typedef struct {
/**
* @brief Timer alarm callback prototype
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @param[in] edata Alarm event data, fed by driver
* @param[in] user_ctx User data, passed from `gptimer_register_event_callbacks()`
* @param[in] user_ctx User data, passed from `gptimer_register_event_callbacks`
* @return Whether a high priority task has been waken up by this function
*/
typedef bool (*gptimer_alarm_cb_t) (gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx);
Expand Down Expand Up @@ -91,9 +91,9 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
* @brief Delete the GPTimer handle
*
* @note A timer can't be in the enable state when this function is invoked.
* See also `gptimer_disable()` for how to disable a timer.
* See also `gptimer_disable` for how to disable a timer.
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @return
* - ESP_OK: Delete GPTimer successfully
* - ESP_ERR_INVALID_ARG: Delete GPTimer failed because of invalid argument
Expand All @@ -109,7 +109,7 @@ esp_err_t gptimer_del_timer(gptimer_handle_t timer);
* @note This function is allowed to run within ISR context
* @note This function is allowed to be executed when Cache is disabled, by enabling `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM`
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @param[in] value Count value to be set
* @return
* - ESP_OK: Set GPTimer raw count value successfully
Expand All @@ -121,11 +121,12 @@ esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, uint64_t value);
/**
* @brief Get GPTimer raw count value
*
* @note This function will trigger a software capture event and then return the captured count value.
* @note With the raw count value and the resolution set in the `gptimer_config_t`, you can convert the count value into seconds.
* @note This function is allowed to run within ISR context
* @note This function is allowed to be executed when Cache is disabled, by enabling `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM`
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @param[out] value Returned GPTimer count value
* @return
* - ESP_OK: Get GPTimer raw count value successfully
Expand All @@ -141,7 +142,7 @@ esp_err_t gptimer_get_raw_count(gptimer_handle_t timer, uint64_t *value);
* @note The first call to this function needs to be before the call to `gptimer_enable`
* @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL.
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @param[in] cbs Group of callback functions
* @param[in] user_data User data, which will be passed to callback functions directly
* @return
Expand All @@ -158,7 +159,7 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer
* @note This function is allowed to run within ISR context, so that user can set new alarm action immediately in the ISR callback.
* @note This function is allowed to be executed when Cache is disabled, by enabling `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM`
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @param[in] config Alarm configuration, especially, set config to NULL means disabling the alarm function
* @return
* - ESP_OK: Set alarm action for GPTimer successfully
Expand All @@ -171,11 +172,11 @@ esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_c
* @brief Enable GPTimer
*
* @note This function will transit the timer state from init to enable.
* @note This function will enable the interrupt service, if it's lazy installed in `gptimer_register_event_callbacks()`.
* @note This function will enable the interrupt service, if it's lazy installed in `gptimer_register_event_callbacks`.
* @note This function will acquire a PM lock, if a specific source clock (e.g. APB) is selected in the `gptimer_config_t`, while `CONFIG_PM_ENABLE` is enabled.
* @note Enable a timer doesn't mean to start it. See also `gptimer_start()` for how to make the timer start counting.
* @note Enable a timer doesn't mean to start it. See also `gptimer_start` for how to make the timer start counting.
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @return
* - ESP_OK: Enable GPTimer successfully
* - ESP_ERR_INVALID_ARG: Enable GPTimer failed because of invalid argument
Expand All @@ -187,10 +188,10 @@ esp_err_t gptimer_enable(gptimer_handle_t timer);
/**
* @brief Disable GPTimer
*
* @note This function will do the opposite work to the `gptimer_enable()`
* @note Disable a timer doesn't mean to stop it. See also `gptimer_stop()` for how to make the timer stop counting.
* @note This function will do the opposite work to the `gptimer_enable`
* @note Disable a timer doesn't mean to stop it. See also `gptimer_stop` for how to make the timer stop counting.
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @return
* - ESP_OK: Disable GPTimer successfully
* - ESP_ERR_INVALID_ARG: Disable GPTimer failed because of invalid argument
Expand All @@ -202,11 +203,11 @@ esp_err_t gptimer_disable(gptimer_handle_t timer);
/**
* @brief Start GPTimer (internal counter starts counting)
*
* @note This function should be called when the timer is in the enable state (i.e. after calling `gptimer_enable()`)
* @note This function should be called when the timer is in the enable state (i.e. after calling `gptimer_enable`)
* @note This function is allowed to run within ISR context
* @note This function will be placed into IRAM if `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` is on, so that it's allowed to be executed when Cache is disabled
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @return
* - ESP_OK: Start GPTimer successfully
* - ESP_ERR_INVALID_ARG: Start GPTimer failed because of invalid argument
Expand All @@ -218,11 +219,11 @@ esp_err_t gptimer_start(gptimer_handle_t timer);
/**
* @brief Stop GPTimer (internal counter stops counting)
*
* @note This function should be called when the timer is in the enable state (i.e. after calling `gptimer_enable()`)
* @note This function should be called when the timer is in the enable state (i.e. after calling `gptimer_enable`)
* @note This function is allowed to run within ISR context
* @note This function will be placed into IRAM if `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` is on, so that it's allowed to be executed when Cache is disabled
*
* @param[in] timer Timer handle created by `gptimer_new_timer()`
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @return
* - ESP_OK: Stop GPTimer successfully
* - ESP_ERR_INVALID_ARG: Stop GPTimer failed because of invalid argument
Expand Down
2 changes: 2 additions & 0 deletions components/driver/test_apps/gptimer/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n
# Disable nano printf, because we need to print the timer count in %llu format
CONFIG_NEWLIB_NANO_FORMAT=n
3 changes: 2 additions & 1 deletion components/esp_adc/test_apps/adc/sdkconfig.ci.iram_safe
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_IRAM_SAFE=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
Expand Down
104 changes: 0 additions & 104 deletions components/esp_rom/include/esp32c2/rom/tjpgd.h

This file was deleted.

19 changes: 15 additions & 4 deletions components/hal/esp32/include/hal/timer_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,32 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
}

/**
* @brief Get counter value
* @brief Trigger software capture event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
{
hw->hw_timer[timer_num].update.tx_update = 1;
// Timer register is in a different clock domain from Timer hardware logic
// We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
}

/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
}

Expand Down
19 changes: 15 additions & 4 deletions components/hal/esp32c2/include/hal/timer_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,32 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
}

/**
* @brief Get counter value
* @brief Trigger software capture event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
{
hw->hw_timer[timer_num].update.tx_update = 1;
// Timer register is in a different clock domain from Timer hardware logic
// We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
}

/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
}

Expand Down
19 changes: 15 additions & 4 deletions components/hal/esp32c3/include/hal/timer_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,32 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
}

/**
* @brief Get counter value
* @brief Trigger software capture event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
{
hw->hw_timer[timer_num].update.tx_update = 1;
// Timer register is in a different clock domain from Timer hardware logic
// We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
}

/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
}

Expand Down

0 comments on commit 060f3a3

Please sign in to comment.