/**
 * \file    drv_gpio.h
 * \brief   Driver GPIO interface definition
 *
 * \details All GPIO pins are defined as input by default, except UART
 *
 * \par     Copyright (c) 2017 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2017-04-05
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2017-04-05  Original Creation
 * 
 */
 
#ifndef __DRV_GPIO_H_
#define __DRV_GPIO_H_


#include "types.h"
#include "utils.h"
#include "drv_reg_intf.h"
#include "drv_interrupt.h"
#include "reg_def_gpio.h"


typedef enum drv_gpio_id_e 
{
    DRV_GPIO_0,
    DRV_GPIO_1,
    DRV_GPIO_2,
    DRV_GPIO_3,
    DRV_GPIO_4,
    DRV_GPIO_5,
    DRV_GPIO_6,
    DRV_GPIO_7,
    DRV_GPIO_8,
    DRV_GPIO_9,
    DRV_GPIO_10,
    DRV_GPIO_11,
    DRV_GPIO_12,
    DRV_GPIO_13,
    DRV_GPIO_14,
    DRV_GPIO_15,
    DRV_GPIO_16,
    DRV_GPIO_17,
    DRV_GPIO_18,
    DRV_GPIO_19,
    DRV_GPIO_20,
    DRV_GPIO_21,
    DRV_GPIO_22,
    DRV_GPIO_23,
    DRV_GPIO_24,
    DRV_GPIO_25,
    DRV_GPIO_26,
    DRV_GPIO_27,
    DRV_GPIO_28,
    DRV_GPIO_29,
    DRV_GPIO_30,
    DRV_GPIO_31,
    DRV_GPIO_MAX
} drv_gpio_id_t;


/** GPIO definitions for function 
 *  General PIN     Function PIN    Function PIN    Function PIN        ADC Channel
 *  GPIO[0]                                         PWM2
 *  GPIO[1]                                         PWM3
 *  GPIO[2]
 *  GPIO[3]                                         PWM0                ADC8
 *  GPIO[4]                                         PWM1                ADC15
 *  GPIO[5]			                                DM1                 ADC5
 *  GPIO[6]			                                DP1                 ADC4
 *  GPIO[7]         UART_TXD		DM0                                 ADC3
 *  GPIO[8]         UART_RXD		DP0                                 ADC2
 *  GPIO[9]         I2C_SCL         BIST_TDO
 *  GPIO[10]        I2C_SDA         BIST_TDI
 *  GPIO[11]			
 *  GPIO[12]        UART_CTS        SEC_UART_RXD	                    ADC14
 *  GPIO[13]        UART_RTS        SEC_UART_TXD	                    ADC13
 *  GPIO[14]                                        PWM4
 *  GPIO[15]                                        PWM5
 *  GPIO[16]                                        SPI_SSN0            ADC12
 *  GPIO[17]                                        SPI_SSN1            ADC11
 *  GPIO[18]                        SEC_I2C_SCL     SPI_SSN2            ADC10
 *  GPIO[19]        TCK             SEC_I2C_SDA     SPI_SSN3/SPI_SLV_SSN ADC9
 *  GPIO[20]        TMS                             SPI_SCK
 *  GPIO[21]        TDI                             SPI_MISO
 *  GPIO[22]        TDO                             SPI_MOSI
 *  GPIO[23]        	
 *  GPIO[24]        
 *  GPIO[25]        
 *  GPIO[26]        
 *  GPIO[27]        
 *  GPIO[28]        
 *  GPIO[29]        
 *  GPIO[30]        
 *  GPIO[31]        
 *  VBUS DISCHARGE                                                      ADC7
 *  CSP                                                                 ADC6
 *  CC1                                                                 ADC0
 *  CC2                                                                 ADC1
 */


#define DM1             DRV_GPIO_5
#define DP1             DRV_GPIO_6

#define UART_TXD        DRV_GPIO_7
#define UART_RXD        DRV_GPIO_8

#define DM0             UART_TXD
#define DP0             UART_RXD

#define UART_CTS        DRV_GPIO_12
#define UART_RTS        DRV_GPIO_13

#define SEC_UART_RXD    DRV_GPIO_12
#define SEC_UART_TXD    DRV_GPIO_13

#define I2C_SCL         DRV_GPIO_9
#define I2C_SDA         DRV_GPIO_10

#define SEC_I2C_SCL     DRV_GPIO_18
#define SEC_I2C_SDA     DRV_GPIO_19

/**
 * Get gpio enable state function
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_gpio_en_get(id)     (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_EN_REG),(id)))

/**
 * Enable/disable gpio function
 *
 * \param id        GPIO index
 * \param flg       Enable(1) or disable(0)
 *
 * \see
 */
#define drv_gpio_en_set(id,flg)     drv_reg_field_set(GPIO_EN_REG,(id),1,(flg))

/**
 * Get gpio output function
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_gpio_oe_get(id)     (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_DDR_REG),(id)))

/**
 * Enable/disable gpio output function
 *
 * \param id        GPIO index
 * \param flg       Enable(1) or disable(0), disable will act as input
 *
 * \see
 */
#define drv_gpio_oe_set(id,flg)     drv_reg_field_set(GPIO_DDR_REG,(id),1,(flg))

/**
 * Get gpio pull-down function
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_gpio_pd_get(id)     (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_PD_REG),(id)))

/**
 * Enable/disable gpio pull-down function
 *
 * \param id        GPIO index
 * \param flg       Enable(1) or disable(0)
 *
 * \see
 */
#define drv_gpio_pd_set(id,flg)     drv_reg_field_set(GPIO_PD_REG,(id),1,(flg))


/**
 * Get gpio pull-up function
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_gpio_pu_get(id)     (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_PU_REG),(id)))

/**
 * Enable/disable gpio pull-up function
 *
 * \param id        GPIO index
 * \param flg       Enable(1) or disable(0)
 *
 * \see
 */
#define drv_gpio_pu_set(id,flg)     drv_reg_field_set(GPIO_PU_REG,(id),1,(flg))


typedef enum DRV_GPIO_OD_TYPE_e
{
    DRV_GPIO_OD_TYPE_NORMAL,
    DRV_GPIO_OD_TYPE_NMOS_NO_PU,
    DRV_GPIO_OD_TYPE_NMOS_10KOHM_PU,
    DRV_GPIO_OD_TYPE_NMOS_1KOHM_PU,
    DRV_GPIO_OD_TYPE_MAX,
} DRV_GPIO_OD_TYPE_t;

/**
 * Get gpio open-drain state function
 *
 * \param id        GPIO index
 * \return          DRV_GPIO_OD_TYPE_t
 *
 * \see
 */
DRV_GPIO_OD_TYPE_t drv_gpio_od_get(u32_t id);

/**
 * Enable/disable gpio open-drain function
 *
 * \param id            GPIO index
 * \param flg           DRV_GPIO_OD_TYPE_t: 
 *                          2'b00 : Normal mode;
 *                          2'b01 : NMOS open-drain w/o internal pull-up;
 *                          2'b10 : NMOS open-drain with 10 KOhm pull-up;
 *                          2'b11 : NMOS open-drain with 1 Kohm pull-up.
 *
 * \see
 */
void drv_gpio_od_set(u32_t id, DRV_GPIO_OD_TYPE_t flg);

/**
 * Get gpio input value function
 *
 * \param id        GPIO index
 * \return          High(1) or low(0)
 *
 * \see
 */
int drv_gpio_val_get(int id);

/**
 * Set gpio output value function
 *
 * \param id        GPIO index
 * \param flg       High(1) or low(0)
 *
 * \see
 */
#define drv_gpio_val_set(id,flg)    drv_reg_field_set(GPIO_DR_REG,(id),1,(flg))


/**
 * Get gpio interrupt enable state function
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_gpio_intr_en_get(id)    (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_INT_EN_REG),(id)))

/**
 * Enable/disable gpio interrupt
 *
 * \param id        GPIO index
 * \param flg       Enable(1) or disable(0)
 *
 * \see
 */
void drv_gpio_intr_en_set(int id, int flg);


/**
 * Get gpio interrupt mask
 *
 * \param id        GPIO index
 * \return          Masked(expressions==true) or unmask(expressions==false)
 *
 * \see
 */
#define drv_gpio_intr_mask_get(id)    (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_INT_MASK_REG),(id)))

/**
 * Mask gpio interrupt
 *
 * \param id        GPIO index
 * \param flg       Masked(1) or unmask(0)
 *
 * \see
 */
void drv_gpio_intr_mask_set(int id, int flg);


/**
 * Get gpio interrupt trigger type
 *
 * \param id        GPIO index
 * \return          false:level trigger; true:edge trigger
 *
 * \see
 */
#define drv_gpio_intr_type_get(id)  (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_INT_TYPE_REG),(id)))

/**
 * Set gpio interrupt trigger type
 *
 * \param id        GPIO index
 * \param flg       0:level trigger; 1:edge trigger
 *
 * \see
 */
#define drv_gpio_intr_type_set(id,flg)  drv_reg_field_set(GPIO_INT_TYPE_REG,(id),1,(flg))


/**
 * Get gpio interrupt trigger polarity
 *
 * \param id        GPIO index
 * \return          false:low level or falling edge; true:high level or rising edge
 *
 * \see
 */
#define drv_gpio_intr_polar_get(id) (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_INT_POLAR_REG),(id)))

/**
 * Set gpio interrupt trigger polarity
 *
 * \param id        GPIO index
 * \param flg       0:low level or falling edge; 1:high level or rising edge
 *
 * \see
 */
#define drv_gpio_intr_polar_set(id, flg)   drv_reg_field_set(GPIO_INT_POLAR_REG,(id),1,(flg))


/**
 * Get gpio masked bits
 *
 * \return          Masked bits
 *
 * \see
 */
#define drv_gpio_masked_bits_get()  (DRV_REG_GET(GPIO_BIT_MASK_REG))


/**
 * Get gpio masked bits
 *
 * \param id        GPIO index
 * \return          false:without mask; true:masked
 *
 * \see
 */
#define drv_gpio_bit_mask_get(id)  (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_BIT_MASK_REG),(id)))

/**
 * Set gpio bit mask
 *
 * \param id        GPIO index
 * \param flg       0:unmask; 1:mask
 *
 * \see
 */
#define drv_gpio_bit_mask_set(id,flg)  drv_reg_field_set(GPIO_BIT_MASK_REG,(id),1,(flg))



/**
 * Get gpio raw interrupt status
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_gpio_intr_sta_get(id)    (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_RAW_INT_STATUS_REG),(id)))


/**
 * Get gpio interrupt masked status
 *
 * \param id        GPIO index
 * \return          Masked(expressions==true) or unmask(expressions==false)
 *
 * \see
 */
#define drv_gpio_intr_sta_masked_get(id)    (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_INT_STATUS_REG),(id)))


/** \brief GPIO interrupt handler initialization
 *
 */
void drv_gpio_intr_handler_init(void);


/** \brief GPIO interrupt initialization
 *
 * \param en        Enable(1) or disable(0)
 */
void drv_gpio_intr_init(bool_t en);


/** \brief Set GPIO interrupt handler
 *
 * \param id            GPIO index
 * \param intr_func     interrupt handler
 */
void drv_gpio_intr_handler_set(int id, v_func_ptr_t intr_func);

/** \brief Set GPIO interrupt handler
 *
 * \param id            GPIO index
 * \param intr_func     interrupt handler
 * \param arg           interrupt handler argument
 */
void drv_gpio_intr_handler_with_arg_set(int id, v_func_ptr_t intr_func, u32_t arg);


/**
 * Get GPIO PAD input schmiter buffer enable state function
 *
 * \param id        GPIO index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 */
#define drv_gpio_sen_get(id)    (SAL_IS_BIT_SET(DRV_REG_GET(GPIO_SEN_REG),(id)))

/**
 * Enable/disable GPIO PAD input schmiter buffer enable
 *
 * \param id        GPIO index
 * \param flg       Enable(1) or disable(0)
 */
#define drv_gpio_sen_set(id,flg)  drv_reg_field_set(GPIO_SEN_REG,(id),1,(flg))


typedef enum DRV_GPIO_OUTPUT_DRIVER_e
{
    DRV_GPIO_OUTPUT_DRIVER_4mA,
    DRV_GPIO_OUTPUT_DRIVER_6mA,
    DRV_GPIO_OUTPUT_DRIVER_8mA,
    DRV_GPIO_OUTPUT_DRIVER_10mA,
    DRV_GPIO_OUTPUT_DRIVER_MAX
} DRV_GPIO_OUTPUT_DRIVER_t;

/**
 * Get gpio output driver type
 *
 * \param id        GPIO index
 * \return          DRV_GPIO_OUTPUT_DRIVER_t
 *
 * \see
 */
DRV_GPIO_OUTPUT_DRIVER_t drv_gpio_output_driver_get(u32_t id);

/**
 * Set gpio output driver
 *
 * \param id            GPIO index
 * \param flg           DRV_GPIO_OUTPUT_DRIVER_t:
							GPIO PAD output driver control:
							2'b00 : 4 mA;
							2'b01 : 6 mA;
							2'b10 : 8 mA;
							2'b11 : 10 mA.
 *
 * \see
 */
void drv_gpio_output_driver_set(u32_t id, DRV_GPIO_OUTPUT_DRIVER_t flg);



#endif /* #ifndef __DRV_GPIO_H_ */

