mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'refactor/gptimer_software_capture' into 'master'
split gptimer software capture in hal driver See merge request espressif/esp-idf!19749
This commit is contained in:
commit
060f3a3b13
@ -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(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);
|
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_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]);
|
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -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(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(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);
|
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;
|
uint32_t div = p_timer_obj[group_num][timer_num]->divider;
|
||||||
// [clk_tree] TODO: replace the following switch table by clk_tree API
|
// [clk_tree] TODO: replace the following switch table by clk_tree API
|
||||||
switch (p_timer_obj[group_num][timer_num]->clk_src) {
|
switch (p_timer_obj[group_num][timer_num]->clk_src) {
|
||||||
@ -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)
|
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);
|
uint64_t val = timer_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -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");
|
ESP_RETURN_ON_FALSE_ISR(timer && value, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
|
||||||
portENTER_CRITICAL_SAFE(&timer->spinlock);
|
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);
|
portEXIT_CRITICAL_SAFE(&timer->spinlock);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -497,7 +497,7 @@ IRAM_ATTR static void gptimer_default_isr(void *args)
|
|||||||
if (intr_status & TIMER_LL_EVENT_ALARM(timer->timer_id)) {
|
if (intr_status & TIMER_LL_EVENT_ALARM(timer->timer_id)) {
|
||||||
// Note: when alarm event happens, the alarm will be disabled automatically by hardware
|
// Note: when alarm event happens, the alarm will be disabled automatically by hardware
|
||||||
gptimer_alarm_event_data_t edata = {
|
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,
|
.alarm_value = timer->alarm_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
* @brief Timer alarm callback prototype
|
* @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] 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
|
* @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);
|
typedef bool (*gptimer_alarm_cb_t) (gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx);
|
||||||
@ -91,9 +91,9 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
|
|||||||
* @brief Delete the GPTimer handle
|
* @brief Delete the GPTimer handle
|
||||||
*
|
*
|
||||||
* @note A timer can't be in the enable state when this function is invoked.
|
* @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
|
* @return
|
||||||
* - ESP_OK: Delete GPTimer successfully
|
* - ESP_OK: Delete GPTimer successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Delete GPTimer failed because of invalid argument
|
* - ESP_ERR_INVALID_ARG: Delete GPTimer failed because of invalid argument
|
||||||
@ -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 run within ISR context
|
||||||
* @note This function is allowed to be executed when Cache is disabled, by enabling `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM`
|
* @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
|
* @param[in] value Count value to be set
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: Set GPTimer raw count value successfully
|
* - ESP_OK: Set GPTimer raw count value successfully
|
||||||
@ -121,11 +121,12 @@ esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, uint64_t value);
|
|||||||
/**
|
/**
|
||||||
* @brief Get GPTimer raw count 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 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 run within ISR context
|
||||||
* @note This function is allowed to be executed when Cache is disabled, by enabling `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM`
|
* @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
|
* @param[out] value Returned GPTimer count value
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: Get GPTimer raw count value successfully
|
* - ESP_OK: Get GPTimer raw count value successfully
|
||||||
@ -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 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.
|
* @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] cbs Group of callback functions
|
||||||
* @param[in] user_data User data, which will be passed to callback functions directly
|
* @param[in] user_data User data, which will be passed to callback functions directly
|
||||||
* @return
|
* @return
|
||||||
@ -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 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`
|
* @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
|
* @param[in] config Alarm configuration, especially, set config to NULL means disabling the alarm function
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: Set alarm action for GPTimer successfully
|
* - ESP_OK: Set alarm action for GPTimer successfully
|
||||||
@ -171,11 +172,11 @@ esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_c
|
|||||||
* @brief Enable GPTimer
|
* @brief Enable GPTimer
|
||||||
*
|
*
|
||||||
* @note This function will transit the timer state from init to enable.
|
* @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 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
|
* @return
|
||||||
* - ESP_OK: Enable GPTimer successfully
|
* - ESP_OK: Enable GPTimer successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Enable GPTimer failed because of invalid argument
|
* - ESP_ERR_INVALID_ARG: Enable GPTimer failed because of invalid argument
|
||||||
@ -187,10 +188,10 @@ esp_err_t gptimer_enable(gptimer_handle_t timer);
|
|||||||
/**
|
/**
|
||||||
* @brief Disable GPTimer
|
* @brief Disable GPTimer
|
||||||
*
|
*
|
||||||
* @note This function will do the opposite work to the `gptimer_enable()`
|
* @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 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
|
* @return
|
||||||
* - ESP_OK: Disable GPTimer successfully
|
* - ESP_OK: Disable GPTimer successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Disable GPTimer failed because of invalid argument
|
* - ESP_ERR_INVALID_ARG: Disable GPTimer failed because of invalid argument
|
||||||
@ -202,11 +203,11 @@ esp_err_t gptimer_disable(gptimer_handle_t timer);
|
|||||||
/**
|
/**
|
||||||
* @brief Start GPTimer (internal counter starts counting)
|
* @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 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
|
* @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
|
* @return
|
||||||
* - ESP_OK: Start GPTimer successfully
|
* - ESP_OK: Start GPTimer successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Start GPTimer failed because of invalid argument
|
* - ESP_ERR_INVALID_ARG: Start GPTimer failed because of invalid argument
|
||||||
@ -218,11 +219,11 @@ esp_err_t gptimer_start(gptimer_handle_t timer);
|
|||||||
/**
|
/**
|
||||||
* @brief Stop GPTimer (internal counter stops counting)
|
* @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 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
|
* @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
|
* @return
|
||||||
* - ESP_OK: Stop GPTimer successfully
|
* - ESP_OK: Stop GPTimer successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Stop GPTimer failed because of invalid argument
|
* - ESP_ERR_INVALID_ARG: Stop GPTimer failed because of invalid argument
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
CONFIG_FREERTOS_HZ=1000
|
CONFIG_FREERTOS_HZ=1000
|
||||||
CONFIG_ESP_TASK_WDT=n
|
CONFIG_ESP_TASK_WDT=n
|
||||||
|
# Disable nano printf, because we need to print the timer count in %llu format
|
||||||
|
CONFIG_NEWLIB_NANO_FORMAT=n
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
||||||
CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y
|
CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y
|
||||||
CONFIG_GPTIMER_ISR_IRAM_SAFE=y
|
CONFIG_GPTIMER_ISR_IRAM_SAFE=y
|
||||||
|
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
|
||||||
CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=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
|
# 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_CHECKS_SILENT=y
|
||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
/*----------------------------------------------------------------------------/
|
|
||||||
/ TJpgDec - Tiny JPEG Decompressor include file (C)ChaN, 2012
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
#ifndef _TJPGDEC
|
|
||||||
#define _TJPGDEC
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/* System Configurations */
|
|
||||||
|
|
||||||
#define JD_SZBUF 512 /* Size of stream input buffer */
|
|
||||||
#define JD_FORMAT 0 /* Output pixel format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */
|
|
||||||
#define JD_USE_SCALE 1 /* Use descaling feature for output */
|
|
||||||
#define JD_TBLCLIP 1 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These types must be 16-bit, 32-bit or larger integer */
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
|
|
||||||
/* These types must be 8-bit integer */
|
|
||||||
typedef char CHAR;
|
|
||||||
typedef unsigned char UCHAR;
|
|
||||||
typedef unsigned char BYTE;
|
|
||||||
|
|
||||||
/* These types must be 16-bit integer */
|
|
||||||
typedef short SHORT;
|
|
||||||
typedef unsigned short USHORT;
|
|
||||||
typedef unsigned short WORD;
|
|
||||||
typedef unsigned short WCHAR;
|
|
||||||
|
|
||||||
/* These types must be 32-bit integer */
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned long ULONG;
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
|
|
||||||
/* Error code */
|
|
||||||
typedef enum {
|
|
||||||
JDR_OK = 0, /* 0: Succeeded */
|
|
||||||
JDR_INTR, /* 1: Interrupted by output function */
|
|
||||||
JDR_INP, /* 2: Device error or wrong termination of input stream */
|
|
||||||
JDR_MEM1, /* 3: Insufficient memory pool for the image */
|
|
||||||
JDR_MEM2, /* 4: Insufficient stream input buffer */
|
|
||||||
JDR_PAR, /* 5: Parameter error */
|
|
||||||
JDR_FMT1, /* 6: Data format error (may be damaged data) */
|
|
||||||
JDR_FMT2, /* 7: Right format but not supported */
|
|
||||||
JDR_FMT3 /* 8: Not supported JPEG standard */
|
|
||||||
} JRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Rectangular structure */
|
|
||||||
typedef struct {
|
|
||||||
WORD left, right, top, bottom;
|
|
||||||
} JRECT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Decompressor object structure */
|
|
||||||
typedef struct JDEC JDEC;
|
|
||||||
struct JDEC {
|
|
||||||
UINT dctr; /* Number of bytes available in the input buffer */
|
|
||||||
BYTE *dptr; /* Current data read ptr */
|
|
||||||
BYTE *inbuf; /* Bit stream input buffer */
|
|
||||||
BYTE dmsk; /* Current bit in the current read byte */
|
|
||||||
BYTE scale; /* Output scaling ratio */
|
|
||||||
BYTE msx, msy; /* MCU size in unit of block (width, height) */
|
|
||||||
BYTE qtid[3]; /* Quantization table ID of each component */
|
|
||||||
SHORT dcv[3]; /* Previous DC element of each component */
|
|
||||||
WORD nrst; /* Restart inverval */
|
|
||||||
UINT width, height; /* Size of the input image (pixel) */
|
|
||||||
BYTE *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */
|
|
||||||
WORD *huffcode[2][2]; /* Huffman code word tables [id][dcac] */
|
|
||||||
BYTE *huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */
|
|
||||||
LONG *qttbl[4]; /* Dequaitizer tables [id] */
|
|
||||||
void *workbuf; /* Working buffer for IDCT and RGB output */
|
|
||||||
BYTE *mcubuf; /* Working buffer for the MCU */
|
|
||||||
void *pool; /* Pointer to available memory pool */
|
|
||||||
UINT sz_pool; /* Size of momory pool (bytes available) */
|
|
||||||
UINT (*infunc)(JDEC *, BYTE *, UINT); /* Pointer to jpeg stream input function */
|
|
||||||
void *device; /* Pointer to I/O device identifiler for the session */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* TJpgDec API functions */
|
|
||||||
JRESULT jd_prepare (JDEC *, UINT(*)(JDEC *, BYTE *, UINT), void *, UINT, void *);
|
|
||||||
JRESULT jd_decomp (JDEC *, UINT(*)(JDEC *, void *, JRECT *), BYTE);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _TJPGDEC */
|
|
@ -112,6 +112,22 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
hw->hw_timer[timer_num].config.tx_en = en;
|
hw->hw_timer[timer_num].config.tx_en = en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger software capture event
|
||||||
|
*
|
||||||
|
* @param hw Timer Group register base address
|
||||||
|
* @param timer_num Timer number in the group
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
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
|
* @brief Get counter value
|
||||||
*
|
*
|
||||||
@ -123,11 +139,6 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
static inline uint64_t timer_ll_get_counter_value(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) {
|
|
||||||
}
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,22 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
hw->hw_timer[timer_num].config.tx_en = en;
|
hw->hw_timer[timer_num].config.tx_en = en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger software capture event
|
||||||
|
*
|
||||||
|
* @param hw Timer Group register base address
|
||||||
|
* @param timer_num Timer number in the group
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
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
|
* @brief Get counter value
|
||||||
*
|
*
|
||||||
@ -126,11 +142,6 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
static inline uint64_t timer_ll_get_counter_value(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) {
|
|
||||||
}
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,22 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
hw->hw_timer[timer_num].config.tx_en = en;
|
hw->hw_timer[timer_num].config.tx_en = en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger software capture event
|
||||||
|
*
|
||||||
|
* @param hw Timer Group register base address
|
||||||
|
* @param timer_num Timer number in the group
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
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
|
* @brief Get counter value
|
||||||
*
|
*
|
||||||
@ -126,11 +142,6 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
static inline uint64_t timer_ll_get_counter_value(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) {
|
|
||||||
}
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,22 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
hw->hw_timer[timer_num].config.tx_en = en;
|
hw->hw_timer[timer_num].config.tx_en = en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger software capture event
|
||||||
|
*
|
||||||
|
* @param hw Timer Group register base address
|
||||||
|
* @param timer_num Timer number in the group
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
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
|
* @brief Get counter value
|
||||||
*
|
*
|
||||||
@ -126,11 +142,6 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
static inline uint64_t timer_ll_get_counter_value(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) {
|
|
||||||
}
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +116,22 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
hw->hw_timer[timer_num].config.tx_en = en;
|
hw->hw_timer[timer_num].config.tx_en = en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger software capture event
|
||||||
|
*
|
||||||
|
* @param hw Timer Group register base address
|
||||||
|
* @param timer_num Timer number in the group
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
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
|
* @brief Get counter value
|
||||||
*
|
*
|
||||||
@ -127,11 +143,6 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
static inline uint64_t timer_ll_get_counter_value(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) {
|
|
||||||
}
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,22 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
hw->hw_timer[timer_num].config.tn_en = en;
|
hw->hw_timer[timer_num].config.tn_en = en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger software capture event
|
||||||
|
*
|
||||||
|
* @param hw Timer Group register base address
|
||||||
|
* @param timer_num Timer number in the group
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
|
||||||
|
{
|
||||||
|
hw->hw_timer[timer_num].update.tn_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.tn_update) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get counter value
|
* @brief Get counter value
|
||||||
*
|
*
|
||||||
@ -126,11 +142,6 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].update.tn_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.tn_update) {
|
|
||||||
}
|
|
||||||
return ((uint64_t)hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_lo);
|
return ((uint64_t)hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -45,6 +45,14 @@ void timer_hal_init(timer_hal_context_t *hal, uint32_t group_num, uint32_t timer
|
|||||||
*/
|
*/
|
||||||
void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val);
|
void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger a software capture event and then return the captured count value
|
||||||
|
*
|
||||||
|
* @param hal Context of the HAL layer
|
||||||
|
* @return Counter value
|
||||||
|
*/
|
||||||
|
uint64_t timer_hal_capture_and_get_counter_value(timer_hal_context_t *hal);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,3 +22,9 @@ void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val)
|
|||||||
// restore the previous reload value
|
// restore the previous reload value
|
||||||
timer_ll_set_reload_value(hal->dev, hal->timer_id, old_reload);
|
timer_ll_set_reload_value(hal->dev, hal->timer_id, old_reload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t timer_hal_capture_and_get_counter_value(timer_hal_context_t *hal)
|
||||||
|
{
|
||||||
|
timer_ll_trigger_soft_capture(hal->dev, hal->timer_id);
|
||||||
|
return timer_ll_get_counter_value(hal->dev, hal->timer_id);
|
||||||
|
}
|
||||||
|
@ -17,18 +17,18 @@ Functional Overview
|
|||||||
|
|
||||||
The following sections of this document cover the typical steps to install and operate a timer:
|
The following sections of this document cover the typical steps to install and operate a timer:
|
||||||
|
|
||||||
- :ref:`resource-allocation` - covers which parameters should be set up to get a timer handle and how to recycle the resources when GPTimer finishes working.
|
- :ref:`gptimer-resource-allocation` - covers which parameters should be set up to get a timer handle and how to recycle the resources when GPTimer finishes working.
|
||||||
- :ref:`set-and-get-count-value` - covers how to force the timer counting from a start point and how to get the count value at anytime.
|
- :ref:`set-and-get-count-value` - covers how to force the timer counting from a start point and how to get the count value at anytime.
|
||||||
- :ref:`set-up-alarm-action` - covers the parameters that should be set up to enable the alarm event.
|
- :ref:`set-up-alarm-action` - covers the parameters that should be set up to enable the alarm event.
|
||||||
- :ref:`register-event-callbacks` - covers how to hook user specific code to the alarm event callback function.
|
- :ref:`gptimer-register-event-callbacks` - covers how to hook user specific code to the alarm event callback function.
|
||||||
- :ref:`enable-and-disable-timer` - covers how to enable and disable the timer.
|
- :ref:`enable-and-disable-timer` - covers how to enable and disable the timer.
|
||||||
- :ref:`start-and-stop-timer` - shows some typical use cases that start the timer with different alarm behavior.
|
- :ref:`start-and-stop-timer` - shows some typical use cases that start the timer with different alarm behavior.
|
||||||
- :ref:`power-management` - describes how different source clock selections can affect power consumption.
|
- :ref:`gptimer-power-management` - describes how different source clock selections can affect power consumption.
|
||||||
- :ref:`iram-safe` - describes tips on how to make the timer interrupt and IO control functions work better along with a disabled cache.
|
- :ref:`gptimer-iram-safe` - describes tips on how to make the timer interrupt and IO control functions work better along with a disabled cache.
|
||||||
- :ref:`thread-safety` - lists which APIs are guaranteed to be thread safe by the driver.
|
- :ref:`gptimer-thread-safety` - lists which APIs are guaranteed to be thread safe by the driver.
|
||||||
- :ref:`kconfig-options` - lists the supported Kconfig options that can be used to make a different effect on driver behavior.
|
- :ref:`gptimer-kconfig-options` - lists the supported Kconfig options that can be used to make a different effect on driver behavior.
|
||||||
|
|
||||||
.. _resource-allocation:
|
.. _gptimer-resource-allocation:
|
||||||
|
|
||||||
Resource Allocation
|
Resource Allocation
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
@ -39,7 +39,7 @@ A GPTimer instance is represented by :cpp:type:`gptimer_handle_t`. The driver be
|
|||||||
|
|
||||||
To install a timer instance, there is a configuration structure that needs to be given in advance: :cpp:type:`gptimer_config_t`:
|
To install a timer instance, there is a configuration structure that needs to be given in advance: :cpp:type:`gptimer_config_t`:
|
||||||
|
|
||||||
- :cpp:member:`gptimer_config_t::clk_src` selects the source clock for the timer. The available clocks are listed in :cpp:type:`gptimer_clock_source_t`, you can only pick one of them. For the effect on power consumption of different clock source, please refer to Section :ref:`power-management`.
|
- :cpp:member:`gptimer_config_t::clk_src` selects the source clock for the timer. The available clocks are listed in :cpp:type:`gptimer_clock_source_t`, you can only pick one of them. For the effect on power consumption of different clock source, please refer to Section :ref:`gptimer-power-management`.
|
||||||
|
|
||||||
- :cpp:member:`gptimer_config_t::direction` sets the counting direction of the timer, supported directions are listed in :cpp:type:`gptimer_count_direction_t`, you can only pick one of them.
|
- :cpp:member:`gptimer_config_t::direction` sets the counting direction of the timer, supported directions are listed in :cpp:type:`gptimer_count_direction_t`, you can only pick one of them.
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ To make the alarm configurations take effect, you should call :cpp:func:`gptimer
|
|||||||
|
|
||||||
If an alarm value is set and the timer has already exceeded this value, the alarm will be triggered immediately.
|
If an alarm value is set and the timer has already exceeded this value, the alarm will be triggered immediately.
|
||||||
|
|
||||||
.. _register-event-callbacks:
|
.. _gptimer-register-event-callbacks:
|
||||||
|
|
||||||
Register Event Callbacks
|
Register Event Callbacks
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -116,7 +116,7 @@ Before doing IO control to the timer, you needs to enable the timer first, by ca
|
|||||||
|
|
||||||
* Switch the timer driver state from **init** to **enable**.
|
* Switch the timer driver state from **init** to **enable**.
|
||||||
* Enable the interrupt service if it has been lazy installed by :cpp:func:`gptimer_register_event_callbacks`.
|
* Enable the interrupt service if it has been lazy installed by :cpp:func:`gptimer_register_event_callbacks`.
|
||||||
* Acquire a proper power management lock if a specific clock source (e.g. APB clock) is selected. See Section :ref:`power-management` for more information.
|
* Acquire a proper power management lock if a specific clock source (e.g. APB clock) is selected. See Section :ref:`gptimer-power-management` for more information.
|
||||||
|
|
||||||
Calling :cpp:func:`gptimer_disable` will do the opposite, that is, put the timer driver back to the **init** state, disable the interrupts service and release the power management lock.
|
Calling :cpp:func:`gptimer_disable` will do the opposite, that is, put the timer driver back to the **init** state, disable the interrupts service and release the power management lock.
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ Alarm value can be updated dynamically inside the ISR handler callback, by chang
|
|||||||
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
||||||
ESP_ERROR_CHECK(gptimer_start(gptimer, &alarm_config));
|
ESP_ERROR_CHECK(gptimer_start(gptimer, &alarm_config));
|
||||||
|
|
||||||
.. _power-management:
|
.. _gptimer-power-management:
|
||||||
|
|
||||||
Power Management
|
Power Management
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
@ -267,7 +267,7 @@ However, the driver can prevent the system from changing APB frequency by acquir
|
|||||||
|
|
||||||
If other gptimer clock sources are selected such as :cpp:enumerator:`GPTIMER_CLK_SRC_XTAL`, then the driver will not install power management lock. The XTAL clock source is more suitable for a low power application as long as the source clock can still provide sufficient resolution.
|
If other gptimer clock sources are selected such as :cpp:enumerator:`GPTIMER_CLK_SRC_XTAL`, then the driver will not install power management lock. The XTAL clock source is more suitable for a low power application as long as the source clock can still provide sufficient resolution.
|
||||||
|
|
||||||
.. _iram-safe:
|
.. _gptimer-iram-safe:
|
||||||
|
|
||||||
IRAM Safe
|
IRAM Safe
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
@ -290,7 +290,7 @@ There is another Kconfig option :ref:`CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` that can
|
|||||||
- :cpp:func:`gptimer_set_raw_count`
|
- :cpp:func:`gptimer_set_raw_count`
|
||||||
- :cpp:func:`gptimer_set_alarm_action`
|
- :cpp:func:`gptimer_set_alarm_action`
|
||||||
|
|
||||||
.. _thread-safety:
|
.. _gptimer-thread-safety:
|
||||||
|
|
||||||
Thread Safety
|
Thread Safety
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
@ -307,13 +307,13 @@ The following functions are allowed to run under ISR context, as the driver uses
|
|||||||
|
|
||||||
Other functions that take :cpp:type:`gptimer_handle_t` as the first positional parameter, are not treated as thread safe, which means you should avoid calling them from multiple tasks.
|
Other functions that take :cpp:type:`gptimer_handle_t` as the first positional parameter, are not treated as thread safe, which means you should avoid calling them from multiple tasks.
|
||||||
|
|
||||||
.. _kconfig-options:
|
.. _gptimer-kconfig-options:
|
||||||
|
|
||||||
Kconfig Options
|
Kconfig Options
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
- :ref:`CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` controls where to place the GPTimer control functions (IRAM or flash), see Section :ref:`iram-safe` for more information.
|
- :ref:`CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` controls where to place the GPTimer control functions (IRAM or flash), see Section :ref:`gptimer-iram-safe` for more information.
|
||||||
- :ref:`CONFIG_GPTIMER_ISR_IRAM_SAFE` controls whether the default ISR handler can work when the cache is disabled, see Section :ref:`iram-safe` for more information.
|
- :ref:`CONFIG_GPTIMER_ISR_IRAM_SAFE` controls whether the default ISR handler can work when the cache is disabled, see Section :ref:`gptimer-iram-safe` for more information.
|
||||||
- :ref:`CONFIG_GPTIMER_ENABLE_DEBUG_LOG` is used to enabled the debug log output. Enable this option will increase the firmware binary size.
|
- :ref:`CONFIG_GPTIMER_ENABLE_DEBUG_LOG` is used to enabled the debug log output. Enable this option will increase the firmware binary size.
|
||||||
|
|
||||||
Application Examples
|
Application Examples
|
||||||
|
@ -17,18 +17,18 @@
|
|||||||
|
|
||||||
下文介绍了配置和操作定时器的常规步骤:
|
下文介绍了配置和操作定时器的常规步骤:
|
||||||
|
|
||||||
- :ref:`resource-allocation` - 获取定时器句柄应设置的参数,以及如何在通用定时器完成工作时回收资源。
|
- :ref:`gptimer-resource-allocation` - 获取定时器句柄应设置的参数,以及如何在通用定时器完成工作时回收资源。
|
||||||
- :ref:`set-and-get-count-value` - 如何强制定时器从起点开始计数,以及如何随时获取计数值。
|
- :ref:`set-and-get-count-value` - 如何强制定时器从起点开始计数,以及如何随时获取计数值。
|
||||||
- :ref:`set-up-alarm-action` - 启动警报事件应设置的参数。
|
- :ref:`set-up-alarm-action` - 启动警报事件应设置的参数。
|
||||||
- :ref:`register-event-callbacks` - 如何将用户的特定代码挂载到警报事件回调函数。
|
- :ref:`gptimer-register-event-callbacks` - 如何将用户的特定代码挂载到警报事件回调函数。
|
||||||
- :ref:`enable-and-disable-timer` - 如何使能和禁用定时器。
|
- :ref:`enable-and-disable-timer` - 如何使能和禁用定时器。
|
||||||
- :ref:`start-and-stop-timer` - 通过不同报警行为启动定时器的典型使用场景。
|
- :ref:`start-and-stop-timer` - 通过不同报警行为启动定时器的典型使用场景。
|
||||||
- :ref:`power-management` - 选择不同的时钟源将会如何影响功耗。
|
- :ref:`gptimer-power-management` - 选择不同的时钟源将会如何影响功耗。
|
||||||
- :ref:`iram-safe` - 在 cache 禁用的情况下,如何更好地让定时器处理中断事务以及实现 IO 控制功能。
|
- :ref:`gptimer-iram-safe` - 在 cache 禁用的情况下,如何更好地让定时器处理中断事务以及实现 IO 控制功能。
|
||||||
- :ref:`thread-safety` - 驱动程序保证哪些 API 线程安全。
|
- :ref:`gptimer-thread-safety` - 驱动程序保证哪些 API 线程安全。
|
||||||
- :ref:`kconfig-options` - 支持的 Kconfig 选项,这些选项会对驱动程序行为产生不同影响。
|
- :ref:`gptimer-kconfig-options` - 支持的 Kconfig 选项,这些选项会对驱动程序行为产生不同影响。
|
||||||
|
|
||||||
.. _resource-allocation:
|
.. _gptimer-resource-allocation:
|
||||||
|
|
||||||
资源分配
|
资源分配
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
要安装一个定时器实例,需要提前提供配置结构体 :cpp:type:`gptimer_config_t`:
|
要安装一个定时器实例,需要提前提供配置结构体 :cpp:type:`gptimer_config_t`:
|
||||||
|
|
||||||
- :cpp:member:`gptimer_config_t::clk_src` 选择定时器的时钟源。:cpp:type:`gptimer_clock_source_t` 中列出多个可用时钟,仅可选择其中一个时钟。了解不同时钟源对功耗的影响,请查看章节 :ref:`power-management`。
|
- :cpp:member:`gptimer_config_t::clk_src` 选择定时器的时钟源。:cpp:type:`gptimer_clock_source_t` 中列出多个可用时钟,仅可选择其中一个时钟。了解不同时钟源对功耗的影响,请查看章节 :ref:`gptimer-power-management`。
|
||||||
|
|
||||||
- :cpp:member:`gptimer_config_t::direction` 设置定时器的计数方向,:cpp:type:`gptimer_count_direction_t` 中列出多个支持的方向,仅可选择其中一个方向。
|
- :cpp:member:`gptimer_config_t::direction` 设置定时器的计数方向,:cpp:type:`gptimer_count_direction_t` 中列出多个支持的方向,仅可选择其中一个方向。
|
||||||
|
|
||||||
@ -94,7 +94,7 @@
|
|||||||
|
|
||||||
如果警报值已设置且定时器超过该值,则会立即触发警报。
|
如果警报值已设置且定时器超过该值,则会立即触发警报。
|
||||||
|
|
||||||
.. _register-event-callbacks:
|
.. _gptimer-register-event-callbacks:
|
||||||
|
|
||||||
注册事件回调函数
|
注册事件回调函数
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -116,7 +116,7 @@
|
|||||||
|
|
||||||
* 此函数将把定时器驱动程序的状态从 **init** 切换为 **enable**。
|
* 此函数将把定时器驱动程序的状态从 **init** 切换为 **enable**。
|
||||||
* 如果 :cpp:func:`gptimer_register_event_callbacks` 已经延迟安装中断服务,此函数将使能中断服务。
|
* 如果 :cpp:func:`gptimer_register_event_callbacks` 已经延迟安装中断服务,此函数将使能中断服务。
|
||||||
* 如果选择了特定的时钟源(例如 APB 时钟),此函数将获取适当的电源管理锁。了解更多信息,请查看章节 :ref:`power-management`。
|
* 如果选择了特定的时钟源(例如 APB 时钟),此函数将获取适当的电源管理锁。了解更多信息,请查看章节 :ref:`gptimer-power-management`。
|
||||||
|
|
||||||
调用 :cpp:func:`gptimer_disable` 会进行相反的操作,即将定时器驱动程序恢复到 **init** 状态,禁用中断服务并释放电源管理锁。
|
调用 :cpp:func:`gptimer_disable` 会进行相反的操作,即将定时器驱动程序恢复到 **init** 状态,禁用中断服务并释放电源管理锁。
|
||||||
|
|
||||||
@ -256,7 +256,7 @@
|
|||||||
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
||||||
ESP_ERROR_CHECK(gptimer_start(gptimer, &alarm_config));
|
ESP_ERROR_CHECK(gptimer_start(gptimer, &alarm_config));
|
||||||
|
|
||||||
.. _power-management:
|
.. _gptimer-power-management:
|
||||||
|
|
||||||
电源管理
|
电源管理
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
@ -267,7 +267,7 @@
|
|||||||
|
|
||||||
如果选择 :cpp:enumerator:`GPTIMER_CLK_SRC_XTAL` 等其他时钟源,那么驱动程序不会安装电源管理锁。只要时钟源仍可提供足够的分辨率,XTAL 时钟源就更适合低功耗应用。
|
如果选择 :cpp:enumerator:`GPTIMER_CLK_SRC_XTAL` 等其他时钟源,那么驱动程序不会安装电源管理锁。只要时钟源仍可提供足够的分辨率,XTAL 时钟源就更适合低功耗应用。
|
||||||
|
|
||||||
.. _iram-safe:
|
.. _gptimer-iram-safe:
|
||||||
|
|
||||||
IRAM 安全
|
IRAM 安全
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
@ -290,7 +290,7 @@ IRAM 安全
|
|||||||
- :cpp:func:`gptimer_set_raw_count`
|
- :cpp:func:`gptimer_set_raw_count`
|
||||||
- :cpp:func:`gptimer_set_alarm_action`
|
- :cpp:func:`gptimer_set_alarm_action`
|
||||||
|
|
||||||
.. _thread-safety:
|
.. _gptimer-thread-safety:
|
||||||
|
|
||||||
线程安全
|
线程安全
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
@ -307,13 +307,13 @@ IRAM 安全
|
|||||||
|
|
||||||
将 :cpp:type:`gptimer_handle_t` 作为第一个位置参数的其他函数不被视作线程安全,也就是说应该避免从多个任务中调用这些函数。
|
将 :cpp:type:`gptimer_handle_t` 作为第一个位置参数的其他函数不被视作线程安全,也就是说应该避免从多个任务中调用这些函数。
|
||||||
|
|
||||||
.. _kconfig-options:
|
.. _gptimer-kconfig-options:
|
||||||
|
|
||||||
Kconfig 选项
|
Kconfig 选项
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
- :ref:`CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` 控制放置通用定时器控制函数(IRAM 或 flash)的位置。了解更多信息,请参考章节 :ref:`iram-safe`。
|
- :ref:`CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` 控制放置通用定时器控制函数(IRAM 或 flash)的位置。了解更多信息,请参考章节 :ref:`gptimer-iram-safe`。
|
||||||
- :ref:`CONFIG_GPTIMER_ISR_IRAM_SAFE` 控制默认 ISR 程序在 cache 禁用时是否可以运行。了解更多信息,请参考章节 :ref:`iram-safe`。
|
- :ref:`CONFIG_GPTIMER_ISR_IRAM_SAFE` 控制默认 ISR 程序在 cache 禁用时是否可以运行。了解更多信息,请参考章节 :ref:`gptimer-iram-safe`。
|
||||||
- :ref:`CONFIG_GPTIMER_ENABLE_DEBUG_LOG` 用于启用调试日志输出。启用这一选项将增加固件二进制文件大小。
|
- :ref:`CONFIG_GPTIMER_ENABLE_DEBUG_LOG` 用于启用调试日志输出。启用这一选项将增加固件二进制文件大小。
|
||||||
|
|
||||||
应用示例
|
应用示例
|
||||||
|
Loading…
Reference in New Issue
Block a user