#ifndef _IO_HAL_GPIO_COMMON_H_
#define _IO_HAL_GPIO_COMMON_H_

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#define EXTI_INTF_ENB
#define GPIO_INTF_ENB

typedef enum
{
   IOAL_GPIO_MODE_INPUT,
   IOAL_GPIO_MODE_OUTPUT_PP,
   IOAL_GPIO_MODE_OUTPUT_OD,
   IOAL_GPIO_MODE_IT_RISING,
   IOAL_GPIO_MODE_IT_FALLING,
   IOAL_GPIO_MODE_IT_RISING_FALLING,
   IOAL_GPIO_MODE_MAX
}ioal_gpio_mode;

typedef enum
{
   IOAL_GPIO_NOPULL,
   IOAL_GPIO_PULLUP,
   IOAL_GPIO_PULLDOWN,
   IOAL_PULL_MAX
}ioal_pull_cfg;

typedef enum
{
    IOAL_GPIO_PIN_1,
    IOAL_GPIO_PIN_2,
    IOAL_GPIO_PIN_3,
    IOAL_GPIO_PIN_4,
    IOAL_GPIO_PIN_5,
    IOAL_GPIO_PIN_6,
    IOAL_GPIO_PIN_7,
    IOAL_GPIO_PIN_8,
    IOAL_GPIO_PIN_9,
    IOAL_GPIO_PIN_10,
    IOAL_GPIO_PIN_11,
    IOAL_GPIO_PIN_12,
    IOAL_GPIO_PIN_13,
    IOAL_GPIO_PIN_14,
    IOAL_GPIO_PIN_15,
    IOAL_GPIO_PIN_16,
    IOAL_GPIO_PIN_17,
    IOAL_GPIO_PIN_18,
    IOAL_GPIO_PIN_19,
    IOAL_GPIO_PIN_20,
    IOAL_GPIO_PIN_21,
    IOAL_GPIO_PIN_22,
    IOAL_GPIO_PIN_23,
    IOAL_GPIO_PIN_24,
    IOAL_GPIO_PIN_25,
    IOAL_GPIO_PIN_26,
    IOAL_GPIO_PIN_27,
    IOAL_GPIO_PIN_28,
    IOAL_GPIO_PIN_29,
    IOAL_GPIO_PIN_30,
    IOAL_GPIO_PIN_31,
    IOAL_GPIO_PIN_32,
    IOAL_GPIO_PIN_33,
    IOAL_GPIO_PIN_34,
    IOAL_GPIO_PIN_35,
    IOAL_GPIO_PIN_36,
    IOAL_GPIO_PIN_37,
    IOAL_GPIO_PIN_38,
    IOAL_GPIO_PIN_39,
    IOAL_GPIO_PIN_40,
    IOAL_GPIO_PIN_41,
    IOAL_GPIO_PIN_42,
    IOAL_GPIO_PIN_43,
    IOAL_GPIO_PIN_44,
    IOAL_GPIO_PIN_45,
    IOAL_GPIO_PIN_46,
    IOAL_GPIO_PIN_47,
    IOAL_GPIO_PIN_48,
    IOAL_GPIO_PIN_49,
    IOAL_GPIO_PIN_50,
    IOAL_GPIO_PIN_51,
    IOAL_GPIO_PIN_52,
    IOAL_GPIO_PIN_53,
    IOAL_GPIO_PIN_54,
    IOAL_GPIO_PIN_55,
    IOAL_GPIO_PIN_56,
    IOAL_GPIO_PIN_57,
    IOAL_GPIO_PIN_58,
    IOAL_GPIO_PIN_59,
    IOAL_GPIO_PIN_60,
    IOAL_GPIO_PIN_61,
    IOAL_GPIO_PIN_62,
    IOAL_GPIO_PIN_63,
    IOAL_GPIO_PIN_64,
    IOAL_GPIO_PIN_65,
    IOAL_GPIO_PIN_66,
    IOAL_GPIO_PIN_67,
    IOAL_GPIO_PIN_68,
    IOAL_GPIO_PIN_69,
    IOAL_GPIO_PIN_70,
    IOAL_GPIO_PIN_71,
    IOAL_GPIO_PIN_72,
    IOAL_GPIO_PIN_73,
    IOAL_GPIO_PIN_74,
    IOAL_GPIO_PIN_75,
    IOAL_GPIO_PIN_76,
    IOAL_GPIO_PIN_77,
    IOAL_GPIO_PIN_78,
    IOAL_GPIO_PIN_79,
    IOAL_GPIO_PIN_80,
    IOAL_GPIO_PIN_81,
    IOAL_GPIO_PIN_82,
    IOAL_GPIO_PIN_83,
    IOAL_GPIO_PIN_84,
    IOAL_GPIO_PIN_85,
    IOAL_GPIO_PIN_86,
    IOAL_GPIO_PIN_87,
    IOAL_GPIO_PIN_88,
    IOAL_GPIO_PIN_89,
    IOAL_GPIO_PIN_90,
    IOAL_GPIO_PIN_91,
    IOAL_GPIO_PIN_92,
    IOAL_GPIO_PIN_93,
    IOAL_GPIO_PIN_94,
    IOAL_GPIO_PIN_95,
    IOAL_GPIO_PIN_96,
    IOAL_GPIO_PIN_97,
    IOAL_GPIO_PIN_98,
    IOAL_GPIO_PIN_99,
    IOAL_GPIO_PIN_100,
    IOAL_GPIO_PIN_101,
    IOAL_GPIO_PIN_102,
    IOAL_GPIO_PIN_103,
    IOAL_GPIO_PIN_104,
    IOAL_GPIO_PIN_105,
    IOAL_GPIO_PIN_106,
    IOAL_GPIO_PIN_107,
    IOAL_GPIO_PIN_108,
    IOAL_GPIO_PIN_109,
    IOAL_GPIO_PIN_110,
    IOAL_GPIO_PIN_111,
    IOAL_GPIO_PIN_112,
    IOAL_GPIO_PIN_113,
    IOAL_GPIO_PIN_114,
    IOAL_GPIO_PIN_115,
    IOAL_GPIO_PIN_116,
    IOAL_GPIO_PIN_117,
    IOAL_GPIO_PIN_118,
    IOAL_GPIO_PIN_119,
    IOAL_GPIO_PIN_120,
    IOAL_GPIO_PIN_121,
    IOAL_GPIO_PIN_122,
    IOAL_GPIO_PIN_123,
    IOAL_GPIO_PIN_124,
    IOAL_GPIO_PIN_125,
    IOAL_GPIO_PIN_126,
    IOAL_GPIO_PIN_127,
    IOAL_GPIO_PIN_128,
    IOAL_GPIO_PIN_129,
    IOAL_GPIO_PIN_130,
    IOAL_GPIO_PIN_131,
    IOAL_GPIO_PIN_132,
    IOAL_GPIO_PIN_133,
    IOAL_GPIO_PIN_134,
    IOAL_GPIO_PIN_135,
    IOAL_GPIO_PIN_136,
    IOAL_GPIO_PIN_137,
    IOAL_GPIO_PIN_138,
    IOAL_GPIO_PIN_139,
    IOAL_GPIO_PIN_140,
    IOAL_GPIO_PIN_141,
    IOAL_GPIO_PIN_142,
    IOAL_GPIO_PIN_143,
    IOAL_GPIO_PIN_144,
    IOAL_GPIO_PIN_145,
    IOAL_GPIO_PIN_146,
    IOAL_GPIO_PIN_147,
    IOAL_GPIO_PIN_148,
    IOAL_GPIO_PIN_149,
    IOAL_GPIO_PIN_150,
    IOAL_GPIO_PIN_151,
    IOAL_GPIO_PIN_152,
    IOAL_GPIO_PIN_153,
    IOAL_GPIO_PIN_154,
    IOAL_GPIO_PIN_155,
    IOAL_GPIO_PIN_156,
    IOAL_GPIO_PIN_157,
    IOAL_GPIO_PIN_158,
    IOAL_GPIO_PIN_159,
    IOAL_GPIO_PIN_160,
    IOAL_GPIO_PIN_161,
    IOAL_GPIO_PIN_162,
    IOAL_GPIO_PIN_163,
    IOAL_GPIO_PIN_164,
    IOAL_GPIO_PIN_165,
    IOAL_GPIO_PIN_166,
    IOAL_GPIO_PIN_167,
    IOAL_GPIO_PIN_168,
    IOAL_MAX_GPIO_PIN

}ioal_gpio_pin_num;

/*!
 * @brief GPIO output logic can be used in iohal_gpio_writepin()
 */
#define GPIO_DRIVE_LOW 0
#define GPIO_DRIVE_HIGH 1

/**
  * @brief ISR_handler function pointer
  */
typedef void (*exti_isr_handler_fptr_t)(void *);

/**
  * @brief External interrupt pointer table structure.
  */
typedef struct
{
  exti_isr_handler_fptr_t isr_handler;              /*!< call back function to be called when interrupt invoked*/
  void *isr_args;						/*!< interface handle of Application hardware drivers*/


} exti_handler_details_t;

/*!
 * @brief GPIO input configuration structure
 */
typedef struct
{
    uint32_t pin_number;       /*!< Specifies the GPIO pins to be configured.
                               This parameter can be any value of @ref GPIO_pins_define */
    uint32_t speed;
    uint32_t mode;          /*!< Specifies the External Interrupt Mode with Input/Rising/Falling edge trigger detection  */
    uint32_t pull_sts;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                               This parameter can be a value of @ref GPIO_pull_define */

    exti_handler_details_t external_int;     /*!< call back function to be called when interrupt invoked*/

}ioal_gpio_config;

typedef enum
{
    IOAL_GPIO_SPEED_FREQ_LOW,
    IOAL_GPIO_SPEED_FREQ_MEDIUM,
    IOAL_GPIO_SPEED_FREQ_HIGH,
    IOAL_GPIO_SPEED_FREQ_VERY_HIGH,
	IOAL_GPIO_SPEED_FREQ_MAX
}ioal_gpio_speed;

typedef enum
{
    IOAL_GPIO_PIN_RESET = 0x0u,
    IOAL_GPIO_PIN_SET,
    IOAL_INVLD_GPIO_PIN_STE
}ioal_gpio_pinstate;

typedef enum
{
    IOAL_GPIO_INPUT_CFG = 0x0u,
    IOAL_GPIO_OUTPUT_CFG,
    IOAL_GPIO_INTERRUPT_CFG
}ioal_gpio_pinconfig;

/**
  * @brief Extracted configuration pin deatils structure.
  *
  */
typedef struct _gpio_port_details
{
    uint16_t port_name;				   /* Contains the port name (i.e) PORTA PORTB... */
    uint16_t port_pin_number;   	   /* Contains the port pin number  (i.e) PIN0, PIN1,,, */
}gpio_port_details;

typedef gpio_port_details* gpio_port_details_hdl;

/*!
 * @brief GPIO pointer table structure
 */
typedef struct _ioal_gpio_gen_info
{
    ioal_gpio_pinconfig mode;         /* operating mode of the GPIO */
    gpio_port_details port;           /* Contains the gpio pin and port details */
}ioal_gpio_gen_info;




void io_hal_gpio_init(ioal_gpio_config* gpio_cfg);
void io_hal_gpio_deinit(uint32_t pin_number);
void io_hal_gpio_writepin(uint32_t pin_number,uint32_t drive_logic);
ioal_gpio_pinstate io_hal_gpio_readpin(uint32_t pin_number);
void io_hal_gpio_togglepin(uint32_t pin_number);
void io_hal_gpio_ptr_table_init(void);



#endif /* _IO_HAL_GPIO_COMMON_H_ */
