ana_cmpr_example_etm.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "driver/gpio.h"
  10. #include "driver/ana_cmpr.h"
  11. #include "driver/ana_cmpr_etm.h"
  12. #include "driver/gpio_etm.h"
  13. #include "esp_etm.h"
  14. #include "esp_log.h"
  15. #include "ana_cmpr_example_main.h"
  16. static const char *TAG = "ana_cmpr_example";
  17. static void example_etm_bind_ana_cmpr_event_with_gpio_task(ana_cmpr_handle_t cmpr)
  18. {
  19. /* Allocate the analog comparator positive & negative cross events */
  20. esp_etm_event_handle_t cmpr_pos_evt = NULL;
  21. esp_etm_event_handle_t cmpr_neg_evt = NULL;
  22. ana_cmpr_etm_event_config_t evt_cfg = {
  23. .event_type = ANA_CMPR_EVENT_POS_CROSS,
  24. };
  25. ESP_ERROR_CHECK(ana_cmpr_new_etm_event(cmpr, &evt_cfg, &cmpr_pos_evt));
  26. evt_cfg.event_type = GPIO_ETM_EVENT_EDGE_NEG;
  27. ESP_ERROR_CHECK(ana_cmpr_new_etm_event(cmpr, &evt_cfg, &cmpr_neg_evt));
  28. /* Allocate the GPIO set & clear tasks */
  29. esp_etm_task_handle_t gpio_pos_task = NULL;
  30. esp_etm_task_handle_t gpio_neg_task = NULL;
  31. gpio_etm_task_config_t task_cfg = {
  32. .action = GPIO_ETM_TASK_ACTION_SET,
  33. };
  34. ESP_ERROR_CHECK(gpio_new_etm_task(&task_cfg, &gpio_pos_task));
  35. task_cfg.action = GPIO_ETM_TASK_ACTION_CLR;
  36. ESP_ERROR_CHECK(gpio_new_etm_task(&task_cfg, &gpio_neg_task));
  37. /* Add task to the monitor GPIO */
  38. ESP_ERROR_CHECK(gpio_etm_task_add_gpio(gpio_pos_task, EXAMPLE_MONITOR_GPIO_NUM));
  39. ESP_ERROR_CHECK(gpio_etm_task_add_gpio(gpio_neg_task, EXAMPLE_MONITOR_GPIO_NUM));
  40. /* Allocate the Event Task Matrix channels */
  41. esp_etm_channel_handle_t etm_pos_handle;
  42. esp_etm_channel_handle_t etm_neg_handle;
  43. esp_etm_channel_config_t etm_cfg = {};
  44. ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &etm_pos_handle));
  45. ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &etm_neg_handle));
  46. /* Bind the events and tasks */
  47. ESP_ERROR_CHECK(esp_etm_channel_connect(etm_pos_handle, cmpr_pos_evt, gpio_pos_task));
  48. ESP_ERROR_CHECK(esp_etm_channel_connect(etm_neg_handle, cmpr_neg_evt, gpio_neg_task));
  49. /* Enable the ETM channels */
  50. ESP_ERROR_CHECK(esp_etm_channel_enable(etm_pos_handle));
  51. ESP_ERROR_CHECK(esp_etm_channel_enable(etm_neg_handle));
  52. }
  53. ana_cmpr_handle_t example_init_analog_comparator_etm(void)
  54. {
  55. /* Step 0: Show the source channel and reference channel GPIO */
  56. int src_gpio = -1;
  57. int ext_ref_gpio = -1;
  58. ESP_ERROR_CHECK(ana_cmpr_get_gpio(EXAMPLE_ANA_CMPR_UNIT, ANA_CMPR_SOURCE_CHAN, &src_gpio));
  59. ESP_ERROR_CHECK(ana_cmpr_get_gpio(EXAMPLE_ANA_CMPR_UNIT, ANA_CMPR_EXT_REF_CHAN, &ext_ref_gpio));
  60. ESP_LOGI(TAG, "Analog Comparator source gpio %d, external reference gpio %d", src_gpio, ext_ref_gpio);
  61. ana_cmpr_handle_t cmpr = NULL;
  62. #if CONFIG_EXAMPLE_INTERNAL_REF
  63. /* Step 1: Allocate the new analog comparator unit */
  64. ana_cmpr_config_t config = {
  65. .unit = EXAMPLE_ANA_CMPR_UNIT,
  66. .clk_src = ANA_CMPR_CLK_SRC_DEFAULT,
  67. .ref_src = ANA_CMPR_REF_SRC_INTERNAL,
  68. .cross_type = ANA_CMPR_CROSS_ANY,
  69. };
  70. ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));
  71. ESP_LOGI(TAG, "Allocate Analog Comparator with internal reference");
  72. /* Step 1.1: As we are using the internal reference source, we need to configure the internal reference */
  73. ana_cmpr_internal_ref_config_t ref_cfg = {
  74. .ref_volt = ANA_CMPR_REF_VOLT_50_PCT_VDD,
  75. };
  76. ESP_ERROR_CHECK(ana_cmpr_set_internal_reference(cmpr, &ref_cfg));
  77. #else
  78. /* Step 1: Allocate the new analog comparator unit */
  79. ana_cmpr_config_t config = {
  80. .unit = EXAMPLE_ANA_CMPR_UNIT,
  81. .clk_src = ANA_CMPR_CLK_SRC_DEFAULT,
  82. .ref_src = ANA_CMPR_REF_SRC_EXTERNAL,
  83. .cross_type = ANA_CMPR_CROSS_ANY,
  84. };
  85. ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));
  86. ESP_LOGI(TAG, "Allocate Analog Comparator with external reference");
  87. #endif // CONFIG_EXAMPLE_INTERNAL_REF
  88. /* Step 2: (Optional) Set the debounce configuration
  89. * It's an optional configuration, if the wait time is set in debounce configuration,
  90. * the cross interrupt will be disabled temporary after it is triggered, and it will be enabled
  91. * automatically enabled after `wait_us`, so that the duplicate interrupts
  92. * can be suppressed while the source signal crossing the reference signal. */
  93. ana_cmpr_debounce_config_t dbc_cfg = {
  94. /* Normally the `wait_us` is related to the relative frequency between the source and reference signal
  95. * comparing to another one. This example adopts an approximate frequency as the relative signal
  96. * frequency, and set the default wait time to EXAMPLE_WAIT_TIME_PROP of the relative signal period.
  97. * We need to estimate an appropriate `freq_approx` and EXAMPLE_WAIT_TIME_PROP
  98. * to make sure the interrupt neither triggers duplicate interrupts, nor misses the next crossing interrupt.
  99. * Here we take 1 KHz for example */
  100. .wait_us = EXAMPLE_WAITE_TIME_US(1000),
  101. };
  102. ESP_ERROR_CHECK(ana_cmpr_set_debounce(cmpr, &dbc_cfg));
  103. /* Step 3: Enable the analog comparator unit */
  104. ESP_ERROR_CHECK(ana_cmpr_enable(cmpr));
  105. #if CONFIG_EXAMPLE_INTERNAL_REF
  106. ESP_LOGI(TAG, "Analog comparator enabled, reference voltage: %d%% * VDD", (int)ref_cfg.ref_volt * 10);
  107. #else
  108. ESP_LOGI(TAG, "Analog comparator enabled, external reference selected");
  109. #endif
  110. return cmpr;
  111. }
  112. void example_analog_comparator_etm_app(void)
  113. {
  114. /* Initialize GPIO to monitor the comparator interrupt */
  115. example_init_monitor_gpio();
  116. /* Initialize Analog Comparator */
  117. ana_cmpr_handle_t cmpr = example_init_analog_comparator_etm();
  118. /* Connect the analog comparator events and gpio tasks via ETM channels */
  119. example_etm_bind_ana_cmpr_event_with_gpio_task(cmpr);
  120. }