1 /* 2 * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #include <stdint.h> 10 #include <stdbool.h> 11 #include "esp_err.h" 12 #include "esp_attr.h" 13 #include "soc/soc_caps.h" 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /** 20 * @brief Type of Dedicated GPIO bundle 21 */ 22 typedef struct dedic_gpio_bundle_t *dedic_gpio_bundle_handle_t; 23 24 /** 25 * @brief Type of Dedicated GPIO bundle configuration 26 */ 27 typedef struct { 28 const int *gpio_array; /*!< Array of GPIO numbers, gpio_array[0] ~ gpio_array[size-1] <=> low_dedic_channel_num ~ high_dedic_channel_num */ 29 size_t array_size; /*!< Number of GPIOs in gpio_array */ 30 struct { 31 unsigned int in_en: 1; /*!< Enable input */ 32 unsigned int in_invert: 1; /*!< Invert input signal */ 33 unsigned int out_en: 1; /*!< Enable output */ 34 unsigned int out_invert: 1; /*!< Invert output signal */ 35 } flags; /*!< Flags to control specific behaviour of GPIO bundle */ 36 } dedic_gpio_bundle_config_t; 37 38 /** 39 * @brief Create GPIO bundle and return the handle 40 * 41 * @param[in] config Configuration of GPIO bundle 42 * @param[out] ret_bundle Returned handle of the new created GPIO bundle 43 * @return 44 * - ESP_OK: Create GPIO bundle successfully 45 * - ESP_ERR_INVALID_ARG: Create GPIO bundle failed because of invalid argument 46 * - ESP_ERR_NO_MEM: Create GPIO bundle failed because of no capable memory 47 * - ESP_ERR_NOT_FOUND: Create GPIO bundle failed because of no enough continuous dedicated channels 48 * - ESP_FAIL: Create GPIO bundle failed because of other error 49 * 50 * @note One has to enable at least input or output mode in "config" parameter. 51 */ 52 esp_err_t dedic_gpio_new_bundle(const dedic_gpio_bundle_config_t *config, dedic_gpio_bundle_handle_t *ret_bundle); 53 54 /** 55 * @brief Destroy GPIO bundle 56 * 57 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 58 * @return 59 * - ESP_OK: Destroy GPIO bundle successfully 60 * - ESP_ERR_INVALID_ARG: Destroy GPIO bundle failed because of invalid argument 61 * - ESP_FAIL: Destroy GPIO bundle failed because of other error 62 */ 63 esp_err_t dedic_gpio_del_bundle(dedic_gpio_bundle_handle_t bundle); 64 65 /**@{*/ 66 /** 67 * @brief Get allocated channel mask 68 * 69 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 70 * @param[out] mask Returned mask value for on specific direction (in or out) 71 * @return 72 * - ESP_OK: Get channel mask successfully 73 * - ESP_ERR_INVALID_ARG: Get channel mask failed because of invalid argument 74 * - ESP_FAIL: Get channel mask failed because of other error 75 * 76 * @note Each bundle should have at least one mask (in or/and out), based on bundle configuration. 77 * @note With the returned mask, user can directly invoke LL function like "dedic_gpio_cpu_ll_write_mask" 78 * or write assembly code with dedicated GPIO instructions, to get better performance on GPIO manipulation. 79 */ 80 esp_err_t dedic_gpio_get_out_mask(dedic_gpio_bundle_handle_t bundle, uint32_t *mask); 81 esp_err_t dedic_gpio_get_in_mask(dedic_gpio_bundle_handle_t bundle, uint32_t *mask); 82 /**@}*/ 83 84 /**@{*/ 85 /** 86 * @brief Get the channel offset of the GPIO bundle 87 * 88 * A GPIO bundle maps the GPIOS of a particular direction to a consecutive set of channels within 89 * a particular GPIO bank of a particular CPU. This function returns the offset to 90 * the bundle's first channel of a particular direction within the bank. 91 * 92 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 93 * @param[out] offset Offset value to the first channel of a specific direction (in or out) 94 * @return 95 * - ESP_OK: Get channel offset successfully 96 * - ESP_ERR_INVALID_ARG: Get channel offset failed because of invalid argument 97 * - ESP_FAIL: Get channel offset failed because of other error 98 */ 99 esp_err_t dedic_gpio_get_out_offset(dedic_gpio_bundle_handle_t bundle, uint32_t *offset); 100 esp_err_t dedic_gpio_get_in_offset(dedic_gpio_bundle_handle_t bundle, uint32_t *offset); 101 /**@}*/ 102 103 /** 104 * @brief Write value to GPIO bundle 105 * 106 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 107 * @param[in] mask Mask of the GPIOs to be written in the given bundle 108 * @param[in] value Value to write to given GPIO bundle, low bit represents low member in the bundle 109 * 110 * @note The mask is seen from the view of GPIO bundle. 111 * For example, bundleA contains [GPIO10, GPIO12, GPIO17], to set GPIO17 individually, the mask should be 0x04. 112 * @note For performance reasons, this function doesn't check the validity of any parameters, and is placed in IRAM. 113 */ 114 void dedic_gpio_bundle_write(dedic_gpio_bundle_handle_t bundle, uint32_t mask, uint32_t value) IRAM_ATTR; 115 116 /** 117 * @brief Read the value that output from the given GPIO bundle 118 * 119 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 120 * @return Value that output from the GPIO bundle, low bit represents low member in the bundle 121 * 122 * @note For performance reasons, this function doesn't check the validity of any parameters, and is placed in IRAM. 123 */ 124 uint32_t dedic_gpio_bundle_read_out(dedic_gpio_bundle_handle_t bundle) IRAM_ATTR; 125 126 /** 127 * @brief Read the value that input to the given GPIO bundle 128 * 129 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 130 * @return Value that input to the GPIO bundle, low bit represents low member in the bundle 131 * 132 * @note For performance reasons, this function doesn't check the validity of any parameters, and is placed in IRAM. 133 */ 134 uint32_t dedic_gpio_bundle_read_in(dedic_gpio_bundle_handle_t bundle) IRAM_ATTR; 135 136 #if SOC_DEDIC_GPIO_HAS_INTERRUPT 137 138 /** 139 * @brief Supported type of dedicated GPIO interrupt 140 */ 141 typedef enum { 142 DEDIC_GPIO_INTR_NONE, /*!< No interrupt */ 143 DEDIC_GPIO_INTR_LOW_LEVEL = 2, /*!< Interrupt on low level */ 144 DEDIC_GPIO_INTR_HIGH_LEVEL, /*!< Interrupt on high level */ 145 DEDIC_GPIO_INTR_NEG_EDGE, /*!< Interrupt on negedge */ 146 DEDIC_GPIO_INTR_POS_EDGE, /*!< Interrupt on posedge */ 147 DEDIC_GPIO_INTR_BOTH_EDGE /*!< Interrupt on both negedge and posedge */ 148 } dedic_gpio_intr_type_t; 149 150 /** 151 * @brief Type of dedicated GPIO ISR callback function 152 * 153 * @param bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 154 * @param index Index of the GPIO in its corresponding bundle (count from 0) 155 * @param args User defined arguments for the callback function. It's passed through `dedic_gpio_bundle_set_interrupt_and_callback` 156 * @return If a high priority task is woken up by the callback function 157 */ 158 typedef bool (*dedic_gpio_isr_callback_t)(dedic_gpio_bundle_handle_t bundle, uint32_t index, void *args); 159 160 /** 161 * @brief Set interrupt and callback function for GPIO bundle 162 * 163 * @param[in] bundle Handle of GPIO bundle that returned from "dedic_gpio_new_bundle" 164 * @param[in] mask Mask of the GPIOs in the given bundle 165 * @param[in] intr_type Interrupt type, set to DEDIC_GPIO_INTR_NONE can disable interrupt 166 * @param[in] cb_isr Callback function, which got invoked in ISR context. A NULL pointer here will bypass the callback 167 * @param[in] cb_args User defined argument to be passed to the callback function 168 * 169 * @note This function is only valid for bundle with input mode enabled. See "dedic_gpio_bundle_config_t" 170 * @note The mask is seen from the view of GPIO Bundle. 171 * For example, bundleA contains [GPIO10, GPIO12, GPIO17], to set GPIO17 individually, the mask should be 0x04. 172 * 173 * @return 174 * - ESP_OK: Set GPIO interrupt and callback function successfully 175 * - ESP_ERR_INVALID_ARG: Set GPIO interrupt and callback function failed because of invalid argument 176 * - ESP_FAIL: Set GPIO interrupt and callback function failed because of other error 177 */ 178 esp_err_t dedic_gpio_bundle_set_interrupt_and_callback(dedic_gpio_bundle_handle_t bundle, uint32_t mask, dedic_gpio_intr_type_t intr_type, dedic_gpio_isr_callback_t cb_isr, void *cb_args); 179 180 #endif // SOC_DEDIC_GPIO_HAS_INTERRUPT 181 182 #ifdef __cplusplus 183 } 184 #endif 185