]> granicus.if.org Git - esp-idf/commitdiff
driver: timer
authorWangjialin <wangjialin@espressif.com>
Wed, 23 Nov 2016 09:23:21 +0000 (17:23 +0800)
committerWangjialin <wangjialin@espressif.com>
Wed, 23 Nov 2016 09:23:21 +0000 (17:23 +0800)
1. minor modifications
2. use TIMG_WDT_INT_ENA_M instead of BIT(2) in wdt.c
3. add doc/api/timer.rst

components/driver/include/driver/timer.h
components/driver/timer.c
components/esp32/int_wdt.c
components/esp32/task_wdt.c
docs/api/timer.rst [new file with mode: 0644]

index cdd129276ddf9bdee36da1bbf76c2a8b2f3d8ba3..c0ad7116e400e6b1a1923d783aecb3b57441bb8d 100644 (file)
@@ -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;
@@ -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;
 
 /**
@@ -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
@@ -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
@@ -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
index ac0a4a377f69b84c72b26a1422583236aa82799d..b305a414686a87e694a68d67a03f3a65b783e807 100644 (file)
@@ -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);\r
     TIMER_CHECK(time != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);\r
 \r
-    portENTER_CRITICAL(&timer_spinlock[group_num]);\r
-    TG[group_num]->hw_timer[timer_num].update = 1;\r
-    uint64_t timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32)\r
-                | (TG[group_num]->hw_timer[timer_num].cnt_low);\r
-    uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider;\r
-    *time = (double)timer_val * div / TIMER_BASE_CLK;\r
-    portEXIT_CRITICAL(&timer_spinlock[group_num]);\r
-    return ESP_OK;\r
+    uint64_t timer_val;\r
+    esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val);\r
+    if (err == ESP_OK) {\r
+        uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider;\r
+        *time = (double)timer_val * div / TIMER_BASE_CLK;\r
+    }\r
+    return err;\r
 }\r
 \r
 esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val)\r
index fe3ddab370705383520401f9cd79d7302c196e35..9d9bbe94c4c5d4b1b4983b22302d510f38a96adf 100644 (file)
@@ -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"
 
@@ -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);
@@ -97,4 +98,4 @@ void esp_int_wdt_init() {
 
 
 
-#endif
\ No newline at end of file
+#endif
index 718f7e3d259025a20a63d25d4b0cd5c452ec0da9..860556b8c5034599f41545d8ead1d91575a34f73 100644 (file)
@@ -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);
 }
 
diff --git a/docs/api/timer.rst b/docs/api/timer.rst
new file mode 100644 (file)
index 0000000..0db0a12
--- /dev/null
@@ -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
+