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