1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #pragma once
7 
8 #include <stdint.h>
9 #include "esp_err.h"
10 #include "esp_etm.h"
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /**
17  * @brief GPIO edges that can be used as ETM event
18  */
19 typedef enum {
20     GPIO_ETM_EVENT_EDGE_POS, /*!< A rising edge on the GPIO will generate an ETM event signal */
21     GPIO_ETM_EVENT_EDGE_NEG, /*!< A falling edge on the GPIO will generate an ETM event signal */
22     GPIO_ETM_EVENT_EDGE_ANY, /*!< Any edge on the GPIO can generate an ETM event signal */
23 } gpio_etm_event_edge_t;
24 
25 /**
26  * @brief GPIO ETM event configuration
27  */
28 typedef struct {
29     gpio_etm_event_edge_t edge; /*!< Which kind of edge can trigger the ETM event module */
30 } gpio_etm_event_config_t;
31 
32 /**
33  * @brief Create an ETM event object for the GPIO peripheral
34  *
35  * @note The created ETM event object can be deleted later by calling `esp_etm_del_event`
36  * @note The newly created ETM event object is not bind to any GPIO, you need to call `gpio_etm_event_bind_gpio` to bind the wanted GPIO
37  *
38  * @param[in] config GPIO ETM event configuration
39  * @param[out] ret_event Returned ETM event handle
40  * @return
41  *      - ESP_OK: Create ETM event successfully
42  *      - ESP_ERR_INVALID_ARG: Create ETM event failed because of invalid argument
43  *      - ESP_ERR_NO_MEM: Create ETM event failed because of out of memory
44  *      - ESP_ERR_NOT_FOUND: Create ETM event failed because all events are used up and no more free one
45  *      - ESP_FAIL: Create ETM event failed because of other reasons
46  */
47 esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event);
48 
49 /**
50  * @brief Bind the GPIO with the ETM event
51  *
52  * @note Calling this function multiple times with different GPIO number can override the previous setting immediately.
53  * @note Only GPIO ETM object can call this function
54  *
55  * @param[in] event ETM event handle that created by `gpio_new_etm_event`
56  * @param[in] gpio_num GPIO number that can trigger the ETM event
57  * @return
58  *      - ESP_OK: Set the GPIO for ETM event successfully
59  *      - ESP_ERR_INVALID_ARG: Set the GPIO for ETM event failed because of invalid argument, e.g. GPIO is not input capable, ETM event is not of GPIO type
60  *      - ESP_FAIL: Set the GPIO for ETM event failed because of other reasons
61  */
62 esp_err_t gpio_etm_event_bind_gpio(esp_etm_event_handle_t event, int gpio_num);
63 
64 /**
65  * @brief GPIO actions that can be taken by the ETM task
66  */
67 typedef enum {
68     GPIO_ETM_TASK_ACTION_SET, /*!< Set the GPIO level to high */
69     GPIO_ETM_TASK_ACTION_CLR, /*!< Clear the GPIO level to low */
70     GPIO_ETM_TASK_ACTION_TOG, /*!< Toggle the GPIO level */
71 } gpio_etm_task_action_t;
72 
73 /**
74  * @brief GPIO ETM task configuration
75  */
76 typedef struct {
77     gpio_etm_task_action_t action; /*!< Which action to take by the ETM task module */
78 } gpio_etm_task_config_t;
79 
80 /**
81  * @brief Create an ETM task object for the GPIO peripheral
82  *
83  * @note The created ETM task object can be deleted later by calling `esp_etm_del_task`
84  * @note The GPIO ETM task works like a container, a newly created ETM task object doesn't have GPIO members to be managed.
85  *       You need to call `gpio_etm_task_add_gpio` to put one or more GPIOs to the container.
86  *
87  * @param[in] config GPIO ETM task configuration
88  * @param[out] ret_task Returned ETM task handle
89  * @return
90  *      - ESP_OK: Create ETM task successfully
91  *      - ESP_ERR_INVALID_ARG: Create ETM task failed because of invalid argument
92  *      - ESP_ERR_NO_MEM: Create ETM task failed because of out of memory
93  *      - ESP_ERR_NOT_FOUND: Create ETM task failed because all tasks are used up and no more free one
94  *      - ESP_FAIL: Create ETM task failed because of other reasons
95  */
96 esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task);
97 
98 /**
99  * @brief Add GPIO to the ETM task.
100  *
101  * @note You can call this function multiple times to add more GPIOs
102  * @note Only GPIO ETM object can call this function
103  *
104  * @param[in] task ETM task handle that created by `gpio_new_etm_task`
105  * @param[in] gpio_num GPIO number that can be controlled by the ETM task
106  * @return
107  *      - ESP_OK: Add GPIO to the ETM task successfully
108  *      - ESP_ERR_INVALID_ARG: Add GPIO to the ETM task failed because of invalid argument, e.g. GPIO is not output capable, ETM task is not of GPIO type
109  *      - ESP_ERR_INVALID_STATE: Add GPIO to the ETM task failed because the GPIO is used by other ETM task already
110  *      - ESP_FAIL: Add GPIO to the ETM task failed because of other reasons
111  */
112 esp_err_t gpio_etm_task_add_gpio(esp_etm_task_handle_t task, int gpio_num);
113 
114 /**
115  * @brief Remove the GPIO from the ETM task
116  *
117  * @note Before deleting the ETM task, you need to remove all the GPIOs from the ETM task by this function
118  * @note Only GPIO ETM object can call this function
119  *
120  * @param[in] task ETM task handle that created by `gpio_new_etm_task`
121  * @param[in] gpio_num GPIO number that to be remove from the ETM task
122  * @return
123  *      - ESP_OK: Remove the GPIO from the ETM task successfully
124  *      - ESP_ERR_INVALID_ARG: Remove the GPIO from the ETM task failed because of invalid argument
125  *      - ESP_ERR_INVALID_STATE: Remove the GPIO from the ETM task failed because the GPIO is not controlled by this ETM task
126  *      - ESP_FAIL: Remove the GPIO from the ETM task failed because of other reasons
127  */
128 esp_err_t gpio_etm_task_rm_gpio(esp_etm_task_handle_t task, int gpio_num);
129 
130 #ifdef __cplusplus
131 }
132 #endif
133