/*******************************************************************************
*
*
* File:          demo_gpio.c
* Description： GPIO测试用例源文件
* Version：      V0.1
* Date：         2023-07-27
* Author：       kevin
 *******************************************************************************/

/*******************************************************************************
* 1.Included files
*******************************************************************************/
#include "hal_gpio.h"
#include "tau_delay.h"
#include "tau_log.h"
#include "test_cfg_global.h"

#if _DEMO_GPIO_EN
/*******************************************************************************
* 2.Global constant and macro definitions using #define
*******************************************************************************/
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "gpio-log"

//output
#define GPIO_OUT_TEST                  1
#define GPIO_OUT_IN_CONNECT            0

//input
#define GPIO_IN_INT_SINGLE             0
//IO mode init
#define GPIO_MODE_INIT                 0

/*******************************************************************************
* 3.Global structures, unions and enumerations using typedef
*******************************************************************************/

/*******************************************************************************
* 4.Global variable extern declarations
*******************************************************************************/
static bool s_gpio_callback_flag = false;
static sys_cfg_trigger_e s_gpio_trig = DETECT_HIGH_LVL;
static io_pad_e s_gpio_demo_pad1 = IO_PAD_AP_TPRSTN;
static io_pad_e s_gpio_demo_pad2 = IO_PAD_AP_PWMEN;

/*******************************************************************************
* 5.Global function prototypes
*******************************************************************************/

/**************************************************************************
* @name : demo_gpio_callback
* @brief : 测试回调函数
* @param[in] :
* @return :
* @retval :
**************************************************************************/
static void demo_gpio_callback(void *data)
{
    gpio_int_e type = *(gpio_int_e *)data;
    gpio_int_e int_type = hal_gpio_get_int_type(s_gpio_demo_pad1);

    TAU_LOGI("demo_gpio_callback type:%d, int_type:%d, s_gpio_trig:%d\r\n", type, int_type, s_gpio_trig);

    hal_gpio_ctrl_eint(s_gpio_demo_pad1, DISABLE);

    if (DETECT_HIGH_LVL == s_gpio_trig)
    {
        hal_gpio_set_output_data(s_gpio_demo_pad2, IO_LVL_LOW);
    }
    else if (DETECT_LOW_LVL == s_gpio_trig)
    {
        hal_gpio_set_output_data(s_gpio_demo_pad2, IO_LVL_HIGH);
    }

    switch (s_gpio_trig)
    {
    case DETECT_HIGH_LVL:
        s_gpio_trig = DETECT_LOW_LVL;
        break;

    case DETECT_LOW_LVL:
        s_gpio_trig = DETECT_RISING_EDGE;
        break;

    case DETECT_RISING_EDGE:
        s_gpio_trig = DETECT_FALLING_EDGE;
        break;

    default:
        return;
    }

    s_gpio_callback_flag = true;
}

/**************************************************************************
* @name : demo_gpio_int
* @brief : gpio测试中断通用配置
* @param[in] :
* @return :
* @retval :
**************************************************************************/
static void demo_gpio_int(io_pad_e pad, sys_cfg_trigger_e trig)
{
    /*1.关闭中断*/
    hal_gpio_ctrl_eint(pad, DISABLE);

    /*2.中断初始化*/
    hal_gpio_init_eint(pad, trig);

    /*3.注册回调*/
    hal_gpio_reg_eint_cb(pad, demo_gpio_callback);

    /*4.使能中断*/
    hal_gpio_ctrl_eint(pad, ENABLE);
}

/**************************************************************************
* @name : demo_gpio_out_case
* @brief : gpio output功能测试
* @param[in] :
* @return :
* @retval :
**************************************************************************/
static void demo_gpio_out_case(void)
{
    gpio_level_e flag = IO_LVL_LOW;

    TAU_LOGI("demo_gpio_out_case\r\n");

    hal_gpio_init_output(s_gpio_demo_pad1, flag);
    while (1)
    {
        delayMs(10);
        flag = (flag == IO_LVL_LOW) ? IO_LVL_HIGH : IO_LVL_LOW;
        hal_gpio_set_output_data(s_gpio_demo_pad1, flag);
    }
}

/**************************************************************************
* @name : demo_gpio_in_case
* @brief : gpio input功能测试
* @param[in] :
* @return :
* @retval :
**************************************************************************/
static void demo_gpio_in_case(void)
{
    gpio_level_e flag = IO_LVL_LOW;

    TAU_LOGI("demo_gpio_in_case\r\n");

    hal_gpio_init_input(s_gpio_demo_pad1);
    hal_gpio_init_output(s_gpio_demo_pad2, flag);
    while (1)
    {
        delayMs(10);
        flag = (flag == IO_LVL_LOW) ? IO_LVL_HIGH : IO_LVL_LOW;
        hal_gpio_set_output_data(s_gpio_demo_pad2, flag);
    }
}

/**************************************************************************
* @name : demo_gpio_int_single
* @brief : gpio input配置单个中断
* @param[in] :
* @return :
* @retval :
**************************************************************************/
static void demo_gpio_int_single(void)
{
    sys_cfg_trigger_e trig = s_gpio_trig;

    TAU_LOGI("demo_gpio_int_single trig:%d\r\n", trig);

    if (DETECT_HIGH_LVL == s_gpio_trig || DETECT_RISING_EDGE == s_gpio_trig)
    {
        hal_gpio_init_output(s_gpio_demo_pad2, IO_LVL_LOW);
    }
    else if (DETECT_LOW_LVL == s_gpio_trig || DETECT_FALLING_EDGE == s_gpio_trig)
    {
        hal_gpio_init_output(s_gpio_demo_pad2, IO_LVL_HIGH);
    }

    demo_gpio_int(s_gpio_demo_pad1, trig);

    if (DETECT_HIGH_LVL == s_gpio_trig || DETECT_RISING_EDGE == s_gpio_trig)
    {
        delayMs(100);
        hal_gpio_set_output_data(s_gpio_demo_pad2, IO_LVL_HIGH);
    }
    else if (DETECT_LOW_LVL == s_gpio_trig || DETECT_FALLING_EDGE == s_gpio_trig)
    {
        delayMs(100);
        hal_gpio_set_output_data(s_gpio_demo_pad2, IO_LVL_LOW);
    }
}

/**
* @brief  GPIO初始化配置,根据实际原理图提前配置IO功能以及状态,默认功能可不配置
*         TP相关I2C/SPI 在tp_transfer.c
* @param  none
* @retval none
*/
static void demo_gpio_init(void)
{
    io_pad_attr_t attrs[] =
    {
        //1.配置成GPIO 输出
        {IO_PIN_8,  PIN8_MODE_GPIO7,    IO_IOE_OUTPUT, IO_LVL_LOW},   /* PIN_8(TD_RSTN), GPIO,输出,低电平 */
        {IO_PIN_17, PIN17_MODE_GPIO8,   IO_IOE_OUTPUT, IO_LVL_LOW},   /* PIN_17(PWMEN), GPIO,输出,低电平 */
        {IO_PIN_16, PIN16_MODE_GPIO2,   IO_IOE_OUTPUT, IO_LVL_LOW},   /* PIN_16(AP_INT),GPIO,输出,低电平 */

        //2.配置成GPIO 输入
        {IO_PIN_29, PIN29_MODE_GPIO3,   IO_IOE_INPUT, IO_LVL_NONE},   /* PIN_29(AP_TE), GPIO,输入 */

        //3.配置UART TX
        {IO_PIN_2, PIN2_MODE_UART0_TX, IO_IOE_NONE, IO_LVL_NONE},      /* PIN_2(UART0_TX), UART,TX  */

        //4.配置I2C
        {IO_PIN_5, PIN5_MODE_I2C1_SCL, IO_IOE_NONE, IO_LVL_NONE},      /* PIN_5(TD_SPIM_CLK), I2C,SCL  */
        {IO_PIN_6, PIN6_MODE_I2C1_SDA, IO_IOE_NONE, IO_LVL_NONE},      /* PIN_6(TD_SPIM_CSN), I2C,SDA  */

        //5.配置SPIS
        {IO_PIN_30, PIN30_MODE_SPIS_MISO, IO_IOE_NONE, IO_LVL_NONE},   /* PIN_30(AP_SPIS_MISO), SPIS,MISO  */
        {IO_PIN_31, PIN31_MODE_SPIS_CSN,  IO_IOE_NONE, IO_LVL_NONE},   /* PIN_31(AP_SPIS_CSN), SPIS,CSN  */
        {IO_PIN_32, PIN32_MODE_SPIS_SCLK, IO_IOE_NONE, IO_LVL_NONE},   /* PIN_32(AP_SPIS_CLK), SPIS,CLK  */
        {IO_PIN_33, PIN33_MODE_SPIS_MOSI, IO_IOE_NONE, IO_LVL_NONE}    /* PIN_33(AP_SPIS_MOSI), SPIS,MOSI  */
    };
    uint8_t size = sizeof(attrs) / sizeof(io_pad_attr_t);
    hal_gpio_config_pad(attrs, size);
}


/**************************************************************************
* @name : demo_gpio_case
* @brief : 测试用例
* @param[in] :
* @return :
* @retval :
**************************************************************************/
void demo_gpio_case(void)
{
    s_gpio_callback_flag = true;

#if GPIO_IN_INT_SINGLE
    while (1)
    {
        if (s_gpio_callback_flag)
        {
            s_gpio_callback_flag = false;
            demo_gpio_int_single();
        }
    }
#elif GPIO_OUT_TEST
    demo_gpio_out_case();
#elif GPIO_OUT_IN_CONNECT
    demo_gpio_in_case();
#elif GPIO_MODE_INIT
    demo_gpio_init();
#endif
}

#endif

