Skip to content

Commit

Permalink
driver: timer
Browse files Browse the repository at this point in the history
1. minor modifications
2. use TIMG_WDT_INT_ENA_M instead of BIT(2) in wdt.c
3. add doc/api/timer.rst
  • Loading branch information
costaud committed Nov 23, 2016
1 parent a3c4a70 commit c533099
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 36 deletions.
56 changes: 31 additions & 25 deletions components/driver/include/driver/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,25 @@ extern "C" {
* @brief Selects a Timer-Group out of 2 available groups
*/
typedef enum {
TIMER_GROUP_0 = 0, /*!<Hw timer group 0*/
TIMER_GROUP_1 = 1, /*!<Hw timer group 1*/
TIMER_GROUP_MAX,
TIMER_GROUP_0 = 0, /*!<Hw timer group 0*/
TIMER_GROUP_1 = 1, /*!<Hw timer group 1*/
TIMER_GROUP_MAX,
} timer_group_t;

/**
* @brief Select a hardware timer from timer groups
*/
typedef enum {
TIMER_0 = 0, /*!<Select timer0 of GROUPx*/
TIMER_1 = 1, /*!<Select timer1 of GROUPx*/
TIMER_MAX,
TIMER_0 = 0, /*!<Select timer0 of GROUPx*/
TIMER_1 = 1, /*!<Select timer1 of GROUPx*/
TIMER_MAX,
} timer_idx_t;

/**
* @brief Decides the direction of counter
*/
typedef enum {
TIMER_COUNT_DOWN = 0, /*!< Descending Count from cnt.high|cnt.low*/
TIMER_COUNT_DOWN = 0, /*!< Descending Count from cnt.high|cnt.low*/
TIMER_COUNT_UP = 1, /*!< Ascending Count from Zero*/
TIMER_COUNT_MAX
} timer_count_dir_t;
Expand All @@ -57,47 +57,47 @@ typedef enum {
* @brief Decides whether timer is on or paused
*/
typedef enum {
TIMER_PAUSE = 0, /*!<Pause timer counter*/
TIMER_START = 1, /*!<Start timer counter*/
TIMER_PAUSE = 0, /*!<Pause timer counter*/
TIMER_START = 1, /*!<Start timer counter*/
} timer_start_t;

/**
* @brief Decides whether to enable alarm mode
*/
typedef enum {
TIMER_ALARM_DIS = 0, /*!< Disable timer alarm*/
TIMER_ALARM_EN = 1, /*!< Enable timer alarm*/
TIMER_ALARM_MAX
TIMER_ALARM_DIS = 0, /*!< Disable timer alarm*/
TIMER_ALARM_EN = 1, /*!< Enable timer alarm*/
TIMER_ALARM_MAX
} timer_alarm_t;

/**
* @brief Select interrupt type if running in alarm mode.
*/
typedef enum {
TIMER_INTR_LEVEL = 0, /*!< Interrupt mode: level mode*/
//TIMER_INTR_EDGE = 1, /*!< Interrupt mode: edge mode, Not supported Now*/
TIMER_INTR_MAX
TIMER_INTR_LEVEL = 0, /*!< Interrupt mode: level mode*/
//TIMER_INTR_EDGE = 1, /*!< Interrupt mode: edge mode, Not supported Now*/
TIMER_INTR_MAX
} timer_intr_mode_t;

/**
* @brief Select if Alarm needs to be loaded by software or automatically reload by hardware.
*/
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_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;

/**
* @brief timer configure struct
*/
typedef struct {
bool alarm_en; /*!< Timer alarm enable */
bool counter_en; /*!< Counter enable */
timer_count_dir_t counter_dir; /*!< Counter direction */
timer_intr_mode_t intr_type; /*!< Interrupt mode */
bool auto_reload; /*!< Timer auto-reload */
uint16_t divider; /*!< Counter clock divider*/
bool alarm_en; /*!< Timer alarm enable */
bool counter_en; /*!< Counter enable */
timer_count_dir_t counter_dir; /*!< Counter direction */
timer_intr_mode_t intr_type; /*!< Interrupt mode */
bool auto_reload; /*!< Timer auto-reload */
uint16_t divider; /*!< Counter clock divider*/
} timer_config_t;

/**
Expand Down Expand Up @@ -255,7 +255,9 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_
* @param intr_type Timer interrupt type
* @param fn Interrupt handler function.
* @note
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
* Code inside the handler function can only call functions in IRAM, so cannot call other timer APIs.
* Use direct register access to access timers from inside the ISR.
*
* @param arg Parameter for handler function
*
* @return
Expand Down Expand Up @@ -296,6 +298,8 @@ esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer
*
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
* @param en_mask Timer interrupt enable mask.
* Use TIMG_T0_INT_ENA_M to enable t0 interrupt
* Use TIMG_T1_INT_ENA_M to enable t1 interrupt
*
* @return
* - ESP_OK Success
Expand All @@ -307,6 +311,8 @@ esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask);
*
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
* @param disable_mask Timer interrupt disable mask.
* Use TIMG_T0_INT_ENA_M to disable t0 interrupt
* Use TIMG_T1_INT_ENA_M to disable t1 interrupt
*
* @return
* - ESP_OK Success
Expand Down
15 changes: 7 additions & 8 deletions components/driver/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,13 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
TIMER_CHECK(time != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);

portENTER_CRITICAL(&timer_spinlock[group_num]);
TG[group_num]->hw_timer[timer_num].update = 1;
uint64_t timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32)
| (TG[group_num]->hw_timer[timer_num].cnt_low);
uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider;
*time = (double)timer_val * div / TIMER_BASE_CLK;
portEXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK;
uint64_t timer_val;
esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val);
if (err == ESP_OK) {
uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider;
*time = (double)timer_val * div / TIMER_BASE_CLK;
}
return err;
}

esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val)
Expand Down
5 changes: 3 additions & 2 deletions components/esp32/int_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "esp_freertos_hooks.h"
#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
#include "driver/timer.h"

#include "esp_int_wdt.h"

Expand Down Expand Up @@ -85,7 +86,7 @@ void esp_int_wdt_init() {
TIMERG1.wdt_feed=1;
TIMERG1.wdt_wprotect=0;
TIMERG1.int_clr_timers.wdt=1;
TIMERG1.int_ena.wdt=1;
timer_group_intr_enable(TIMER_GROUP_1, TIMG_WDT_INT_ENA_M);
esp_register_freertos_tick_hook(tick_hook);
ESP_INTR_DISABLE(WDT_INT_NUM);
intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM);
Expand All @@ -97,4 +98,4 @@ void esp_int_wdt_init() {



#endif
#endif
2 changes: 1 addition & 1 deletion components/esp32/task_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ void esp_task_wdt_init() {
intr_matrix_set(xPortGetCoreID(), ETS_TG0_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM);
xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL);
TIMERG0.int_clr_timers.wdt=1;
timer_group_intr_enable(TIMER_GROUP_0, BIT(2));
timer_group_intr_enable(TIMER_GROUP_0, TIMG_WDT_INT_ENA_M);
ESP_INTR_ENABLE(ETS_T0_WDT_INUM);
}

Expand Down
73 changes: 73 additions & 0 deletions docs/api/timer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
TIMER
========

Overview
--------

ESP32 chip contains two hardware timer groups, each containing two general-purpose hardware timers.

They are all 64-bit generic timers based on 16-bit prescalers and 64-bit auto-reload-capable up/down counters.


Application Example
-------------------

64-bit hardware timer example: `examples/13_timer_group <https://github.com/espressif/esp-idf/tree/master/examples/13_timer_group>`_.

API Reference
-------------

Header Files
^^^^^^^^^^^^

* `components/driver/timer.h <https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/timer.h>`_

Macros
^^^^^^

.. doxygendefine:: TIMER_BASE_CLK

Type Definitions
^^^^^^^^^^^^^^^^


Enumerations
^^^^^^^^^^^^

.. doxygenenum:: timer_group_t
.. doxygenenum:: timer_idx_t
.. doxygenenum:: timer_count_dir_t
.. doxygenenum:: timer_start_t
.. doxygenenum:: timer_alarm_t
.. doxygenenum:: timer_intr_mode_t
.. doxygenenum:: timer_autoreload_t

Structures
^^^^^^^^^^

.. doxygenstruct:: timer_config_t
:members:


Functions
^^^^^^^^^

.. doxygenfunction:: timer_get_counter_value
.. doxygenfunction:: timer_get_counter_time_sec
.. doxygenfunction:: timer_set_counter_value
.. doxygenfunction:: timer_start
.. doxygenfunction:: timer_pause
.. doxygenfunction:: timer_set_counter_mode
.. doxygenfunction:: timer_set_auto_reload
.. doxygenfunction:: timer_set_divider
.. doxygenfunction:: timer_set_alarm_value
.. doxygenfunction:: timer_get_alarm_value
.. doxygenfunction:: timer_set_alarm
.. doxygenfunction:: timer_isr_register
.. doxygenfunction:: timer_init
.. doxygenfunction:: timer_get_config
.. doxygenfunction:: timer_group_intr_enable
.. doxygenfunction:: timer_group_intr_disable
.. doxygenfunction:: timer_enable_intr
.. doxygenfunction:: timer_disable_intr

0 comments on commit c533099

Please sign in to comment.