// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "soc/gpio_periph.h"
#include "soc/gpio_caps.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    GPIO_PORT_0 = 0,
    GPIO_PORT_MAX,
} gpio_port_t;

#define GPIO_SEL_0              (BIT(0))                         /*!< Pin 0 selected */
#define GPIO_SEL_1              (BIT(1))                         /*!< Pin 1 selected */
#define GPIO_SEL_2              (BIT(2))                         /*!< Pin 2 selected */
#define GPIO_SEL_3              (BIT(3))                         /*!< Pin 3 selected */
#define GPIO_SEL_4              (BIT(4))                         /*!< Pin 4 selected */
#define GPIO_SEL_5              (BIT(5))                         /*!< Pin 5 selected */
#define GPIO_SEL_6              (BIT(6))                         /*!< Pin 6 selected */
#define GPIO_SEL_7              (BIT(7))                         /*!< Pin 7 selected */
#define GPIO_SEL_8              (BIT(8))                         /*!< Pin 8 selected */
#define GPIO_SEL_9              (BIT(9))                         /*!< Pin 9 selected */
#define GPIO_SEL_10             (BIT(10))                        /*!< Pin 10 selected */
#define GPIO_SEL_11             (BIT(11))                        /*!< Pin 11 selected */
#define GPIO_SEL_12             (BIT(12))                        /*!< Pin 12 selected */
#define GPIO_SEL_13             (BIT(13))                        /*!< Pin 13 selected */
#define GPIO_SEL_14             (BIT(14))                        /*!< Pin 14 selected */
#define GPIO_SEL_15             (BIT(15))                        /*!< Pin 15 selected */
#define GPIO_SEL_16             (BIT(16))                        /*!< Pin 16 selected */
#define GPIO_SEL_17             (BIT(17))                        /*!< Pin 17 selected */
#define GPIO_SEL_18             (BIT(18))                        /*!< Pin 18 selected */
#define GPIO_SEL_19             (BIT(19))                        /*!< Pin 19 selected */
#define GPIO_SEL_20             (BIT(20))                        /*!< Pin 20 selected */
#define GPIO_SEL_21             (BIT(21))                        /*!< Pin 21 selected */
#if CONFIG_IDF_TARGET_ESP32
#define GPIO_SEL_22             (BIT(22))                        /*!< Pin 22 selected */
#define GPIO_SEL_23             (BIT(23))                        /*!< Pin 23 selected */

#define GPIO_SEL_25             (BIT(25))                        /*!< Pin 25 selected */
#endif
#define GPIO_SEL_26             (BIT(26))                        /*!< Pin 26 selected */
#define GPIO_SEL_27             (BIT(27))                        /*!< Pin 27 selected */
#define GPIO_SEL_28             (BIT(28))                        /*!< Pin 28 selected */
#define GPIO_SEL_29             (BIT(29))                        /*!< Pin 29 selected */
#define GPIO_SEL_30             (BIT(30))                        /*!< Pin 30 selected */
#define GPIO_SEL_31             (BIT(31))                        /*!< Pin 31 selected */
#define GPIO_SEL_32             ((uint64_t)(((uint64_t)1)<<32))  /*!< Pin 32 selected */
#define GPIO_SEL_33             ((uint64_t)(((uint64_t)1)<<33))  /*!< Pin 33 selected */
#define GPIO_SEL_34             ((uint64_t)(((uint64_t)1)<<34))  /*!< Pin 34 selected */
#define GPIO_SEL_35             ((uint64_t)(((uint64_t)1)<<35))  /*!< Pin 35 selected */
#define GPIO_SEL_36             ((uint64_t)(((uint64_t)1)<<36))  /*!< Pin 36 selected */
#define GPIO_SEL_37             ((uint64_t)(((uint64_t)1)<<37))  /*!< Pin 37 selected */
#define GPIO_SEL_38             ((uint64_t)(((uint64_t)1)<<38))  /*!< Pin 38 selected */
#define GPIO_SEL_39             ((uint64_t)(((uint64_t)1)<<39))  /*!< Pin 39 selected */
#if GPIO_PIN_COUNT > 40
#define GPIO_SEL_40             ((uint64_t)(((uint64_t)1)<<40))  /*!< Pin 40 selected */
#define GPIO_SEL_41             ((uint64_t)(((uint64_t)1)<<41))  /*!< Pin 41 selected */
#define GPIO_SEL_42             ((uint64_t)(((uint64_t)1)<<42))  /*!< Pin 42 selected */
#define GPIO_SEL_43             ((uint64_t)(((uint64_t)1)<<43))  /*!< Pin 43 selected */
#define GPIO_SEL_44             ((uint64_t)(((uint64_t)1)<<44))  /*!< Pin 44 selected */
#define GPIO_SEL_45             ((uint64_t)(((uint64_t)1)<<45))  /*!< Pin 45 selected */
#define GPIO_SEL_46             ((uint64_t)(((uint64_t)1)<<46))  /*!< Pin 46 selected */
#endif

#define GPIO_PIN_REG_0          IO_MUX_GPIO0_REG
#define GPIO_PIN_REG_1          IO_MUX_GPIO1_REG
#define GPIO_PIN_REG_2          IO_MUX_GPIO2_REG
#define GPIO_PIN_REG_3          IO_MUX_GPIO3_REG
#define GPIO_PIN_REG_4          IO_MUX_GPIO4_REG
#define GPIO_PIN_REG_5          IO_MUX_GPIO5_REG
#define GPIO_PIN_REG_6          IO_MUX_GPIO6_REG
#define GPIO_PIN_REG_7          IO_MUX_GPIO7_REG
#define GPIO_PIN_REG_8          IO_MUX_GPIO8_REG
#define GPIO_PIN_REG_9          IO_MUX_GPIO9_REG
#define GPIO_PIN_REG_10          IO_MUX_GPIO10_REG
#define GPIO_PIN_REG_11          IO_MUX_GPIO11_REG
#define GPIO_PIN_REG_12          IO_MUX_GPIO12_REG
#define GPIO_PIN_REG_13          IO_MUX_GPIO13_REG
#define GPIO_PIN_REG_14          IO_MUX_GPIO14_REG
#define GPIO_PIN_REG_15          IO_MUX_GPIO15_REG
#define GPIO_PIN_REG_16          IO_MUX_GPIO16_REG
#define GPIO_PIN_REG_17          IO_MUX_GPIO17_REG
#define GPIO_PIN_REG_18          IO_MUX_GPIO18_REG
#define GPIO_PIN_REG_19          IO_MUX_GPIO19_REG
#define GPIO_PIN_REG_20          IO_MUX_GPIO20_REG
#define GPIO_PIN_REG_21          IO_MUX_GPIO21_REG
#define GPIO_PIN_REG_22          IO_MUX_GPIO22_REG
#define GPIO_PIN_REG_23          IO_MUX_GPIO23_REG
#define GPIO_PIN_REG_24          IO_MUX_GPIO24_REG
#define GPIO_PIN_REG_25          IO_MUX_GPIO25_REG
#define GPIO_PIN_REG_26          IO_MUX_GPIO26_REG
#define GPIO_PIN_REG_27          IO_MUX_GPIO27_REG
#if CONFIG_IDF_TARGET_ESP32S2
#define GPIO_PIN_REG_28          IO_MUX_GPIO28_REG
#define GPIO_PIN_REG_29          IO_MUX_GPIO29_REG
#define GPIO_PIN_REG_30          IO_MUX_GPIO30_REG
#define GPIO_PIN_REG_31          IO_MUX_GPIO31_REG
#endif
#define GPIO_PIN_REG_32          IO_MUX_GPIO32_REG
#define GPIO_PIN_REG_33          IO_MUX_GPIO33_REG
#define GPIO_PIN_REG_34          IO_MUX_GPIO34_REG
#define GPIO_PIN_REG_35          IO_MUX_GPIO35_REG
#define GPIO_PIN_REG_36          IO_MUX_GPIO36_REG
#define GPIO_PIN_REG_37          IO_MUX_GPIO37_REG
#define GPIO_PIN_REG_38          IO_MUX_GPIO38_REG
#define GPIO_PIN_REG_39          IO_MUX_GPIO39_REG
#if GPIO_PIN_COUNT > 40
#define GPIO_PIN_REG_40          IO_MUX_GPIO40_REG
#define GPIO_PIN_REG_41          IO_MUX_GPIO41_REG
#define GPIO_PIN_REG_42          IO_MUX_GPIO42_REG
#define GPIO_PIN_REG_43          IO_MUX_GPIO43_REG
#define GPIO_PIN_REG_44          IO_MUX_GPIO44_REG
#define GPIO_PIN_REG_45          IO_MUX_GPIO45_REG
#define GPIO_PIN_REG_46          IO_MUX_GPIO46_REG
#endif

typedef enum {
    GPIO_NUM_NC = -1,    /*!< Use to signal not connected to S/W */
    GPIO_NUM_0 = 0,     /*!< GPIO0, input and output */
    GPIO_NUM_1 = 1,     /*!< GPIO1, input and output */
    GPIO_NUM_2 = 2,     /*!< GPIO2, input and output */
    GPIO_NUM_3 = 3,     /*!< GPIO3, input and output */
    GPIO_NUM_4 = 4,     /*!< GPIO4, input and output */
    GPIO_NUM_5 = 5,     /*!< GPIO5, input and output */
    GPIO_NUM_6 = 6,     /*!< GPIO6, input and output */
    GPIO_NUM_7 = 7,     /*!< GPIO7, input and output */
    GPIO_NUM_8 = 8,     /*!< GPIO8, input and output */
    GPIO_NUM_9 = 9,     /*!< GPIO9, input and output */
    GPIO_NUM_10 = 10,   /*!< GPIO10, input and output */
    GPIO_NUM_11 = 11,   /*!< GPIO11, input and output */
    GPIO_NUM_12 = 12,   /*!< GPIO12, input and output */
    GPIO_NUM_13 = 13,   /*!< GPIO13, input and output */
    GPIO_NUM_14 = 14,   /*!< GPIO14, input and output */
    GPIO_NUM_15 = 15,   /*!< GPIO15, input and output */
    GPIO_NUM_16 = 16,   /*!< GPIO16, input and output */
    GPIO_NUM_17 = 17,   /*!< GPIO17, input and output */
    GPIO_NUM_18 = 18,   /*!< GPIO18, input and output */
    GPIO_NUM_19 = 19,   /*!< GPIO19, input and output */
    GPIO_NUM_20 = 20,   /*!< GPIO20, input and output */
    GPIO_NUM_21 = 21,   /*!< GPIO21, input and output */
#if CONFIG_IDF_TARGET_ESP32
    GPIO_NUM_22 = 22,   /*!< GPIO22, input and output */
    GPIO_NUM_23 = 23,   /*!< GPIO23, input and output */

    GPIO_NUM_25 = 25,   /*!< GPIO25, input and output */
#endif
    /* Note: The missing IO is because it is used inside the chip. */
    GPIO_NUM_26 = 26,   /*!< GPIO26, input and output */
    GPIO_NUM_27 = 27,   /*!< GPIO27, input and output */
    GPIO_NUM_28 = 28,   /*!< GPIO28, input and output */
    GPIO_NUM_29 = 29,   /*!< GPIO29, input and output */
    GPIO_NUM_30 = 30,   /*!< GPIO30, input and output */
    GPIO_NUM_31 = 31,   /*!< GPIO31, input and output */
    GPIO_NUM_32 = 32,   /*!< GPIO32, input and output */
    GPIO_NUM_33 = 33,   /*!< GPIO33, input and output */
    GPIO_NUM_34 = 34,   /*!< GPIO34, input mode only(ESP32) / input and output(ESP32-S2) */
    GPIO_NUM_35 = 35,   /*!< GPIO35, input mode only(ESP32) / input and output(ESP32-S2) */
    GPIO_NUM_36 = 36,   /*!< GPIO36, input mode only(ESP32) / input and output(ESP32-S2) */
    GPIO_NUM_37 = 37,   /*!< GPIO37, input mode only(ESP32) / input and output(ESP32-S2) */
    GPIO_NUM_38 = 38,   /*!< GPIO38, input mode only(ESP32) / input and output(ESP32-S2) */
    GPIO_NUM_39 = 39,   /*!< GPIO39, input mode only(ESP32) / input and output(ESP32-S2) */
#if GPIO_PIN_COUNT > 40
    GPIO_NUM_40 = 40,   /*!< GPIO40, input and output */
    GPIO_NUM_41 = 41,   /*!< GPIO41, input and output */
    GPIO_NUM_42 = 42,   /*!< GPIO42, input and output */
    GPIO_NUM_43 = 43,   /*!< GPIO43, input and output */
    GPIO_NUM_44 = 44,   /*!< GPIO44, input and output */
    GPIO_NUM_45 = 45,   /*!< GPIO45, input and output */
    GPIO_NUM_46 = 46,   /*!< GPIO46, input mode only */
#endif
    GPIO_NUM_MAX,
/** @endcond */
} gpio_num_t;

typedef enum {
    GPIO_INTR_DISABLE = 0,     /*!< Disable GPIO interrupt                             */
    GPIO_INTR_POSEDGE = 1,     /*!< GPIO interrupt type : rising edge                  */
    GPIO_INTR_NEGEDGE = 2,     /*!< GPIO interrupt type : falling edge                 */
    GPIO_INTR_ANYEDGE = 3,     /*!< GPIO interrupt type : both rising and falling edge */
    GPIO_INTR_LOW_LEVEL = 4,   /*!< GPIO interrupt type : input low level trigger      */
    GPIO_INTR_HIGH_LEVEL = 5,  /*!< GPIO interrupt type : input high level trigger     */
    GPIO_INTR_MAX,
} gpio_int_type_t;

typedef enum {
    GPIO_MODE_DISABLE = GPIO_MODE_DEF_DISABLE,                                                         /*!< GPIO mode : disable input and output             */
    GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT,                                                             /*!< GPIO mode : input only                           */
    GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT,                                                           /*!< GPIO mode : output only mode                     */
    GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)),                               /*!< GPIO mode : output only with open-drain mode     */
    GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/
    GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT)),                         /*!< GPIO mode : output and input mode                */
} gpio_mode_t;

typedef enum {
    GPIO_PULLUP_DISABLE = 0x0,     /*!< Disable GPIO pull-up resistor */
    GPIO_PULLUP_ENABLE = 0x1,      /*!< Enable GPIO pull-up resistor */
} gpio_pullup_t;

typedef enum {
    GPIO_PULLDOWN_DISABLE = 0x0,   /*!< Disable GPIO pull-down resistor */
    GPIO_PULLDOWN_ENABLE = 0x1,    /*!< Enable GPIO pull-down resistor  */
} gpio_pulldown_t;

/**
 * @brief Configuration parameters of GPIO pad for gpio_config function
 */
typedef struct {
    uint64_t pin_bit_mask;          /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
    gpio_mode_t mode;               /*!< GPIO mode: set input/output mode                     */
    gpio_pullup_t pull_up_en;       /*!< GPIO pull-up                                         */
    gpio_pulldown_t pull_down_en;   /*!< GPIO pull-down                                       */
    gpio_int_type_t intr_type;      /*!< GPIO interrupt type                                  */
} gpio_config_t;

typedef enum {
    GPIO_PULLUP_ONLY,               /*!< Pad pull up            */
    GPIO_PULLDOWN_ONLY,             /*!< Pad pull down          */
    GPIO_PULLUP_PULLDOWN,           /*!< Pad pull up + pull down*/
    GPIO_FLOATING,                  /*!< Pad floating           */
} gpio_pull_mode_t;

typedef enum {
    GPIO_DRIVE_CAP_0       = 0,    /*!< Pad drive capability: weak          */
    GPIO_DRIVE_CAP_1       = 1,    /*!< Pad drive capability: stronger      */
    GPIO_DRIVE_CAP_2       = 2,    /*!< Pad drive capability: medium */
    GPIO_DRIVE_CAP_DEFAULT = 2,    /*!< Pad drive capability: medium */
    GPIO_DRIVE_CAP_3       = 3,    /*!< Pad drive capability: strongest     */
    GPIO_DRIVE_CAP_MAX,
} gpio_drive_cap_t;

typedef void (*gpio_isr_t)(void *);

#ifdef __cplusplus
}
#endif
