/**
 *file    sys_gpio.c
 *brief   
 * 
 *par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 *author  James
 *date    2018-03-20
 *version 
 * 
 *history 
 *  Date        Note
 *  2018-03-20  Original Creation
 * 
 */

#include "libc.h"
#include "drivers.h"
#include "sys_defs.h"
#include "sys_gpio.h"
#include "sys_config.h"
#include "usbpd.h"

/** GPIO definitions for function 
 *  General PIN     Function PIN    Function PIN    Function PIN        ADC Channel
 *  GPIO[0]         VCONN1_EN                       PWM[2]
 *  GPIO[1]         VCONN2_EN                       PWM[3]
 *  GPIO[2]
 *  GPIO[3]                                         PWM[0]
 *  GPIO[4]                                         PWM[1]
 *  GPIO[5]			
 *  GPIO[6]			
 *  GPIO[7]         UART_TXD		
 *  GPIO[8]         UART_RXD		
 *  GPIO[9]         I2C_SCL         BIST_TDO
 *  GPIO[10]        I2C_SDA         BIST_TDI
 *  GPIO[11]			
 *  GPIO[12]        UART_CTS        SEC_UART_RXD	
 *  GPIO[13]        UART_RTS        SEC_UART_TXD	
 *  GPIO[14]                                        PWM[4]
 *  GPIO[15]                                        PWM[5]
 *  GPIO[16]                                        SPI_SSN[0]
 *  GPIO[17]                                        SPI_SSN[1]
 *  GPIO[18]                        SEC_I2C_SCL     SPI_SSN[2]
 *  GPIO[19]        TCK             SEC_I2C_SDA     SPI_SSN[3]/SPI_SLV_SSN
 *  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]        SOURCE_EN
 *  GPIO[31]    
 */

void sys_gpio_init()
{
    // VBUS EN PIN HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_VBUS_EN,0);
    drv_gpio_oe_set(SYS_IO_VBUS_EN,1);
    drv_gpio_en_set(SYS_IO_VBUS_EN,1);

    // LED VBUS 5V  HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED1,0);
    drv_gpio_oe_set(SYS_IO_LED1,1);
    drv_gpio_en_set(SYS_IO_LED1,1);

    // LED VBUS 9V  HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED2,0);
    drv_gpio_oe_set(SYS_IO_LED2,1);
    drv_gpio_en_set(SYS_IO_LED2,1);

    // LED VBUS 12V  HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED3,0);
    drv_gpio_oe_set(SYS_IO_LED3,1);
    drv_gpio_en_set(SYS_IO_LED3,1);

    // LED VBUS 15V  HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED4,0);
    drv_gpio_oe_set(SYS_IO_LED4,1);
    drv_gpio_en_set(SYS_IO_LED4,1);

    // LED VBUS 20V  HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED5,0);
    drv_gpio_oe_set(SYS_IO_LED5,1);
    drv_gpio_en_set(SYS_IO_LED5,1);

    // LED VBUS PPS  HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED6,0);
    drv_gpio_oe_set(SYS_IO_LED6,1);
    drv_gpio_en_set(SYS_IO_LED6,1);
    // VBUS EN PIN HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_LED7,0);
    drv_gpio_oe_set(SYS_IO_LED7,1);
    drv_gpio_en_set(SYS_IO_LED7,1);

    // VCONN1_EN PIN HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_VCONN1_EN,0);
    drv_gpio_oe_set(SYS_IO_VCONN1_EN,1);
    drv_gpio_en_set(SYS_IO_VCONN1_EN,1);

    // VCONN2_EN PIN HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_VCONN2_EN,0);
    drv_gpio_oe_set(SYS_IO_VCONN2_EN,1);
    drv_gpio_en_set(SYS_IO_VCONN2_EN,1);

    // VBUS DET PIN 
    drv_gpio_oe_set(SYS_IO_VBUS_DET,0);
    drv_gpio_en_set(SYS_IO_VBUS_DET,1);

    // VBUS DC EN PIN LOW EFFECTIVE
    drv_gpio_val_set(SYS_IO_DC_CHIP_EN,1);
    drv_gpio_oe_set(SYS_IO_DC_CHIP_EN,1);
    drv_gpio_en_set(SYS_IO_DC_CHIP_EN,1);

    // SNK REQUEST PIN 
    drv_gpio_oe_set(SYS_IO_SNK_REQUEST,0);
    drv_gpio_en_set(SYS_IO_SNK_REQUEST,1);

    // VBUS DISCHARGE HIGH EFFECTIVE
    drv_gpio_val_set(SYS_IO_VBUS_DISCHARGE,0);
    drv_gpio_oe_set(SYS_IO_VBUS_DISCHARGE,1);
    drv_gpio_en_set(SYS_IO_VBUS_DISCHARGE,1);

    // PWM VOLT CTR
    drv_gpio_en_set(SYS_IO_PWM_350,0);

    //OLED CTR PIN 
    drv_gpio_val_set(SYS_IO_OLED_DC,0);
    drv_gpio_oe_set(SYS_IO_OLED_DC,1);
    drv_gpio_en_set(SYS_IO_OLED_DC,1);

    //OLED RESET PIN 
    drv_gpio_val_set(SYS_IO_OLED_RESET,0);
    drv_gpio_oe_set(SYS_IO_OLED_RESET,1);
    drv_gpio_en_set(SYS_IO_OLED_RESET,1);
    
    //OLED CS PIN 
    drv_gpio_val_set(SYS_IO_SPI_CS,0);
    drv_gpio_oe_set(SYS_IO_SPI_CS,1);
    drv_gpio_en_set(SYS_IO_SPI_CS,1);
    
   //OLED PWM  PIN 
    drv_gpio_en_set(SYS_IO_PWM_OLED,0);
#if 0   
    // VCONN1 EN PIN, high effective
    drv_gpio_val_set(0,0);
    drv_gpio_oe_set(0,1);
    drv_gpio_en_set(0,1);

    // VCONN2 EN PIN, high effective
    drv_gpio_val_set(1,0);
    drv_gpio_oe_set(1,1);
    drv_gpio_en_set(1,1);

    // Enable UART1 for standard input/output
    drv_gpio_en_set(12,0);
    drv_gpio_en_set(13,0);

    // SOURCE EN PIN, high effective
    drv_gpio_val_set(30,0);
    drv_gpio_oe_set(30,1);
    drv_gpio_en_set(30,1);

    drv_gpio_en_set(2,0);
    drv_gpio_en_set(3,0);
    drv_gpio_en_set(4,0);
    drv_gpio_en_set(5,0);
    drv_gpio_en_set(6,0);
    
    drv_gpio_en_set(11,0);
    drv_gpio_en_set(14,0);
    drv_gpio_en_set(15,0);
    drv_gpio_en_set(16,0);
    drv_gpio_en_set(17,0);
#if SYS_SMG_DISPLAY_ENABLED  /* modified by James Gan - 2019-09-03 */
    drv_gpio_oe_set(18,0);
    drv_gpio_en_set(18,1);
    drv_gpio_oe_set(19,0);
    drv_gpio_en_set(19,1);
    drv_gpio_oe_set(20,0);
    drv_gpio_en_set(20,1);
    drv_gpio_oe_set(21,0);
    drv_gpio_en_set(21,1);
    drv_gpio_oe_set(22,0);
    drv_gpio_en_set(22,1);
#else
    drv_gpio_en_set(18,0);
    drv_gpio_en_set(19,0);
    drv_gpio_en_set(20,0);
    drv_gpio_en_set(21,0);
    drv_gpio_en_set(22,0);
#endif /* #if SYS_SMG_DISPLAY_ENABLED */
    drv_gpio_en_set(23,0);
    drv_gpio_en_set(24,0);
    drv_gpio_en_set(25,0);
    drv_gpio_en_set(26,0);
    drv_gpio_en_set(29,0);
    drv_gpio_en_set(31,0);
#endif
    drv_chip_dp0_500kohm_pull_down_set(TRUE);
    //drv_chip_dp1_500kohm_pull_down_set(TRUE);
}

void sys_gpio_uart0_enable_set(bool_t en)
{
    bool_t old = drv_gpio_en_get(UART_RXD) ? FALSE : TRUE;
    if (old != en)
    {
        if (en)
        {
            drv_gpio_en_set(UART_TXD,FALSE);
            drv_gpio_pd_set(UART_TXD,FALSE);
            drv_gpio_pu_set(UART_TXD,FALSE);

            drv_gpio_en_set(UART_RXD,FALSE);
            drv_gpio_pd_set(UART_RXD,FALSE);
            drv_gpio_pu_set(UART_RXD,FALSE);

#if SYS_QUICK_CHARGE_ENABLED
            if (!usbpd_cfg_port_quick_charge_en_get())
            {
                drv_chip_dp0_dm0_short_set(FALSE);
            }
#else
            drv_chip_dp0_dm0_short_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        }
        else {
            drv_gpio_en_set(UART_TXD,TRUE);
            drv_gpio_oe_set(UART_TXD,FALSE);

            drv_gpio_en_set(UART_RXD,TRUE);
            drv_gpio_oe_set(UART_RXD,FALSE);

#if SYS_QUICK_CHARGE_ENABLED
            if (!usbpd_cfg_port_quick_charge_en_get())
            {
                drv_chip_dp0_dm0_short_set(TRUE);
            }
#else
            drv_chip_dp0_dm0_short_set(TRUE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        }
    }
}

void sys_gpio_uart1_enable_set(bool_t en)
{
    bool_t old = drv_gpio_en_get(SEC_UART_RXD) ? FALSE : TRUE;
    if (old != en)
    {
        if (en)
        {
            drv_gpio_en_set(SEC_UART_TXD,FALSE);
            drv_gpio_pd_set(SEC_UART_TXD,FALSE);
            drv_gpio_pu_set(SEC_UART_TXD,FALSE);

            drv_gpio_en_set(SEC_UART_RXD,FALSE);
            drv_gpio_pd_set(SEC_UART_RXD,FALSE);
            drv_gpio_pu_set(SEC_UART_RXD,FALSE);
        }
        else {
            drv_gpio_en_set(SEC_UART_TXD,TRUE);
            drv_gpio_oe_set(SEC_UART_TXD,FALSE);

            drv_gpio_en_set(SEC_UART_RXD,TRUE);
            drv_gpio_oe_set(SEC_UART_RXD,FALSE);
        }
    }
}

void sys_gpio_in_capture_handler_init()
{
    drv_pd_intr_handler_set(DRV_PD_INTR_TYPE_HW_TIMER1_OR_GPIO_CAP0, sys_gpio_in_capture0_isr);
    drv_pd_intr_handler_set(DRV_PD_INTR_TYPE_HW_TIMER2_OR_GPIO_CAP1, sys_gpio_in_capture1_isr);
}

void sys_gpio_in_capture0_isr(u32_t arg)
{
    // TODO: remove, the below code is for test only
    if (sys_cfg_dbg_get())
    {
        drv_uart_puts("IN_CAP0");
    }
}

void sys_gpio_in_capture1_isr(u32_t arg)
{
    // TODO: remove, the below code is for test only
    if (sys_cfg_dbg_get())
    {
        drv_uart_puts("IN_CAP1");
    }
}


void sys_gpio_uart0_disable(void)
{
    if ((dpm_vbus_volt_get() > 2500U) &&
        (drv_flash_firmware_is_unbroken()))
    {
        drv_gpio_en_set(UART_TXD,TRUE);
        drv_gpio_pd_set(UART_TXD,FALSE);
        drv_gpio_oe_set(UART_TXD,FALSE);

        drv_gpio_en_set(UART_RXD,TRUE);
        drv_gpio_pd_set(UART_RXD,FALSE);
        drv_gpio_oe_set(UART_RXD,FALSE);
        drv_chip_dp0_dm0_short_set(TRUE);
    }
}

void sys_gpio_uart0_enable(void)
{
    drv_gpio_en_set(UART_TXD,FALSE);
    drv_gpio_pd_set(UART_TXD,FALSE);
    drv_gpio_pu_set(UART_TXD,FALSE);

    drv_gpio_en_set(UART_RXD,FALSE);
    drv_gpio_pd_set(UART_RXD,FALSE);
    drv_gpio_pu_set(UART_RXD,FALSE);
    drv_chip_dp0_dm0_short_set(FALSE);
}

#if ((SYS_LED_ENABLED)&&(!SYS_SMG_DISPLAY_ENABLED))

// IO map for source capacity LEDs
const u8_t src_cap_led_iomap[SYS_LED_NUM] = {SYS_IO_LED1,SYS_IO_LED2,SYS_IO_LED3,SYS_IO_LED4,SYS_IO_LED5,SYS_IO_LED6,SYS_IO_LED7};

void sys_gpio_src_cap_led_control(u32_t bitmap)
{
    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_1))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_1],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_1],FALSE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_2))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_2],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_2],FALSE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_3))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_3],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_3],FALSE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_4))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_4],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_4],FALSE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_5))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_5],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_5],FALSE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_6))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_6],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_6],FALSE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_SRC_CAP_LED_7))
    {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_7],TRUE);
    }
    else {
        drv_gpio_val_set(src_cap_led_iomap[SYS_GPIO_SRC_CAP_LED_7],FALSE);
    }
}


#endif


