timer.rst 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. TIMER
  2. =====
  3. Introduction
  4. ------------
  5. The ESP32 chip contains two hardware timer groups. Each group has 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.
  6. Functional Overview
  7. -------------------
  8. Typical steps to configure an operate the timer are described in the following sections:
  9. * :ref:`timer-api-timer-initialization` - what parameters should be set up to get the timer working and what specific functionality is provided depending on the set up.
  10. * :ref:`timer-api-timer-control` - how to read the timer's value, pause / start the timer, and change how it operates.
  11. * :ref:`timer-api-alarms` - setting and using alarms.
  12. * :ref:`timer-api-interrupts`- how to enable and use interrupts.
  13. .. _timer-api-timer-initialization:
  14. Timer Initialization
  15. ^^^^^^^^^^^^^^^^^^^^
  16. The two timer groups on-board of the ESP32 are identified using :cpp:type:`timer_group_t`. Individual timers in a group are identified with :cpp:type:`timer_idx_t`. The two groups, each having two timers, provide the total of four individual timers to our disposal.
  17. Before starting the timer, it should be initialized by calling :cpp:func:`timer_init`. This function should be provided with a structure :cpp:type:`timer_config_t` to define how timer should operate. In particular the following timer's parameters may be set:
  18. * **Divider**: How quickly the timer's counter is "ticking". This depends on the setting of :cpp:member:`divider`, that will be used as divisor of the incoming 80 MHz APB_CLK clock.
  19. * **Mode**: If the the counter is incrementing or decrementing, defined using :cpp:member:`counter_dir` by selecting one of values from :cpp:type:`timer_count_dir_t`.
  20. * **Counter Enable**: If the counter is enabled, then it will start incrementing / decrementing immediately after calling :cpp:func:`timer_init`. This action is set using :cpp:member:`counter_en` by selecting one of vales from :cpp:type:`timer_start_t`.
  21. * **Alarm Enable**: Determined by the setting of :cpp:member:`alarm_en`.
  22. * **Auto Reload**: Whether the counter should :cpp:member:`auto_reload` a specific initial value on the timer's alarm, or continue incrementing or decrementing.
  23. * **Interrupt Type**: Whether an interrupt is triggered on timer's alarm. Set the value defined in :cpp:type:`timer_intr_mode_t`.
  24. To get the current values of the timers settings, use function :cpp:func:`timer_get_config`.
  25. .. _timer-api-timer-control:
  26. Timer Control
  27. ^^^^^^^^^^^^^
  28. Once the timer is configured and enabled, it is already "ticking". To check it's current value call :cpp:func:`timer_get_counter_value` or :cpp:func:`timer_get_counter_time_sec`. To set the timer to specific starting value call :cpp:func:`timer_set_counter_value`.
  29. The timer may be paused at any time by calling :cpp:func:`timer_pause`. To start it again call :cpp:func:`timer_start`.
  30. To change how the timer operates you can call once more :cpp:func:`timer_init` described in section :ref:`timer-api-timer-initialization`. Another option is to use dedicated functions to change individual settings:
  31. * **Divider** value - :cpp:func:`timer_set_divider`. **Note:** the timer should be paused when changing the divider to avoid unpredictable results. If the timer is already running, :cpp:func:`timer_set_divider` will first pause the timer, change the divider, and finally start the timer again.
  32. * **Mode** (whether the counter incrementing or decrementing) - :cpp:func:`timer_set_counter_mode`
  33. * **Auto Reload** counter on alarm - :cpp:func:`timer_set_auto_reload`
  34. .. _timer-api-alarms:
  35. Alarms
  36. ^^^^^^
  37. To set an alarm, call function :cpp:func:`timer_set_alarm_value` and then enable it with :cpp:func:`timer_set_alarm`. The alarm may be also enabled during the timer initialization stage, when :cpp:func:`timer_init` is called.
  38. After the alarm is enabled and the timer reaches the alarm value, depending on configuration, the following two actions may happen:
  39. * An interrupt will be triggered, if previously configured. See section :ref:`timer-api-interrupts` how to configure interrupts.
  40. * When :cpp:member:`auto_reload` is enabled, the timer's counter will be reloaded to start counting from specific initial value. The value to start should be set in advance with :cpp:func:`timer_set_counter_value`.
  41. .. note::
  42. The alarm will be triggered immediately, if an alarm value is set and the timer has already passed this value.
  43. To check what alarm value has been set up, call :cpp:func:`timer_get_alarm_value`.
  44. .. _timer-api-interrupts:
  45. Interrupts
  46. ^^^^^^^^^^
  47. Registration of the interrupt handler for a specific timer group and timer is done be calling :cpp:func:`timer_isr_register`.
  48. To enable interrupts for a timer group call :cpp:func:`timer_group_intr_enable`. To do it for a specific timer, call :cpp:func:`timer_enable_intr`. Disabling of interrupts is done with corresponding functions :cpp:func:`timer_group_intr_disable` and :cpp:func:`timer_disable_intr`.
  49. When servicing an interrupt within an ISR, the interrupt need to explicitly cleared. To do so, set the ``TIMERGN.int_clr_timers.tM`` structure defined in :component_file:`soc/esp32/include/soc/timer_group_struct.h`, where N is the timer group number [0, 1] and M is the timer number [0, 1]. For example to clear an interrupt for the timer 1 in the timer group 0, call the following::
  50. TIMERG0.int_clr_timers.t1 = 1
  51. See the application example below how to use interrupts.
  52. Application Example
  53. -------------------
  54. The 64-bit hardware timer example: :example:`peripherals/timer_group`.
  55. API Reference
  56. -------------
  57. .. include:: /_build/inc/timer.inc